Add elevators improvements (#29)

This commit is contained in:
Alexander Batalov 2022-08-03 12:34:13 +03:00
parent 8a2ca4b733
commit f5060c301b
5 changed files with 83 additions and 5 deletions

View File

@ -12,11 +12,14 @@
#include "map.h"
#include "pipboy.h"
#include "scripts.h"
#include "sfall_config.h"
#include "window_manager.h"
#include <ctype.h>
#include <string.h>
#include <algorithm>
// The maximum number of elevator levels.
#define ELEVATOR_LEVEL_MAX (4)
@ -26,6 +29,10 @@
// (instead of using NULL).
#define ELEVATOR_BACKGROUND_NULL ((unsigned char*)(-1))
// Max number of elevators that can be loaded from elevators.ini. This limit is
// emposed by Sfall.
#define ELEVATORS_MAX 50
typedef enum ElevatorFrm {
ELEVATOR_FRM_BUTTON_DOWN,
ELEVATOR_FRM_BUTTON_UP,
@ -56,7 +63,7 @@ static const int gElevatorFrmIds[ELEVATOR_FRM_COUNT] = {
};
// 0x43E95C
static const ElevatorBackground gElevatorBackgrounds[ELEVATOR_COUNT] = {
static ElevatorBackground gElevatorBackgrounds[ELEVATORS_MAX] = {
{ 143, -1 },
{ 143, 150 },
{ 144, -1 },
@ -86,7 +93,7 @@ static const ElevatorBackground gElevatorBackgrounds[ELEVATOR_COUNT] = {
// Number of levels for eleveators.
//
// 0x43EA1C
static const int gElevatorLevels[ELEVATOR_COUNT] = {
static int gElevatorLevels[ELEVATORS_MAX] = {
4,
2,
3,
@ -114,7 +121,7 @@ static const int gElevatorLevels[ELEVATOR_COUNT] = {
};
// 0x43EA7C
static const ElevatorDescription gElevatorDescriptions[ELEVATOR_COUNT][ELEVATOR_LEVEL_MAX] = {
static ElevatorDescription gElevatorDescriptions[ELEVATORS_MAX][ELEVATOR_LEVEL_MAX] = {
{
{ 14, 0, 18940 },
{ 14, 1, 18936 },
@ -264,7 +271,7 @@ static const ElevatorDescription gElevatorDescriptions[ELEVATOR_COUNT][ELEVATOR_
// NOTE: These values are also used as key bindings.
//
// 0x43EEFC
static const char gElevatorLevelLabels[ELEVATOR_COUNT][ELEVATOR_LEVEL_MAX] = {
static char gElevatorLevelLabels[ELEVATORS_MAX][ELEVATOR_LEVEL_MAX] = {
{ '1', '2', '3', '4' },
{ 'G', '1', '\0', '\0' },
{ '1', '2', '3', '\0' },
@ -360,10 +367,11 @@ static unsigned char* gElevatorPanelFrmData;
// 0x43EF5C
int elevatorSelectLevel(int elevator, int* mapPtr, int* elevationPtr, int* tilePtr)
{
if (elevator < 0 || elevator >= ELEVATOR_COUNT) {
if (elevator < 0 || elevator >= ELEVATORS_MAX) {
return -1;
}
// SFALL
if (elevatorWindowInit(elevator) == -1) {
return -1;
}
@ -681,3 +689,65 @@ static int elevatorGetLevelFromKeyCode(int elevator, int keyCode)
}
return 0;
}
void elevatorsInit()
{
char* elevatorsFileName;
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_ELEVATORS_FILE_KEY, &elevatorsFileName);
if (elevatorsFileName != NULL && *elevatorsFileName == '\0') {
elevatorsFileName = NULL;
}
if (elevatorsFileName != NULL) {
Config elevatorsConfig;
if (configInit(&elevatorsConfig)) {
if (configRead(&elevatorsConfig, elevatorsFileName, false)) {
char sectionKey[4];
char key[32];
for (int index = 0; index < ELEVATORS_MAX; index++) {
sprintf(sectionKey, "%d", index);
if (index >= ELEVATOR_COUNT) {
int levels = 0;
configGetInt(&elevatorsConfig, sectionKey, "ButtonCount", &levels);
gElevatorLevels[index] = std::clamp(levels, 2, ELEVATOR_LEVEL_MAX);
}
configGetInt(&elevatorsConfig, sectionKey, "MainFrm", &(gElevatorBackgrounds[index].backgroundFrmId));
configGetInt(&elevatorsConfig, sectionKey, "ButtonsFrm", &(gElevatorBackgrounds[index].panelFrmId));
for (int level = 0; level < ELEVATOR_LEVEL_MAX; level++) {
sprintf(key, "ID%d", level + 1);
configGetInt(&elevatorsConfig, sectionKey, key, &(gElevatorDescriptions[index][level].map));
sprintf(key, "Elevation%d", level + 1);
configGetInt(&elevatorsConfig, sectionKey, key, &(gElevatorDescriptions[index][level].elevation));
sprintf(key, "Tile%d", level + 1);
configGetInt(&elevatorsConfig, sectionKey, key, &(gElevatorDescriptions[index][level].tile));
}
}
// NOTE: Sfall implementation is slightly different. It uses one
// loop and stores `type` value in a separate lookup table. This
// value is then used in the certain places to remap from
// requested elevator to the new one.
for (int index = 0; index < ELEVATORS_MAX; index++) {
sprintf(sectionKey, "%d", index);
int type;
if (configGetInt(&elevatorsConfig, sectionKey, "Image", &type)) {
type = std::clamp(type, 0, ELEVATORS_MAX - 1);
if (index != type) {
memcpy(&(gElevatorBackgrounds[index]), &(gElevatorBackgrounds[type]), sizeof(*gElevatorBackgrounds));
memcpy(&(gElevatorLevels[index]), &(gElevatorLevels[type]), sizeof(*gElevatorLevels));
memcpy(&(gElevatorLevelLabels[index]), &(gElevatorLevelLabels[type]), sizeof(*gElevatorLevelLabels));
}
}
}
}
configFree(&elevatorsConfig);
}
}
}

View File

@ -20,4 +20,6 @@ typedef enum Elevator {
int elevatorSelectLevel(int elevator, int* mapPtr, int* elevationPtr, int* tilePtr);
void elevatorsInit();
#endif /* ELEVATOR_H */

View File

@ -11,6 +11,7 @@
#include "cycle.h"
#include "debug.h"
#include "draw.h"
#include "elevator.h"
#include "game.h"
#include "game_config.h"
#include "game_mouse.h"
@ -215,6 +216,9 @@ int isoInit()
debugPrint(">intface_init\t\t");
// SFALL
elevatorsInit();
mapMakeMapsDirectory();
gEnteringElevation = -1;

View File

@ -38,6 +38,7 @@ bool sfallConfigInit(int argc, char** argv)
configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_OVERRIDE_CRITICALS_FILE_KEY, "");
configSetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_REMOVE_CRITICALS_TIME_LIMITS_KEY, false);
configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BOOKS_FILE_KEY, "");
configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_ELEVATORS_FILE_KEY, "");
char path[COMPAT_MAX_PATH];
char* executable = argv[0];

View File

@ -26,6 +26,7 @@
#define SFALL_CONFIG_OVERRIDE_CRITICALS_FILE_KEY "OverrideCriticalFile"
#define SFALL_CONFIG_REMOVE_CRITICALS_TIME_LIMITS_KEY "RemoveCriticalTimelimits"
#define SFALL_CONFIG_BOOKS_FILE_KEY "BooksFile"
#define SFALL_CONFIG_ELEVATORS_FILE_KEY "ElevatorsFile"
extern bool gSfallConfigInitialized;
extern Config gSfallConfig;