wynnbuilder-forked-for-changes/build.js

255 lines
13 KiB
JavaScript
Raw Normal View History

2021-01-07 00:08:19 +00:00
/*Turns the input amount of skill points into a float precision percentage.
* @param skp - the integer skillpoint count to be converted
*/
function skillPointsToPercentage(skp){
if (skp<=0){
return 0.0;
}else if(skp>=150){
return 0.808;
}else{
return(-0.0000000066695* Math.pow(Math.E, -0.00924033 * skp + 18.9) + 1.0771);
//return(-0.0000000066695* Math.pow(Math.E, -0.00924033 * skp + 18.9) + 1.0771).toFixed(3);
}
}
/*Turns the input amount of levels into skillpoints available.
*
* @param level - the integer level count te be converted
*/
function levelToSkillPoints(level){
if(level < 1){
return 0;
}else if(level >= 101){
return 200;
}else{
return (level - 1) * 2;
}
}
/*Turns the input amount of levels in to base HP.
* @param level - the integer level count to be converted
*/
function levelToHPBase(level){
if(level < 1){ //bad level
return this.levelToHPBase(1);
}else if (level > 106){ //also bad level
return this.levelToHPBase(106);
}else{ //good level
return 5*level + 5;
}
}
2021-01-08 04:31:29 +00:00
const baseDamageMultiplier = {
SUPER_SLOW: 0.51,
VERY_SLOW: 0.83,
SLOW: 1.5,
NORMAL: 2.05,
FAST: 2.5,
VERY_FAST: 3.1,
SUPER_FAST: 4.3
};
const attackSpeeds = ["SUPER_SLOW", "VERY_SLOW", "SLOW", "NORMAL", "FAST", "VERY_FAST", "SUPER_FAST"];
2021-01-07 00:02:10 +00:00
/*Class that represents a wynn player's build.
*/
class Build{
/*Construct a build.
*/
constructor(level,helmet,chestplate,leggings,boots,ring1,ring2,bracelet,necklace,weapon){
if(helmet.type.valueOf() != "helmet".valueOf()){
throw new TypeError("No such helmet named ", helmet.name);
}else{
this.helmet = helmet;
}
if(chestplate.type.valueOf() != "chestplate"){
throw new TypeError("No such chestplate named ", chestplate.name);
}else{
this.chestplate = chestplate;
}
if(leggings.type.valueOf() != "leggings"){
throw new TypeError("No such leggings named ", leggings.name);
}else{
this.leggings = leggings;
}
if(boots.type.valueOf() != "boots"){
throw new TypeError("No such boots named ", boots.name);
}else{
this.boots = boots;
}
if(ring1.type.valueOf() != "ring"){
throw new TypeError("No such ring named ", ring1.name);
}else{
this.ring1 = ring1;
}
if(ring2.type.valueOf() != "ring"){
throw new TypeError("No such ring named ", ring2.name);
}else{
this.ring2 = ring2;
}
if(bracelet.type.valueOf() != "bracelet"){
throw new TypeError("No such bracelet named ", bracelet.name);
}else{
this.bracelet = bracelet;
}
if(necklace.type.valueOf() != "necklace"){
throw new TypeError("No such necklace named ", necklace.name);
}else{
this.necklace = necklace;
}
if(weapon.type.valueOf() == "wand" || weapon.type.valueOf() == "bow" || weapon.type.valueOf() == "dagger" || weapon.type.valueOf() == "spear" || weapon.type.valueOf() == "relik"){
this.weapon = weapon;
}else{
throw new TypeError("No such weapon named ", weapon.name);
}
if(level < 1){ //Should these be constants?
this.level = 1;
}else if (level > 106){
this.level = 106;
}else{
this.level = level;
}
2021-01-07 06:41:41 +00:00
this.availableSkillpoints = levelToSkillPoints(this.level);
this.equipment = [ helmet, chestplate, leggings, boots, ring1, ring2, bracelet, necklace ];
2021-01-08 04:31:29 +00:00
this.items = this.equipment.concat([weapon]);
2021-01-07 06:41:41 +00:00
// return [equip_order, best_skillpoints, final_skillpoints, best_total];
let result = calculate_skillpoints(this.equipment, weapon);
this.equip_order = result[0];
this.base_skillpoints = result[1];
this.total_skillpoints = result[2];
this.assigned_skillpoints = result[3];
2021-01-08 04:31:29 +00:00
this.initBuildStats();
2021-01-07 00:02:10 +00:00
}
/*Returns build in string format
2021-01-07 06:41:41 +00:00
*/
2021-01-07 00:02:10 +00:00
toString(){
return this.helmet.name + ", " + this.chestplate.name + ", " + this.leggings.name + ", " + this.boots.name + ", " + this.ring1.name + ", " + this.ring2.name + ", " + this.bracelet.name + ", " + this.necklace.name + ", " + this.weapon.name;
}
2021-01-07 06:41:41 +00:00
/* Getters */
2021-01-07 21:32:36 +00:00
/* Get total health for build.
*/
2021-01-07 00:02:10 +00:00
getHealth(){
health = parseInt(this.helmet.hp,10) + parseInt(this.helmet.hpBonus,10) + parseInt(this.chestplate.hp,10) + parseInt(this.chestplate.hpBonus,10) + parseInt(this.leggings.hp,10) + parseInt(this.leggings.hpBonus,10) + parseInt(this.boots.hp,10) + parseInt(this.boots.hpBonus,10) + parseInt(this.ring1.hp,10) + parseInt(this.ring1.hpBonus,10) + parseInt(this.ring2.hp,10) + parseInt(this.ring2.hpBonus,10) + parseInt(this.bracelet.hp,10) + parseInt(this.bracelet.hpBonus,10) + parseInt(this.necklace.hp,10) + parseInt(this.necklace.hpBonus,10) + parseInt(this.weapon.hp,10) + parseInt(this.weapon.hpBonus,10) + levelToHPBase(this.level);
if(health<5){
return 5;
}else{
return health;
}
}
/* Get melee stats for build.
Returns an array in the order:
2021-01-07 21:32:36 +00:00
*/
getMeleeStats(){
2021-01-07 21:32:36 +00:00
let stats = this.getBuildStats();
let nDam = stats.get("nDam").split("-").map(Number);
2021-01-08 04:31:29 +00:00
let damages = []
let eDam = stats.get("eDam").split("-").map(Number);
let tDam = stats.get("tDam").split("-").map(Number);
let wDam = stats.get("wDam").split("-").map(Number);
let fDam = stats.get("fDam").split("-").map(Number);
let aDam = stats.get("aDam").split("-").map(Number);
let mdRaw = stats.get("maxStats").get("mdRaw");
let mdPct = stats.get("maxStats").get("mdPct");
let eDamPct = stats.get("maxStats").get("eDamPct");
let tDamPct = stats.get("maxStats").get("tDamPct");
let wDamPct = stats.get("maxStats").get("wDamPct");
let fDamPct = stats.get("maxStats").get("fDamPct");
let aDamPct = stats.get("maxStats").get("aDamPct");
let baseAtkTier = stats.get("atkSpd");
let atkTier = stats.get("maxStats").get("atkTier");
let adjAtkSpd = atkSpdToNum.get(baseAtkTier) + atkTier;
if(adjAtkSpd > 3){
adjAtkSpd = 3;
}else if(adjAtkSpd < -3){
adjAtkSpd = -3;
}
adjAtkSpd = numToAtkSpd.get(adjAtkSpd);
let str = stats.get("str");
let strReq = stats.get("strReq");
str = str + strReq;
let dex = stats.get("dex");
let dexReq = stats.get("dexReq");
dex = dex + dexReq;
let int = stats.get("int");
let intReq = stats.get("intReq");
int = int + intReq;
let def = stats.get("def");
let defReq = stats.get("defReq");
def = def + defReq;
let agi = stats.get("agi");
let agiReq = stats.get("agiReq");
agi = agi + agiReq;
let poison = stats.get("maxStats").get("poison");
2021-01-07 21:32:36 +00:00
2021-01-08 04:31:29 +00:00
console.log(str);
console.log(dex);
//Now do math
let nDamAdj = [Math.round(nDam[0] * ((100 + mdPct + skillPointsToPercentage(str) * 100) / 100.) + mdRaw), Math.round(nDam[1] * ((100 + mdPct + skillPointsToPercentage(str) * 100) / 100.) + mdRaw), Math.round(nDam[0] * ((200 + mdPct + skillPointsToPercentage(str) * 100) / 100.) + mdRaw), Math.round(nDam[1] * ((200 + mdPct + skillPointsToPercentage(str) * 100) / 100.) + mdRaw)];
let eDamAdj = [Math.round(eDam[0] * ((100 + mdPct + eDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(str) * 100) / 100.)), Math.round(eDam[1] * ((100 + mdPct + eDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(str) * 100) / 100.)), Math.round(eDam[0] * ((200 + mdPct + eDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(str) * 100) / 100.)), Math.round(eDam[1] * ((200 + mdPct + eDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(str) * 100) / 100.))];
let tDamAdj = [Math.round(tDam[0] * ((100 + mdPct + tDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(dex) * 100) / 100.)), Math.round(tDam[1] * ((100 + mdPct + tDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(dex) * 100) / 100.)), Math.round(tDam[0] * ((200 + mdPct + tDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(dex) * 100) / 100.)), Math.round(tDam[1] * ((200 + mdPct + tDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(dex) * 100) / 100.))];
let wDamAdj = [Math.round(wDam[0] * ((100 + mdPct + wDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(int) * 100) / 100.)), Math.round(wDam[1] * ((100 + mdPct + wDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(int) * 100) / 100.)), Math.round(wDam[0] * ((200 + mdPct + wDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(int) * 100) / 100.)), Math.round(wDam[1] * ((200 + mdPct + wDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(int) * 100) / 100.))];
let fDamAdj = [Math.round(fDam[0] * ((100 + mdPct + fDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(def) * 100) / 100.)), Math.round(fDam[1] * ((100 + mdPct + fDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(def) * 100) / 100.)), Math.round(fDam[0] * ((200 + mdPct + fDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(def) * 100) / 100.)), Math.round(fDam[1] * ((200 + mdPct + fDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(def) * 100) / 100.))];
let aDamAdj = [Math.round(aDam[0] * ((100 + mdPct + aDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(agi) * 100) / 100.)), Math.round(aDam[1] * ((100 + mdPct + aDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(agi) * 100) / 100.)), Math.round(aDam[0] * ((200 + mdPct + aDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(agi) * 100) / 100.)), Math.round(aDam[1] * ((200 + mdPct + aDamPct + skillPointsToPercentage(str) * 100 + skillPointsToPercentage(agi) * 100) / 100.))];
let totalDamNorm = [nDamAdj[0]+eDamAdj[0]+tDamAdj[0]+wDamAdj[0]+fDamAdj[0]+aDamAdj[0], nDamAdj[1]+eDamAdj[1]+tDamAdj[1]+wDamAdj[1]+fDamAdj[1]+aDamAdj[1]];
let totalDamCrit = [nDamAdj[2]+eDamAdj[2]+tDamAdj[2]+wDamAdj[2]+fDamAdj[2]+aDamAdj[2], nDamAdj[3]+eDamAdj[3]+tDamAdj[3]+wDamAdj[3]+fDamAdj[3]+aDamAdj[3]];
let normDPS = (totalDamNorm[0]+totalDamNorm[1])/2 * meleeMult.get(adjAtkSpd);
let critDPS = (totalDamCrit[0]+totalDamCrit[1])/2 * meleeMult.get(adjAtkSpd);
let avgDPS = (normDPS * (1 - skillPointsToPercentage(dex))) + (critDPS * (skillPointsToPercentage(dex))) + (poison / 3.0 * (1 + skillPointsToPercentage(str)));
//console.log([nDamAdj,eDamAdj,tDamAdj,wDamAdj,fDamAdj,aDamAdj,totalDamNorm,totalDamCrit,normDPS,critDPS,avgDPS]);
return [nDamAdj,eDamAdj,tDamAdj,wDamAdj,fDamAdj,aDamAdj,totalDamNorm,totalDamCrit,normDPS,critDPS,avgDPS];
2021-01-07 21:32:36 +00:00
}
/* Get all stats for this build. Returns a map w/ sums of all IDs.
@dep test.js.item_fields
@dep test.js.rolledIDs
@dep test.js.nonRolledIDs
@dep test.js.expandItem()
@pre The build itself should be valid. No checking of validity of pieces is done here.
@post The map returned will contain non-stacking IDs w/ a value null.
*/
2021-01-08 04:31:29 +00:00
initBuildStats(){
let staticIDs = ["hp", "eDef", "tDef", "wDef", "fDef", "aDef"];
2021-01-07 21:32:36 +00:00
//Create a map of this build's stats
//This is universal for every possible build, so it's possible to move this elsewhere.
let statMap = new Map();
2021-01-08 04:31:29 +00:00
for (const staticID of staticIDs) {
statMap.set(staticID, 0);
2021-01-07 21:32:36 +00:00
}
2021-01-08 04:31:29 +00:00
statMap.set("hp", 505); //TODO: Add player base health
2021-01-08 04:31:29 +00:00
for (const _item of this.items){
let item = expandItem(_item);
for (let [id, value] of item.get("maxRolls")) {
statMap.set(id,(statMap.get(id) || 0)+value);
}
for (const staticID of staticIDs) {
if (item[staticID]) { statMap.set(statMap.get(staticID) + item[staticID]); }
2021-01-07 21:32:36 +00:00
}
}
2021-01-07 06:41:41 +00:00
2021-01-08 04:31:29 +00:00
// The stuff relevant for damage calculation!!! @ferricles
statMap.set("atkSpd", this.weapon["atkSpd"]);
statMap.set("damageRaw", [this.weapon["nDam"], this.weapon["fDam"], this.weapon["wDam"], this.weapon["aDam"], this.weapon["tDam"], this.weapon["eDam"]]);
statMap.set("damageBonus", [statMap.get("fDamPct"), statMap.get("wDamPct"), statMap.get("aDamPct"), statMap.get("tDamPct"), statMap.get("eDamPct")]);
statMap.set("defRaw", [statMap.get("fDef"), statMap.get("wDef"), statMap.get("aDef"), statMap.get("tDef"), statMap.get("eDef")]);
statMap.set("defBonus", [statMap.get("fDefPct"), statMap.get("wDefPct"), statMap.get("aDefPct"), statMap.get("tDefPct"), statMap.get("eDefPct")]);
2021-01-07 06:41:41 +00:00
2021-01-08 04:31:29 +00:00
console.log(statMap);
this.statMap = statMap;
}
2021-01-07 00:02:10 +00:00
}