From b5534788d16036ae811c4b8c21ed9dff289a8ef2 Mon Sep 17 00:00:00 2001 From: Sergiotarxz Date: Mon, 10 Jul 2023 00:04:30 +0200 Subject: [PATCH] Primitive conversations now working. --- js-src/components/bottom-panel.tsx | 14 ++++- js-src/components/game.tsx | 2 +- js-src/output-packet/talk.ts | 30 +++++++++ js-src/talk-npc.ts | 6 ++ lib/LasTres/CombatCapableEntity.pm | 15 ++++- .../Controller/Websocket/InputPacket/Talk.pm | 63 +++++++++++++++++++ lib/LasTres/Schema/Result/PJ.pm | 29 +++++---- lib/LasTres/TalkingNPC.pm | 2 +- lib/LasTres/TalkingNPC/AncianoTribuLima.pm | 29 ++++++--- lib/LasTres/Word/Devota.pm | 5 ++ public/js/bundle.js | 14 ++++- 11 files changed, 181 insertions(+), 28 deletions(-) create mode 100644 js-src/output-packet/talk.ts create mode 100644 js-src/talk-npc.ts create mode 100644 lib/LasTres/Controller/Websocket/InputPacket/Talk.pm diff --git a/js-src/components/bottom-panel.tsx b/js-src/components/bottom-panel.tsx index 2238b67..3a6756f 100644 --- a/js-src/components/bottom-panel.tsx +++ b/js-src/components/bottom-panel.tsx @@ -4,6 +4,7 @@ import type { Action, ActionHash } from '@lastres/action' import type { TalkNPCs, TalkNPC } from '@lastres/talk-npc' import OutputPacketExecuteAction from '@lastres/output-packet/execute_action' +import OutputPacketTalk from '@lastres/output-packet/talk'; import PresentationItem from '@lastres/components/presentation-item' import Presentation from '@lastres/components/presentation' @@ -81,6 +82,13 @@ export default function BottomPanel (props: BottomPanelProps): JSX.Element {
} + + function onWordlesslyTalk (npc: TalkNPC): void { + if (props.websocket === null) { + return + } + new OutputPacketTalk(npc.identifier).send(props.websocket) + } function printTalkNpcs (): JSX.Element { const npcs = props.talkNPCs if (npcs === null) { @@ -102,8 +110,10 @@ export default function BottomPanel (props: BottomPanelProps): JSX.Element {
- - + +
diff --git a/js-src/components/game.tsx b/js-src/components/game.tsx index 6a01866..ed4f1d1 100644 --- a/js-src/components/game.tsx +++ b/js-src/components/game.tsx @@ -76,7 +76,7 @@ export default function Game (props: GameProps): JSX.Element { return } window.clearInterval(interval) - }, 100000) + }, 50000) } const inputPackets = new InputPackets(setTeamPJs, setEnemyTeamPJs, setIsBattling, diff --git a/js-src/output-packet/talk.ts b/js-src/output-packet/talk.ts new file mode 100644 index 0000000..cb039c2 --- /dev/null +++ b/js-src/output-packet/talk.ts @@ -0,0 +1,30 @@ +import OutputPacket from '@lastres/output-packet' + +export interface OutputPacketTalkData { + npc: string + word?: string +} + +export default class OutputPacketTalk extends OutputPacket { + npc: string + word: string | null + constructor (npc: string, word: string | null = null) { + super() + this.npc = npc + this.word = word + } + + command (): string { + return 'talk' + } + + data (): OutputPacketTalkData { + const output: OutputPacketTalkData = { + npc: this.npc + } + if (this.word !== null) { + output.word = this.word + } + return output + } +} diff --git a/js-src/talk-npc.ts b/js-src/talk-npc.ts new file mode 100644 index 0000000..faad985 --- /dev/null +++ b/js-src/talk-npc.ts @@ -0,0 +1,6 @@ +export type TalkNPCs = Record +export interface TalkNPC { + icon?: string + name: string + identifier: string +} diff --git a/lib/LasTres/CombatCapableEntity.pm b/lib/LasTres/CombatCapableEntity.pm index 04d4554..cb8e87c 100644 --- a/lib/LasTres/CombatCapableEntity.pm +++ b/lib/LasTres/CombatCapableEntity.pm @@ -15,10 +15,23 @@ requires( 'uuid', 'race_string', 'nick', 'born_stats', 'health', 'mana', 'training_stats', 'experience', 'combat_action', 'combat_target', 'team', - 'gain_experience', 'update_team_sprites', 'get_from_storage', + 'gain_experience', 'get_from_storage', ); +## OVERRIDE +sub update_location { +} + +## OVERRIDE +sub update_actions { +} + +## OVERRIDE sub append_log_line { +} + +## OVERRIDE +sub update_team_sprites { } sub race ($self) { diff --git a/lib/LasTres/Controller/Websocket/InputPacket/Talk.pm b/lib/LasTres/Controller/Websocket/InputPacket/Talk.pm new file mode 100644 index 0000000..c346931 --- /dev/null +++ b/lib/LasTres/Controller/Websocket/InputPacket/Talk.pm @@ -0,0 +1,63 @@ +package LasTres::Controller::Websocket::InputPacket::Talk; + +use v5.36.0; +use strict; +use warnings; +use utf8; + +use Moo; +use List::AllUtils; + +use JSON qw/to_json/; + +sub identifier { + return 'talk'; +} + +sub handle ( $self, $ws, $session, $data ) { + if ( ref $data ne 'HASH' ) { + return $ws->send( to_json( { error => "Data should be a hashref." } ) ); + } + if ( !defined $session->{pj} ) { + return $ws->send( + to_json( { error => 'The pj for this session does not exist.' } ) ); + } + $session->{pj} = $session->{pj}->get_from_storage; + my $pj = $session->{pj}; + my $npc_identifier = $data->{npc}; + if ( !defined $npc_identifier ) { + return $ws->send( + to_json( { error => 'You did not send a npc to talk with.' } ) ); + } + my $available_npcs = $pj->talk_npcs; + my $npc = $available_npcs->{$npc_identifier}; + if ( !defined $npc ) { + return $ws->send( + to_json( + { error => 'The npc you sent is not available to talk with.' } + ) + ); + } + my $possible_word_identifier = $data->{word}; + if ( !defined $possible_word_identifier ) { + $self->handle_wordlessly_talk( $ws, $pj, $npc ); + return; + } + return $ws->send( + to_json( { error => 'Sending a word still not supported.' } ) ); +} + +sub handle_wordlessly_talk ( $self, $ws, $pj, $npc ) { + $npc->talk( $pj, undef ); + $self->end_conversation($pj); +} + +sub end_conversation ( $self, $pj ) { + my $team = $pj->team; + for my $member ( $team->combat_members->@* ) { + $pj->update_location; + $pj->update_actions; + $pj->update_team_sprites; + } +} +1; diff --git a/lib/LasTres/Schema/Result/PJ.pm b/lib/LasTres/Schema/Result/PJ.pm index 7a3adc1..0bb0f10 100644 --- a/lib/LasTres/Schema/Result/PJ.pm +++ b/lib/LasTres/Schema/Result/PJ.pm @@ -160,7 +160,7 @@ sub teach_word ( $self, $word ) { } my $known_word = $result_set_words->new( { identifier => $word->identifier, owner => $self->uuid } ); - $known_word->insert; + $known_word->insert_or_update; my $team = $self->team; $team->append_log_line([ { @@ -205,18 +205,19 @@ sub knows_location ( $self, $location ) { sub set_known_location ( $self, $location ) { require LasTres::Schema; my $array = $location->to_array; - my ( $planet, $super_area, $area ) = @$array[ 0 .. 2 ]; - $location = $array->[3]; + my ( $planet, $super_area, $area, $location_id ) = @$array[ 0 .. 3 ]; my $schema = LasTres::Schema->Schema; - $schema->resultset('PJKnownPlaces')->new( - { - owner => $self->uuid, - planet => $planet, - super_area => $super_area, - area => $area, - location => $location - } - )->insert; + if (!$self->knows_location($location)) { + $schema->resultset('PJKnownPlaces')->new( + { + owner => $self->uuid, + planet => $planet, + super_area => $super_area, + area => $area, + location => $location_id + } + )->insert; + } } sub hash ($self) { @@ -559,9 +560,11 @@ sub talk_npcs ($self) { my $team = $self->team; my $location = $team->location; if ( defined $team->battle ) { - return $self->_npc_list_to_hash( \@npcs ); + return {}; } if ( $team->is_moving ) { + # There will be random encounters for + # some movement frames in certain areas. return $self->_npc_list_to_hash( \@npcs ); } my $location_npcs = $location->npcs($self); diff --git a/lib/LasTres/TalkingNPC.pm b/lib/LasTres/TalkingNPC.pm index f024322..a1b1b3a 100644 --- a/lib/LasTres/TalkingNPC.pm +++ b/lib/LasTres/TalkingNPC.pm @@ -136,7 +136,7 @@ sub show_wordlessly_talk_started ( $self, $pj ) { ## OVERRIDE (Always use $self->SUPER::talk.) # You should override with whatever is going to be said # by the npc using send_response_dialog($self,$pj,$array_text) -# and if you want with what happens on talk with +# and.- if you want.- with what happens on talk with # the npc that is not a dialog with the common # append_log_line, is polite to send all # the team members the contents of diff --git a/lib/LasTres/TalkingNPC/AncianoTribuLima.pm b/lib/LasTres/TalkingNPC/AncianoTribuLima.pm index 61f2715..ea91127 100644 --- a/lib/LasTres/TalkingNPC/AncianoTribuLima.pm +++ b/lib/LasTres/TalkingNPC/AncianoTribuLima.pm @@ -10,10 +10,12 @@ use feature 'signatures'; use Moo; use LasTres::Flags; +use LasTres::Word::Devota; -with 'LasTres::TalkingNPC'; +use parent 'LasTres::TalkingNPC'; sub talk ( $self, $pj, $word ) { + $self->SUPER::talk( $pj, $word ); if ( !defined $word ) { $self->wordlessly_talk($pj); return; @@ -32,16 +34,27 @@ sub name { return 'Anciano'; } +sub verb ( $self, $pj ) { + if ( $pj->knows_word( LasTres::Word::Devota->instance ) ) { + return 'indica'; + } + return 'farfulla'; +} + sub wordlessly_talk ( $self, $pj ) { - if ($pj->get_flag(LasTres::Flags::TALKED_WITH_OLD_MAN_AND_LEARNED_TO_SAY_DEVOTA)) { - $self->send_response_dialog([ - { - text => '¿A que esperas, ve a hablar con la Devota?' - } - ]); + if ( $pj->knows_word( LasTres::Word::Devota->instance ) ) { + $self->send_response_dialog( + $pj, + [ + { + text => '¿A que esperas? Ve a hablar con la Devota.' + } + ] + ); return; } $self->send_response_dialog( + $pj, [ { text => ( @@ -57,6 +70,6 @@ sub wordlessly_talk ( $self, $pj ) { } ] ); - $pj->set_flag(LasTres::Flags::TALKED_WITH_OLD_MAN_AND_LEARNED_TO_SAY_DEVOTA); + $pj->teach_word( LasTres::Word::Devota->instance ); } 1; diff --git a/lib/LasTres/Word/Devota.pm b/lib/LasTres/Word/Devota.pm index 3532e77..c71d993 100644 --- a/lib/LasTres/Word/Devota.pm +++ b/lib/LasTres/Word/Devota.pm @@ -7,6 +7,10 @@ use utf8; use feature 'signatures'; +use Moo; + +with 'LasTres::Word'; + sub name { return 'Devota'; } @@ -14,3 +18,4 @@ sub name { sub identifier { return 'devota'; } +1; diff --git a/public/js/bundle.js b/public/js/bundle.js index 7108641..ac74b3d 100644 --- a/public/js/bundle.js +++ b/public/js/bundle.js @@ -86,7 +86,7 @@ eval("\n\nif (false) {} else {\n module.exports = __webpack_require__(/*! ./cjs \********************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ BottomPanel)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _lastres_output_packet_execute_action__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lastres/output-packet/execute_action */ \"./js-src/output-packet/execute_action.ts\");\n/* harmony import */ var _lastres_components_presentation_item__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @lastres/components/presentation-item */ \"./js-src/components/presentation-item.tsx\");\n/* harmony import */ var _lastres_components_presentation__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @lastres/components/presentation */ \"./js-src/components/presentation.tsx\");\n\n\n\n\nfunction BottomPanel(props) {\n const actionHash = props.actionHash;\n function printListActions() {\n if (actionHash === null) {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null);\n }\n const listOfActionKeys = Object.keys(actionHash).sort((a, b) => {\n const isDisabledComparisionValue = +actionHash[a].is_disabled - +actionHash[b].is_disabled;\n if (isDisabledComparisionValue !== 0) {\n return isDisabledComparisionValue;\n }\n if (actionHash[a].name < actionHash[b].name) {\n return -1;\n }\n if (actionHash[a].name > actionHash[b].name) {\n return 1;\n }\n return 0;\n });\n function printDisabledReason(action) {\n if (!action.is_disabled || action.disabled_reason === null) {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null);\n }\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", { className: \"disabled-reason\", style: { color: 'red' } }, action.disabled_reason));\n }\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null, \"Acciones disponibles.\"),\n listOfActionKeys.map((key) => {\n const style = {};\n const action = actionHash[key];\n if (action.is_disabled) {\n style.background = 'lightgray';\n }\n function onClick() {\n if (action.is_disabled) {\n return;\n }\n if (props.websocket !== null) {\n new _lastres_output_packet_execute_action__WEBPACK_IMPORTED_MODULE_1__[\"default\"](action.identifier)\n .send(props.websocket);\n }\n }\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { onClick: onClick, className: \"action\", style: style, key: action.identifier },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null, action.name),\n printDisabledReason(action));\n }));\n }\n function printAvatar(npc) {\n if (npc.icon === undefined) {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null);\n }\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"avatar\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"img\", { src: npc.icon }),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"shadow\" }));\n }\n function printTalkNpcs() {\n const npcs = props.talkNPCs;\n if (npcs === null) {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null);\n }\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, Object.keys(npcs).map((identifier) => {\n const npc = npcs[identifier];\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { key: npc.identifier, className: \"talk-npc\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"detail\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"name-container\" },\n printAvatar(npc),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"name\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null, npc.name))),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"buttons\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", null, \"Hablar.\"),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", null, \"Decir palabra.\"))));\n })));\n }\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_presentation__WEBPACK_IMPORTED_MODULE_3__[\"default\"], null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_presentation_item__WEBPACK_IMPORTED_MODULE_2__[\"default\"], null, printListActions()),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_presentation_item__WEBPACK_IMPORTED_MODULE_2__[\"default\"], null, printTalkNpcs()),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_presentation_item__WEBPACK_IMPORTED_MODULE_2__[\"default\"], null)));\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/components/bottom-panel.tsx?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ BottomPanel)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _lastres_output_packet_execute_action__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lastres/output-packet/execute_action */ \"./js-src/output-packet/execute_action.ts\");\n/* harmony import */ var _lastres_output_packet_talk__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @lastres/output-packet/talk */ \"./js-src/output-packet/talk.ts\");\n/* harmony import */ var _lastres_components_presentation_item__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @lastres/components/presentation-item */ \"./js-src/components/presentation-item.tsx\");\n/* harmony import */ var _lastres_components_presentation__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @lastres/components/presentation */ \"./js-src/components/presentation.tsx\");\n\n\n\n\n\nfunction BottomPanel(props) {\n const actionHash = props.actionHash;\n function printListActions() {\n if (actionHash === null) {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null);\n }\n const listOfActionKeys = Object.keys(actionHash).sort((a, b) => {\n const isDisabledComparisionValue = +actionHash[a].is_disabled - +actionHash[b].is_disabled;\n if (isDisabledComparisionValue !== 0) {\n return isDisabledComparisionValue;\n }\n if (actionHash[a].name < actionHash[b].name) {\n return -1;\n }\n if (actionHash[a].name > actionHash[b].name) {\n return 1;\n }\n return 0;\n });\n function printDisabledReason(action) {\n if (!action.is_disabled || action.disabled_reason === null) {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null);\n }\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", { className: \"disabled-reason\", style: { color: 'red' } }, action.disabled_reason));\n }\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null, \"Acciones disponibles.\"),\n listOfActionKeys.map((key) => {\n const style = {};\n const action = actionHash[key];\n if (action.is_disabled) {\n style.background = 'lightgray';\n }\n function onClick() {\n if (action.is_disabled) {\n return;\n }\n if (props.websocket !== null) {\n new _lastres_output_packet_execute_action__WEBPACK_IMPORTED_MODULE_1__[\"default\"](action.identifier)\n .send(props.websocket);\n }\n }\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { onClick: onClick, className: \"action\", style: style, key: action.identifier },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null, action.name),\n printDisabledReason(action));\n }));\n }\n function printAvatar(npc) {\n if (npc.icon === undefined) {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null);\n }\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"avatar\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"img\", { src: npc.icon }),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"shadow\" }));\n }\n function onWordlesslyTalk(npc) {\n if (props.websocket === null) {\n return;\n }\n new _lastres_output_packet_talk__WEBPACK_IMPORTED_MODULE_2__[\"default\"](npc.identifier).send(props.websocket);\n }\n function printTalkNpcs() {\n const npcs = props.talkNPCs;\n if (npcs === null) {\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null);\n }\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, Object.keys(npcs).map((identifier) => {\n const npc = npcs[identifier];\n return react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { key: npc.identifier, className: \"talk-npc\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"detail\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"name-container\" },\n printAvatar(npc),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"name\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"p\", null, npc.name))),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"buttons\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", { onClick: () => {\n onWordlesslyTalk(npc);\n } }, \"Hablar\"),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"button\", null, \"Decir palabra\"))));\n })));\n }\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_presentation__WEBPACK_IMPORTED_MODULE_4__[\"default\"], null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_presentation_item__WEBPACK_IMPORTED_MODULE_3__[\"default\"], null, printListActions()),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_presentation_item__WEBPACK_IMPORTED_MODULE_3__[\"default\"], null, printTalkNpcs()),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_presentation_item__WEBPACK_IMPORTED_MODULE_3__[\"default\"], null)));\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/components/bottom-panel.tsx?"); /***/ }), @@ -96,7 +96,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ Game)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _lastres_components_upper_panel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lastres/components/upper-panel */ \"./js-src/components/upper-panel.tsx\");\n/* harmony import */ var _lastres_components_bottom_panel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @lastres/components/bottom-panel */ \"./js-src/components/bottom-panel.tsx\");\n/* harmony import */ var _lastres_components_pj_selection_menu__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @lastres/components/pj-selection-menu */ \"./js-src/components/pj-selection-menu.tsx\");\n/* harmony import */ var _lastres_output_packet_init__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @lastres/output-packet/init */ \"./js-src/output-packet/init.ts\");\n/* harmony import */ var _lastres_output_packet_ping__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @lastres/output-packet/ping */ \"./js-src/output-packet/ping.ts\");\n/* harmony import */ var _lastres_input_packets__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @lastres/input-packets */ \"./js-src/input-packets.ts\");\n\n\n\n\n\n\n\nfunction Game(props) {\n const selectedPJ = props.selectedPJ;\n if (selectedPJ === null) {\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_pj_selection_menu__WEBPACK_IMPORTED_MODULE_3__[\"default\"], { setSelectedPJ: props.setSelectedPJ, userWantsToCreatePJ: props.userWantsToCreatePJ, setUserWantsToCreatePJ: props.setUserWantsToCreatePJ, error: props.error, setError: props.setError })));\n }\n const [teamPJs, setTeamPJs] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [enemyTeamPJs, setEnemyTeamPJs] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [isBattling, setIsBattling] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [currentLocation, setCurrentLocation] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [connectedLocations, setConnectedLocations] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [logLines, setLogLines] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [error, setError] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [scrollLog, setScrollLog] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [movingTo, setMovingTo] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [remainingFrames, setRemainingFrames] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [actionHash, setActionHash] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [talkNPCs, setTalkNPCs] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const logPresentationRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const websocket = props.websocket;\n const setWebsocket = props.setWebsocket;\n window.setTimeout(() => {\n setWebsocket((websocket) => {\n if (websocket === null) {\n console.log('Opening websocket');\n const locationProtocol = window.location.protocol;\n if (locationProtocol == null) {\n return null;\n }\n const protocol = locationProtocol.match(/https:/) != null ? 'wss' : 'ws';\n const webSocket = new WebSocket(`${protocol}://${window.location.host}/ws`);\n webSocket.onopen = () => {\n new _lastres_output_packet_init__WEBPACK_IMPORTED_MODULE_4__[\"default\"](selectedPJ.uuid).send(webSocket);\n let interval = 0;\n interval = window.setInterval(() => {\n if (webSocket.readyState === WebSocket.CONNECTING) {\n return;\n }\n if (webSocket.readyState === WebSocket.OPEN) {\n new _lastres_output_packet_ping__WEBPACK_IMPORTED_MODULE_5__[\"default\"]().send(webSocket);\n return;\n }\n window.clearInterval(interval);\n }, 100000);\n };\n const inputPackets = new _lastres_input_packets__WEBPACK_IMPORTED_MODULE_6__[\"default\"](setTeamPJs, setEnemyTeamPJs, setIsBattling, setCurrentLocation, setConnectedLocations, logLines, setLogLines, setError, setScrollLog, logPresentationRef, setMovingTo, setRemainingFrames, setActionHash, setTalkNPCs);\n webSocket.onmessage = (event) => {\n const packet = JSON.parse(event.data);\n inputPackets.handle(packet);\n };\n webSocket.onerror = (event) => {\n console.log(event);\n };\n webSocket.onclose = (event) => {\n console.log('Websocket closed');\n setWebsocket(null);\n };\n return webSocket;\n }\n return websocket;\n });\n }, 300);\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_upper_panel__WEBPACK_IMPORTED_MODULE_1__[\"default\"], { teamPJs: teamPJs, enemyTeamPJs: enemyTeamPJs, isBattling: isBattling, currentLocation: currentLocation, connectedLocations: connectedLocations, logLines: logLines, websocket: websocket, logPresentationRef: logPresentationRef, movingTo: movingTo, remainingFrames: remainingFrames }),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_bottom_panel__WEBPACK_IMPORTED_MODULE_2__[\"default\"], { actionHash: actionHash, websocket: websocket, talkNPCs: talkNPCs })));\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/components/game.tsx?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ Game)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _lastres_components_upper_panel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @lastres/components/upper-panel */ \"./js-src/components/upper-panel.tsx\");\n/* harmony import */ var _lastres_components_bottom_panel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @lastres/components/bottom-panel */ \"./js-src/components/bottom-panel.tsx\");\n/* harmony import */ var _lastres_components_pj_selection_menu__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @lastres/components/pj-selection-menu */ \"./js-src/components/pj-selection-menu.tsx\");\n/* harmony import */ var _lastres_output_packet_init__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @lastres/output-packet/init */ \"./js-src/output-packet/init.ts\");\n/* harmony import */ var _lastres_output_packet_ping__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @lastres/output-packet/ping */ \"./js-src/output-packet/ping.ts\");\n/* harmony import */ var _lastres_input_packets__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @lastres/input-packets */ \"./js-src/input-packets.ts\");\n\n\n\n\n\n\n\nfunction Game(props) {\n const selectedPJ = props.selectedPJ;\n if (selectedPJ === null) {\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_pj_selection_menu__WEBPACK_IMPORTED_MODULE_3__[\"default\"], { setSelectedPJ: props.setSelectedPJ, userWantsToCreatePJ: props.userWantsToCreatePJ, setUserWantsToCreatePJ: props.setUserWantsToCreatePJ, error: props.error, setError: props.setError })));\n }\n const [teamPJs, setTeamPJs] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [enemyTeamPJs, setEnemyTeamPJs] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [isBattling, setIsBattling] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [currentLocation, setCurrentLocation] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [connectedLocations, setConnectedLocations] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [logLines, setLogLines] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [error, setError] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [scrollLog, setScrollLog] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [movingTo, setMovingTo] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [remainingFrames, setRemainingFrames] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [actionHash, setActionHash] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const [talkNPCs, setTalkNPCs] = react__WEBPACK_IMPORTED_MODULE_0__.useState(null);\n const logPresentationRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const websocket = props.websocket;\n const setWebsocket = props.setWebsocket;\n window.setTimeout(() => {\n setWebsocket((websocket) => {\n if (websocket === null) {\n console.log('Opening websocket');\n const locationProtocol = window.location.protocol;\n if (locationProtocol == null) {\n return null;\n }\n const protocol = locationProtocol.match(/https:/) != null ? 'wss' : 'ws';\n const webSocket = new WebSocket(`${protocol}://${window.location.host}/ws`);\n webSocket.onopen = () => {\n new _lastres_output_packet_init__WEBPACK_IMPORTED_MODULE_4__[\"default\"](selectedPJ.uuid).send(webSocket);\n let interval = 0;\n interval = window.setInterval(() => {\n if (webSocket.readyState === WebSocket.CONNECTING) {\n return;\n }\n if (webSocket.readyState === WebSocket.OPEN) {\n new _lastres_output_packet_ping__WEBPACK_IMPORTED_MODULE_5__[\"default\"]().send(webSocket);\n return;\n }\n window.clearInterval(interval);\n }, 50000);\n };\n const inputPackets = new _lastres_input_packets__WEBPACK_IMPORTED_MODULE_6__[\"default\"](setTeamPJs, setEnemyTeamPJs, setIsBattling, setCurrentLocation, setConnectedLocations, logLines, setLogLines, setError, setScrollLog, logPresentationRef, setMovingTo, setRemainingFrames, setActionHash, setTalkNPCs);\n webSocket.onmessage = (event) => {\n const packet = JSON.parse(event.data);\n inputPackets.handle(packet);\n };\n webSocket.onerror = (event) => {\n console.log(event);\n };\n webSocket.onclose = (event) => {\n console.log('Websocket closed');\n setWebsocket(null);\n };\n return webSocket;\n }\n return websocket;\n });\n }, 300);\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_upper_panel__WEBPACK_IMPORTED_MODULE_1__[\"default\"], { teamPJs: teamPJs, enemyTeamPJs: enemyTeamPJs, isBattling: isBattling, currentLocation: currentLocation, connectedLocations: connectedLocations, logLines: logLines, websocket: websocket, logPresentationRef: logPresentationRef, movingTo: movingTo, remainingFrames: remainingFrames }),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_lastres_components_bottom_panel__WEBPACK_IMPORTED_MODULE_2__[\"default\"], { actionHash: actionHash, websocket: websocket, talkNPCs: talkNPCs })));\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/components/game.tsx?"); /***/ }), @@ -330,6 +330,16 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ }), +/***/ "./js-src/output-packet/talk.ts": +/*!**************************************!*\ + !*** ./js-src/output-packet/talk.ts ***! + \**************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ OutputPacketTalk)\n/* harmony export */ });\n/* harmony import */ var _lastres_output_packet__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @lastres/output-packet */ \"./js-src/output-packet.ts\");\n\nclass OutputPacketTalk extends _lastres_output_packet__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\n constructor(npc, word = null) {\n super();\n this.npc = npc;\n this.word = word;\n }\n command() {\n return 'talk';\n }\n data() {\n const output = {\n npc: this.npc\n };\n if (this.word !== null) {\n output.word = this.word;\n }\n return output;\n }\n}\n\n\n//# sourceURL=webpack://LasTres/./js-src/output-packet/talk.ts?"); + +/***/ }), + /***/ "./js-src/pj.ts": /*!**********************!*\ !*** ./js-src/pj.ts ***!