mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a3b3fe8a5 | ||
|
|
1db054e47a | ||
|
|
8e60a2fba2 | ||
|
|
ca89abad6c | ||
|
|
21a98bebb1 | ||
|
|
283107bebe |
@@ -42,7 +42,18 @@ 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` |
|
||||
| `Sound` | `MainMenuMusic` | `sound` | `main_menu_music` |
|
||||
| `Sound` | `WorldMapMusic` | `sound` | `worldmap_music` |
|
||||
| `Sound` | `WorldMapCarMusic` | `sound` | `worldmap_car_music` |
|
||||
| `Sound` | `EndGameMovieMusic0` | `sound` | `endgame_movie_music0` |
|
||||
| `Sound` | `EndGameMovieMusic1` | `sound` | `endgame_movie_music1` |
|
||||
| `Sound` | `MapLoadingSound` | `sound` | `map_loading_sound` |
|
||||
|
||||
## 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
|
||||
@@ -59,6 +65,18 @@ offset_y=0
|
||||
credits_offset_x=0
|
||||
credits_offset_y=0
|
||||
|
||||
[sound]
|
||||
; Background music played on the main menu.
|
||||
main_menu_music=07desert
|
||||
; Background music played while viewing the world map on foot or in the car.
|
||||
worldmap_music=03wrldmp
|
||||
worldmap_car_music=20car
|
||||
; Music played before and during the end-game credits/movie sequence.
|
||||
endgame_movie_music0=maybe
|
||||
endgame_movie_music1=10labone
|
||||
; Music file played as looping ambience while maps are loading.
|
||||
map_loading_sound=wind2
|
||||
|
||||
[movies]
|
||||
; Number of days after game start when each Hakunin dream sequence becomes available.
|
||||
artimer1=90
|
||||
|
||||
@@ -165,6 +165,16 @@ main_menu_scale_mode=1
|
||||
; Set to 1 to show a Help option in the in-game options menu which opens the F1 help screen.
|
||||
in_game_menu_help=1
|
||||
|
||||
; Weight/size indicator for PC, critters and containers
|
||||
; Set to 0 for vanilla behavior (no weight indicator)
|
||||
; Set to 1 to show a simple weight indicator; works with all inventory_columns values
|
||||
; Set to 2 to show a detailed weight indicator; works with inventory_columns > 1 only
|
||||
loot_weight_indicator=1
|
||||
|
||||
; Set to 0 to show container indicator at all times
|
||||
; Set to XX to show container indicator when size reaches XX%
|
||||
; Set to 100 to show container indicator when full
|
||||
loot_container_size_indicator_threshold=50
|
||||
|
||||
[qol]
|
||||
; Automatically open doors that are unlocked and has no script attached.
|
||||
|
||||
+3
-1
@@ -1789,11 +1789,13 @@ void FrmImage::resetInternal()
|
||||
|
||||
bool FrmImage::setFrame(const Art* art, int frame, int direction)
|
||||
{
|
||||
unsigned char* data = artGetFrameData(art, frame, direction, &_width, &_height, &_xOffset, &_yOffset);
|
||||
unsigned char* data = artGetFrameData(art, frame, direction, &_width, &_height, nullptr, nullptr);
|
||||
if (data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_xOffset = art->xOffsets[direction];
|
||||
_yOffset = art->yOffsets[direction];
|
||||
_data = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace fallout {
|
||||
#define CONTENT_CONFIG_ITEMS_SECTION "items"
|
||||
#define CONTENT_CONFIG_DIALOG_SECTION "dialog"
|
||||
#define CONTENT_CONFIG_MAIN_MENU_SECTION "main_menu"
|
||||
#define CONTENT_CONFIG_SOUND_SECTION "sound"
|
||||
#define CONTENT_CONFIG_MOVIES_SECTION "movies"
|
||||
#define CONTENT_CONFIG_COMBAT_SECTION "combat"
|
||||
#define CONTENT_CONFIG_EXPLOSIONS_SECTION "explosions"
|
||||
|
||||
+11
-2
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "art.h"
|
||||
#include "color.h"
|
||||
#include "content_config.h"
|
||||
#include "credits.h"
|
||||
#include "cycle.h"
|
||||
#include "db.h"
|
||||
@@ -78,6 +79,7 @@ static void _endgame_voiceover_callback();
|
||||
static int endgameEndingSubtitlesLoad(const char* filePath);
|
||||
static void endgameEndingRefreshSubtitles();
|
||||
static void endgameEndingSubtitlesFree();
|
||||
static const char* endgameGetSoundConfig(const char* key, const char* defaultValue);
|
||||
static void _endgame_movie_callback();
|
||||
static void _endgame_movie_bk_process();
|
||||
static int endgameEndingInit();
|
||||
@@ -239,7 +241,7 @@ void endgamePlayMovie()
|
||||
_endgame_maybe_done = 0;
|
||||
tickersAdd(_endgame_movie_bk_process);
|
||||
backgroundSoundSetEndCallback(_endgame_movie_callback);
|
||||
backgroundSoundLoad("akiss", GSOUND_LIMIT_AFTER, GSOUND_STREAM, GSOUND_NO_LOOP);
|
||||
backgroundSoundLoad(endgameGetSoundConfig("endgame_movie_music0", "maybe"), GSOUND_LIMIT_AFTER, GSOUND_STREAM, GSOUND_NO_LOOP);
|
||||
inputPauseForTocks(3000);
|
||||
|
||||
// NOTE: Result is ignored. I guess there was some kind of switch for male
|
||||
@@ -872,6 +874,13 @@ static void endgameEndingSubtitlesFree()
|
||||
gEndgameEndingSubtitlesLength = 0;
|
||||
}
|
||||
|
||||
static const char* endgameGetSoundConfig(const char* key, const char* defaultValue)
|
||||
{
|
||||
char* value = nullptr;
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_SOUND_SECTION, key, &value, nullptr);
|
||||
return value != nullptr && value[0] != '\0' ? value : defaultValue;
|
||||
}
|
||||
|
||||
// 0x440728 endgame_movie_callback
|
||||
static void _endgame_movie_callback()
|
||||
{
|
||||
@@ -882,7 +891,7 @@ static void _endgame_movie_callback()
|
||||
static void _endgame_movie_bk_process()
|
||||
{
|
||||
if (_endgame_maybe_done) {
|
||||
backgroundSoundLoad("10labone", GSOUND_LIMIT_BEFORE, GSOUND_STREAM, GSOUND_LOOP);
|
||||
backgroundSoundLoad(endgameGetSoundConfig("endgame_movie_music1", "10labone"), GSOUND_LIMIT_BEFORE, GSOUND_STREAM, GSOUND_LOOP);
|
||||
backgroundSoundSetEndCallback(nullptr);
|
||||
tickersRemove(_endgame_movie_bk_process);
|
||||
}
|
||||
|
||||
@@ -161,6 +161,7 @@ namespace {
|
||||
|
||||
constexpr char kSfallMisc[] = "Misc";
|
||||
constexpr char kSfallInterface[] = "Interface";
|
||||
constexpr char kSfallSound[] = "Sound";
|
||||
|
||||
struct SfallMigrationEntry {
|
||||
const char* sfallSection;
|
||||
@@ -175,6 +176,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" },
|
||||
@@ -195,6 +200,13 @@ namespace {
|
||||
{ kSfallMisc, "MainMenuOffsetY", CONTENT_CONFIG_MAIN_MENU_SECTION, "offset_y", "0" },
|
||||
{ kSfallMisc, "MainMenuCreditsOffsetX", CONTENT_CONFIG_MAIN_MENU_SECTION, "credits_offset_x", "0" },
|
||||
{ kSfallMisc, "MainMenuCreditsOffsetY", CONTENT_CONFIG_MAIN_MENU_SECTION, "credits_offset_y", "0" },
|
||||
// [sound]
|
||||
{ kSfallSound, "MainMenuMusic", CONTENT_CONFIG_SOUND_SECTION, "main_menu_music", "07desert" },
|
||||
{ kSfallSound, "WorldMapMusic", CONTENT_CONFIG_SOUND_SECTION, "worldmap_music", "03wrldmp" },
|
||||
{ kSfallSound, "WorldMapCarMusic", CONTENT_CONFIG_SOUND_SECTION, "worldmap_car_music", "20car" },
|
||||
{ kSfallSound, "EndGameMovieMusic0", CONTENT_CONFIG_SOUND_SECTION, "endgame_movie_music0", "maybe" },
|
||||
{ kSfallSound, "EndGameMovieMusic1", CONTENT_CONFIG_SOUND_SECTION, "endgame_movie_music1", "10labone" },
|
||||
{ kSfallSound, "MapLoadingSound", CONTENT_CONFIG_SOUND_SECTION, "map_loading_sound", "wind2" },
|
||||
// [movies]
|
||||
{ kSfallMisc, "MovieTimer_artimer1", CONTENT_CONFIG_MOVIES_SECTION, "artimer1", "90" },
|
||||
{ kSfallMisc, "MovieTimer_artimer2", CONTENT_CONFIG_MOVIES_SECTION, "artimer2", "180" },
|
||||
|
||||
@@ -3500,6 +3500,11 @@ int gameDialogGetWindow()
|
||||
return windowGetWindow(gGameDialogWindow) != nullptr ? gGameDialogWindow : -1;
|
||||
}
|
||||
|
||||
int gameDialogGetBackgroundWindow()
|
||||
{
|
||||
return windowGetWindow(gGameDialogBackgroundWindow) != nullptr ? gGameDialogBackgroundWindow : -1;
|
||||
}
|
||||
|
||||
// 0x448660 gdialog_barter_cleanup_tables
|
||||
void gameDialogBarterCleanupTables()
|
||||
{
|
||||
|
||||
@@ -41,6 +41,7 @@ int gameDialogBarter(int modifier);
|
||||
void gameDialogEndBarter();
|
||||
bool gameDialogIsBarterWindowExpanded();
|
||||
int gameDialogGetWindow();
|
||||
int gameDialogGetBackgroundWindow();
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
|
||||
+65
-12
@@ -5,6 +5,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
@@ -925,7 +926,31 @@ static bool inventoryLootMouseHitTestScroller(bool targetInventory)
|
||||
|
||||
static void inventoryLootRenderPaneWeight(unsigned char* windowBuffer, int pitch, bool targetPane, Object* object, int extraWeight)
|
||||
{
|
||||
char formattedText[20];
|
||||
int loot_weight_indicator = settings.ui.loot_weight_indicator;
|
||||
|
||||
bool showLabel = inventoryLootLayout.columns > 1;
|
||||
bool showDetailed = loot_weight_indicator == 2 && showLabel;
|
||||
bool showSimple = loot_weight_indicator == 1 || (loot_weight_indicator == 2 && !showLabel);
|
||||
|
||||
if (!showDetailed && !showSimple) {
|
||||
return;
|
||||
}
|
||||
|
||||
int containerSizeThreshold = settings.ui.loot_container_size_indicator_threshold;
|
||||
|
||||
// Wt.
|
||||
MessageListItem messageListItem;
|
||||
messageListItem.num = 30;
|
||||
|
||||
if (showLabel) {
|
||||
if (!messageListGetItem(&gInventoryMessageList, &messageListItem)) {
|
||||
showSimple = true;
|
||||
showDetailed = false;
|
||||
showLabel = false;
|
||||
}
|
||||
}
|
||||
|
||||
char formattedText[30];
|
||||
formattedText[0] = '\0';
|
||||
|
||||
int oldFont = fontGetCurrent();
|
||||
@@ -942,26 +967,54 @@ static void inventoryLootRenderPaneWeight(unsigned char* windowBuffer, int pitch
|
||||
pitch);
|
||||
}
|
||||
|
||||
int color = COLOR_GREEN;
|
||||
int color = COLOR_WHITE;
|
||||
int inventoryWeight = objectGetInventoryWeight(object);
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
int currentWeight = objectGetInventoryWeight(object) + extraWeight;
|
||||
int currentWeight = inventoryWeight + extraWeight;
|
||||
int maxWeight = critterGetStat(object, STAT_CARRY_WEIGHT);
|
||||
snprintf(formattedText, sizeof(formattedText), "%d/%d", currentWeight, maxWeight);
|
||||
int weightPercentage = maxWeight < 1 ? 0 : (int)std::ceil(currentWeight * 100 / (float)maxWeight);
|
||||
|
||||
if (showSimple) {
|
||||
if (showLabel) {
|
||||
snprintf(formattedText, sizeof(formattedText), "%s %d/%d", messageListItem.text, currentWeight, maxWeight);
|
||||
} else {
|
||||
snprintf(formattedText, sizeof(formattedText), "%d/%d", currentWeight, maxWeight);
|
||||
}
|
||||
} else if (showDetailed) {
|
||||
snprintf(formattedText, sizeof(formattedText), "%s %d/%d (%d%%)", messageListItem.text, currentWeight, maxWeight, weightPercentage);
|
||||
}
|
||||
|
||||
if (currentWeight > maxWeight) {
|
||||
color = COLOR_RED;
|
||||
}
|
||||
} else if (targetPane && PID_TYPE(object->pid) == OBJ_TYPE_ITEM && itemGetType(object) == ITEM_TYPE_CONTAINER) {
|
||||
int currentSize = containerGetTotalSize(object);
|
||||
int maxSize = containerGetMaxSize(object);
|
||||
snprintf(formattedText, sizeof(formattedText), "%d/%d", currentSize, maxSize);
|
||||
int sizePercentage = maxSize < 1 ? 0 : (int)std::ceil(currentSize * 100 / (float)maxSize);
|
||||
|
||||
if (sizePercentage < containerSizeThreshold) {
|
||||
fontSetCurrent(oldFont);
|
||||
return;
|
||||
}
|
||||
|
||||
if (showSimple) {
|
||||
snprintf(formattedText, sizeof(formattedText), "%d%%", sizePercentage);
|
||||
} else if (showDetailed) {
|
||||
snprintf(formattedText, sizeof(formattedText), "%s %d (%d%%)", messageListItem.text, inventoryWeight, sizePercentage);
|
||||
}
|
||||
} else {
|
||||
int inventoryWeight = objectGetInventoryWeight(object);
|
||||
snprintf(formattedText, sizeof(formattedText), "%d", inventoryWeight);
|
||||
if (showLabel) {
|
||||
snprintf(formattedText, sizeof(formattedText), "%s %d", messageListItem.text, inventoryWeight);
|
||||
} else {
|
||||
snprintf(formattedText, sizeof(formattedText), "%d", inventoryWeight);
|
||||
}
|
||||
}
|
||||
|
||||
int x = targetPane ? inventoryLootLayout.rightScrollerX : inventoryLootLayout.leftScrollerX;
|
||||
int y = (targetPane ? inventoryLootLayout.rightScrollerY : inventoryLootLayout.leftScrollerY) + inventoryLootLayout.scrollerHeight + 2;
|
||||
inventoryDrawCenteredText(windowBuffer, pitch, inventoryLootLayout.scrollerWidth, x, y, formattedText, color);
|
||||
if (strlen(formattedText) > 0) {
|
||||
int x = targetPane ? inventoryLootLayout.rightScrollerX : inventoryLootLayout.leftScrollerX;
|
||||
int y = (targetPane ? inventoryLootLayout.rightScrollerY : inventoryLootLayout.leftScrollerY) + inventoryLootLayout.scrollerHeight + 2;
|
||||
inventoryDrawCenteredText(windowBuffer, pitch, inventoryLootLayout.scrollerWidth, x, y, formattedText, color);
|
||||
}
|
||||
|
||||
fontSetCurrent(oldFont);
|
||||
}
|
||||
@@ -4096,10 +4149,10 @@ static void displayLootPanePartyName(unsigned char* windowBuffer, int windowPitc
|
||||
|
||||
int oldFont = fontGetCurrent();
|
||||
fontSetCurrent(101);
|
||||
int nameY = rect.bottom - fontGetLineHeight() - 2;
|
||||
int nameY = rect.bottom - fontGetLineHeight();
|
||||
fontSetCurrent(oldFont);
|
||||
|
||||
inventoryDrawCenteredText(windowBuffer, windowPitch, INVENTORY_BODY_VIEW_WIDTH, rect.left, nameY, name, COLOR_GREEN);
|
||||
inventoryDrawCenteredText(windowBuffer, windowPitch, INVENTORY_BODY_VIEW_WIDTH, rect.left, nameY, name, COLOR_WHITE);
|
||||
}
|
||||
|
||||
// Displays item description.
|
||||
|
||||
+22
-1
@@ -56,6 +56,7 @@ static int main_loadgame_new();
|
||||
static void main_unload_new();
|
||||
static void mainParseCommandLineArguments(int argc, char** argv);
|
||||
static bool mainTryParseDevLoadGameSlot(const char* value, int* slotPtr);
|
||||
static const char* mainGetSoundConfig(const char* key, const char* defaultValue);
|
||||
static void mainLoop();
|
||||
static void showDeath();
|
||||
static void _main_death_voiceover_callback();
|
||||
@@ -105,7 +106,7 @@ int falloutMain(int argc, char** argv)
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
keyboardReset();
|
||||
_gsound_background_play_level_music("07desert", GSOUND_LIMIT_BEFORE);
|
||||
_gsound_background_play_level_music(mainGetSoundConfig("main_menu_music", "07desert"), GSOUND_LIMIT_BEFORE);
|
||||
mainMenuWindowUnhide(true);
|
||||
|
||||
mouseShowCursor();
|
||||
@@ -277,6 +278,13 @@ static void mainParseCommandLineArguments(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
static const char* mainGetSoundConfig(const char* key, const char* defaultValue)
|
||||
{
|
||||
char* value = nullptr;
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_SOUND_SECTION, key, &value, nullptr);
|
||||
return value != nullptr && value[0] != '\0' ? value : defaultValue;
|
||||
}
|
||||
|
||||
static bool mainTryParseDevLoadGameSlot(const char* value, int* slotPtr)
|
||||
{
|
||||
if (value == nullptr || slotPtr == nullptr) {
|
||||
@@ -331,6 +339,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);
|
||||
|
||||
+14
-2
@@ -12,6 +12,7 @@
|
||||
#include "character_editor.h"
|
||||
#include "color.h"
|
||||
#include "combat.h"
|
||||
#include "content_config.h"
|
||||
#include "critter.h"
|
||||
#include "cycle.h"
|
||||
#include "debug.h"
|
||||
@@ -64,6 +65,7 @@ static int mapGlobalVariablesLoad(File* stream);
|
||||
static int mapLocalVariablesInit(int count);
|
||||
static void mapLocalVariablesFree();
|
||||
static int mapLocalVariablesLoad(File* stream);
|
||||
static const char* mapGetSoundConfig(const char* key, const char* defaultValue);
|
||||
static void _map_place_dude_and_mouse();
|
||||
static void square_init();
|
||||
static void _square_reset();
|
||||
@@ -789,6 +791,13 @@ void mapNewMap()
|
||||
tileWindowRefresh();
|
||||
}
|
||||
|
||||
static const char* mapGetSoundConfig(const char* key, const char* defaultValue)
|
||||
{
|
||||
char* value = nullptr;
|
||||
configGetString(&gContentConfig, CONTENT_CONFIG_SOUND_SECTION, key, &value, nullptr);
|
||||
return value != nullptr && value[0] != '\0' ? value : defaultValue;
|
||||
}
|
||||
|
||||
// 0x482A68 map_load
|
||||
int mapLoadByName(char* fileName)
|
||||
{
|
||||
@@ -862,7 +871,10 @@ static int mapLoad(File* stream)
|
||||
if (backgoundSoundIsPlaying()) {
|
||||
// Use the sfall sound path so the map-loading ambience does not depend
|
||||
// on the native background music loader.
|
||||
mapLoadSoundId = scriptSoundPlay("sound\\music\\WIND2.ACM", SCRIPT_SOUND_MODE_LOOP);
|
||||
const char* mapLoadingSound = mapGetSoundConfig("map_loading_sound", "wind2");
|
||||
char mapLoadingSoundPath[COMPAT_MAX_PATH];
|
||||
snprintf(mapLoadingSoundPath, sizeof(mapLoadingSoundPath), "sound\\music\\%s.ACM", mapLoadingSound);
|
||||
mapLoadSoundId = scriptSoundPlay(mapLoadingSoundPath, SCRIPT_SOUND_MODE_LOOP);
|
||||
}
|
||||
}
|
||||
isoDisable();
|
||||
@@ -978,7 +990,7 @@ static int mapLoad(File* stream)
|
||||
}
|
||||
|
||||
lightSetAmbientIntensity(LIGHT_INTENSITY_MAX, false);
|
||||
objectSetLocation(gDude, gCenterTile, gElevation, nullptr);
|
||||
objectSetLocation(gDude, gEnteringTile, gElevation, nullptr);
|
||||
objectSetRotation(gDude, gEnteringRotation, nullptr);
|
||||
gMapHeader.index = wmMapMatchNameToIdx(gMapHeader.name);
|
||||
|
||||
|
||||
+3
-2
@@ -501,13 +501,14 @@ int pipboyOpen(int intent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ScopedGameMode gm(GameMode::kPipboy);
|
||||
|
||||
intent = pipboyWindowInit(intent);
|
||||
if (intent == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ScopedGameMode gm(GameMode::kPipboy);
|
||||
windowRefresh(gPipboyWindow);
|
||||
|
||||
touch_set_touchscreen_mode(true);
|
||||
|
||||
mouseGetPositionInWindow(gPipboyWindow, &gPipboyPreviousMouseX, &gPipboyPreviousMouseY);
|
||||
|
||||
@@ -172,6 +172,8 @@ void initSettingsRegistry(bool isMapper)
|
||||
SETTING(extend_ap_bar);
|
||||
SETTING(expand_barter_window);
|
||||
SETTING_P(inventory_columns, clamp(1, 2));
|
||||
SETTING_P(loot_weight_indicator, clamp(0, 2));
|
||||
SETTING_P(loot_container_size_indicator_threshold, clamp(0, 100));
|
||||
#undef SECT
|
||||
|
||||
#define SECT preferences
|
||||
|
||||
@@ -95,6 +95,16 @@ struct UISettings {
|
||||
bool enable_high_resolution_stencil = true;
|
||||
// Maximum number of columns in inventory and loot windows
|
||||
int inventory_columns = 1;
|
||||
|
||||
// 0 - No indicator, vanilla
|
||||
// 1 - Simple indicator
|
||||
// 2 - Detailed indicator, works with inventory_columns > 1 only
|
||||
int loot_weight_indicator = 1;
|
||||
|
||||
// 0 - Container indicator is always visible
|
||||
// XX - Container indicator is visible when size reaches XX percent
|
||||
// 100 - Container indicator is visible when fully loaded
|
||||
int loot_container_size_indicator_threshold = 50;
|
||||
};
|
||||
|
||||
// These are settings handled by preferences UI and saved in save games.
|
||||
|
||||
+3
-32
@@ -958,7 +958,7 @@ static InterfaceWindowLookupResult getInterfaceWindowByType(int winType, int& wi
|
||||
window = inventoryGetWindow();
|
||||
break;
|
||||
case 1:
|
||||
window = gameDialogGetWindow();
|
||||
window = gameDialogGetBackgroundWindow();
|
||||
break;
|
||||
case 2:
|
||||
window = pipboyGetWindow();
|
||||
@@ -989,35 +989,6 @@ static InterfaceWindowLookupResult getInterfaceWindowByType(int winType, int& wi
|
||||
return window != -1 ? InterfaceWindowLookupResult::Found : InterfaceWindowLookupResult::Missing;
|
||||
}
|
||||
|
||||
static int getCurrentInterfaceWindow()
|
||||
{
|
||||
int window = -1;
|
||||
if (GameMode::isInGameMode(GameMode::kInventory)
|
||||
|| GameMode::isInGameMode(GameMode::kUseOn)
|
||||
|| GameMode::isInGameMode(GameMode::kLoot)
|
||||
|| GameMode::isInGameMode(GameMode::kBarter)) {
|
||||
window = inventoryGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kDialog)) {
|
||||
window = gameDialogGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kPipboy)) {
|
||||
window = pipboyGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kWorldmap)) {
|
||||
window = worldmapGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kEditor)) {
|
||||
window = characterEditorGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kSkilldex)) {
|
||||
window = skilldexGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kOptions)) {
|
||||
window = optionsGetWindow();
|
||||
} else if (GameMode::isInGameMode(GameMode::kAutomap)) {
|
||||
window = automapGetWindow();
|
||||
} else if (windowGetWindow(gInterfaceBarWindow) != nullptr) {
|
||||
window = gInterfaceBarWindow;
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static bool clampWindowFillRect(int windowWidth, int windowHeight, int& x, int& y, int& width, int& height)
|
||||
{
|
||||
if (x < 0) {
|
||||
@@ -1870,10 +1841,10 @@ void mf_set_window_flag(OpcodeContext& ctx)
|
||||
|
||||
int windowId = ctx.arg(0).asInt();
|
||||
if (windowId <= 0) {
|
||||
windowId = getCurrentInterfaceWindow();
|
||||
windowId = inventoryGetWindow();
|
||||
}
|
||||
|
||||
if (windowId == -1) {
|
||||
if (windowId == -1 || windowGetWindow(windowId) == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+105
-5
@@ -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();
|
||||
@@ -4667,7 +4738,16 @@ static int wmInterfaceInit()
|
||||
|
||||
_map_save_in_game(true);
|
||||
|
||||
const char* backgroundSoundFileName = wmGenData.isInCar ? "20car" : "23world";
|
||||
char* configuredBackgroundSoundFileName = nullptr;
|
||||
const char* backgroundSoundFileName = wmGenData.isInCar ? "20car" : "03wrldmp";
|
||||
configGetString(&gContentConfig,
|
||||
CONTENT_CONFIG_SOUND_SECTION,
|
||||
wmGenData.isInCar ? "worldmap_car_music" : "worldmap_music",
|
||||
&configuredBackgroundSoundFileName,
|
||||
nullptr);
|
||||
if (configuredBackgroundSoundFileName != nullptr && configuredBackgroundSoundFileName[0] != '\0') {
|
||||
backgroundSoundFileName = configuredBackgroundSoundFileName;
|
||||
}
|
||||
_gsound_background_play_level_music(backgroundSoundFileName, GSOUND_LIMIT_AFTER);
|
||||
|
||||
// CE: Hide entire interface, not just indicator bar, and disable tile
|
||||
@@ -6170,6 +6250,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 +7175,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