Skip to content

Commit

Permalink
Merge pull request #430 from m-h-c-t/fi-stage-rework
Browse files Browse the repository at this point in the history
Rework Floating Island stages
  • Loading branch information
hymccord authored Oct 5, 2023
2 parents aa576e4 + 329d61f commit 95d0640
Show file tree
Hide file tree
Showing 8 changed files with 382 additions and 46 deletions.
1 change: 0 additions & 1 deletion src/scripts/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -1200,7 +1200,6 @@ import * as detailingFuncs from './modules/details/legacy';
"Festive Comet": stagingFuncs.addFestiveCometStage,
"Frozen Vacant Lot": stagingFuncs.addFestiveCometStage,
"Fiery Warpath": stagingFuncs.addFieryWarpathStage,
"Floating Islands": stagingFuncs.addFloatingIslandsStage,
"Foreword Farm": stagingFuncs.addForewordFarmStage,
"Fort Rox": stagingFuncs.addFortRoxStage,
"Furoma Rift": stagingFuncs.addFuromaRiftStage,
Expand Down
93 changes: 93 additions & 0 deletions src/scripts/modules/stages/environments/floatingIslands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import {type User} from '@scripts/types/hg';
import {type IntakeMessage} from '@scripts/types/mhct';
import {type IslandModType} from '@scripts/types/quests/floatingIslands';
import {type IStager} from '../stages.types';

// See floatingIslands.spec.ts for docs about all stage names

export class FloatingIslandsStager implements IStager {
readonly environment: string = 'Floating Islands';

addStage(message: IntakeMessage, userPre: User, userPost: User, journal: unknown): void {
const quest = userPre.quests.QuestFloatingIslands;

if (!quest) {
throw new Error('QuestFloatingIslands is undefined');
}

const hsa = quest.hunting_site_atts;
const getCountOfActiveModType = (type: IslandModType): number => {
return hsa.activated_island_mod_types.filter(t => t == type).length;
};

const matcher = hsa.island_name.match(/^(\w+) .*$/);
if (!matcher) {
throw new Error('Failed to match Floating Island\'s island name.');
}

const powerType = matcher[1];

if (hsa.is_low_tier_island) {
message.stage = `${powerType} Low`;
} else if (hsa.is_high_tier_island) {
message.stage = `${powerType} High`;
} else if (hsa.is_vault_island) {
message.stage = `${powerType} Palace`;
} else {
throw new Error('Unknown Floating Island stage');
}

const numActiveLootCaches = getCountOfActiveModType('loot_cache');

if (hsa.is_enemy_encounter) {
if (hsa.is_low_tier_island)
message.stage = "Warden";
else if (hsa.is_high_tier_island)
message.stage = `${powerType} Paragon`;
else if (hsa.is_vault_island)
message.stage = "Empress";
else
message.stage += " Enemy Encounter";
}
else if (userPre.bait_name === "Sky Pirate Swiss Cheese") {
const numActivePirates = getCountOfActiveModType('sky_pirates');
message.stage = hsa.is_vault_island ? "Palace" : "Low|High";
message.stage += ` - ${numActivePirates}x Pirates`;
}
else if (userPre.bait_name?.endsWith("Cloud Cheesecake") && numActiveLootCaches >= 2) {
message.stage += ` - ${numActiveLootCaches}x Loot`;
}
// If a vault run has 3 or more active mods of the same type, add it to the stage name
else if (hsa.is_vault_island && Array.isArray(hsa.activated_island_mod_types)) {
// Takes an array of items, and returns a Map with the
// counts of each item in the array.
const panels: Record<string, number> = {};
hsa.activated_island_mod_types.forEach(t => t in panels ? panels[t]++ : panels[t] = 1);

for (const [islandType, count] of Object.entries(panels)) {
if (count < 3) {
continue;
}

let mod_type = hsa.island_mod_panels.find(p => p.type === islandType)?.name;

if (mod_type == null) {
throw new Error('The active island type could not be found in current island panels (this shouldn\'t be possible).');
}

const shortMod: Record<string, string> = {
'Ancient Jade Stockpile': 'Jade',
'Empyrean Seal Stowage': 'Emp Seal',
'Ore and Glass Deposit': 'Glass + Ore',
'Sky Pirate Den': 'Pirates',
};

if (shortMod[mod_type]) {
mod_type = shortMod[mod_type];
}

message.stage += ` - ${count}x ${mod_type}`;
}
}
}
}
2 changes: 2 additions & 0 deletions src/scripts/modules/stages/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import {type IStager} from './stages.types';
import {BountifulBeanstalkStager} from './environments/bountifulBeanstalk';
import {FloatingIslandsStager} from './environments/floatingIslands';
import {ForbiddenGroveStager} from './environments/forbiddenGrove';
import {FungalCavernStager} from './environments/fungalCavern';
import {IceFortressStager} from './environments/iceFortress';
import {SuperBrieFactoryStager} from './environments/superBrieFactory';

