mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Improved the functionality of ElevatorsFile to allow to change the FRM images of the elevator panel and create new elevator types (from Mr.Stalin)
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
;Controls the elevators
|
||||
;Image must match up with the image of an existing elevator
|
||||
;Image must match up with the image of an existing elevator (can be overrided in sfall 4.1.4 or newer)
|
||||
;Make sure you specify the correct number of exit targets
|
||||
;The maximum number of elevators is currently capped at 50
|
||||
;Use the line number (0-indexed) of the corresponding FRM in intrface.lst to set the appearance of the elevator
|
||||
|
||||
;Override elevator 0
|
||||
[000]
|
||||
;This elevator uses the frm of the original forth elevator
|
||||
[0]
|
||||
;This elevator will use the settings of the original forth elevator
|
||||
Image=4
|
||||
|
||||
;Set up the first exit point
|
||||
@@ -24,3 +25,22 @@ Elevation3=0
|
||||
Tile3=12944
|
||||
|
||||
;No forth exit point
|
||||
|
||||
;Override FRM images of elevator 0. Set ButtonsFrm to -1 to use default buttons from MainFrm
|
||||
MainFrm=143
|
||||
ButtonsFrm=-1
|
||||
|
||||
|
||||
;An example of a new elevator
|
||||
[24]
|
||||
;Set Image to 24 to create a new elevator type (0-23 are the original elevator types)
|
||||
Image=24
|
||||
|
||||
;Set the number of buttons
|
||||
ButtonCount=3
|
||||
|
||||
;Set up the appearance of the elevator
|
||||
MainFrm=148
|
||||
ButtonsFrm=151
|
||||
|
||||
;Set up the exit points for all three buttons (see examples above)
|
||||
|
||||
@@ -260,6 +260,12 @@ struct ElevatorExit {
|
||||
long tile;
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
struct ElevatorFrms {
|
||||
DWORD main;
|
||||
DWORD buttons;
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
struct FrmFile {
|
||||
long id; //0x00
|
||||
|
||||
+56
-32
@@ -27,70 +27,74 @@ namespace sfall
|
||||
static const int exitsPerElevator = 4;
|
||||
static const int vanillaElevatorCount = 24;
|
||||
static const int elevatorCount = 50;
|
||||
static char elevFile[MAX_PATH];
|
||||
|
||||
static fo::ElevatorExit elevatorExits[elevatorCount][exitsPerElevator];
|
||||
static DWORD menus[elevatorCount];
|
||||
static char elevFile[MAX_PATH] = ".\\";
|
||||
|
||||
static DWORD elevatorType[elevatorCount];
|
||||
static fo::ElevatorExit elevatorExits[elevatorCount][exitsPerElevator]; // _retvals
|
||||
static fo::ElevatorFrms elevatorsFrms[elevatorCount]; // _intotal
|
||||
static DWORD elevatorsBtnCount[elevatorCount]; // _btncount
|
||||
|
||||
static void __declspec(naked) GetMenuHook() {
|
||||
__asm {
|
||||
push ebx;
|
||||
lea ebx, menus;
|
||||
lea edx, elevatorType;
|
||||
shl eax, 2;
|
||||
mov eax, [ebx+eax];
|
||||
call fo::funcoffs::elevator_start_;
|
||||
pop ebx;
|
||||
ret;
|
||||
mov eax, [edx + eax];
|
||||
jmp fo::funcoffs::elevator_start_;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) UnknownHook() {
|
||||
static void __declspec(naked) CheckHotKeysHook() {
|
||||
__asm {
|
||||
cmp eax, vanillaElevatorCount;
|
||||
jge skip; // skip hotkeys data
|
||||
push ebx;
|
||||
lea ebx, menus;
|
||||
lea ebx, elevatorType;
|
||||
shl eax, 2;
|
||||
mov eax, [ebx + eax];
|
||||
call fo::funcoffs::Check4Keys_;
|
||||
pop ebx;
|
||||
ret;
|
||||
retn;
|
||||
skip:
|
||||
xor eax, eax;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static void __declspec(naked) UnknownHook2() {
|
||||
__asm {
|
||||
push ebx;
|
||||
lea ebx, menus;
|
||||
lea edx, elevatorType;
|
||||
shl eax, 2;
|
||||
mov eax, [ebx+eax];
|
||||
call fo::funcoffs::elevator_end_;
|
||||
pop ebx;
|
||||
ret;
|
||||
mov eax, [edx + eax];
|
||||
jmp fo::funcoffs::elevator_end_;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static void __declspec(naked) GetNumButtonsHook1() {
|
||||
__asm {
|
||||
lea esi, menus;
|
||||
lea esi, elevatorType;
|
||||
mov eax, [esi + edi * 4];
|
||||
mov eax, [FO_VAR_btncnt + eax*4];
|
||||
mov eax, [elevatorsBtnCount + eax * 4];
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) GetNumButtonsHook2() {
|
||||
__asm {
|
||||
lea edx, menus;
|
||||
lea edx, elevatorType;
|
||||
mov eax, [edx + edi * 4];
|
||||
mov eax, [FO_VAR_btncnt + eax*4];
|
||||
mov eax, [elevatorsBtnCount + eax * 4];
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) GetNumButtonsHook3() {
|
||||
__asm {
|
||||
lea eax, menus;
|
||||
lea eax, elevatorType;
|
||||
mov eax, [eax + edi * 4];
|
||||
mov eax, [FO_VAR_btncnt+eax*4];
|
||||
mov eax, [elevatorsBtnCount + eax * 4];
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -98,13 +102,28 @@ static void __declspec(naked) GetNumButtonsHook3() {
|
||||
void ResetElevators() {
|
||||
memcpy(elevatorExits, fo::var::retvals, sizeof(fo::ElevatorExit) * vanillaElevatorCount * exitsPerElevator);
|
||||
memset(&elevatorExits[vanillaElevatorCount], 0, sizeof(fo::ElevatorExit) * (elevatorCount - vanillaElevatorCount) * exitsPerElevator);
|
||||
for (int i = 0; i < vanillaElevatorCount; i++) menus[i] = i;
|
||||
for (int i = vanillaElevatorCount; i < elevatorCount; i++) menus[i] = 0;
|
||||
|
||||
memcpy(elevatorsFrms, (void*)FO_VAR_intotal, sizeof(fo::ElevatorFrms) * vanillaElevatorCount);
|
||||
memset(&elevatorsFrms[vanillaElevatorCount], 0, sizeof(fo::ElevatorFrms) * (elevatorCount - vanillaElevatorCount));
|
||||
|
||||
memcpy(elevatorsBtnCount, (void*)FO_VAR_btncnt, sizeof(DWORD) * vanillaElevatorCount);
|
||||
|
||||
for (int i = 0; i < vanillaElevatorCount; i++) elevatorType[i] = i;
|
||||
for (int i = vanillaElevatorCount; i < elevatorCount; i++) elevatorType[i] = 0;
|
||||
|
||||
char section[4];
|
||||
if (elevFile) {
|
||||
for (int i = 0; i < elevatorCount; i++) {
|
||||
_itoa_s(i, section, 10);
|
||||
menus[i] = GetPrivateProfileIntA(section, "Image", menus[i], elevFile);
|
||||
int type = GetPrivateProfileIntA(section, "Image", elevatorType[i], elevFile);
|
||||
elevatorType[i] = min(type, elevatorCount - 1);
|
||||
if (i >= vanillaElevatorCount) {
|
||||
int cBtn = GetPrivateProfileIntA(section, "ButtonCount", 2, elevFile);
|
||||
if (cBtn > exitsPerElevator) cBtn = exitsPerElevator;
|
||||
elevatorsBtnCount[i] = max(2, cBtn);
|
||||
}
|
||||
elevatorsFrms[i].main = GetPrivateProfileIntA(section, "MainFrm", elevatorsFrms[i].main, elevFile);
|
||||
elevatorsFrms[i].buttons = GetPrivateProfileIntA(section, "ButtonsFrm", elevatorsFrms[i].buttons, elevFile);
|
||||
char setting[32];
|
||||
for (int j = 0; j < exitsPerElevator; j++) {
|
||||
sprintf_s(setting, "ID%d", j + 1);
|
||||
@@ -119,21 +138,26 @@ void ResetElevators() {
|
||||
}
|
||||
|
||||
void ElevatorsInit(const char* file) {
|
||||
strcpy_s(elevFile, ".\\");
|
||||
strcat_s(elevFile, file);
|
||||
|
||||
HookCall(0x43EF83, GetMenuHook);
|
||||
HookCall(0x43F141, UnknownHook);
|
||||
HookCall(0x43F2D2, UnknownHook2);
|
||||
HookCall(0x43F141, CheckHotKeysHook);
|
||||
//HookCall(0x43F2D2, UnknownHook2); // unused
|
||||
|
||||
SafeWrite8(0x43EF76, (BYTE)elevatorCount);
|
||||
SafeWrite32(0x43EFA4, (DWORD)elevatorExits);
|
||||
SafeWrite32(0x43EFB9, (DWORD)elevatorExits);
|
||||
SafeWrite32(0x43EFEA, (DWORD)&elevatorExits[0][0].tile);
|
||||
SafeWrite32(0x43F2FC, (DWORD)elevatorExits);
|
||||
SafeWrite32(0x43F309, (DWORD)&elevatorExits[0][0].elevation);
|
||||
SafeWrite32(0x43EFEA, (DWORD)&elevatorExits[0][0].tile);
|
||||
SafeWrite32(0x43F315, (DWORD)&elevatorExits[0][0].tile);
|
||||
SafeWrite32(0x43F309, (DWORD)&elevatorExits[0][0].elevation);
|
||||
|
||||
SafeWrite32(0x43F438, (DWORD)&elevatorsFrms[0].main);
|
||||
SafeWrite32(0x43F475, (DWORD)&elevatorsFrms[0].buttons);
|
||||
|
||||
// _btncnt
|
||||
SafeWrite32(0x43F65E, (DWORD)elevatorsBtnCount);
|
||||
SafeWrite32(0x43F6BB, (DWORD)elevatorsBtnCount);
|
||||
MakeCall(0x43F05D, GetNumButtonsHook1, 2);
|
||||
MakeCall(0x43F184, GetNumButtonsHook2, 2);
|
||||
MakeCall(0x43F1E4, GetNumButtonsHook3, 2);
|
||||
|
||||
Reference in New Issue
Block a user