Skip to content

Commit

Permalink
Merge pull request #421 from Kathund/woolwars
Browse files Browse the repository at this point in the history
FEAT: Wool Wars
  • Loading branch information
StavZ authored Sep 23, 2023
2 parents ac77e3f + 09a310b commit b7c53c9
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ module.exports = {
VampireZ: require('./structures/MiniGames/VampireZ.js'),
Walls: require('./structures/MiniGames/Walls.js'),
Warlords: require('./structures/MiniGames/Warlords.js'),
WoolWars: require('./structures/MiniGames/WoolWars.js'),

/* Leaderboards */
Leaderboard: require('./structures/Leaderboard.js'),
Expand Down
123 changes: 123 additions & 0 deletions src/structures/MiniGames/WoolWars.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
const { divide } = require('../../utils');

/**
* Wool Wars Class
*/
class WoolWars {
/**
* Constructor
* @param {Record<string,unknown>} data Data from API
*/
constructor(data) {
/**
* Sheep layers, similar to prestige
* @type {number}
*/
this.layers = data.progression?.available_layers || 0;
/**
* Wool Wars XP
* @type {number}
*/
this.xp = data.progression?.experience || 0;
/**
* Wool Wars Decimal Level
* @type {number}
*/
this.exactLevel = WoolWars.convertXPToLevel(this.xp);
/**
* Wool wars level (as shown in game)
* @type {number}
*/
this.level = Math.floor(this.exactLevel);
/**
* Coins
* @type {number}
*/
this.coins = data.coins || 0;
/**
* Selected class, or NONE if field isn't present in API for some reason
* @type {'ASSAULT'|'TANK'|'GOLEM'|'SWORDSMAN'|'ENGINEER'|'ARCHER'|'NONE'}
*/
this.selectedClass = data.wool_wars.selected_class || 'NONE';
this.stats = {
overall: WoolWars.generateStatsFor(data.wool_wars.stats, ''),
assault: WoolWars.generateStatsFor(data.wool_wars.stats, 'assault'),
tank: WoolWars.generateStatsFor(data.wool_wars.stats, 'tank'),
golem: WoolWars.generateStatsFor(data.wool_wars.stats, 'golem'),
swordsman: WoolWars.generateStatsFor(data.wool_wars.stats, 'swordsman'),
engineer: WoolWars.generateStatsFor(data.wool_wars.stats, 'engineer'),
archer: WoolWars.generateStatsFor(data.wool_wars.stats, 'archer')
};
// Misc fields ig
/**
* Owned Cosmetics
* @type {string[]}
*/
this.ownedCosmetics = data.packages || [];
/**
* Private Games config
* @type {PrivateGamesConfig}
*/
this.privateGamesConfig = data.privategames || {};
}
/**
* Converts XP to Level
* @param {number} exp xp
* @return {number}
*/
static convertXPToLevel(exp) {
const minimalExp = [0, 1e3, 3e3, 6e3, 1e4, 15e3]; // NB: progression is 1k, 2k, 3k, 4k, 5k
const baseLevel = minimalExp.length;
const baseExp = minimalExp[minimalExp.length - 1];
const expToLevel100 = 49e4;
if (exp < baseExp) return minimalExp.findIndex((x)=>exp < x);
const theoreticalLevel = ((exp - baseExp) / 5e3) + baseLevel;
if (theoreticalLevel > 100) return 100 + this.convertXPToLevel(exp - expToLevel100);
return theoreticalLevel;
}
/**
* Generates stats per class/overall
* @param {Record<string, unknwon>} data data
* @param {string} [_class=''] Class
* @return {WoolWarsStats}
*/
static generateStatsFor(data, _class) {
// N.B i called it _class instead of class because reserved keyword
const workingData = (_class ? data?.['classes'][_class] : data) || {};
return {
roundWins: workingData.wins || 0,
gamesPlayed: workingData.games_played || 0,
woolsPlaced: workingData.wool_placed || 0,
blocksBroken: workingData.blocks_broken || 0,
placeBreakRatio: divide(workingData.wool_placed, workingData.blocks_broken),
kills: workingData.kills || 0,
deaths: workingData.deaths || 0,
KDRatio: divide(workingData.kills, workingData.deaths),
assists: workingData.assists || 0,
powerups: workingData.powerups_gotten || 0
};
}
}
/**
* @typedef {Object} PrivateGamesConfig NB. There could be more fields
* @property {boolean} one_hit_one_kill One hit one kill
* @property {'Enabled'|'Disabled'} rainbow_wool Rainbow wool
* @property {string} health_buff Health Buff
* @property {string} game_speed Game speed
* @property {string} speed Player speed
* @property {'Enabled'|'Disabled'} no_class No class
*/
/**
* @typedef {Object} WoolWarsStats
* @property {number} roundWins round wins
* @property {number} gamesPlayed games played
* @property {number} woolsPlaced wools placed
* @property {number} blocksBroken blocks broken
* @property {number} placeBreakRatio broken blocks to placed wool ratio
* @property {number} kills kills
* @property {number} deaths deaths
* @property {number} KDRatio KDR
* @property {number} assists assists (not included in KDR)
* @property {number} powerups number of powerups picked up
*/
module.exports = WoolWars;
4 changes: 3 additions & 1 deletion src/structures/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const Paintball = require('./MiniGames/Paintball');
const Quakecraft = require('./MiniGames/Quakecraft');
const Walls = require('./MiniGames/Walls');
const Warlords = require('./MiniGames/Warlords');
const WoolWars = require('./MiniGames/WoolWars');
/**
* Player class
*/
Expand Down Expand Up @@ -233,7 +234,8 @@ class Player {
turbokartracers: (data.stats.GingerBread ? new TurboKartRacers(data.stats.GingerBread) : null),
walls: (data.stats.Walls ? new Walls(data.stats.Walls) : null),
warlords: (data.stats.Battleground ? new Warlords(data.stats.Battleground) : null),
pit: null
pit: null,
woolwars: (data.stats.WoolGames ? new WoolWars(data.stats.WoolGames) : null)
} : null);
/**
* User's current language
Expand Down
6 changes: 5 additions & 1 deletion tests/test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-undef */
const { Client, Game, SkyWars, BedWars, UHC, SpeedUHC, MurderMystery, Duels, BuildBattle, MegaWalls, CopsAndCrims, TNTGames, SmashHeroes, VampireZ, BlitzSurvivalGames, ArenaBrawl, Guild, PlayerCosmetics, Pets, Pet, Color, ServerInfo } = require('../src');
const client = new Client(process.env.HYPIXEL_KEY, { cache: true });
const { Client, Game, SkyWars, BedWars, UHC, SpeedUHC, MurderMystery, Duels, BuildBattle, MegaWalls, CopsAndCrims, TNTGames, SmashHeroes, VampireZ, BlitzSurvivalGames, ArenaBrawl, Guild, PlayerCosmetics, Pets, Pet, Color, ServerInfo, WoolWars } = require('../src');
const { expect } = require('chai');
describe('Client#getPlayer', () => {
let player;
Expand Down Expand Up @@ -173,6 +173,10 @@ describe('Client#getPlayer', () => {
if (player.stats.arena) {
expect(player.stats.arena).instanceOf(ArenaBrawl);
}
if (player.stats.woolwars) {
console.log(player.stats.woolwars);
expect(player.stats.woolwars).instanceOf(WoolWars);
}
}
});
});
Expand Down
44 changes: 43 additions & 1 deletion typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1001,11 +1001,53 @@ declare module 'hypixel-api-reborn' {
turbokartracers?: TurboKartRacers;
walls?: Walls;
warlords?: Warlords;
arcade?: Arcade;
arcade?: Arcade,
woolwars?: WoolWars;
};
getRecentGames(): Promise<RecentGame[]>;
recentGames?: RecentGame[];
toString(): string;
} class WoolWars {
static convertXPToLevel(exp: number): number;
static generateStatsFor(data: Record<string, unknown>, _class?: string | undefined): WoolWarsStats;
constructor(data: Record<string, unknown>);
layers: number;
xp: number;
exactLevel: number;
level: number;
coins: number;
selectedClass: 'ASSAULT' | 'TANK' | 'GOLEM' | 'SWORDSMAN' | 'ENGINEER' | 'ARCHER' | 'NONE';
stats: {
overall: WoolWarsStats;
assault: WoolWarsStats;
tank: WoolWarsStats;
golem: WoolWarsStats;
swordsman: WoolWarsStats;
engineer: WoolWarsStats;
archer: WoolWarsStats;
};
ownedCosmetics: string[];
privateGamesConfig: PrivateGamesConfig;
}
type WoolWarsStats = {
roundWins: number;
gamesPlayed: number;
woolsPlaced: number;
blocksBroken: number;
placeBreakRatio: number;
kills: number;
deaths: number;
KDRatio: number;
assists: number;
powerups: number;
}
type PrivateGamesConfig = {
one_hit_one_kill: boolean;
rainbow_wool: 'Enabled' | 'Disabled';
health_buff: string;
game_speed: string;
speed: string;
no_class: 'Enabled' | 'Disabled';
}
class SkyWarsRanked {
constructor(data: Record<string, unknown>);
Expand Down

0 comments on commit b7c53c9

Please sign in to comment.