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;
|
soundIndex = 0;
|
||||||
|
|
||||||
frameDuration = 0; // The duration of the frame in (1/100)th seconds.
|
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[] = [];
|
branchInfo: AcsBranchInfo[] = [];
|
||||||
overlayInfo: AcsOverlayInfo[] = [];
|
overlayInfo: AcsOverlayInfo[] = [];
|
||||||
|
@ -106,7 +109,7 @@ export class AcsAnimationFrameInfo {
|
||||||
|
|
||||||
info.soundIndex = buffer.readS16LE();
|
info.soundIndex = buffer.readS16LE();
|
||||||
info.frameDuration = buffer.readU16LE();
|
info.frameDuration = buffer.readU16LE();
|
||||||
info.nextFrame = buffer.readS16LE();
|
info.branchExitFrameIndex = buffer.readS16LE();
|
||||||
|
|
||||||
info.branchInfo = buffer.readCountedList(() => {
|
info.branchInfo = buffer.readCountedList(() => {
|
||||||
return AcsBranchInfo.read(buffer);
|
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 { AcsData } from '@msagent.js/core';
|
||||||
import { ContextMenu, ContextMenuItem } from './contextmenu.js';
|
import { ContextMenu, ContextMenuItem } from './contextmenu.js';
|
||||||
import { AcsAnimation, AcsAnimationFrameInfo } from '@msagent.js/core';
|
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 { Point, Size } from '@msagent.js/core';
|
||||||
import { wordballoonDrawImage, wordballoonDrawText } from './wordballoon.js';
|
import { wordballoonDrawImage, wordballoonDrawText } from './wordballoon.js';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function randint(min: number, max: number) {
|
function randint(min: number, max: number) {
|
||||||
return Math.floor(Math.random() * (max - min) + min);
|
return Math.floor(Math.random() * (max - min) + min);
|
||||||
}
|
}
|
||||||
|
@ -42,6 +40,51 @@ class AgentAnimationState {
|
||||||
nextFrame() {
|
nextFrame() {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
if (this.cancelled) return;
|
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++]);
|
this.char.drawAnimationFrame(this.anim.frameInfo[this.frameIndex++]);
|
||||||
|
|
||||||
if (this.frameIndex >= this.anim.frameInfo.length) {
|
if (this.frameIndex >= this.anim.frameInfo.length) {
|
||||||
|
|
Loading…
Reference in a new issue