mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a9433c0f1 |
+2
-2
@@ -373,8 +373,8 @@ if(APPLE)
|
||||
endif()
|
||||
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.alexbatalov.fallout2-ce")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "1.3.0")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "1.3.0")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "1.4.0")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "1.4.0")
|
||||
endif()
|
||||
|
||||
if((NOT ${CMAKE_SYSTEM_NAME} MATCHES "Emscripten"))
|
||||
|
||||
@@ -61,7 +61,7 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
|
||||
| CalcAPCost | `HOOK_CALCAPCOST` | đźš« | - |
|
||||
| DeathAnim1 | `HOOK_DEATHANIM1` | đźš« | Use DEATHANIM2 instead |
|
||||
| DeathAnim2 | `HOOK_DEATHANIM2` | âś… | - |
|
||||
| CombatDamage | `HOOK_COMBATDAMAGE` | âś… | - |
|
||||
| CombatDamage | `HOOK_COMBATDAMAGE` | âś… | CE passes the raw `Attack*` as the final mixed argument, matching sfall's shape. |
|
||||
| OnDeath | `HOOK_ONDEATH` | đźš« | - |
|
||||
| FindTarget | `HOOK_FINDTARGET` | đźš« | (maybe) |
|
||||
| UseObjOn | `HOOK_USEOBJON` | âś… | - |
|
||||
@@ -71,12 +71,12 @@ See [`https://sfall-team.github.io/sfall/`](https://sfall-team.github.io/sfall/)
|
||||
| MoveCost | `HOOK_MOVECOST` | đźš« | - |
|
||||
| ItemDamage | `HOOK_ITEMDAMAGE` | đźš« | - |
|
||||
| AmmoCost | `HOOK_AMMOCOST` | đźš« | Et tu |
|
||||
| KeyPress | `HOOK_KEYPRESS` | âś… | Third hook arg is currently `0`; CE doesn't use VK codes. |
|
||||
| KeyPress | `HOOK_KEYPRESS` | âś… | Third hook arg is currently `0`; CE notes that sfall used VK codes there. |
|
||||
| MouseClick | `HOOK_MOUSECLICK` | đźš« | - |
|
||||
| UseSkill | `HOOK_USESKILL` | đźš« | - |
|
||||
| Steal | `HOOK_STEAL` | đźš« | Et tu |
|
||||
| WithinPerception | `HOOK_WITHINPERCEPTION` | đźš« | Et tu |
|
||||
| InventoryMove | `HOOK_INVENTORYMOVE` | âś… | - |
|
||||
| InventoryMove | `HOOK_INVENTORYMOVE` | đźš« | Et tu |
|
||||
| InvenWield | `HOOK_INVENWIELD` | đźš« | - |
|
||||
| AdjustFID | `HOOK_ADJUSTFID` | đźš« | - |
|
||||
| CombatTurn | `HOOK_COMBATTURN` | đźš« | - |
|
||||
|
||||
@@ -9,8 +9,8 @@ android {
|
||||
applicationId 'com.alexbatalov.fallout2ce'
|
||||
minSdk 21
|
||||
targetSdk 32
|
||||
versionCode 4
|
||||
versionName '1.3.0'
|
||||
versionCode 5
|
||||
versionName '1.4.0'
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments '-DANDROID_STL=c++_static'
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.alexbatalov.fallout2ce"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0.0"
|
||||
android:versionCode="5"
|
||||
android:versionName="1.4.0"
|
||||
android:installLocation="auto">
|
||||
|
||||
<!-- OpenGL ES 2.0 -->
|
||||
|
||||
@@ -13,23 +13,18 @@ import java.io.OutputStream;
|
||||
public class FileUtils {
|
||||
|
||||
static boolean copyRecursively(ContentResolver contentResolver, DocumentFile src, File dest) {
|
||||
if (dest == null || (!dest.exists() && !dest.mkdirs())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final DocumentFile[] documentFiles = src.listFiles();
|
||||
for (final DocumentFile documentFile : documentFiles) {
|
||||
final String name = documentFile.getName();
|
||||
if (name == null || name.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (documentFile.isFile()) {
|
||||
if (!copyFile(contentResolver, documentFile, new File(dest, name))) {
|
||||
if (!copyFile(contentResolver, documentFile, new File(dest, documentFile.getName()))) {
|
||||
return false;
|
||||
}
|
||||
} else if (documentFile.isDirectory()) {
|
||||
final File subdirectory = new File(dest, name);
|
||||
final File subdirectory = new File(dest, documentFile.getName());
|
||||
if (!subdirectory.exists()) {
|
||||
subdirectory.mkdir();
|
||||
}
|
||||
|
||||
if (!copyRecursively(contentResolver, documentFile, subdirectory)) {
|
||||
return false;
|
||||
}
|
||||
@@ -39,22 +34,18 @@ public class FileUtils {
|
||||
}
|
||||
|
||||
private static boolean copyFile(ContentResolver contentResolver, DocumentFile src, File dest) {
|
||||
final File parent = dest.getParentFile();
|
||||
if (parent != null && !parent.exists() && !parent.mkdirs()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try (final InputStream inputStream = contentResolver.openInputStream(src.getUri());
|
||||
final OutputStream outputStream = new FileOutputStream(dest)) {
|
||||
if (inputStream == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
final InputStream inputStream = contentResolver.openInputStream(src.getUri());
|
||||
final OutputStream outputStream = new FileOutputStream(dest);
|
||||
|
||||
final byte[] buffer = new byte[16384];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
inputStream.close();
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
|
||||
@@ -2,12 +2,10 @@ package com.alexbatalov.fallout2ce;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
|
||||
@@ -19,18 +17,18 @@ public class ImportActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
launchImportPicker();
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
startActivityForResult(intent, IMPORT_REQUEST_CODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent resultData) {
|
||||
if (requestCode == IMPORT_REQUEST_CODE) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
final Uri treeUri = resultData != null ? resultData.getData() : null;
|
||||
final Uri treeUri = resultData.getData();
|
||||
if (treeUri != null) {
|
||||
grantImportPermissions(treeUri, resultData);
|
||||
final DocumentFile treeDocument = DocumentFile.fromTreeUri(this, treeUri);
|
||||
if (treeDocument != null && treeDocument.isDirectory()) {
|
||||
if (treeDocument != null) {
|
||||
copyFiles(treeDocument);
|
||||
return;
|
||||
}
|
||||
@@ -44,57 +42,18 @@ public class ImportActivity extends Activity {
|
||||
}
|
||||
|
||||
private void copyFiles(DocumentFile treeDocument) {
|
||||
final ProgressDialog dialog = createProgressDialog();
|
||||
ProgressDialog dialog = createProgressDialog();
|
||||
dialog.show();
|
||||
|
||||
new Thread(() -> {
|
||||
final ContentResolver contentResolver = getContentResolver();
|
||||
final File externalFilesDir = getExternalFilesDir(null);
|
||||
final boolean success = externalFilesDir != null
|
||||
&& FileUtils.copyRecursively(contentResolver, treeDocument, externalFilesDir);
|
||||
ContentResolver contentResolver = getContentResolver();
|
||||
File externalFilesDir = getExternalFilesDir(null);
|
||||
FileUtils.copyRecursively(contentResolver, treeDocument, externalFilesDir);
|
||||
|
||||
runOnUiThread(() -> {
|
||||
dialog.dismiss();
|
||||
|
||||
if (success) {
|
||||
startMainActivity();
|
||||
} else {
|
||||
Toast.makeText(this, R.string.import_failed, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
finish();
|
||||
});
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void launchImportPicker() {
|
||||
final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
|
||||
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
|
||||
|
||||
try {
|
||||
startActivityForResult(intent, IMPORT_REQUEST_CODE);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Toast.makeText(this, R.string.import_picker_unavailable, Toast.LENGTH_LONG).show();
|
||||
startMainActivity();
|
||||
dialog.dismiss();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void grantImportPermissions(Uri treeUri, Intent resultData) {
|
||||
int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
||||
if (resultData != null) {
|
||||
flags = resultData.getFlags()
|
||||
& (Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
|
||||
}
|
||||
|
||||
try {
|
||||
getContentResolver().takePersistableUriPermission(treeUri, flags);
|
||||
} catch (SecurityException ignored) {
|
||||
// Some providers do not offer persistable grants. One-shot access is enough for import.
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void startMainActivity() {
|
||||
|
||||
@@ -2,6 +2,4 @@
|
||||
<string name="app_name">Fallout 2</string>
|
||||
<string name="loading_dialog_title">PLEASE STAND BY</string>
|
||||
<string name="loading_dialog_message">Copying files…</string>
|
||||
<string name="import_failed">Failed to import game files. Please pick a valid Fallout 2 folder and try again.</string>
|
||||
<string name="import_picker_unavailable">No compatible folder picker is available on this device.</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#include "sfall.h"
|
||||
#include "dik.h"
|
||||
#include "lib.arrays.h"
|
||||
|
||||
variable inventorymove_blocking := false;
|
||||
|
||||
procedure inventorymove_handler begin
|
||||
variable
|
||||
args := get_sfall_args,
|
||||
action := args[0],
|
||||
item := args[1],
|
||||
arg2 := args[2],
|
||||
action_name := "unknown";
|
||||
|
||||
if (action == 0) then action_name := "main_backpack";
|
||||
else if (action == 1) then action_name := "left_hand";
|
||||
else if (action == 2) then action_name := "right_hand";
|
||||
else if (action == 3) then action_name := "armor_slot";
|
||||
else if (action == 4) then action_name := "weapon_reload";
|
||||
else if (action == 5) then action_name := "container";
|
||||
else if (action == 6) then action_name := "ground";
|
||||
else if (action == 7) then action_name := "pickup";
|
||||
else if (action == 8) then action_name := "character_portrait";
|
||||
|
||||
display_msg(string_format2("inventorymove %s args=%s", action_name, debug_array_str(args)));
|
||||
if (item) then
|
||||
display_msg(string_format2("inventorymove item=%s pid=%d", obj_name(item), obj_pid(item)));
|
||||
if (arg2) then
|
||||
display_msg(string_format2("inventorymove arg2=%s pid=%d", obj_name(arg2), obj_pid(arg2)));
|
||||
display_msg(string_format1("inventorymove blocking=%d", inventorymove_blocking));
|
||||
|
||||
if (inventorymove_blocking) then begin
|
||||
display_msg("inventorymove blocked");
|
||||
set_sfall_return(0);
|
||||
end
|
||||
end
|
||||
|
||||
procedure keypress_handler begin
|
||||
variable
|
||||
pressed := get_sfall_arg_at(0),
|
||||
key := get_sfall_arg_at(1);
|
||||
|
||||
if (not pressed) then return;
|
||||
if (key != DIK_X) then return;
|
||||
|
||||
inventorymove_blocking := not inventorymove_blocking;
|
||||
display_msg(string_format1("inventorymove blocking %d", inventorymove_blocking));
|
||||
end
|
||||
|
||||
procedure start begin
|
||||
if (not game_loaded) then return;
|
||||
|
||||
display_msg("inventorymove manual test ready: press X to toggle blocking");
|
||||
|
||||
register_hook_proc(HOOK_KEYPRESS, keypress_handler);
|
||||
register_hook_proc(HOOK_INVENTORYMOVE, inventorymove_handler);
|
||||
end
|
||||
+25
-85
@@ -247,12 +247,6 @@ typedef enum InventoryMoveResult {
|
||||
INVENTORY_MOVE_RESULT_SUCCESS,
|
||||
} InventoryMoveResult;
|
||||
|
||||
typedef enum InventoryAmmoMoveResult {
|
||||
INVENTORY_AMMO_MOVE_RESULT_FAILED = -1,
|
||||
INVENTORY_AMMO_MOVE_RESULT_SUCCESS = 0,
|
||||
INVENTORY_AMMO_MOVE_RESULT_BLOCKED = 1,
|
||||
} InventoryAmmoMoveResult;
|
||||
|
||||
static int inventoryMessageListInit();
|
||||
static int inventoryMessageListFree();
|
||||
static bool _setup_inventory(int inventoryWindowType);
|
||||
@@ -286,7 +280,7 @@ static void barterDisplayTables(int win, Object* leftTable, Object* rightTable,
|
||||
static void _container_enter(int keyCode, int inventoryWindowType);
|
||||
static void _container_exit(int keyCode, int inventoryWindowType);
|
||||
static int _drop_into_container(Object* container, Object* item, int sourceIndex, Object** itemSlot, int quantity);
|
||||
static InventoryAmmoMoveResult _drop_ammo_into_weapon(Object* weapon, Object* ammo, Object** ammoItemSlot, int quantity, int keyCode);
|
||||
static int _drop_ammo_into_weapon(Object* weapon, Object* ammo, Object** ammoItemSlot, int quantity, int keyCode);
|
||||
static void _draw_amount(int value, int inventoryWindowType);
|
||||
static int inventoryQuantitySelect(int inventoryWindowType, Object* item, int maximum, int defaultValue = 1);
|
||||
static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item);
|
||||
@@ -2446,18 +2440,14 @@ static void _inven_pickup(int buttonCode, int indexOffset)
|
||||
itemIndex = 0;
|
||||
}
|
||||
} else {
|
||||
if (_drop_ammo_into_weapon(targetItem, item, itemSlot, count, buttonCode) == INVENTORY_AMMO_MOVE_RESULT_SUCCESS) {
|
||||
if (_drop_ammo_into_weapon(targetItem, item, itemSlot, count, buttonCode) == 0) {
|
||||
itemIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (immediate || itemIndex == -1) {
|
||||
if (!scriptHooks_InventoryMove(HOOK_INVENTORYMOVE_MAIN_BACKPACK, item, nullptr)) {
|
||||
goto inventory_move_done;
|
||||
}
|
||||
|
||||
if (immediate || pickUpFromSlot) {
|
||||
// TODO: Holy shit, needs refactoring.
|
||||
*itemSlot = nullptr;
|
||||
if (itemAdd(_inven_dude, item, 1)) {
|
||||
@@ -2475,38 +2465,30 @@ static void _inven_pickup(int buttonCode, int indexOffset)
|
||||
// default to first empty hand, or left hand if both are full
|
||||
bool left = gInventoryLeftHandItem == nullptr || gInventoryRightHandItem != nullptr;
|
||||
if (left) {
|
||||
_switch_hand(item, &gInventoryLeftHandItem, itemSlot, itemIndex);
|
||||
_switch_hand(item, &gInventoryLeftHandItem, itemSlot, buttonCode);
|
||||
} else {
|
||||
_switch_hand(item, &gInventoryRightHandItem, itemSlot, itemIndex);
|
||||
_switch_hand(item, &gInventoryRightHandItem, itemSlot, buttonCode);
|
||||
}
|
||||
|
||||
// drop in left hand slot
|
||||
} else if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_LEFT_HAND_SLOT_X, INVENTORY_LEFT_HAND_SLOT_Y, INVENTORY_LEFT_HAND_SLOT_MAX_X, INVENTORY_LEFT_HAND_SLOT_MAX_Y)) {
|
||||
if (gInventoryLeftHandItem != nullptr && itemGetType(gInventoryLeftHandItem) == ITEM_TYPE_CONTAINER && gInventoryLeftHandItem != item) {
|
||||
_drop_into_container(gInventoryLeftHandItem, item, itemIndex, itemSlot, count);
|
||||
} else if (gInventoryLeftHandItem == nullptr) {
|
||||
_switch_hand(item, &gInventoryLeftHandItem, itemSlot, itemIndex);
|
||||
} else if (_drop_ammo_into_weapon(gInventoryLeftHandItem, item, itemSlot, count, buttonCode) == INVENTORY_AMMO_MOVE_RESULT_FAILED) {
|
||||
_switch_hand(item, &gInventoryLeftHandItem, itemSlot, itemIndex);
|
||||
} else if (gInventoryLeftHandItem == nullptr || _drop_ammo_into_weapon(gInventoryLeftHandItem, item, itemSlot, count, buttonCode)) {
|
||||
_switch_hand(item, &gInventoryLeftHandItem, itemSlot, buttonCode);
|
||||
}
|
||||
|
||||
// drop in right hand slot
|
||||
} else if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_RIGHT_HAND_SLOT_X, INVENTORY_RIGHT_HAND_SLOT_Y, INVENTORY_RIGHT_HAND_SLOT_MAX_X, INVENTORY_RIGHT_HAND_SLOT_MAX_Y)) {
|
||||
if (gInventoryRightHandItem != nullptr && itemGetType(gInventoryRightHandItem) == ITEM_TYPE_CONTAINER && gInventoryRightHandItem != item) {
|
||||
_drop_into_container(gInventoryRightHandItem, item, itemIndex, itemSlot, count);
|
||||
} else if (gInventoryRightHandItem == nullptr) {
|
||||
_switch_hand(item, &gInventoryRightHandItem, itemSlot, itemIndex);
|
||||
} else if (_drop_ammo_into_weapon(gInventoryRightHandItem, item, itemSlot, count, buttonCode) == INVENTORY_AMMO_MOVE_RESULT_FAILED) {
|
||||
} else if (gInventoryRightHandItem == nullptr || _drop_ammo_into_weapon(gInventoryRightHandItem, item, itemSlot, count, buttonCode)) {
|
||||
_switch_hand(item, &gInventoryRightHandItem, itemSlot, itemIndex);
|
||||
}
|
||||
|
||||
} else if ((immediate && itemGetType(item) == ITEM_TYPE_ARMOR) || mouseHitTestInWindow(gInventoryWindow, INVENTORY_ARMOR_SLOT_X, INVENTORY_ARMOR_SLOT_Y, INVENTORY_ARMOR_SLOT_MAX_X, INVENTORY_ARMOR_SLOT_MAX_Y)) {
|
||||
if (itemGetType(item) == ITEM_TYPE_ARMOR) {
|
||||
Object* currentArmor = gInventoryArmor;
|
||||
if (!scriptHooks_InventoryMove(HOOK_INVENTORYMOVE_ARMOR_SLOT, item, currentArmor)) {
|
||||
goto inventory_move_done;
|
||||
}
|
||||
|
||||
int itemAddResult = 0;
|
||||
if (itemIndex != -1) {
|
||||
itemRemove(_inven_dude, item, 1);
|
||||
@@ -2536,19 +2518,13 @@ static void _inven_pickup(int buttonCode, int indexOffset)
|
||||
}
|
||||
}
|
||||
} else if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_PC_BODY_VIEW_X, INVENTORY_PC_BODY_VIEW_Y, INVENTORY_PC_BODY_VIEW_MAX_X, INVENTORY_PC_BODY_VIEW_MAX_Y)) {
|
||||
if (_curr_stack == 0) {
|
||||
// Call the hook when dropping item on the PC portrait when not in a container. Return value is irrelevant.
|
||||
if (!scriptHooks_InventoryMove(HOOK_INVENTORYMOVE_CHARACTER_PORTRAIT, item, nullptr)) {
|
||||
goto inventory_move_done;
|
||||
}
|
||||
} else {
|
||||
if (_curr_stack != 0) {
|
||||
// If we are looking inside nested inventory (such as backpack item), we see this item in the PC Body View instead of the player.
|
||||
// So we drop item into it.
|
||||
_drop_into_container(_stack[_curr_stack - 1], item, itemIndex, itemSlot, count);
|
||||
}
|
||||
}
|
||||
|
||||
inventory_move_done:
|
||||
_adjust_fid();
|
||||
inventoryRenderSummary();
|
||||
_display_inventory(indexOffset, -1, INVENTORY_WINDOW_TYPE_NORMAL);
|
||||
@@ -2574,16 +2550,7 @@ static void _switch_hand(Object* sourceItem, Object** targetSlot, Object** sourc
|
||||
if (itemGetType(*targetSlot) == ITEM_TYPE_WEAPON && itemGetType(sourceItem) == ITEM_TYPE_AMMO) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
HookInventoryMoveType targetSlotType = targetSlot == &gInventoryLeftHandItem
|
||||
? HOOK_INVENTORYMOVE_LEFT_HAND
|
||||
: HOOK_INVENTORYMOVE_RIGHT_HAND;
|
||||
if (!scriptHooks_InventoryMove(targetSlotType, sourceItem, *targetSlot)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (*targetSlot != nullptr) {
|
||||
if (sourceSlot != nullptr && (sourceSlot != &gInventoryArmor || itemGetType(*targetSlot) == ITEM_TYPE_ARMOR)) {
|
||||
if (sourceSlot == &gInventoryArmor) {
|
||||
adjustCritterStatsOnArmorChange(_stack[0], gInventoryArmor, *targetSlot);
|
||||
@@ -3966,14 +3933,8 @@ static void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType)
|
||||
|
||||
int actionMenuItem = actionMenuItems[menuItemIndex];
|
||||
switch (actionMenuItem) {
|
||||
case GAME_MOUSE_ACTION_MENU_ITEM_DROP: {
|
||||
bool inventoryMoveAlreadyChecked = false;
|
||||
case GAME_MOUSE_ACTION_MENU_ITEM_DROP:
|
||||
if (itemSlot != nullptr) {
|
||||
if (!scriptHooks_InventoryMove(HOOK_INVENTORYMOVE_GROUND, item, nullptr)) {
|
||||
break;
|
||||
}
|
||||
|
||||
inventoryMoveAlreadyChecked = true;
|
||||
if (itemSlot == &gInventoryArmor) {
|
||||
adjustCritterStatsOnArmorChange(_stack[0], item, nullptr);
|
||||
}
|
||||
@@ -3991,20 +3952,14 @@ static void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType)
|
||||
|
||||
if (quantity > 0) {
|
||||
if (quantity == 1) {
|
||||
if (inventoryMoveAlreadyChecked || scriptHooks_InventoryMove(HOOK_INVENTORYMOVE_GROUND, item, nullptr)) {
|
||||
itemSetMoney(item, 1);
|
||||
objectDrop(owner, item);
|
||||
}
|
||||
itemSetMoney(item, 1);
|
||||
objectDrop(owner, item);
|
||||
} else {
|
||||
if (itemRemove(owner, item, quantity - 1) == 0) {
|
||||
Object* item2;
|
||||
if (_inven_from_button(keyCode, &item2, &itemSlot, &owner) != 0) {
|
||||
if (scriptHooks_InventoryMove(HOOK_INVENTORYMOVE_GROUND, item2, nullptr)) {
|
||||
itemSetMoney(item2, quantity);
|
||||
objectDrop(owner, item2);
|
||||
} else {
|
||||
itemAdd(owner, item, quantity - 1);
|
||||
}
|
||||
itemSetMoney(item2, quantity);
|
||||
objectDrop(owner, item2);
|
||||
} else {
|
||||
itemAdd(owner, item, quantity - 1);
|
||||
}
|
||||
@@ -4012,29 +3967,22 @@ static void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType)
|
||||
}
|
||||
}
|
||||
} else if (explosiveIsActiveExplosive(item->pid)) {
|
||||
if (inventoryMoveAlreadyChecked || scriptHooks_InventoryMove(HOOK_INVENTORYMOVE_GROUND, item, nullptr)) {
|
||||
_dropped_explosive = 1;
|
||||
objectDrop(owner, item);
|
||||
}
|
||||
_dropped_explosive = 1;
|
||||
objectDrop(owner, item);
|
||||
} else {
|
||||
if (quantity > 1) {
|
||||
quantity = inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, item, quantity);
|
||||
|
||||
for (int index = 0; index < quantity; index++) {
|
||||
if (_inven_from_button(keyCode, &item, &itemSlot, &owner) != 0) {
|
||||
if (scriptHooks_InventoryMove(HOOK_INVENTORYMOVE_GROUND, item, nullptr)) {
|
||||
objectDrop(owner, item);
|
||||
}
|
||||
objectDrop(owner, item);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (inventoryMoveAlreadyChecked || scriptHooks_InventoryMove(HOOK_INVENTORYMOVE_GROUND, item, nullptr)) {
|
||||
objectDrop(owner, item);
|
||||
}
|
||||
objectDrop(owner, item);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GAME_MOUSE_ACTION_MENU_ITEM_LOOK:
|
||||
if (inventoryWindowType != INVENTORY_WINDOW_TYPE_NORMAL) {
|
||||
objectExamineFunc(_stack[0], item, gInventoryPrintItemDescriptionHandler);
|
||||
@@ -5539,10 +5487,6 @@ static void _container_exit(int keyCode, int inventoryWindowType)
|
||||
// 0x476464
|
||||
static int _drop_into_container(Object* container, Object* item, int sourceIndex, Object** itemSlot, int quantity)
|
||||
{
|
||||
if (!scriptHooks_InventoryMove(HOOK_INVENTORYMOVE_CONTAINER, item, container)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int quantityToMove;
|
||||
if (quantity > 1) {
|
||||
quantityToMove = inventoryQuantitySelect(INVENTORY_WINDOW_TYPE_MOVE_ITEMS, item, quantity);
|
||||
@@ -5581,22 +5525,18 @@ static int _drop_into_container(Object* container, Object* item, int sourceIndex
|
||||
}
|
||||
|
||||
// 0x47650C
|
||||
static InventoryAmmoMoveResult _drop_ammo_into_weapon(Object* weapon, Object* ammo, Object** ammoItemSlot, int quantity, int keyCode)
|
||||
static int _drop_ammo_into_weapon(Object* weapon, Object* ammo, Object** ammoItemSlot, int quantity, int keyCode)
|
||||
{
|
||||
if (itemGetType(weapon) != ITEM_TYPE_WEAPON) {
|
||||
return INVENTORY_AMMO_MOVE_RESULT_FAILED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (itemGetType(ammo) != ITEM_TYPE_AMMO) {
|
||||
return INVENTORY_AMMO_MOVE_RESULT_FAILED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!weaponCanBeReloadedWith(weapon, ammo)) {
|
||||
return INVENTORY_AMMO_MOVE_RESULT_FAILED;
|
||||
}
|
||||
|
||||
if (!scriptHooks_InventoryMove(HOOK_INVENTORYMOVE_WEAPON_RELOAD, ammo, weapon)) {
|
||||
return INVENTORY_AMMO_MOVE_RESULT_BLOCKED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int quantityToMove;
|
||||
@@ -5607,7 +5547,7 @@ static InventoryAmmoMoveResult _drop_ammo_into_weapon(Object* weapon, Object* am
|
||||
}
|
||||
|
||||
if (quantityToMove == -1) {
|
||||
return INVENTORY_AMMO_MOVE_RESULT_FAILED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Object* sourceItem = ammo;
|
||||
@@ -5640,13 +5580,13 @@ static InventoryAmmoMoveResult _drop_ammo_into_weapon(Object* weapon, Object* am
|
||||
}
|
||||
|
||||
if (!isReloaded) {
|
||||
return INVENTORY_AMMO_MOVE_RESULT_FAILED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* sfx = sfxBuildWeaponName(WEAPON_SOUND_EFFECT_READY, weapon, HIT_MODE_RIGHT_WEAPON_PRIMARY, nullptr);
|
||||
soundPlayFile(sfx);
|
||||
|
||||
return INVENTORY_AMMO_MOVE_RESULT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x47664C
|
||||
|
||||
@@ -570,10 +570,6 @@ int objectPickup(Object* critter, Object* item)
|
||||
{
|
||||
bool overriden = false;
|
||||
|
||||
if (critter == gDude && !scriptHooks_InventoryMove(HOOK_INVENTORYMOVE_PICKUP, item, nullptr)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (item->sid != -1) {
|
||||
scriptSetObjects(item->sid, critter, item);
|
||||
scriptExecProc(item->sid, SCRIPT_PROC_PICKUP);
|
||||
|
||||
@@ -164,36 +164,6 @@ void scriptHooks_GameModeChange(int exit, int previousGameMode)
|
||||
ScriptHookCall(HOOK_GAMEMODECHANGE, 0, { exit, previousGameMode }).call();
|
||||
}
|
||||
|
||||
/*
|
||||
Runs before moving items between inventory slots in dude interface. You can override the action.
|
||||
|
||||
int arg0 - Target slot:
|
||||
0 - main backpack
|
||||
1 - left hand
|
||||
2 - right hand
|
||||
3 - armor slot
|
||||
4 - weapon, when reloading it by dropping ammo
|
||||
5 - container, like bag/backpack
|
||||
6 - dropping on the ground
|
||||
7 - picking up item
|
||||
8 - dropping item on the character portrait
|
||||
Item arg1 - Item being moved
|
||||
Item arg2 - Item being replaced, weapon being reloaded, or container being filled (can be 0)
|
||||
|
||||
int ret0 - Override setting (-1 - use engine handler, any other value - prevent relocation)
|
||||
*/
|
||||
bool scriptHooks_InventoryMove(HookInventoryMoveType actionType, Object* item, Object* targetItem)
|
||||
{
|
||||
ScriptHookCall hook(HOOK_INVENTORYMOVE, 1, { actionType, item, targetItem });
|
||||
hook.call();
|
||||
|
||||
if (hook.numReturnValues() <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return hook.getReturnValueAt(0).asInt() == -1;
|
||||
}
|
||||
|
||||
/*
|
||||
Runs when Fallout is calculating the chances of an attack striking a target.
|
||||
Runs after the hit chance is fully calculated normally, including applying the 95% cap.
|
||||
|
||||
@@ -154,18 +154,6 @@ typedef enum {
|
||||
HOOK_COUNT,
|
||||
} HookType;
|
||||
|
||||
typedef enum {
|
||||
HOOK_INVENTORYMOVE_MAIN_BACKPACK = 0,
|
||||
HOOK_INVENTORYMOVE_LEFT_HAND = 1,
|
||||
HOOK_INVENTORYMOVE_RIGHT_HAND = 2,
|
||||
HOOK_INVENTORYMOVE_ARMOR_SLOT = 3,
|
||||
HOOK_INVENTORYMOVE_WEAPON_RELOAD = 4,
|
||||
HOOK_INVENTORYMOVE_CONTAINER = 5,
|
||||
HOOK_INVENTORYMOVE_GROUND = 6,
|
||||
HOOK_INVENTORYMOVE_PICKUP = 7,
|
||||
HOOK_INVENTORYMOVE_CHARACTER_PORTRAIT = 8,
|
||||
} HookInventoryMoveType;
|
||||
|
||||
constexpr size_t HOOKS_MAX_ARGUMENTS = 16;
|
||||
constexpr size_t HOOKS_MAX_RETURN_VALUES = 8;
|
||||
|
||||
@@ -244,7 +232,6 @@ void scriptHooksReset();
|
||||
void scriptHooksExit();
|
||||
|
||||
void scriptHooks_GameModeChange(int exit, int previousGameMode);
|
||||
bool scriptHooks_InventoryMove(HookInventoryMoveType actionType, Object* item, Object* targetItem);
|
||||
int scriptHooks_ToHit(Object* attacker, Object* defender, int tile, int hitMode, int hitLocation, int hitChance, int hitChanceUncapped, bool useDistance);
|
||||
void scriptHooks_DeathAnim(Object* attacker, Object* defender, Object* weapon, int damage, int* anim);
|
||||
int scriptHooks_UseItem(Object* user, Object* objUsed);
|
||||
|
||||
+54
-70
@@ -71,11 +71,6 @@ namespace fallout {
|
||||
#define WM_WINDOW_DIAL_X (532)
|
||||
#define WM_WINDOW_DIAL_Y (48)
|
||||
|
||||
#define WM_TOWN_LIST_X (501)
|
||||
#define WM_TOWN_LIST_Y (135)
|
||||
#define WM_TOWN_LIST_WIDTH (119)
|
||||
#define WM_TOWN_LIST_HEIGHT (178)
|
||||
|
||||
#define WM_TOWN_LIST_SCROLL_UP_X (480)
|
||||
#define WM_TOWN_LIST_SCROLL_UP_Y (137)
|
||||
|
||||
@@ -98,9 +93,6 @@ namespace fallout {
|
||||
#define WM_TOWN_WORLD_SWITCH_X (519)
|
||||
#define WM_TOWN_WORLD_SWITCH_Y (439)
|
||||
|
||||
#define WM_TOWN_LIST_VISIBLE_SLOT_COUNT (7)
|
||||
#define WM_TOWN_LIST_SLOT_HEIGHT (27)
|
||||
|
||||
#define WM_TILE_WIDTH (350)
|
||||
#define WM_TILE_HEIGHT (300)
|
||||
|
||||
@@ -826,7 +818,7 @@ static int wmRndOriginalCenterTile;
|
||||
static Config* pConfigCfg;
|
||||
|
||||
// 0x672FD8
|
||||
static int wmTownMapSubButtonIds[WM_TOWN_LIST_VISIBLE_SLOT_COUNT];
|
||||
static int wmTownMapSubButtonIds[7];
|
||||
|
||||
// 0x672FF4
|
||||
static Encounter* wmEncBaseTypeList;
|
||||
@@ -3270,11 +3262,11 @@ static int wmWorldMapFunc(int a1)
|
||||
// NOTE: Uninline.
|
||||
wmInterfaceScroll(1, 0, nullptr);
|
||||
} else if (keyCode == KEY_CTRL_ARROW_UP) {
|
||||
wmInterfaceScrollTabsStart(-WM_TOWN_LIST_SLOT_HEIGHT);
|
||||
wmInterfaceScrollTabsStart(-27);
|
||||
} else if (keyCode == KEY_CTRL_ARROW_DOWN) {
|
||||
wmInterfaceScrollTabsStart(WM_TOWN_LIST_SLOT_HEIGHT);
|
||||
wmInterfaceScrollTabsStart(27);
|
||||
} else if (keyCode >= KEY_CTRL_F1 && keyCode <= KEY_CTRL_F7) {
|
||||
int quickDestinationIndex = wmGenData.tabsOffsetY / WM_TOWN_LIST_SLOT_HEIGHT + (keyCode - KEY_CTRL_F1);
|
||||
int quickDestinationIndex = wmGenData.tabsOffsetY / 27 + (keyCode - KEY_CTRL_F1);
|
||||
if (quickDestinationIndex < wmLabelCount) {
|
||||
int areaIdx = wmLabelList[quickDestinationIndex];
|
||||
CityInfo* city = &(wmAreaInfoList[areaIdx]);
|
||||
@@ -3302,13 +3294,9 @@ static int wmWorldMapFunc(int a1)
|
||||
|
||||
if (mouseHitTestInWindow(wmBkWin, WM_VIEW_X, WM_VIEW_Y, WM_VIEW_WIDTH + WM_VIEW_X, WM_VIEW_HEIGHT + WM_VIEW_Y)) {
|
||||
wmInterfaceScrollPixel(20, 20, wheelX, -wheelY, nullptr, true);
|
||||
} else if (mouseHitTestInWindow(wmBkWin,
|
||||
WM_TOWN_LIST_X,
|
||||
WM_TOWN_LIST_Y,
|
||||
WM_TOWN_LIST_X + WM_TOWN_LIST_WIDTH,
|
||||
WM_TOWN_LIST_Y + WM_TOWN_LIST_HEIGHT)) {
|
||||
} else if (mouseHitTestInWindow(wmBkWin, 501, 135, 501 + 119, 135 + 178)) {
|
||||
if (wheelY != 0) {
|
||||
wmInterfaceScrollTabsStart(wheelY > 0 ? WM_TOWN_LIST_SLOT_HEIGHT : -WM_TOWN_LIST_SLOT_HEIGHT);
|
||||
wmInterfaceScrollTabsStart(wheelY > 0 ? 27 : -27);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4441,14 +4429,11 @@ static void wmPartyWalkingStep()
|
||||
// 0x4C219C
|
||||
static void wmInterfaceScrollTabsStart(int delta)
|
||||
{
|
||||
int tabsScrollMaxOffsetY = std::max(0,
|
||||
wmGenData.tabsBackgroundFrmImage.getHeight() - (WM_TOWN_LIST_HEIGHT + 52));
|
||||
|
||||
// SFALL: Fix world map cities list scrolling bug that might leave buttons
|
||||
// in the disabled state.
|
||||
if (delta >= 0) {
|
||||
if (wmGenData.tabsOffsetY < tabsScrollMaxOffsetY) {
|
||||
wmGenData.oldTabsOffsetY = std::min(wmGenData.tabsOffsetY + delta, tabsScrollMaxOffsetY);
|
||||
if (wmGenData.tabsOffsetY < wmGenData.tabsBackgroundFrmImage.getHeight() - 230) {
|
||||
wmGenData.oldTabsOffsetY = std::min(wmGenData.tabsOffsetY + delta, wmGenData.tabsBackgroundFrmImage.getHeight() - 230);
|
||||
wmGenData.tabsScrollingDelta = delta;
|
||||
}
|
||||
} else {
|
||||
@@ -4462,7 +4447,7 @@ static void wmInterfaceScrollTabsStart(int delta)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int index = 0; index < WM_TOWN_LIST_VISIBLE_SLOT_COUNT; index++) {
|
||||
for (int index = 0; index < 7; index++) {
|
||||
buttonDisable(wmTownMapSubButtonIds[index]);
|
||||
}
|
||||
|
||||
@@ -4474,7 +4459,7 @@ static void wmInterfaceScrollTabsStop()
|
||||
{
|
||||
wmGenData.tabsScrollingDelta = 0;
|
||||
|
||||
for (int index = 0; index < WM_TOWN_LIST_VISIBLE_SLOT_COUNT; index++) {
|
||||
for (int index = 0; index < 7; index++) {
|
||||
buttonEnable(wmTownMapSubButtonIds[index]);
|
||||
}
|
||||
}
|
||||
@@ -4686,10 +4671,10 @@ static int wmInterfaceInit()
|
||||
buttonSetCallbacks(switchBtn, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||
}
|
||||
|
||||
for (int index = 0; index < WM_TOWN_LIST_VISIBLE_SLOT_COUNT; index++) {
|
||||
for (int index = 0; index < 7; index++) {
|
||||
wmTownMapSubButtonIds[index] = buttonCreate(wmBkWin,
|
||||
508,
|
||||
138 + WM_TOWN_LIST_SLOT_HEIGHT * index,
|
||||
138 + 27 * index,
|
||||
wmGenData.redButtonNormalFrmImage.getWidth(),
|
||||
wmGenData.redButtonNormalFrmImage.getHeight(),
|
||||
-1,
|
||||
@@ -6092,7 +6077,7 @@ static int wmTownMapFunc(int* mapIdxPtr)
|
||||
}
|
||||
|
||||
if (keyCode >= KEY_CTRL_F1 && keyCode <= KEY_CTRL_F7) {
|
||||
int quickDestinationIndex = wmGenData.tabsOffsetY / WM_TOWN_LIST_SLOT_HEIGHT + keyCode - KEY_CTRL_F1;
|
||||
int quickDestinationIndex = wmGenData.tabsOffsetY / 27 + keyCode - KEY_CTRL_F1;
|
||||
if (quickDestinationIndex < wmLabelCount) {
|
||||
int areaIdx = wmLabelList[quickDestinationIndex];
|
||||
CityInfo* city = &(wmAreaInfoList[areaIdx]);
|
||||
@@ -6115,9 +6100,9 @@ static int wmTownMapFunc(int* mapIdxPtr)
|
||||
}
|
||||
} else {
|
||||
if (keyCode == KEY_CTRL_ARROW_UP) {
|
||||
wmInterfaceScrollTabsStart(-WM_TOWN_LIST_SLOT_HEIGHT);
|
||||
wmInterfaceScrollTabsStart(-27);
|
||||
} else if (keyCode == KEY_CTRL_ARROW_DOWN) {
|
||||
wmInterfaceScrollTabsStart(WM_TOWN_LIST_SLOT_HEIGHT);
|
||||
wmInterfaceScrollTabsStart(27);
|
||||
} else if (keyCode == 2069) {
|
||||
if (wmTownMapRefresh() == -1) {
|
||||
return -1;
|
||||
@@ -6531,64 +6516,63 @@ static void wmInterfaceRefreshCarFuel()
|
||||
// 0x4C52B0
|
||||
static int wmRefreshTabs()
|
||||
{
|
||||
unsigned char* firstTabBottomDest;
|
||||
unsigned char* firstTabDest;
|
||||
int firstVisibleLabelIndex;
|
||||
unsigned char* v30;
|
||||
unsigned char* v0;
|
||||
int v31;
|
||||
CityInfo* city;
|
||||
int firstTabVisibleHeight;
|
||||
unsigned char* firstTabSrc;
|
||||
unsigned char* firstTabClampedDest;
|
||||
int lastLabelIndexToDraw;
|
||||
unsigned char* nextTabDest;
|
||||
int v10;
|
||||
unsigned char* v11;
|
||||
unsigned char* v12;
|
||||
int v32;
|
||||
unsigned char* v13;
|
||||
FrmImage labelFrm;
|
||||
|
||||
// CE: Skip first empty tab (original code does this in the
|
||||
// `wmInterfaceInit`).
|
||||
unsigned char* src = wmGenData.tabsBackgroundFrmImage.getData() + wmGenData.tabsBackgroundFrmImage.getWidth() * WM_TOWN_LIST_SLOT_HEIGHT;
|
||||
unsigned char* src = wmGenData.tabsBackgroundFrmImage.getData() + wmGenData.tabsBackgroundFrmImage.getWidth() * 27;
|
||||
blitBufferToBufferTrans(src + wmGenData.tabsBackgroundFrmImage.getWidth() * wmGenData.tabsOffsetY + 9,
|
||||
WM_TOWN_LIST_WIDTH,
|
||||
WM_TOWN_LIST_HEIGHT,
|
||||
119,
|
||||
178,
|
||||
wmGenData.tabsBackgroundFrmImage.getWidth(),
|
||||
wmBkWinBuf + WM_WINDOW_WIDTH * WM_TOWN_LIST_Y + WM_TOWN_LIST_X,
|
||||
wmBkWinBuf + WM_WINDOW_WIDTH * 135 + 501,
|
||||
WM_WINDOW_WIDTH);
|
||||
|
||||
int tabsOffsetWithinSlot = wmGenData.tabsOffsetY % WM_TOWN_LIST_SLOT_HEIGHT;
|
||||
firstTabBottomDest = wmBkWinBuf + WM_WINDOW_WIDTH * 138 + 530;
|
||||
firstTabDest = firstTabBottomDest - WM_WINDOW_WIDTH * tabsOffsetWithinSlot;
|
||||
firstVisibleLabelIndex = wmGenData.tabsOffsetY / WM_TOWN_LIST_SLOT_HEIGHT;
|
||||
v30 = wmBkWinBuf + WM_WINDOW_WIDTH * 138 + 530;
|
||||
v0 = wmBkWinBuf + WM_WINDOW_WIDTH * 138 + 530 - WM_WINDOW_WIDTH * (wmGenData.tabsOffsetY % 27);
|
||||
v31 = wmGenData.tabsOffsetY / 27;
|
||||
|
||||
if (firstVisibleLabelIndex < wmLabelCount) {
|
||||
city = &(wmAreaInfoList[wmLabelList[firstVisibleLabelIndex]]);
|
||||
if (v31 < wmLabelCount) {
|
||||
city = &(wmAreaInfoList[wmLabelList[v31]]);
|
||||
if (city->labelFid != -1) {
|
||||
if (!labelFrm.lock(city->labelFid)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
firstTabVisibleHeight = labelFrm.getHeight() - tabsOffsetWithinSlot;
|
||||
firstTabSrc = labelFrm.getData() + labelFrm.getWidth() * tabsOffsetWithinSlot;
|
||||
v10 = labelFrm.getHeight() - wmGenData.tabsOffsetY % 27;
|
||||
v11 = labelFrm.getData() + labelFrm.getWidth() * (wmGenData.tabsOffsetY % 27);
|
||||
|
||||
firstTabClampedDest = firstTabDest;
|
||||
if (firstTabDest < firstTabBottomDest - WM_WINDOW_WIDTH) {
|
||||
firstTabClampedDest = firstTabBottomDest - WM_WINDOW_WIDTH;
|
||||
v12 = v0;
|
||||
if (v0 < v30 - WM_WINDOW_WIDTH) {
|
||||
v12 = v30 - WM_WINDOW_WIDTH;
|
||||
}
|
||||
|
||||
blitBufferToBuffer(firstTabSrc,
|
||||
blitBufferToBuffer(v11,
|
||||
labelFrm.getWidth(),
|
||||
firstTabVisibleHeight,
|
||||
v10,
|
||||
labelFrm.getWidth(),
|
||||
firstTabClampedDest,
|
||||
v12,
|
||||
WM_WINDOW_WIDTH);
|
||||
|
||||
labelFrm.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
nextTabDest = firstTabDest + WM_WINDOW_WIDTH * WM_TOWN_LIST_SLOT_HEIGHT;
|
||||
lastLabelIndexToDraw = firstVisibleLabelIndex + (WM_TOWN_LIST_VISIBLE_SLOT_COUNT - 1);
|
||||
v13 = v0 + WM_WINDOW_WIDTH * 27;
|
||||
v32 = v31 + 6;
|
||||
|
||||
for (int labelIndex = firstVisibleLabelIndex + 1; labelIndex < lastLabelIndexToDraw; labelIndex++) {
|
||||
if (labelIndex < wmLabelCount) {
|
||||
city = &(wmAreaInfoList[wmLabelList[labelIndex]]);
|
||||
for (int v14 = v31 + 1; v14 < v32; v14++) {
|
||||
if (v14 < wmLabelCount) {
|
||||
city = &(wmAreaInfoList[wmLabelList[v14]]);
|
||||
if (city->labelFid != -1) {
|
||||
if (!labelFrm.lock(city->labelFid)) {
|
||||
return -1;
|
||||
@@ -6598,17 +6582,17 @@ static int wmRefreshTabs()
|
||||
labelFrm.getWidth(),
|
||||
labelFrm.getHeight(),
|
||||
labelFrm.getWidth(),
|
||||
nextTabDest,
|
||||
v13,
|
||||
WM_WINDOW_WIDTH);
|
||||
|
||||
labelFrm.unlock();
|
||||
}
|
||||
}
|
||||
nextTabDest += WM_WINDOW_WIDTH * WM_TOWN_LIST_SLOT_HEIGHT;
|
||||
v13 += WM_WINDOW_WIDTH * 27;
|
||||
}
|
||||
|
||||
if (lastLabelIndexToDraw < wmLabelCount) {
|
||||
city = &(wmAreaInfoList[wmLabelList[lastLabelIndexToDraw]]);
|
||||
if (v31 + 6 < wmLabelCount) {
|
||||
city = &(wmAreaInfoList[wmLabelList[v31 + 6]]);
|
||||
if (city->labelFid != -1) {
|
||||
if (!labelFrm.lock(city->labelFid)) {
|
||||
return -1;
|
||||
@@ -6618,7 +6602,7 @@ static int wmRefreshTabs()
|
||||
labelFrm.getWidth(),
|
||||
labelFrm.getHeight() - 5,
|
||||
labelFrm.getWidth(),
|
||||
nextTabDest,
|
||||
v13,
|
||||
WM_WINDOW_WIDTH);
|
||||
|
||||
labelFrm.unlock();
|
||||
@@ -6626,10 +6610,10 @@ static int wmRefreshTabs()
|
||||
}
|
||||
|
||||
blitBufferToBufferTrans(wmGenData.tabsBorderFrmImage.getData(),
|
||||
WM_TOWN_LIST_WIDTH,
|
||||
WM_TOWN_LIST_HEIGHT,
|
||||
WM_TOWN_LIST_WIDTH,
|
||||
wmBkWinBuf + WM_WINDOW_WIDTH * WM_TOWN_LIST_Y + WM_TOWN_LIST_X,
|
||||
119,
|
||||
178,
|
||||
119,
|
||||
wmBkWinBuf + WM_WINDOW_WIDTH * 135 + 501,
|
||||
WM_WINDOW_WIDTH);
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user