audio updtes and core classes.

This commit is contained in:
2025-08-21 23:50:06 -04:00
parent 431346d126
commit f684776a4d
5 changed files with 277 additions and 9 deletions

View File

@@ -2,7 +2,133 @@
let aio: AIO = {};
if(!aio.AddAddon()) {
const audioHandlers = aio.AddHandlers('AIOAudioPlayer', {});
audioHandlers.PlaySingleSound = (sound: string) => {
PlaySoundFile(sound, "Master");
};
// Define an interface for audio options
interface AudioOptions {
volume?: number; // 0.0 to 1.0 (for relative volume control)
duration?: number; // Duration in seconds before restoring original volume
}
// Track which sounds have been played for each player
const playedSounds: Record<string, string[]> = {};
// Store the default SFX volume for restoration
let defaultSFXVolume: string | null = null;
// Function to get the current SFX volume safely
function getSFXVolume(): string {
try {
// @ts-ignore - WoW API
return GetCVar("Sound_SFXVolume");
} catch (e) {
return "1.0";
}
}
// Function to set the SFX volume safely
function setSFXVolume(volume: string): void {
try {
// @ts-ignore - WoW API
SetCVar("Sound_SFXVolume", volume);
} catch (e) {
// Silently fail if SetCVar is not available
}
}
// Create a timer system for WoW 3.3.5
let totalElapsed = 0;
let targetTime = 0;
let isTimerActive = false;
// Create the timer frame
const timerFrame = CreateFrame("Frame", "hiddenTimingFrame");
// Set up the OnUpdate handler
timerFrame.SetScript("OnUpdate", function(self: WoWAPI.Frame, elapsed: number) {
if (!isTimerActive) return;
// Accumulate elapsed time (elapsed is in seconds)
totalElapsed += elapsed;
// Check if we've reached the target time
if (totalElapsed >= targetTime) {
// Restore the volume
if (defaultSFXVolume !== null) {
setSFXVolume(defaultSFXVolume);
}
// Reset the timer
isTimerActive = false;
totalElapsed = 0;
}
});
// Function to start the timer
function startVolumeRestoreTimer(duration: number): void {
if (duration <= 0) return;
// Set the timer parameters
totalElapsed = 0;
targetTime = duration;
isTimerActive = true;
}
audioHandlers.PlaySingleSound = (sound: string, options?: AudioOptions, playerName?: string) => {
const volume = options?.volume !== undefined ? options.volume : 1.0;
const duration = options?.duration !== undefined ? options.duration : 0;
if (defaultSFXVolume === null) {
defaultSFXVolume = getSFXVolume();
}
if (volume !== 1.0) {
setSFXVolume(volume.toString());
// Start the timer to restore volume if duration is specified
if (duration > 0) {
startVolumeRestoreTimer(duration);
}
}
// Always play through SFX channel
// @ts-ignore - WoW API
PlaySoundFile(sound, "SFX");
// If player name is provided, track that this sound was played for this player
if (playerName) {
if (!playedSounds[playerName]) {
playedSounds[playerName] = [];
}
// Add this sound to the player's played sounds list
if (!playedSounds[playerName].includes(sound)) {
playedSounds[playerName].push(sound);
}
}
};
// Add a function to check if a sound has been played for a player
audioHandlers.HasPlayedSound = (sound: string, playerName: string) => {
return playedSounds[playerName] && playedSounds[playerName].includes(sound);
};
// Add a function to reset played sounds for a player or instance
audioHandlers.ResetPlayedSounds = (playerName?: string) => {
if (playerName) {
// Reset for specific player
playedSounds[playerName] = [];
} else {
// Reset for all players
for (const player in playedSounds) {
playedSounds[player] = [];
}
}
};
// Add a function to restore the default volume
audioHandlers.RestoreDefaultVolume = () => {
if (defaultSFXVolume !== null) {
setSFXVolume(defaultSFXVolume);
}
};
}

View File

@@ -2,6 +2,17 @@ import { Logger } from "./logger";
const logger = new Logger("MapZones");
// Base Game map difficulties
export enum MapDifficulties {
NORMAL = 1,
HEROIC = 2,
}
export enum MapTypes {
DUNGEON = 1,
RAID = 2,
}
export enum MapNames {
// Classic WoW dungeons
RAGEFIRE_CHASM = 'ragefire_chasm',
@@ -534,3 +545,23 @@ export function getBossByName(name: string): Boss | undefined {
export const BossIDs: Record<number, boolean> = Object.fromEntries(
Bosses.map(b => [b.entry, true])
);
export function isBossDbCheck(entry: number): boolean {
const sql = `
select distinct entry
from acore_world.creature_template ct
left join creature c on ct.entry = c.id1
left join map_dbc m on c.map = m.ID
where
(ct.\`rank\` = 3 and InstanceType > 0)
OR (ct.\`rank\` = 3 and ct.ScriptName like 'boss_%')
OR (ExpansionID = 1 and ct.ScriptName like '%boss%')
OR (m.InstanceType = 1 and ExperienceModifier = 2)
and entry = ${entry}`;
const result = WorldDBQuery(sql);
if(result) {
return true;
}
return false;
}

View File

@@ -1,4 +1,6 @@
import { timeStamp } from "console";
// A function that will take a min and a max and return a random number between them
export function rollDice(min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1) + min);
}
}

View File

