I am getting some problems regarding classes in my game, although I am serializing things more appropriately, I feel that something is still not quite correct. Here the class…
class Player {
constructor(dataObj: dataObj) {
if (!dataObj) {
throw new TypeError("Data property undefined!")
}
this.data = dataObj;
}
// Return a new instance containing our own data.
clone() {
return new Player(clone(this.data))
}
toJSON() {
return JSON.reviveWrapper('new setup.Player($ReviveData$)', clone(this.data))
}
learnSpell = (newSpell: Spell) => {
const _spell = clone(newSpell)
this.data.spells.push(_spell)
}
getMove = () => {
const _player = variables().player;
if (_player.data.equipments.rightHand[0]) {
const _equipment: Weapon = _player.data.equipments.rightHand[0];
_player.data.myCurMovement = {
type : _equipment.type,
name : _equipment.name,
element : _equipment.elemental.element,
damage : _equipment.elemental.damage(),
setEffect() {
// Basic damage calc, based on enemies primary resistance status
let _damage = Math.round(this.damage - setup.selectedEnemy.data.resistances[this.element])
// enemies armor calc
_damage -= Math.floor(setup.selectedEnemy.data.status.armor - _player.data.attributes.armorPen)
// Hit chance for the player, based on the enemy/player agility
let _hitChance = random(0, setup.selectedEnemy.agility)
if (_player.agility > _hitChance) {
setup.selectedEnemy.health -= _damage;
switch(this.type) {
case 'sword':
return `You wield your sword and in an instant you use your speed, appearing before your enemy and connecting the sword to his body causing ${_damage} damage!.`
}
}
else {
return `You try to hit your opponent with your ${this.name}, applying maximum strength, but at the last moment he manages to escape the attack.`;
}
}
}
}
else {
_player.data.myCurMovement = {
type : "neutral",
name : "none",
element : "physical",
damage : _player.force,
setEffect() {
let _damage = Math.floor(this.damage - setup.selectedEnemy.data.resistances[this.element])
let _hitChance = random(0, setup.selectedEnemy.agility)
if (_player.agility > _hitChance) {
setup.selectedEnemy.health -= _damage;
return `You hit your opponent with your fists, applying maximum strength, doing ${_damage} damage!`;
}
else {
return `You try to hit your opponent with your fists, applying maximum strength, but at the last moment he manages to escape the attack.`;
}
}
}
}
}
// Runs the effects received from enemies
runTempEffect = () => {
const _tempEffect = variables().player.data.tempEffect;
_tempEffect.forEach((effect, index) => {
if (effect.multiEffect) {
effect.setEffect()
}
effect.turns -= 1;
if (effect.turns <= 0) {
effect.removeEffect()
_tempEffect.splice(index, 1)
_tempEffect[index]
? _tempEffect[index].turns--
: ''
}
})
}
getSpell = (spell: Spell) => {
const _player = this;
const _spell = spell.prop;
_spell.countdown[1] = _spell.countdown[0];
_player.data.myCurSpell = {
name : _spell.name,
element : _spell.element,
desc : _spell.desc,
panel : _spell.panel,
cost : _spell.cost,
damage : _spell.damage,
setEffect : _spell.effect,
runEffect() {
const output = this.setEffect()
setup.getBattleMenu()
return output;
}
}
}
hasShield = () => {
if (typeof this.data.equipments.leftHand === 'object') {
return true;
}
}
/*
Inventory functions
*/
addItem = (_item: Weapon | Shield | Equipment) => {
this.data.inventory.push(_item)
}
get invItems() {
const _inventory = this.data.inventory;
const _output: string[] = []
if (_inventory.length > 0) {
_inventory.forEach((item) => {
_output.push(item.name)
})
return _output;
}
else {
return 'You have no items.';
}
}
/*
Getters and setters
*/
get name() {
return this.data.firstName;
}
get surname() {
return this.data.secondName;
}
get sex() {
return this.data.sex;
}
set sex(value) {
this.data.sex = value;
}
get race() {
return this.data.race;
}
set race(value) {
this.data.race = value;
}
get classDesc() {
const desc = this.data.sex + ' ' + this.data.race + ',' + ' ' + this.data.class
return desc;
}
// Experience getter
get experience() {
return this.data.status.experience;
}
set experience(value) {
if (typeof value !== 'number') {
throw new TypeError(`Typeof ${value} is invalid!`)
}
this.data.status.experience = value;
}
get maxExperience() {
return this.data.status.maxExperience;
}
set maxExperience(value) {
if (typeof value !== 'number') {
throw new TypeError(`Typeof ${value} is invalid!`)
}
this.data.status.maxExperience = value;
}
// Body traits
get eyeColor() {
return this.data.body.eyeColor;
}
set eyeColor(value) {
this.data.body.eyeColor = value;
}
get hairColor() {
return this.data.body.hairColor;
}
set hairColor(value) {
this.data.body.hairColor = value;
}
get skinColor() {
return this.data.body.skinColor;
}
set skinColor(value) {
this.data.body.skinColor = value;
}
get health() {
return this.data.status.health;
}
set health(value: number) {
if (typeof value !== 'number') {
throw new TypeError(`Typeof ${value} is invalid!`)
}
this.data.status.health = value;
}
get maxHealth() {
return this.data.status.maxHealth;
}
set maxHealth(value: number) {
this.data.status.maxHealth = value;
}
get energy() {
return this.data.status.energy;
}
set energy(value) {
if (typeof value !== 'number') {
throw new TypeError(`Typeof ${value} is invalid!`)
}
this.data.status.energy = value;
}
get maxEnergy() {
return this.data.status.maxEnergy
}
set maxEnergy(value) {
if (typeof value !== 'number') {
throw new TypeError(`Typeof ${value} is invalid!`)
}
this.data.status.maxEnergy = value;
}
// CurMovement
get myCurMovement() {
return this.data.myCurMovement;
}
set myCurMovement(value) {
this.data.myCurMovement = value;
}
// myCurSpell
get myCurSpell() {
return this.data.myCurSpell;
}
set myCurSpell(value) {
this.data.myCurSpell = value;
}
// TempEffect getters
get tempEffect() {
return this.data.tempEffect;
}
// Get spells
get spells() {
return this.data.spells;
}
// Battle attributes
get force() {
return this.data.attributes.force;
}
set force(value: number) {
this.data.attributes.force = value;
}
get endurance() {
return this.data.attributes.endurance;
}
set endurance(value: number) {
this.data.attributes.endurance = value;
}
get agility() {
return this.data.attributes.agility;
}
set agility(value: number) {
this.data.attributes.agility = value;
}
get intelect() {
return this.data.attributes.intelect;
}
set intelect(value: number) {
this.data.attributes.intelect = value;
}
// Item getters
get weapon(): any {
if (this.data.equipments.rightHand) {
let weapon;
typeof this.data.equipments.rightHand[0] === 'object'
? weapon = this.data.equipments.rightHand[0]
: weapon = false
return weapon;
}
}
set weapon(value: any) {
if (typeof this.data.equipments.rightHand[0] === 'object') {
this.data.equipments.rightHand[0] = value;
}
}
get attackType(): string {
if (typeof this.data.equipments.rightHand[0] === 'object') {
switch(this.data.equipments.rightHand[0].type) {
case "sword":
return "Slash"
default:
return "Attack"
}
}
else {
return "Attack";
}
}
}
During the execution of the getMove function in combat, errors start to appear, such as “random()” is undefined, and “variables” is undefined.
Does this lead me to think that the functions should also be inside the .data object to be serialized correctly? I still don’t fully understand how it works.
Detail, the problems happen only after the save is loaded, so I strongly think that this is due to an error in serialization.