<commit_before>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

import { initUpdatable, Updatable, executeUpdateCallbacks } from '../../../_baseGame/GameClientModels/_Updatable';

declare global {
  interface EntityStateModel {
    entityID: string;
    name: string;
    isAlive: boolean;
    position: Vec3f;
    statuses: ArrayMap<Status>;
  }

  interface PlayerStateModel extends EntityStateModel {
    type: 'player';
    characterKind: CharacterKind;
    characterID: string;
    health: CurrentMax[];
    blood: CurrentMax;
    stamina: CurrentMax;
    level: number;
    race: Race;
    gender: Gender;
    classID: Archetype;
    currentDeaths: number;
    maxDeaths: number;
    totalKills: number;
    scenarioRoundState: ScenarioRoundState;

    // in world time
    scenarioRoundStateEndTime: number;
    scenarioRoundStateStartTime: number;
  }

  type AnyEntityStateModel = PlayerStateModel;
  type AnyEntityState = Readonly<AnyEntityStateModel> & Updatable;

  type PlayerStateUpdatable = Readonly<PlayerStateModel> & Updatable;
  interface PlayerState extends PlayerStateUpdatable {}

  type ImmutablePlayerState = DeepImmutableObject<PlayerState>;
  type ImmutableEntityState = DeepImmutableObject<AnyEntityStateModel & Updatable>;
}

function defaultEntityStateModel(): EntityStateModel {
  return {
    entityID: '',
    name: 'unknown',
    isAlive: false,
    position: { x: NaN, y: NaN, z: NaN },
    statuses: {},
  };
}

function defaultCurrentMax(): CurrentMax {
  return {
    current: 100,
    max: 100,
  }
}

export function defaultPlayerStateModel(): PlayerStateModel {
  return {
    ...defaultEntityStateModel(),
    type: 'player',
    characterKind: CharacterKind.User,
    characterID: 'default-character-id',
    health: [defaultCurrentMax()],
    stamina: defaultCurrentMax(),
    blood: defaultCurrentMax(),
    level: 1,
    race: Race.PerftestMultiStabber,
    classID: null,
    gender: Gender.Male,
    currentDeaths: 0,
    maxDeaths: 0,
    totalKills: 0,
    scenarioRoundState: ScenarioRoundState.Uninitialized,
    scenarioRoundStateEndTime: 0,
    scenarioRoundStateStartTime: 0,
  };
}

export const EntityState_Update = 'entityState.update';
export const EntityState_Removed = 'entityState.removed';

function onReceiveEntityStateUpdate(state: AnyEntityState) {
  if (game.debug) {
    console.groupCollapsed(`Client > ${EntityState_Update}`);
    try {
      console.log(JSON.stringify(state));
    } catch {}
    console.groupEnd();
  }

  if (typeof hordetest._devGame.entities[state.entityID] === 'undefined') {
    hordetest._devGame.entities[state.entityID] = cloneDeep(state);
    hordetest._devGame.entities[state.entityID].updateEventName = EntityState_Update;
    // init Updatable.
    initUpdatable(hordetest._devGame.entities[state.entityID]);
  } else {
    hordetest._devGame.entities[state.entityID] = cloneDeep(state);
    hordetest._devGame.entities[state.entityID].updateEventName = EntityState_Update;
  }

  if (state.entityID === hordetest.game.selfPlayerState.entityID) {
    executeUpdateCallbacks(hordetest.game.selfPlayerState);
  }

  executeUpdateCallbacks(hordetest._devGame.entities[state.entityID]);
}

function onReceiveEntityStateRemoved(entityID: string) {
  if (game.debug) {
    console.groupCollapsed(`Client > ${EntityState_Removed}`);
    console.log(entityID);
    console.groupEnd();
  }

  if (typeof hordetest._devGame.entities[entityID] === 'undefined') {
    return;
  }

  delete hordetest._devGame.entities[entityID];
}

export default function() {
  if (typeof engine !== 'undefined') {
    engine.on(EntityState_Update, onReceiveEntityStateUpdate);
    engine.on(EntityState_Removed, onReceiveEntityStateRemoved);
  }
}
<commit_msg>Clear entities map in library when the scenario round ends<commit_after>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

import { initUpdatable, Updatable, executeUpdateCallbacks } from '../../../_baseGame/GameClientModels/_Updatable';

