Files
2026-08-24 22:20:36 +02:00

147 lines
3.7 KiB
JavaScript

const Entity = require("./Entity");
const constants = require("../Data/constants");
const { TYPES, EVENTS, TIMING_EVENTS, MAXIMUM } = constants;
const { ENTITY_TYPE_PLAYER, ENTITY_TYPE_MONSTER } = TYPES;
const { TIMING_EVENT_RESPAWN } = TIMING_EVENTS;
const { EVENT_DIE } = EVENTS;
const { MAX_SAFE_INTEGER } = MAXIMUM;
class Monster extends Entity {
constructor(info) {
super({
type: ENTITY_TYPE_MONSTER,
id: info.id,
map: info.map,
isAlive: true,
position: info.position
});
this.hp = {
maximum: info.maximumHitpoint,
current: info.currentHitpoint
};
this.entityTypeID = info.entityTypeID;
this.parentEntityTypeID = info.parentEntityTypeID ?? 0;
this.respawnTime = info.respawnTime * 1000;
this.isAdmiral = info.isAdmiral ?? false;
this.attackers = [];
this.totalDamageReceived = 0;
this.damageReceived = {};
this.dieCallback = info.dieCallback;
this.attackCallback = info.attackCallback;
this.rewardCallback = info.rewardCallback;
this.reward = info.reward;
const { map, id } = this;
map.monsters.set(id, this);
const nearbyPlayersID = map.getNearbyPlayersGameID(this);
for (let i = 0; i < nearbyPlayersID.length; i++) {
const player = map.getEntityFromSubgroup(nearbyPlayersID[i]);
player.inDistance[id] = 0x01;
};
}
increaseCurrentHitpoint(amount) {
this.hp.current = Math.min(this.hp.maximum, this.hp.current + amount);
return this.hp.current;
}
decreaseCurrentHitpoint(amount, author) {
const { authorID } = author;
amount = Math.abs(amount);
const damage = Math.min(this.hp.current, amount);
if (this.damageReceived[authorID]) this.damageReceived[authorID] += damage;
else this.damageReceived[authorID] = damage;
this.totalDamageReceived += damage;
this.hp.current -= damage;
this.attackCallback({
typeID: this.typeID,
entityTypeID: this.entityTypeID,
authorID,
damage
});
const isOverSafeLimit = this.totalDamageReceived >= MAX_SAFE_INTEGER;
if (isOverSafeLimit) this.totalDamageReceived = MAX_SAFE_INTEGER;
if (this.hp.current === 0 || isOverSafeLimit) {
const die = {
typeID: this.typeID,
lastShotTypeID: 1,
lastShotID: author.authorID,
targetID: this.id,
targetEntityTypeID: this.entityTypeID
};
this.die(die);
// this.setSingleEvent(11, 0, die);
};
return {
normalizedAmount: damage,
currentHitpoint: this.hp.current
};
}
isAtMaximumHitpoints() {
return this.hp.current === this.hp.maximum;
}
die(die) {
super.die();
this.hp.current = 0;
this.attackers.forEach(data => {
const attackerEntity = this.map.getEntityFromSubgroup(data.attackerEntry);
attackerEntity.wipeAttack();
});
this.attackers.length = 0;
this.emit(EVENT_DIE, die, this.id);
const admiralProperties = {
typeID: this.typeID,
entityTypeID: this.entityTypeID,
parentEntityTypeID: this.parentEntityTypeID,
id: this.id,
isAdmiral: this.isAdmiral,
authorID: die.lastShotID
};
this.dieCallback(admiralProperties);
this.removeEvent(11);
this.damageReceived = {};
if (!this.isAdmiral) this.setEvent(TIMING_EVENT_RESPAWN, this.respawnTime);
}
respawn() {
if (this.isAlive) return;
this.hp.current = this.hp.maximum;
super.respawn();
this.removeEvent(TIMING_EVENT_RESPAWN);
}
getProperties() {
const { position, id, hp, type, typeID, isAdmiral, entityTypeID } = this;
return { position, id, hp, type, typeID, isAdmiral, entityTypeID };
}
};
module.exports = Monster;