@@ -16,4 +16,93 @@ export function colors(name: string) {
} else {
return colors.WHITE;
}
}
}
/**
* Creates an item button with tooltip functionality
* @param parent The parent frame
* @param name Unique name for the button
* @param itemId The item entry ID
* @param size Size of the button (width and height)
* @param x X position relative to anchor point
* @param y Y position relative to anchor point
* @param anchorPoint Anchor point on the parent frame
* @returns The created button
*/
export function CreateItemButton(
parent: WoWAPI.Frame,
name: string,
itemId: number,
size: number = 36,
x: number = 0,
y: number = 0,
anchorPoint: WoWAPI.Point = "LEFT"
): WoWAPI.Button {
// Create or get existing button
AIO_debug(`New button being generated for: ${name} inside of ${parent.GetName()}`);
// IF it already exists just update the texture and gametooltip
let button: WoWAPI.Button;
let iconTexture: WoWAPI.Texture;
button = _G[name];
iconTexture = _G[`${name}_icon`];
if(!button) {
button = CreateFrame("Button", name, parent);
button.SetSize(size, size);
iconTexture = button.CreateTexture(`${name}_icon`, "BACKGROUND");
iconTexture.SetAllPoints();
}
// const [itemName, itemLink] = GetItemInfo(itemId);
// if(!itemName) {
// AIO_debug(`Failed to retrieve item! ${itemId}`);
// return;
// }
const itemTexture = GetItemIcon(itemId);
if(!itemTexture) {
AIO_debug(`Failed to retrieve item texture!`);
return;
}
iconTexture.SetTexture(itemTexture);
// AIO_debug(`The item link is as follows: for item:::: ${itemId}:::::: ${itemLink} :::::: ${itemTexture}`);
// Add tooltip handlers
button.SetScript("OnEnter", function(self) {
GameTooltip.SetOwner(self, "ANCHOR_RIGHT");
GameTooltip.SetHyperlink(`item:${itemId}`);
GameTooltip.Show();
});
button.SetScript("OnLeave", function() {
GameTooltip.Hide();
});
// // Position the button
button.ClearAllPoints();
button.SetPoint(anchorPoint, parent, anchorPoint, x, y);
return button;
}
// Just makes a frame closable by escape
/** @noSelf **/
export function EscapeCloseable(frame: WoWAPI.Frame) {
_G[frame.GetName()] = frame;
tinsert(_G["UISpecialFrames"], frame.GetName());
}
/** @noSelf **/
export function MakeDraggable(frame: WoWAPI.Frame) {
frame.SetMovable(true);
frame.EnableMouse(true);
frame.RegisterForDrag("LeftButton");
frame.SetScript("OnDragStart", frame.StartMoving);
frame.SetScript("OnDragStop", frame.StopMovingOrSizing);
}

View File

@@ -253,7 +253,12 @@ const onSpell: player_event_on_spell_cast = (event: number, player: Player, spel
for(let i = 0; i < members.length; i++) {
player.SendChatMessageToPlayer(ChatMsg.CHAT_MSG_RAID_BOSS_EMOTE,Language.LANG_COMMON,`${player.GetName()} is taking a gamble!`, members[i]);
aio.Handle(members[i], 'AIOAudioPlayer', 'PlaySingleSound',sound);
// Use the updated audio player with player name and audio options
aio.Handle(members[i], 'AIOAudioPlayer', 'PlaySingleSound', sound, {
channel: "SFX",
volume: 0.5,
duration: 12.0 // Most opening sounds are short
}, members[i].GetName());
}
}
@@ -281,7 +286,12 @@ const onLootStateChange: gameobject_event_on_loot_state_change = (event: number,
const players = gameObject.GetPlayersInRange(50);
for(let i = 0; i < players.length; i++) {
const player = players[i];
aio.Handle(player, 'AIOAudioPlayer', 'PlaySingleSound', sound);
// Use the updated audio player with player name and audio options
aio.Handle(player, 'AIOAudioPlayer', 'PlaySingleSound', sound, {
channel: "SFX",
volume: 0.5, // Trap sounds should be louder
duration: 8.0 // Most trap sounds are short
}, player.GetName());
}
if(player.IsAlive()) {
@@ -304,7 +314,12 @@ const onLootStateChange: gameobject_event_on_loot_state_change = (event: number,
for(let i = 0; i < members.length; i++) {
members[i].SendBroadcastMessage(`{player.GetName()} has triggered trap number ${effect}, hate that guy!`);
aio.Handle(members[i], 'AIOAudioPlayer', 'PlaySingleSound',sound);
// Use the updated audio player with player name and audio options
aio.Handle(members[i], 'AIOAudioPlayer', 'PlaySingleSound', sound, {
channel: "SFX",
volume: 0.5,
duration: 8.0 // Most trap sounds are short
}, members[i].GetName());
}
player.CastSpell(player, effect, true);
@@ -319,7 +334,12 @@ const onLootStateChange: gameobject_event_on_loot_state_change = (event: number,
const players = gameObject.GetPlayersInRange(50);
for(let i = 0; i < players.length; i++) {
const player = players[i];
aio.Handle(player, 'AIOAudioPlayer', 'PlaySingleSound', LootGoodSound);
// Use the updated audio player with player name and audio options
aio.Handle(player, 'AIOAudioPlayer', 'PlaySingleSound', LootGoodSound, {
channel: "SFX",
volume: 0.5,
duration: 25.0 // Loot sound is short
}, player.GetName());
}
}