declare global {
  interface EntityStateModel {
    entityID: string;
    name: string;
    isAlive: boolean;
    position: Vec3f;
    statuses: ArrayMap<Status>;
  }

  interface PlayerStateModel extends EntityStateModel {
    type: 'player';
    characterKind: CharacterKind;
    characterID: string;
    health: CurrentMax[];
    blood: CurrentMax;
    stamina: CurrentMax;
    level: number;
    race: Race;
    gender: Gender;
    classID: Archetype;
    currentDeaths: number;
    maxDeaths: number;
    totalKills: number;
    scenarioRoundState: ScenarioRoundState;

    // in world time
    scenarioRoundStateEndTime: number;
    scenarioRoundStateStartTime: number;
  }

  type AnyEntityStateModel = PlayerStateModel;
  type AnyEntityState = Readonly<AnyEntityStateModel> & Updatable;

  type PlayerStateUpdatable = Readonly<PlayerStateModel> & Updatable;
  interface PlayerState extends PlayerStateUpdatable {}

  type ImmutablePlayerState = DeepImmutableObject<PlayerState>;
  type ImmutableEntityState = DeepImmutableObject<AnyEntityStateModel & Updatable>;
}

function defaultEntityStateModel(): EntityStateModel {
  return {
    entityID: '',
    name: 'unknown',
    isAlive: false,
    position: { x: NaN, y: NaN, z: NaN },
    statuses: {},
  };
}

function defaultCurrentMax(): CurrentMax {
  return {
    current: 100,
    max: 100,
  }
}

export function defaultPlayerStateModel(): PlayerStateModel {
  return {
    ...defaultEntityStateModel(),
    type: 'player',
    characterKind: CharacterKind.User,
    characterID: 'default-character-id',
    health: [defaultCurrentMax()],
    stamina: defaultCurrentMax(),
    blood: defaultCurrentMax(),
    level: 1,
    race: Race.PerftestMultiStabber,
    classID: null,
    gender: Gender.Male,
    currentDeaths: 0,
    maxDeaths: 0,
    totalKills: 0,
    scenarioRoundState: ScenarioRoundState.Uninitialized,
    scenarioRoundStateEndTime: 0,
    scenarioRoundStateStartTime: 0,
  };
}

export const EntityState_Update = 'entityState.update';
export const EntityState_Removed = 'entityState.removed';

function onReceiveEntityStateUpdate(state: AnyEntityState) {
  if (game.debug) {
    console.groupCollapsed(`Client > ${EntityState_Update}`);
    try {
      console.log(JSON.stringify(state));
    } catch {}
    console.groupEnd();
  }

  if (typeof hordetest._devGame.entities[state.entityID] === 'undefined') {
    hordetest._devGame.entities[state.entityID] = cloneDeep(state);
    hordetest._devGame.entities[state.entityID].updateEventName = EntityState_Update;
    // init Updatable.
    initUpdatable(hordetest._devGame.entities[state.entityID]);
  } else {
    hordetest._devGame.entities[state.entityID] = cloneDeep(state);
    hordetest._devGame.entities[state.entityID].updateEventName = EntityState_Update;
  }

  if (state.entityID === hordetest.game.selfPlayerState.entityID) {
    executeUpdateCallbacks(hordetest.game.selfPlayerState);
  }

  executeUpdateCallbacks(hordetest._devGame.entities[state.entityID]);
}

function onReceiveEntityStateRemoved(entityID: string) {
  if (game.debug) {
    console.groupCollapsed(`Client > ${EntityState_Removed}`);
    console.log(entityID);
    console.groupEnd();
  }

  if (typeof hordetest._devGame.entities[entityID] === 'undefined') {
    return;
  }

  delete hordetest._devGame.entities[entityID];
}

function onScenarioRoundEnd() {
  // Scenario has ended, remove all entities from the list.
  Object.keys(hordetest._devGame.entities).forEach((entityID) => {
    if (typeof hordetest._devGame.entities[entityID] === 'undefined') {
      return;
    }

    delete hordetest._devGame.entities[entityID];
  });
}

export default function() {
  if (typeof engine !== 'undefined') {
    engine.on(EntityState_Update, onReceiveEntityStateUpdate);
    engine.on(EntityState_Removed, onReceiveEntityStateRemoved);
    engine.on('scenarioRoundEnd', onScenarioRoundEnd);
  }
}

{'fraction_non_alphanumeric': 0.11013538236370289, 'fraction_numerical': 0.004146847176484937, 'mean_word_length': 4.2030456852791875, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5041992', 'n_tokens_mistral': 2579, 'n_tokens_neox': 2544, 'n_words': 522}