From 3caff338e459f4047e0b79ae6a8b508603ace9f2 Mon Sep 17 00:00:00 2001 From: Leonid Pospelov Date: Sun, 31 Mar 2024 19:52:40 +0500 Subject: [PATCH] refact(skymp5-client): improve types & fix build (#1898) --- .../services/messages/createActorMessage.ts | 42 ++++++++++++++++--- .../src/services/services/remoteServer.ts | 27 ++++++------ skymp5-client/src/view/model.ts | 18 ++------ 3 files changed, 53 insertions(+), 34 deletions(-) diff --git a/skymp5-client/src/services/messages/createActorMessage.ts b/skymp5-client/src/services/messages/createActorMessage.ts index 2b548ad2d8..07f639c5ac 100644 --- a/skymp5-client/src/services/messages/createActorMessage.ts +++ b/skymp5-client/src/services/messages/createActorMessage.ts @@ -4,18 +4,50 @@ import { Inventory } from "../../sync/inventory"; import { Transform } from "../../sync/movement"; import { Animation } from "../../sync/animation"; -export interface CreateActorMessage { +export interface CreateActorMessage extends CreateActorMessageMainProps { type: "createActor"; idx: number; - refrId?: number; baseRecordType: "DOOR" | undefined; // see PartOne.cpp transform: Transform; isMe: boolean; + props?: CreateActorMessageAdditionalProps; +} + +export interface CreateActorMessageMainProps { + refrId?: number; + baseId?: number; appearance?: Appearance; equipment?: Equipment; + animation?: Animation; + inventory?: Inventory; - baseId?: number; isDead?: boolean; - props?: Record; - animation?: Animation; +} + +export interface CreateActorMessageAdditionalProps { + isOpen?: boolean; + isHarvested?: boolean; + setNodeTextureSet?: Record; + disabled?: boolean; + lastAnimation?: string; + displayName?: string; + isHostedByOther?: boolean; + isRaceMenuOpen?: boolean; + learnedSpells?: number[]; + healRate?: number; + healRateMult?: number; + health?: number; + magickaRate?: number; + magickaRateMult?: number; + magicka?: number; + staminaRate?: number; + staminaRateMult?: number; + stamina?: number; + healthPercentage?: number; + staminaPercentage?: number; + magickaPercentage?: number; + templateChain?: number[]; + + inventory?: Inventory; // TODO: take a look why doubles CreateActorMessageMainProps + isDead?: boolean; // TODO: take a look why doubles CreateActorMessageMainProps } diff --git a/skymp5-client/src/services/services/remoteServer.ts b/skymp5-client/src/services/services/remoteServer.ts index 7903cb60c8..134a4e17b5 100644 --- a/skymp5-client/src/services/services/remoteServer.ts +++ b/skymp5-client/src/services/services/remoteServer.ts @@ -49,8 +49,7 @@ import { HostStartMessage } from '../messages/hostStartMessage'; import { HostStopMessage } from '../messages/hostStopMessage'; import { ConnectionMessage } from '../events/connectionMessage'; import { SetInventoryMessage } from '../messages/setInventoryMessage'; -import { CreateActorMessage } from '../messages/createActorMessage'; -import { UpdateGamemodeDataMessage } from '../messages/updateGameModeDataMessage'; +import { CreateActorMessage, CreateActorMessageAdditionalProps } from '../messages/createActorMessage'; import { CustomPacketMessage2 } from '../messages/customPacketMessage2'; import { DestroyActorMessage } from '../messages/destroyActorMessage'; import { SetRaceMenuOpenMessage } from '../messages/setRaceMenuOpenMessage'; @@ -120,7 +119,7 @@ on('update', () => { if (Date.now() - pcInvLastApply > 5000) { pcInvLastApply = Date.now(); const pcInv = getPcInventory(); - if (pcInv) applyInventory(Game.getPlayer() as Actor, pcInv, false, true); + if (pcInv) applyInventory(Game.getPlayer()!, pcInv, false, true); } }); @@ -296,14 +295,14 @@ export class RemoteServer extends ClientListener { // TODO: move to a separate module if (msg.props.setNodeTextureSet) { - const setNodeTextureSet = msg.props.setNodeTextureSet as Record; + const setNodeTextureSet = msg.props.setNodeTextureSet; for (const key in setNodeTextureSet) { const textureSetId = setNodeTextureSet[key]; const firstPerson = false; const textureSet = this.sp.TextureSet.from(Game.getFormEx(textureSetId)); if (textureSet !== null) { - sp.NetImmerse.setNodeTextureSet(refr, key, textureSet, firstPerson); + this.sp.NetImmerse.setNodeTextureSet(refr, key, textureSet, firstPerson); this.logTrace(`Applied texture set ${textureSetId.toString(16)} to ${key}`); } else { this.logError(`Failed to apply texture set ${textureSetId.toString(16)} to ${key}`); @@ -349,9 +348,9 @@ export class RemoteServer extends ClientListener { const i = this.getIdManager().allocateIdFor(msg.idx); if (this.worldModel.forms.length <= i) this.worldModel.forms.length = i + 1; - let movement: Movement = null as unknown as Movement; + let movement: Movement | undefined = undefined; // TODO: better check if it is an npc (not an object reference) - if ((msg.refrId as number) >= 0xff000000) { + if (msg.refrId !== undefined && msg.refrId >= 0xff000000) { movement = { pos: msg.transform.pos, rot: msg.transform.rot, @@ -398,7 +397,7 @@ export class RemoteServer extends ClientListener { if (msg.props) { for (const propName in msg.props) { const i = this.getIdManager().getId(msg.idx); - (form as Record)[propName] = msg.props[propName]; + (form as Record)[propName] = msg.props[propName as keyof CreateActorMessageAdditionalProps]; } } @@ -414,20 +413,20 @@ export class RemoteServer extends ClientListener { const applyPcInv = () => { if (msg.equipment) { - applyEquipment(Game.getPlayer() as Actor, msg.equipment) + applyEquipment(Game.getPlayer()!, msg.equipment) } if (msg.props && msg.props.inventory) this.onSetInventoryMessage({ message: { type: 'setInventory', - inventory: (msg.props as any).inventory as Inventory, + inventory: msg.props.inventory } }); }; - if (msg.isMe && msg.props) { - const learnedSpells = msg.props['learnedSpells'] as Array; + if (msg.isMe && msg.props && msg.props.learnedSpells) { + const learnedSpells = msg.props.learnedSpells; once('update', () => { Utility.wait(1).then(() => { @@ -503,7 +502,7 @@ export class RemoteServer extends ClientListener { applyAppearanceToPlayer(msg.appearance); if (msg.appearance.isFemale) // Fix gender-specific walking anim - (Game.getPlayer() as Actor).resurrect(); + (Game.getPlayer()!).resurrect(); } } @@ -581,7 +580,7 @@ export class RemoteServer extends ClientListener { applyAppearanceToPlayer(msg.appearance); if (msg.appearance.isFemale) // Fix gender-specific walking anim - (Game.getPlayer() as Actor).resurrect(); + (Game.getPlayer()!).resurrect(); } }); } diff --git a/skymp5-client/src/view/model.ts b/skymp5-client/src/view/model.ts index 36fc826cf9..a8f1ac2c46 100644 --- a/skymp5-client/src/view/model.ts +++ b/skymp5-client/src/view/model.ts @@ -3,26 +3,14 @@ import { Animation } from "../sync/animation"; import { Appearance } from "../sync/appearance"; import { Equipment } from "../sync/equipment"; import { Inventory } from "../sync/inventory"; +import { CreateActorMessageMainProps, CreateActorMessageAdditionalProps } from "src/services/messages/createActorMessage"; -export interface FormModel { +// Own properties (not inherited) are being assigned locally +export interface FormModel extends CreateActorMessageAdditionalProps, CreateActorMessageMainProps{ idx?: number; - baseId?: number; - refrId?: number; movement?: Movement; - animation?: Animation; numMovementChanges?: number; - appearance?: Appearance; numAppearanceChanges?: number; - equipment?: Equipment; - isHarvested?: boolean; - isOpen?: boolean; - inventory?: Inventory; - isHostedByOther?: boolean; - isDead?: boolean; - templateChain?: number[]; - lastAnimation?: string; - - // Assigned locally isMyClone?: boolean; }