mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67be4333ac | ||
|
|
04e4ca1ac3 | ||
|
|
f89e5043b8 | ||
|
|
a95fcd69a1 | ||
|
|
f8b3cebc77 | ||
|
|
fd806bb3a1 | ||
|
|
8e60a2fba2 | ||
|
|
ca89abad6c | ||
|
|
21a98bebb1 | ||
|
|
283107bebe |
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+37
-24
@@ -704,6 +704,24 @@ void gameMouseRefresh()
|
||||
int primaryAction = -1;
|
||||
|
||||
switch (FID_TYPE(pointedObject->fid)) {
|
||||
case OBJ_TYPE_SCENERY:
|
||||
case OBJ_TYPE_WALL:
|
||||
case OBJ_TYPE_MISC: {
|
||||
if (_obj_action_can_use(pointedObject)) {
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_USE;
|
||||
break;
|
||||
}
|
||||
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_LOOK;
|
||||
|
||||
// if the pointedObject is scenery/wall/misc object then it finds possible outlined item object behind it
|
||||
Object* itemObject = gameMouseGetObjectUnderCursor(OBJ_TYPE_ITEM, true, gElevation);
|
||||
if (itemObject == nullptr) {
|
||||
break;
|
||||
}
|
||||
pointedObject = itemObject;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
case OBJ_TYPE_ITEM:
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_USE;
|
||||
if (gGameMouseItemHighlightEnabled) {
|
||||
@@ -733,16 +751,6 @@ void gameMouseRefresh()
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OBJ_TYPE_SCENERY:
|
||||
if (!_obj_action_can_use(pointedObject)) {
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_LOOK;
|
||||
} else {
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_USE;
|
||||
}
|
||||
break;
|
||||
case OBJ_TYPE_WALL:
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_LOOK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (primaryAction != -1) {
|
||||
@@ -993,6 +1001,25 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
||||
Object* targetObj = gameMouseGetObjectUnderCursor(-1, true, gElevation);
|
||||
if (targetObj != nullptr) {
|
||||
switch (FID_TYPE(targetObj->fid)) {
|
||||
case OBJ_TYPE_WALL:
|
||||
case OBJ_TYPE_SCENERY:
|
||||
case OBJ_TYPE_MISC: {
|
||||
// if the targetObj is wall/scenery/misc object then it allows to pickup outlined items potentially behind
|
||||
Object* itemObj = gameMouseGetObjectUnderCursor(OBJ_TYPE_ITEM, true, gElevation);
|
||||
if (!objectIsOutlined(itemObj)) {
|
||||
if (_obj_action_can_use(targetObj)) {
|
||||
_action_use_an_object(gDude, targetObj);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
targetObj = itemObj;
|
||||
|
||||
if (objectExamine(gDude, targetObj) == -1) {
|
||||
objectLookAt(gDude, targetObj);
|
||||
}
|
||||
}
|
||||
// FALLTHROUGH
|
||||
case OBJ_TYPE_ITEM:
|
||||
actionPickUp(gDude, targetObj);
|
||||
break;
|
||||
@@ -1018,20 +1045,6 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OBJ_TYPE_SCENERY:
|
||||
if (_obj_action_can_use(targetObj)) {
|
||||
_action_use_an_object(gDude, targetObj);
|
||||
} else {
|
||||
if (objectExamine(gDude, targetObj) == -1) {
|
||||
objectLookAt(gDude, targetObj);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OBJ_TYPE_WALL:
|
||||
if (objectExamine(gDude, targetObj) == -1) {
|
||||
objectLookAt(gDude, targetObj);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
+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.
|
||||
|
||||
+1
-1
@@ -978,7 +978,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);
|
||||
|
||||
|
||||
+13
-15
@@ -821,10 +821,8 @@ void _obj_render_pre_roof(Rect* rect, int elevation)
|
||||
if ((objectListNode->obj->flags & OBJECT_HIDDEN) == 0) {
|
||||
_obj_render_object(objectListNode->obj, &updatedRect, lightIntensity);
|
||||
|
||||
if ((objectListNode->obj->outline & OUTLINE_TYPE_MASK) != 0) {
|
||||
if ((objectListNode->obj->outline & OUTLINE_DISABLED) == 0 && _outlineCount < 100) {
|
||||
_outlinedObjects[_outlineCount++] = objectListNode->obj;
|
||||
}
|
||||
if (objectIsOutlined(objectListNode->obj) && _outlineCount < 100) {
|
||||
_outlinedObjects[_outlineCount++] = objectListNode->obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -859,10 +857,8 @@ void _obj_render_pre_roof(Rect* rect, int elevation)
|
||||
if ((objectListNode->obj->flags & OBJECT_HIDDEN) == 0) {
|
||||
_obj_render_object(object, &updatedRect, lightIntensity);
|
||||
|
||||
if ((objectListNode->obj->outline & OUTLINE_TYPE_MASK) != 0) {
|
||||
if ((objectListNode->obj->outline & OUTLINE_DISABLED) == 0 && _outlineCount < 100) {
|
||||
_outlinedObjects[_outlineCount++] = objectListNode->obj;
|
||||
}
|
||||
if (objectIsOutlined(objectListNode->obj) && _outlineCount < 100) {
|
||||
_outlinedObjects[_outlineCount++] = objectListNode->obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1881,7 +1877,7 @@ int objectHide(Object* object, Rect* rect)
|
||||
|
||||
object->flags |= OBJECT_HIDDEN;
|
||||
|
||||
if ((object->outline & OUTLINE_TYPE_MASK) != 0) {
|
||||
if (objectIsOutlined(object)) {
|
||||
object->outline |= OUTLINE_DISABLED;
|
||||
}
|
||||
|
||||
@@ -1919,7 +1915,7 @@ int objectDisableOutline(Object* object, Rect* rect)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((object->outline & OUTLINE_TYPE_MASK) != 0) {
|
||||
if (objectIsOutlined(object)) {
|
||||
object->outline |= OUTLINE_DISABLED;
|
||||
}
|
||||
|
||||
@@ -2335,10 +2331,7 @@ void objectGetRect(Object* obj, Rect* rect)
|
||||
return;
|
||||
}
|
||||
|
||||
bool isOutlined = false;
|
||||
if ((obj->outline & OUTLINE_TYPE_MASK) != 0) {
|
||||
isOutlined = true;
|
||||
}
|
||||
bool isOutlined = objectIsOutlined(obj);
|
||||
|
||||
CacheEntry* artHandle;
|
||||
Art* art = artLock(obj->fid, &artHandle);
|
||||
@@ -2888,6 +2881,11 @@ void _intensity_mask_buf_to_buf(unsigned char* src, int srcWidth, int srcHeight,
|
||||
}
|
||||
}
|
||||
|
||||
bool objectIsOutlined(Object* obj)
|
||||
{
|
||||
return obj != nullptr && (obj->outline & OUTLINE_TYPE_MASK) != 0 && (obj->outline & OUTLINE_DISABLED) == 0;
|
||||
}
|
||||
|
||||
// 0x48C2B4 obj_outline_object
|
||||
int objectSetOutline(Object* obj, int outlineType, Rect* rect)
|
||||
{
|
||||
@@ -2895,7 +2893,7 @@ int objectSetOutline(Object* obj, int outlineType, Rect* rect)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((obj->outline & OUTLINE_TYPE_MASK) != 0) {
|
||||
if (objectIsOutlined(obj)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@ void _obj_fix_violence_settings(int* fid);
|
||||
|
||||
Object* objectTypedFindById(int id, int type);
|
||||
bool isExitGridAt(int tile, int elevation);
|
||||
bool objectIsOutlined(Object* obj);
|
||||
|
||||
// RAII wrapper for Object*.
|
||||
class UniqueObject {
|
||||
|
||||
+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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user