const stageModules: IStager[] = [
new BountifulBeanstalkStager(),
new FloatingIslandsStager(),
new ForbiddenGroveStager(),
new FungalCavernStager(),
new IceFortressStager(),
Expand Down
44 changes: 0 additions & 44 deletions src/scripts/modules/stages/legacy.js
Original file line number Diff line number Diff line change
Expand Up @@ -684,47 +684,3 @@ export function addValourRiftStage(message, user, user_post, hunt) {
break;
}
}

export function addFloatingIslandsStage(message, user, user_post, hunt) {
const envAttributes = user.environment_atts || user.enviroment_atts;
const pirates = ["No Pirates", "Pirates x1", "Pirates x2", "Pirates x3", "Pirates x4"];
const hsa = envAttributes.hunting_site_atts;
message.stage = hsa.island_name;

if (hsa.is_enemy_encounter) {
if (hsa.is_low_tier_island)
message.stage = "Warden";
else if (hsa.is_high_tier_island)
message.stage += " Paragon";
else if (hsa.is_vault_island)
message.stage = "Empress";
else
message.stage += " Enemy Encounter";
}
else if (user.bait_name === "Sky Pirate Swiss Cheese") {
message.stage = hsa.is_vault_island ? "Vault " : "Island ";
message.stage += pirates[hsa.activated_island_mod_types.filter(item => item === "sky_pirates").length];
}
else if (((user.bait_name === "Extra Rich Cloud Cheesecake") || (user.bait_name === "Cloud Cheesecake")) &&
(hsa.activated_island_mod_types.filter(item => item === "loot_cache").length >= 2)) {
message.stage += ` - Loot x${hsa.activated_island_mod_types.filter(item => item === "loot_cache").length}`;
}
// This is a new if situation to account for the above scenarios. It adds to them.
else if (hsa.is_vault_island
&& 'activated_island_mod_types' in hsa
&& Array.isArray(hsa.activated_island_mod_types)) {
//NOTE: There is a paperdoll attribute that may be quicker to use
const panels = {};
hsa.activated_island_mod_types.forEach(t => t in panels ? panels[t]++ : panels[t] = 1);
let counter = 0;
let mod_type = '';
for (const [type, num] of Object.entries(panels)) {
if (num >= 3) {
counter = num;
mod_type = hsa.island_mod_panels.filter(p => p.type === type)[0].name;
}
}
if (counter && mod_type)
message.stage += ` ${counter}x ${mod_type}`;
}
}
3 changes: 2 additions & 1 deletion src/scripts/types/hg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export interface User {
environment_name: string;
environment_id: number;
quests: Quests;
enviroment_atts: EnvironmentAttributes;
enviroment_atts?: EnvironmentAttributes;
environment_atts?: EnvironmentAttributes;
viewing_atts: ViewingAttributes;
}
Expand All @@ -42,6 +42,7 @@ export interface Quests {
QuestBalacksCove?: unknown
QuestBountifulBeanstalk?: quests.QuestBountifulBeanstalk
QuestClawShotCity?: quests.QuestClawShotCity
QuestFloatingIslands?: quests.QuestFloatingIslands
QuestForbiddenGrove?: quests.QuestForbiddenGrove
QuestForewordFarm?: unknown
QuestFortRox?: unknown
Expand Down
40 changes: 40 additions & 0 deletions src/scripts/types/quests/floatingIslands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
export interface QuestFloatingIslands {
hunting_site_atts: FloatingIslandHuntingSiteAtts
}

export interface FloatingIslandHuntingSiteAtts {
island_name: string;
is_enemy_encounter: boolean | null;
is_low_tier_island: boolean | null;
is_high_tier_island: boolean | null;
is_vault_island: boolean | null;
activated_island_mod_types: IslandModType[];
island_mod_panels: IslandModPanel[];
}

interface IslandModPanel {
type: IslandModType;
name: string;
}

export const IslandModTypes = [
'empty',
'empty_sky',
'gem_bonus',
'ore_bonus',
'sky_cheese',
'sky_pirates',
'loot_cache',
'wind_shrine',
'rain_shrine',
'frost_shrine',
'fog_shrine',
'paragon_cache_a',
'paragon_cache_d',
'paragon_cache_c',
'paragon_cache_b',
'ore_gem_bonus',
'cloudstone_bonus',
'charm_bonus',
] as const;
export type IslandModType = typeof IslandModTypes[number];
1 change: 1 addition & 0 deletions src/scripts/types/quests/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from '@scripts/types/quests/bountifulBeanstalk';
export * from '@scripts/types/quests/clawShotCity';
export * from '@scripts/types/quests/floatingIslands';
export * from '@scripts/types/quests/forbiddenGrove';
export * from '@scripts/types/quests/iceberg';
export * from '@scripts/types/quests/iceFortress';
Expand Down
Loading

0 comments on commit 95d0640

Please sign in to comment.