msagent.js/web: Implement animation branching
This commit is contained in:
parent
883ef7357c
commit
74743a1824
2 changed files with 51 additions and 5 deletions
|
@ -92,7 +92,10 @@ export class AcsAnimationFrameInfo {
|
|||
soundIndex = 0;
|
||||
|
||||
frameDuration = 0; // The duration of the frame in (1/100)th seconds.
|
||||
nextFrame = 0; // -2 = animation has ended (although, I imagine this could be detected in better ways!)
|
||||
|
||||
// Index of frame to go to when exiting a branch
|
||||
// -2 = animation has ended/no exit? idk (although, I imagine this could be detected in better ways!)
|
||||
branchExitFrameIndex = 0;
|
||||
|
||||
branchInfo: AcsBranchInfo[] = [];
|
||||
overlayInfo: AcsOverlayInfo[] = [];
|
||||
|
@ -106,7 +109,7 @@ export class AcsAnimationFrameInfo {
|
|||
|
||||
info.soundIndex = buffer.readS16LE();
|
||||
info.frameDuration = buffer.readU16LE();
|
||||
info.nextFrame = buffer.readS16LE();
|
||||
info.branchExitFrameIndex = buffer.readS16LE();
|
||||
|
||||
info.branchInfo = buffer.readCountedList(() => {
|
||||
return AcsBranchInfo.read(buffer);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { BufferStream, SeekDir, imageDrawToBuffer } from '@msagent.js/core';
|
||||
import { AcsBranchInfo, BufferStream, SeekDir, imageDrawToBuffer } from '@msagent.js/core';
|
||||
import { AcsData } from '@msagent.js/core';
|
||||
import { ContextMenu, ContextMenuItem } from './contextmenu.js';
|
||||
import { AcsAnimation, AcsAnimationFrameInfo } from '@msagent.js/core';
|
||||
|
@ -6,8 +6,6 @@ import { AcsImageEntry } from '@msagent.js/core';
|
|||
import { Point, Size } from '@msagent.js/core';
|
||||
import { wordballoonDrawImage, wordballoonDrawText } from './wordballoon.js';
|
||||
|
||||
|
||||
|
||||
function randint(min: number, max: number) {
|
||||
return Math.floor(Math.random() * (max - min) + min);
|
||||
}
|
||||
|
@ -42,6 +40,51 @@ class AgentAnimationState {
|
|||
nextFrame() {
|
||||
requestAnimationFrame(() => {
|
||||
if (this.cancelled) return;
|
||||
|
||||
// Handle animation branching, if it is required
|
||||
let bi = this.anim.frameInfo[this.frameIndex].branchInfo;
|
||||
if (bi.length != 0) {
|
||||
let biCopy = [...bi];
|
||||
|
||||
// This happens more often then you'd think, but this basically handles
|
||||
// a branch that will always be taken.
|
||||
//
|
||||
// This is often used for looping from my understanding?
|
||||
if (bi.length == 1 && bi[0].branchFrameProbability == 100) {
|
||||
this.frameIndex = bi[0].branchFrameIndex;
|
||||
} else {
|
||||
let probabilityOnlyList = bi.map((bii) => bii.branchFrameProbability);
|
||||
let totalProbability = probabilityOnlyList.reduce((sum, pro) => {
|
||||
return sum + pro;
|
||||
});
|
||||
|
||||
// Handles the off chance that there is a branch info list that sums less than 100%.
|
||||
// (Office Logo 'Idle3', Victor has a couple, ...)
|
||||
//
|
||||
// I'm not entirely sure the correct action in this case but I just
|
||||
// have this do nothing.
|
||||
if (totalProbability != 100) {
|
||||
let nothingBranchItem = new AcsBranchInfo();
|
||||
nothingBranchItem.branchFrameIndex = this.frameIndex;
|
||||
nothingBranchItem.branchFrameProbability = 100 - totalProbability;
|
||||
biCopy.push(nothingBranchItem);
|
||||
}
|
||||
|
||||
// Pick a random branch
|
||||
let randProbability = randint(0, 100);
|
||||
let cumulativeProbability = 0;
|
||||
|
||||
for (const branchItem of biCopy) {
|
||||
cumulativeProbability += branchItem.branchFrameProbability;
|
||||
if (randProbability < cumulativeProbability) {
|
||||
//console.log('picked', branchItem);
|
||||
this.frameIndex = branchItem.branchFrameIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.char.drawAnimationFrame(this.anim.frameInfo[this.frameIndex++]);
|
||||
|
||||
if (this.frameIndex >= this.anim.frameInfo.length) {
|
||||
|
|
Loading…
Reference in a new issue