mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
[Et tu] Implement Start{X|Y}Pos (#585)
* [Et tu] Implement `Start{X|Y}Pos`, `ViewX|Y`
This commit is contained in:
@@ -42,6 +42,11 @@ The following settings were moved into [`<DAT>/config/game.cfg`](files/ce.dat/co
|
||||
|
||||
| ddraw.ini section | ddraw.ini key | game.cfg section | game.cfg key |
|
||||
| --- | --- | --- | --- |
|
||||
| `Misc` | `StartingMap` | `start` | `map` |
|
||||
| `Misc` | `StartXPos` | `start` | `worldmap_x` |
|
||||
| `Misc` | `StartYPos` | `start` | `worldmap_y` |
|
||||
| `Misc` | `ViewXPos` | `start` | `worldmap_view_x` |
|
||||
| `Misc` | `ViewYPos` | `start` | `worldmap_view_y` |
|
||||
| `Misc` | `StartGDialogFix` | `dialog` | `start_gdialog_fix` |
|
||||
|
||||
## Opcodes / Metarules
|
||||
|
||||
@@ -11,6 +11,12 @@ month=6
|
||||
day=24
|
||||
; To start a new game somewhere other than artemple.map, set this to the map file name.
|
||||
map=
|
||||
; Starting worldmap marker position. -1 uses the starting map's world area.
|
||||
worldmap_x=-1
|
||||
worldmap_y=-1
|
||||
; Starting worldmap viewport position. -1 uses the default upper-left view.
|
||||
worldmap_view_x=-1
|
||||
worldmap_view_y=-1
|
||||
; Starting (tribal) and default (jumpsuit) player models. Can also be changed in-game via script.
|
||||
model_male=hmwarr
|
||||
model_male_default=hmjmps
|
||||
|
||||
@@ -175,6 +175,10 @@ namespace {
|
||||
constexpr SfallMigrationEntry kSfallMigrationEntries[] = {
|
||||
// [start]
|
||||
{ kSfallMisc, "StartingMap", CONTENT_CONFIG_START_SECTION, "map", "" },
|
||||
{ kSfallMisc, "StartXPos", CONTENT_CONFIG_START_SECTION, "worldmap_x", "-1" },
|
||||
{ kSfallMisc, "StartYPos", CONTENT_CONFIG_START_SECTION, "worldmap_y", "-1" },
|
||||
{ kSfallMisc, "ViewXPos", CONTENT_CONFIG_START_SECTION, "worldmap_view_x", "-1" },
|
||||
{ kSfallMisc, "ViewYPos", CONTENT_CONFIG_START_SECTION, "worldmap_view_y", "-1" },
|
||||
{ kSfallMisc, "MaleStartModel", CONTENT_CONFIG_START_SECTION, "model_male", "hmwarr" },
|
||||
{ kSfallMisc, "MaleDefaultModel", CONTENT_CONFIG_START_SECTION, "model_male_default", "hmjmps" },
|
||||
{ kSfallMisc, "FemaleStartModel", CONTENT_CONFIG_START_SECTION, "model_female", "hfprim" },
|
||||
|
||||
+13
@@ -331,6 +331,19 @@ static int _main_load_new(char* mapFileName)
|
||||
gameMouseSetCursor(MOUSE_CURSOR_NONE);
|
||||
mouseShowCursor();
|
||||
mapLoadByName(mapFileName);
|
||||
|
||||
// SFALL: Fix the starting position of the player's marker on the world map
|
||||
// when starting a new game with a custom starting map.
|
||||
int areaIdx;
|
||||
if (wmMatchAreaContainingMapIdx(gMapHeader.index, &areaIdx) == 0) {
|
||||
if (wmStartWorldPosIsConfigured()) {
|
||||
wmSetPartyCurArea(areaIdx);
|
||||
wmClearPartyWalking();
|
||||
} else {
|
||||
wmTeleportToArea(areaIdx);
|
||||
}
|
||||
}
|
||||
|
||||
wmMapMusicStart();
|
||||
paletteFadeTo(gPaletteWhite);
|
||||
windowDestroy(win);
|
||||
|
||||
+95
-4
@@ -480,6 +480,10 @@ static std::vector<std::pair<int, std::string>> wmTerrainNameOverrides;
|
||||
static void wmSetFlags(int* flagsPtr, int flag, int value);
|
||||
static int wmGenDataInit();
|
||||
static int wmGenDataReset();
|
||||
static void wmGenDataSetStartWorldPos();
|
||||
static bool wmGetStartWorldMapConfigValue(const char* key, int* valuePtr);
|
||||
static void wmGenDataClampWorldPosToBounds();
|
||||
static void wmSetStartWorldView();
|
||||
static int wmWorldMapSaveTempData();
|
||||
static int wmWorldMapLoadTempData();
|
||||
static int wmConfigInit();
|
||||
@@ -979,8 +983,11 @@ int wmWorldMap_init()
|
||||
return -1;
|
||||
}
|
||||
|
||||
wmGenDataClampWorldPosToBounds();
|
||||
|
||||
wmGenData.viewportMaxX = WM_TILE_WIDTH * wmNumHorizontalTiles - WM_VIEW_WIDTH;
|
||||
wmGenData.viewportMaxY = WM_TILE_HEIGHT * (wmMaxTileNum / wmNumHorizontalTiles) - WM_VIEW_HEIGHT;
|
||||
wmSetStartWorldView();
|
||||
circleBlendTable = _getColorBlendTable(COLOR_GREEN);
|
||||
|
||||
wmMarkSubTileRadiusVisited(wmGenData.worldPosX, wmGenData.worldPosY);
|
||||
@@ -1009,8 +1016,7 @@ static int wmGenDataInit()
|
||||
{
|
||||
gDidMeetFrankHorrigan = false;
|
||||
wmGenData.currentAreaId = -1;
|
||||
wmGenData.worldPosX = 173;
|
||||
wmGenData.worldPosY = 122;
|
||||
wmGenDataSetStartWorldPos();
|
||||
wmGenData.currentSubtile = nullptr;
|
||||
wmGenData.dword_672E18 = 0;
|
||||
wmGenData.isWalking = false;
|
||||
@@ -1076,8 +1082,8 @@ static int wmGenDataReset()
|
||||
wmGenData.encounterIconIsVisible = false;
|
||||
mousePressed = false;
|
||||
wmGenData.currentAreaId = -1;
|
||||
wmGenData.worldPosX = 173;
|
||||
wmGenData.worldPosY = 122;
|
||||
wmGenDataSetStartWorldPos();
|
||||
wmGenDataClampWorldPosToBounds();
|
||||
wmGenData.walkDestinationX = -1;
|
||||
wmGenData.walkDestinationY = -1;
|
||||
wmGenData.encounterMapId = -1;
|
||||
@@ -1113,6 +1119,70 @@ static int wmGenDataReset()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wmGenDataSetStartWorldPos()
|
||||
{
|
||||
wmGenData.worldPosX = 173;
|
||||
wmGenData.worldPosY = 122;
|
||||
|
||||
int value;
|
||||
if (wmGetStartWorldMapConfigValue("worldmap_x", &value)) {
|
||||
wmGenData.worldPosX = value;
|
||||
}
|
||||
|
||||
if (wmGetStartWorldMapConfigValue("worldmap_y", &value)) {
|
||||
wmGenData.worldPosY = value;
|
||||
}
|
||||
}
|
||||
|
||||
static bool wmGetStartWorldMapConfigValue(const char* key, int* valuePtr)
|
||||
{
|
||||
assert(key != nullptr);
|
||||
assert(valuePtr != nullptr);
|
||||
|
||||
int value;
|
||||
if (!configGetInt(&gContentConfig, CONTENT_CONFIG_START_SECTION, key, &value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*valuePtr = std::max(value, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void wmGenDataClampWorldPosToBounds()
|
||||
{
|
||||
if (wmNumHorizontalTiles <= 0 || wmMaxTileNum <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int worldMaxX = WM_TILE_WIDTH * wmNumHorizontalTiles;
|
||||
int worldMaxY = WM_TILE_HEIGHT * (wmMaxTileNum / wmNumHorizontalTiles);
|
||||
if (worldMaxX <= 0 || worldMaxY <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
wmGenData.worldPosX = std::clamp(wmGenData.worldPosX, 0, worldMaxX - 1);
|
||||
wmGenData.worldPosY = std::clamp(wmGenData.worldPosY, 0, worldMaxY - 1);
|
||||
}
|
||||
|
||||
static void wmSetStartWorldView()
|
||||
{
|
||||
wmWorldOffsetX = 0;
|
||||
wmWorldOffsetY = 0;
|
||||
|
||||
int value;
|
||||
if (wmGetStartWorldMapConfigValue("worldmap_view_x", &value)) {
|
||||
wmWorldOffsetX = std::clamp(value, 0, std::max(wmGenData.viewportMaxX, 0));
|
||||
}
|
||||
|
||||
if (wmGetStartWorldMapConfigValue("worldmap_view_y", &value)) {
|
||||
wmWorldOffsetY = std::clamp(value, 0, std::max(wmGenData.viewportMaxY, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// 0x4BCE00 wmWorldMap_exit
|
||||
void wmWorldMap_exit()
|
||||
{
|
||||
@@ -1177,6 +1247,7 @@ int wmWorldMap_reset()
|
||||
gGameTimeIncRemainder = 0.0;
|
||||
|
||||
wmWorldMapLoadTempData();
|
||||
wmSetStartWorldView();
|
||||
wmMarkAllSubTiles(0);
|
||||
|
||||
return wmGenDataReset();
|
||||
@@ -6170,6 +6241,14 @@ int wmGetPartyCurArea(int* areaIdxPtr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool wmStartWorldPosIsConfigured()
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
return wmGetStartWorldMapConfigValue("worldmap_x", &x)
|
||||
|| wmGetStartWorldMapConfigValue("worldmap_y", &y);
|
||||
}
|
||||
|
||||
// 0x4C47D8 wmMarkAllSubTiles
|
||||
static void wmMarkAllSubTiles(int state)
|
||||
{
|
||||
@@ -7087,6 +7166,18 @@ void wmSetPartyWorldPos(int x, int y)
|
||||
wmGenData.worldPosY = y;
|
||||
}
|
||||
|
||||
void wmSetPartyCurArea(int areaIdx)
|
||||
{
|
||||
wmGenData.currentAreaId = cityIsValid(areaIdx) ? areaIdx : -1;
|
||||
}
|
||||
|
||||
void wmClearPartyWalking()
|
||||
{
|
||||
wmGenData.walkDestinationX = 0;
|
||||
wmGenData.walkDestinationY = 0;
|
||||
wmGenData.isWalking = false;
|
||||
}
|
||||
|
||||
void wmCarSetCurrentArea(int area)
|
||||
{
|
||||
wmGenData.currentCarAreaId = area;
|
||||
|
||||
@@ -285,6 +285,9 @@ int wmMatchAreaContainingMapIdx(int mapIdx, int* areaIdxPtr);
|
||||
int wmTeleportToArea(int areaIdx);
|
||||
|
||||
// CE
|
||||
bool wmStartWorldPosIsConfigured();
|
||||
void wmSetPartyCurArea(int areaIdx);
|
||||
void wmClearPartyWalking();
|
||||
void wmSetPartyWorldPos(int x, int y);
|
||||
void wmCarSetCurrentArea(int area);
|
||||
void wmForceEncounter(int map, unsigned int flags);
|
||||
|
||||
Reference in New Issue
Block a user