Rewrote the code in Animations.cpp

Fixed gl_auto_closebox not closing containers in some cases.
This commit is contained in:
NovaRain
2021-05-11 10:43:06 +08:00
parent fc53df5a16
commit 6b7e83ab15
6 changed files with 100 additions and 136 deletions
Binary file not shown.
Binary file not shown.
+4 -4
View File
@@ -226,10 +226,10 @@ end
procedure canuseweapon_handler begin
variable critter, canWield;
critter := get_sfall_arg;
if (critter) then begin
//if (critter) then begin
canWield := check_weapon_change(critter, get_sfall_arg, true);
//if (canWield != 0) then canWield := 1;
set_sfall_arg(3, canWield); // override result
// override result
set_sfall_arg(3, canWield);
set_sfall_return(canWield);
end
//end
end
+4 -4
View File
@@ -25,7 +25,7 @@ end
// Gets the string value from the specified ini
procedure GetIniConfigStr(variable section, variable key, variable def, variable inifile) begin
variable val := get_ini_string(inifile + "|" + section + "|" + key);
if val == -1 or val == "" then val := def;
if val == -1 orElse val == "" then val := def;
return val;
end
@@ -39,14 +39,14 @@ end
// Gets the string value from sfall-mods.ini
procedure GetConfigStr(variable section, variable key, variable def) begin
variable val := get_ini_string(ini + "|" + section + "|" + key);
if val == -1 or val == "" then val := def;
if val == -1 orElse val == "" then val := def;
return val;
end
// Gets the value from sfall-mods.ini as a temp array of strings
procedure GetConfigList(variable section, variable key) begin
variable val := get_ini_string(ini + "|" + section + "|" + key);
if val == -1 or val == "" then return [];
if val == -1 orElse val == "" then return [];
return string_split(val, ",");
end
@@ -65,7 +65,7 @@ end
// Translates given string using Translations.ini
procedure Translate(variable id, variable def) begin
variable str := get_ini_string(translationIni + "|Sfall|" + id);
if not str or (strlen(str) == 0) then begin
if (str == 0 orElse (strlen(str) == 0)) then begin
str := def;
end
return str;
+26 -1
View File
@@ -61,8 +61,9 @@ struct Art {
struct AnimationSet {
long currentAnim;
long counter;
long animCounter;
long totalAnimCount;
long flags;
struct Animation {
long number;
long source;
@@ -81,6 +82,30 @@ struct AnimationSet {
static_assert(sizeof(AnimationSet) == 2656, "Incorrect AnimationSet definition.");
struct AnimationSad {
long flags;
long source;
long fid;
long animCode;
long ticks;
long tpf; // fps
long currAnimSet;
long pathCount; // len
long currentAnim;
short dstTile;
char rotation1;
char rotation2;
struct BuildPathData {
long tile;
long elevation;
long sX;
long sY;
} pathData[200];
};
static_assert(sizeof(AnimationSad) == 3240, "Incorrect AnimationSad definition.");
// Bounding rectangle, used by tile_refresh_rect and related functions.
struct BoundRect {
long x;
+66 -127
View File
@@ -25,17 +25,14 @@
namespace sfall
{
static constexpr int animRecordSize = sizeof(fo::AnimationSet);
static constexpr int sadSize = 3240;
static int animationLimit = 32;
//static int animationLimit = 32;
//pointers to new animation struct arrays
static std::vector<fo::AnimationSet> new_anim_set;
static std::vector<BYTE> new_sad;
static std::vector<fo::AnimationSet> sf_anim_set;
static std::vector<fo::AnimationSad> sf_sad;
static DWORD animSetAddr = FO_VAR_anim_set;
static DWORD sadAddr = FO_VAR_sad;
static fo::AnimationSet* animSet = (fo::AnimationSet*)FO_VAR_anim_set;
static fo::AnimationSad* animSad = (fo::AnimationSad*)FO_VAR_sad;
static const DWORD animPCMove[] = {
0x416E11, 0x416F64, 0x417143, 0x41725C, 0x4179CC,
@@ -49,11 +46,7 @@ static const DWORD animMaxSizeCheck[] = {
0x413AA9, 0x413CB7, 0x413DC2, 0x417F3A,
};
static const DWORD fake_anim_set_C[] = {
0x413AA4, 0x413DBC,
};
static const DWORD anim_set_0[] = {
static const DWORD anim_set_0[] = { // curr_anim
0x413B96, 0x413C5A, 0x413CF0, 0x413DE1, 0x413E66, 0x413EF3, 0x413FA2,
0x414161, 0x4142D3, 0x41449A, 0x41460B, 0x4146FF, 0x414826, 0x41491A,
0x4149F8, 0x414AD0, 0x414BA4, 0x414C8C, 0x414CF0, 0x414D60, 0x414DD0,
@@ -63,32 +56,36 @@ static const DWORD anim_set_0[] = {
0x415BB6, 0x415C7C, 0x415CA3, /*0x415DE4, - conflct with 0x415DE2*/
};
static const DWORD anim_set_4[] = {
static const DWORD anim_set_4[] = { // counter
0x413D07, 0x415700, 0x415B6B, 0x415B78, 0x415C2D, 0x415D38, 0x415D56,
0x415D63, 0x415DCF,
};
static const DWORD anim_set_8[] = {
static const DWORD anim_set_8[] = { // anim_counter
0x413C6A, 0x413CA3, 0x413CF6, 0x413E76, 0x413EA4, 0x413F03, 0x413F20,
0x413F3A, 0x4156EC, 0x415B72, 0x415C18, 0x415C58, 0x415C6D, 0x415DBE,
};
static const DWORD anim_set_C[] = {
static const DWORD anim_set_C[] = { // flags
0x413B2A, 0x413B33, 0x413B43, 0x413B54, 0x413B66, 0x413BA2, 0x413BAB,
0x413BC0, 0x413BCD, 0x413C3C, 0x413C87, 0x413D01, 0x413D10, 0x413D36,
0x413D53, 0x413DAD, 0x413E93, 0x4155DF, 0x415AE2, 0x415D9A, 0x415DDE,
0x415E06, 0x415E12, 0x417F25, 0x417F30,
};
static const DWORD anim_set_10[] = {
static const DWORD anim_set_C_shift[] = { // flags
0x413AA4, 0x413DBC,
};
static const DWORD anim_set_10[] = { // anim_0
0x413C7E, 0x413E8A, 0x413F17, 0x415C24, 0x415D16, 0x415D44,
};
static const DWORD anim_set_14[] = {
static const DWORD anim_set_14[] = { // anim_0.source
0x413C76, 0x413E82, 0x413F0F, 0x415C3E, 0x415D0E, 0x415D4D,
};
static const DWORD anim_set_28[] = {
static const DWORD anim_set_28[] = { // anim_0.delay
0x413D1C, 0x41570D, 0x415720,
};
@@ -153,42 +150,26 @@ static const DWORD sad_28[] = {
0x4173CE, 0x4174C1, 0x4175F1, 0x417730,
};
static DWORD __fastcall AnimCombatFix(fo::GameObject* src, BYTE combatFlag) {
DWORD animAddr = animSetAddr;
if (animationLimit > 32) {
animAddr += animRecordSize; // include a dummy
}
if (combatFlag & 2) { // combat flag is set
__asm call fo::funcoffs::combat_anim_finished_;
}
return animAddr;
}
static void __declspec(naked) anim_set_end_hack() {
__asm {
push ecx;
call AnimCombatFix;
mov [eax][esi], ebx;
pop ecx;
xor dl, dl; // for goto 0x415DF2;
test dl, 2; // is combat flag set?
jz skip;
call fo::funcoffs::combat_anim_finished_;
skip:
mov eax, animSet;
mov [eax][esi], ebx; // anim_set.curr_anim = -1000
retn;
}
}
static DWORD __fastcall CheckSetSad(BYTE openFlag, DWORD valueMul) {
bool result = false;
int offset = (sadSize * valueMul) + 32;
if (*(DWORD*)(sadAddr + offset) == -1000) {
result = true;
static bool __fastcall CheckSetSad(BYTE openFlag, DWORD slot) {
if (animSad[slot].currentAnim == -1000) {
return true;
} else if (!InCombat() && !(openFlag & 1)) {
*(DWORD*)(sadAddr + offset) = -1000;
result = true;
animSad[slot].currentAnim = -1000;
return true;
}
return result;
return false;
}
static void __declspec(naked) object_move_hack() {
@@ -196,9 +177,9 @@ static void __declspec(naked) object_move_hack() {
static const DWORD object_move_back1 = 0x417616;
__asm {
mov ecx, ds:[ecx + 0x3C]; // openFlag
mov edx, [esp + 0x4C - 0x20]; // valueMul
mov edx, [esp + 0x4C - 0x20]; // slot (valueMul)
call CheckSetSad;
test eax, eax;
test al, al;
jz end;
jmp object_move_back0; // fixed jump
end:
@@ -245,105 +226,61 @@ void ApplyAnimationsAtOncePatches(signed char aniMax) {
if (aniMax <= 32) return;
//allocate memory to store larger animation struct arrays
new_anim_set.resize(aniMax + 1);
new_sad.resize(sadSize * (aniMax + 1));
sf_anim_set.resize(aniMax + 1); // include a dummy
sf_sad.resize(aniMax + 1); // -8?
animSetAddr = reinterpret_cast<DWORD>(new_anim_set.data());
sadAddr = reinterpret_cast<DWORD>(new_sad.data());
//replace addresses for arrays
animSet = &sf_anim_set[1]; // the zero slot for the game remains unused
animSad = sf_sad.data();
//set general animation limit check (old 20) aniMax-12 -- +12 reserved for PC movement(4) + other critical animations(8)?
//set general animation limit check (old 20) aniMax-12 (4 reserved for PC movement + 8 other critical animations?)
SafeWriteBatch<BYTE>(aniMax - 12, { 0x413C07 });
//PC movement animation limit checks (old 24) aniMax-8 -- +8 reserved for other critical animations?.
//PC movement animation limit checks (old 24) aniMax-8 (8 reserved for other critical animations?)
SafeWriteBatch<BYTE>(aniMax - 8, animPCMove);
//Max animation limit checks (old 32) aniMax
SafeWriteBatch<BYTE>(aniMax, animMaxCheck);
//Max animations checks - animation struct size * max num of animations (old 2656*32=84992)
SafeWriteBatch<DWORD>(animRecordSize * aniMax, animMaxSizeCheck);
SafeWriteBatch<DWORD>(sizeof(fo::AnimationSet) * aniMax, animMaxSizeCheck);
//divert old animation structure list pointers to newly allocated memory
//struct array 1///////////////////
fo::AnimationSet* animSetAddr = &sf_anim_set[0];
//old addr 0x54C1B4
SafeWriteBatch<DWORD>(animSetAddr, { 0x413A9E });
SafeWriteBatch<DWORD>((DWORD)&animSetAddr->currentAnim, { 0x413A9E }); // anim_reset_
//old addr 0x54C1C0
SafeWriteBatch<DWORD>(12 + animSetAddr, fake_anim_set_C);
SafeWriteBatch<DWORD>((DWORD)&animSetAddr->flags, anim_set_C_shift);
//old addr 0x54CC14
SafeWriteBatch<DWORD>(animRecordSize + animSetAddr, anim_set_0);
SafeWriteBatch<DWORD>((DWORD)&animSet->currentAnim, anim_set_0);
SafeWriteBatch<DWORD>((DWORD)&animSet->counter, anim_set_4);
SafeWriteBatch<DWORD>((DWORD)&animSet->totalAnimCount, anim_set_8);
SafeWriteBatch<DWORD>((DWORD)&animSet->flags, anim_set_C);
SafeWriteBatch<DWORD>((DWORD)&animSet->animations[0].number, anim_set_10);
SafeWriteBatch<DWORD>((DWORD)&animSet->animations[0].source, anim_set_14);
SafeWriteBatch<DWORD>((DWORD)&animSet->animations[0].animCode, { 0x413F29 });
SafeWriteBatch<DWORD>((DWORD)&animSet->animations[0].delay, anim_set_28);
SafeWriteBatch<DWORD>((DWORD)&animSet->animations[0].flags, { 0x415C35 });
//old addr 0x54CC18
SafeWriteBatch<DWORD>(animRecordSize + 4 + animSetAddr, anim_set_4);
//old addr 0x54CC1C
SafeWriteBatch<DWORD>(animRecordSize + 8 + animSetAddr, anim_set_8);
//old addr 0x54CC20
SafeWriteBatch<DWORD>(animRecordSize + 12 + animSetAddr, anim_set_C);
//old addr 0x54CC24
SafeWriteBatch<DWORD>(animRecordSize + 16 + animSetAddr, anim_set_10);
//old addr 0x54CC28
SafeWriteBatch<DWORD>(animRecordSize + 20 + animSetAddr, anim_set_14);
//old addr 0x54CC38
SafeWriteBatch<DWORD>(animRecordSize + 36 + animSetAddr, { 0x413F29 });
//old addr 0x54CC3C
SafeWriteBatch<DWORD>(animRecordSize + 40 + animSetAddr, anim_set_28);
//old addr 0x54CC48
SafeWriteBatch<DWORD>(animRecordSize + 52 + animSetAddr, { 0x415C35 });
//struct array 2///////////////////
//old addr 0x530014
SafeWriteBatch<DWORD>(sadAddr, sad_0);
//old addr 0x530018
SafeWriteBatch<DWORD>(4 + sadAddr, sad_4);
//old addr 0x53001C
SafeWriteBatch<DWORD>(8 + sadAddr, sad_8);
//old addr 0x530020
SafeWriteBatch<DWORD>(12 + sadAddr, sad_C);
//old addr 0x530024
SafeWriteBatch<DWORD>(16 + sadAddr, sad_10);
//old addr 0x530028
SafeWriteBatch<DWORD>(20 + sadAddr, sad_14);
//old addr 0x53002C
SafeWriteBatch<DWORD>(24 + sadAddr, sad_18);
//old addr 0x530030
SafeWriteBatch<DWORD>(28 + sadAddr, sad_1C);
//old addr 0x530034
SafeWriteBatch<DWORD>(32 + sadAddr, sad_20);
//old addr 0x530038
SafeWriteBatch<DWORD>(36 + sadAddr, sad_24);
//old addr 0x53003A
SafeWriteBatch<DWORD>(38 + sadAddr, { 0x416903 });
//old addr 0x53003B
SafeWriteBatch<DWORD>(39 + sadAddr, sad_27);
//old addr 0x53003C
SafeWriteBatch<DWORD>(40 + sadAddr, sad_28);
SafeWriteBatch<DWORD>((DWORD)&animSad->flags, sad_0);
SafeWriteBatch<DWORD>((DWORD)&animSad->source, sad_4);
SafeWriteBatch<DWORD>((DWORD)&animSad->fid, sad_8);
SafeWriteBatch<DWORD>((DWORD)&animSad->animCode, sad_C);
SafeWriteBatch<DWORD>((DWORD)&animSad->ticks, sad_10);
SafeWriteBatch<DWORD>((DWORD)&animSad->tpf, sad_14);
SafeWriteBatch<DWORD>((DWORD)&animSad->currAnimSet, sad_18);
SafeWriteBatch<DWORD>((DWORD)&animSad->pathCount, sad_1C);
SafeWriteBatch<DWORD>((DWORD)&animSad->currentAnim, sad_20);
SafeWriteBatch<DWORD>((DWORD)&animSad->dstTile, sad_24);
SafeWriteBatch<DWORD>((DWORD)&animSad->rotation1, { 0x416903 });
SafeWriteBatch<DWORD>((DWORD)&animSad->rotation2, sad_27);
SafeWriteBatch<DWORD>((DWORD)&animSad->pathData[0].tile, sad_28);
}
void Animations::init() {
animationLimit = IniReader::GetConfigInt("Misc", "AnimationsAtOnceLimit", 32);
int animationLimit = IniReader::GetConfigInt("Misc", "AnimationsAtOnceLimit", 32);
if (animationLimit > 32) {
if (animationLimit > 127) {
animationLimit = 127;
@@ -352,8 +289,10 @@ void Animations::init() {
ApplyAnimationsAtOncePatches(animationLimit);
dlogr(" Done", DL_INIT);
}
// Fix for calling anim() functions in combat
MakeCall(0x415DE2, anim_set_end_hack, 1);
SafeWrite8(0x415DEB, CodeType::JumpShort); // jz > jmp
// Fix crash when the critter goes through a door with animation trigger
MakeJump(0x41755E, object_move_hack);