UNPKG

alclient

Version:

A node client for interacting with Adventure Land - The Code MMORPG. This package extends the functionality of 'alclient' by managing a mongo database.

230 lines 7.29 kB
import { Tools } from "./Tools.js"; import { Constants } from "./Constants.js"; import { TradeItem } from "./TradeItem.js"; export class Player { G; afk; id; ctype; abs; angle; armor = 0; apiercing = 0; attack; avoidance = 0; cid; crit = 0; critdamage = 0; damage_type; evasion = 0; frequency; going_x; going_y; heal; level = 1; move_num; moving; name; party; reflection = 0; resistance = 0; rpiercing = 0; target; team; x; y; s = {}; c = {}; cx; focus; hp; max_hp; max_mp; mp; npc; owner; pdps; q = {}; range; rip; skin; slots; speed; stand; tp; // Soft Properties in; map; width = Constants.CHARACTER_WIDTH; height = Constants.CHARACTER_HEIGHT; constructor(data, map, instance, g) { this.G = g; // Set soft properties this.map = map; this.in = instance; if (!data.npc) this.damage_type = this.G.classes[data.ctype].damage_type; // Set everything else this.updateData(data); } updateData(data) { if (this.id !== undefined && this.id !== data.id) throw new Error("The entity's ID does not match"); // Set everything for (const key in data) this[key] = data[key]; } calculateDamageRange(defender, skill = "attack") { const gSkill = this.G.skills[skill]; // If the entity is immune, most skills won't do damage if (defender.immune && skill !== "attack" && !gSkill?.pierces_immunity) return [0, 0]; if (defender["1hp"] || skill == "taunt") return this.crit ? [1, 2] : [1, 1]; let baseDamage = this.attack; if (skill == "heal") baseDamage = this.heal; if (!gSkill) console.debug(`calculateDamageRange DEBUG: '${skill}' isn't a skill!?`); if (gSkill?.damage) baseDamage = gSkill.damage; // NOTE: I asked Wizard to add something to G.conditions.cursed and .marked so we don't need these hardcoded. if (defender.s.cursed) baseDamage *= 1.2; if (defender.s.marked) baseDamage *= 1.1; const damage_type = gSkill[skill]?.damage_type ?? this.damage_type; let additionalApiercing = 0; if (gSkill?.apiercing) additionalApiercing = gSkill.apiercing; // NOTE: currently no skills with rpiercing // let additionalRpiercing = 0 // if (gSkill?.rpiercing) additionalRpiercing = gSkill.rpiercing if (damage_type == "physical") baseDamage *= Tools.damage_multiplier(defender.armor - this.apiercing - additionalApiercing); else if (damage_type == "magical") baseDamage *= Tools.damage_multiplier(defender.resistance - this.rpiercing /** - additionalRpiercing */); if (gSkill?.damage_multiplier) baseDamage *= gSkill.damage_multiplier; let lowerLimit = baseDamage * 0.9; let upperLimit = baseDamage * 1.1; if (this.crit) { if (this.crit >= 100) { lowerLimit *= 2 + this.critdamage / 100; } upperLimit *= 2 + this.critdamage / 100; } // NOTE: This information is from @Wizard on Discord on May 1st, 2020 // https://discord.com/channels/238332476743745536/243707345887166465/705722706250694737 if (skill == "cleave") { lowerLimit *= 0.1; upperLimit *= 0.9; } return [lowerLimit, upperLimit]; } /** * Returns the items that the player is selling in their trade slots. * * @see getWantedItems for items the player is buying */ getItemsForSale() { const slots = new Map(); for (const s in this.slots) { const slot = s; const item = this.slots[slot]; if (!item) continue; // Nothing in the slot if (!item.rid) continue; // Not a trade item if (item.b) continue; // They are buying, not selling slots.set(slot, new TradeItem(item, this.G)); } return slots; } /** * Returns the items that the player is purchasing in their trade slots * * @see getItemsForSale for items the player is selling */ getWantedItems() { const slots = new Map(); for (const s in this.slots) { const slot = s; const item = this.slots[slot]; if (!item) continue; // Nothing in the slot if (!item.rid) continue; // Not a trade item if (!item.b) continue; // They are selling, not buying slots.set(slot, new TradeItem(item, this.G)); } return slots; } /** * Returns true if the player is attacking us, or one of our party members * @param player The player whose party to check if they are attacking */ isAttackingPartyMember(player) { // Check if the entity is targeting anything if (this.target == undefined) return false; // Check if the entity is attacking us // NOTE: I don't want to get in to the semantics if we are actually in a party, I'm assuming if we aren't in a party, we're a party of "1". if (this.isAttackingUs(player)) return true; // Check if the entity is targeting a party member if (player?.partyData?.list?.includes(this.target)) return true; return false; } /** * Returns true if they are attacking us specifically, false otherwise * @param player The player to check if they are attacking */ isAttackingUs(player) { return this.target == player.id; } /** * If the player is disabled, they cannot move or attack * @returns If the player is disabled */ isDisabled() { return this.rip || (this.s.stunned || this.s.fingered || this.s.deepfreezed || this.s.sleeping) !== undefined; } /** * Returns true if the player is "friendly", for example, if it's one of our characters, in our party, or in our friends list. * @param character Our character (e.g.: bot.character) */ isFriendly(bot) { // Check if it's an NPC if (this.npc) return true; // Check if it's us if (bot.id == this.id) return true; // Check if we're the owner if (this.owner && bot.owner == this.owner) return true; // Check if we're in the same party if (this.party && bot.party == this.party) return true; // Check if we're on the same team if (this.team && bot.team == this.team) return true; // TODO: Check if they're in our friends list // They're not friendly >:( return false; } /** * Returns true if this player is an NPC. * * @return {*} {boolean} * @memberof Player */ isNPC() { return this.npc !== undefined; } } //# sourceMappingURL=Player.js.map