mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Moved code from main.cpp to new LoadOrder/Karma.cpp
Slightly refactored list_* functions with 4.x codebase. Changed the initialization order in main.cpp to 4.x's.
This commit is contained in:
+4
-13
@@ -97,21 +97,12 @@ static void RunEditorInternal(SOCKET &s) {
|
||||
std::vector<DWORD*> vec = std::vector<DWORD*>();
|
||||
for (int elv = 0; elv < 3; elv++) {
|
||||
for (int tile = 0; tile < 40000; tile++) {
|
||||
DWORD* obj;
|
||||
__asm {
|
||||
mov edx, tile;
|
||||
mov eax, elv;
|
||||
call obj_find_first_at_tile_;
|
||||
mov obj, eax;
|
||||
}
|
||||
TGameObj* obj = ObjFindFirstAtTile(elv, tile);
|
||||
while (obj) {
|
||||
DWORD otype = obj[25];
|
||||
otype = (otype & 0xFF000000) >> 24;
|
||||
if (otype == 1) vec.push_back(obj);
|
||||
__asm {
|
||||
call obj_find_next_at_tile_;
|
||||
mov obj, eax;
|
||||
if (obj->pid >> 24 == OBJ_TYPE_CRITTER) {
|
||||
vec.push_back(reinterpret_cast<DWORD*>(obj));
|
||||
}
|
||||
obj = ObjFindNextAtTile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1083,10 +1083,22 @@ TGameObj* __stdcall ObjFindFirst() {
|
||||
__asm call obj_find_first_;
|
||||
}
|
||||
|
||||
TGameObj* __stdcall ObjFindFirstAtTile(long elevation, long tileNum) {
|
||||
__asm {
|
||||
mov edx, tileNum;
|
||||
mov eax, elevation;
|
||||
call obj_find_first_at_tile_;
|
||||
}
|
||||
}
|
||||
|
||||
TGameObj* __stdcall ObjFindNext() {
|
||||
__asm call obj_find_next_;
|
||||
}
|
||||
|
||||
TGameObj* __stdcall ObjFindNextAtTile() {
|
||||
__asm call obj_find_next_at_tile_;
|
||||
}
|
||||
|
||||
long __stdcall NewObjId() {
|
||||
__asm call new_obj_id_;
|
||||
}
|
||||
|
||||
@@ -1073,8 +1073,12 @@ long __stdcall QueueFindFirst(TGameObj* object, long qType);
|
||||
|
||||
TGameObj* __stdcall ObjFindFirst();
|
||||
|
||||
TGameObj* __stdcall ObjFindFirstAtTile(long elevation, long tileNum);
|
||||
|
||||
TGameObj* __stdcall ObjFindNext();
|
||||
|
||||
TGameObj* __stdcall ObjFindNextAtTile();
|
||||
|
||||
long __stdcall NewObjId();
|
||||
|
||||
FrmFrameData* __fastcall FramePtr(FrmHeaderData* frm, long frame, long direction);
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* sfall
|
||||
* Copyright (C) 2008-2017 The sfall team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "main.h"
|
||||
#include "FalloutEngine.h"
|
||||
|
||||
struct KarmaFrmSetting {
|
||||
DWORD frm;
|
||||
int points;
|
||||
};
|
||||
|
||||
static std::vector<KarmaFrmSetting> karmaFrms;
|
||||
|
||||
static char KarmaGainMsg[128];
|
||||
static char KarmaLossMsg[128];
|
||||
|
||||
static DWORD _stdcall DrawCard() {
|
||||
int reputation = **(int**)_game_global_vars;
|
||||
for (std::vector<KarmaFrmSetting>::const_iterator it = karmaFrms.begin(); it != karmaFrms.end(); ++it) {
|
||||
if (reputation < it->points) {
|
||||
return it->frm;
|
||||
}
|
||||
}
|
||||
return karmaFrms.end()->frm;
|
||||
}
|
||||
|
||||
static void __declspec(naked) DrawInfoWin_hook() {
|
||||
__asm {
|
||||
cmp ds:[_info_line], 10;
|
||||
jne skip;
|
||||
cmp eax, 0x30;
|
||||
jne skip;
|
||||
push ecx;
|
||||
push edx;
|
||||
call DrawCard;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
skip:
|
||||
jmp DrawCard_;
|
||||
}
|
||||
}
|
||||
|
||||
static void _stdcall SetKarma(int value) {
|
||||
int old;
|
||||
__asm {
|
||||
xor eax, eax;
|
||||
call game_get_global_var_;
|
||||
mov old, eax;
|
||||
}
|
||||
old = value - old;
|
||||
char buf[128];
|
||||
if (old == 0) return;
|
||||
if (old > 0) {
|
||||
sprintf_s(buf, KarmaGainMsg, old);
|
||||
} else {
|
||||
sprintf_s(buf, KarmaLossMsg, -old);
|
||||
}
|
||||
DisplayConsoleMessage(buf);
|
||||
}
|
||||
|
||||
static void __declspec(naked) SetGlobalVarWrapper() {
|
||||
__asm {
|
||||
test eax, eax; // GVar number
|
||||
jnz end;
|
||||
pushadc;
|
||||
push edx;
|
||||
call SetKarma;
|
||||
popadc;
|
||||
end:
|
||||
jmp game_set_global_var_;
|
||||
}
|
||||
}
|
||||
|
||||
void KarmaInit() {
|
||||
if (GetConfigInt("Misc", "DisplayKarmaChanges", 0)) {
|
||||
dlog("Applying display karma changes patch.", DL_INIT);
|
||||
Translate("sfall", "KarmaGain", "You gained %d karma.", KarmaGainMsg);
|
||||
Translate("sfall", "KarmaLoss", "You lost %d karma.", KarmaLossMsg);
|
||||
HookCall(0x455A6D, SetGlobalVarWrapper);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
std::vector<std::string> karmaFrmList = GetConfigList("Misc", "KarmaFRMs", "", 512);
|
||||
size_t countFrm = karmaFrmList.size();
|
||||
if (countFrm) {
|
||||
dlog("Applying karma FRM patch.", DL_INIT);
|
||||
std::vector<std::string> karmaPointsList = GetConfigList("Misc", "KarmaPoints", "", 512);
|
||||
|
||||
karmaFrms.resize(countFrm);
|
||||
size_t countPoints = karmaPointsList.size();
|
||||
for (size_t i = 0; i < countFrm; i++) {
|
||||
karmaFrms[i].frm = atoi(karmaFrmList[i].c_str());
|
||||
karmaFrms[i].points = (countPoints > i)
|
||||
? atoi(karmaPointsList[i].c_str())
|
||||
: INT_MAX;
|
||||
}
|
||||
HookCall(0x4367A9, DrawInfoWin_hook);
|
||||
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* sfall
|
||||
* Copyright (C) 2008-2017 The sfall team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
void KarmaInit();
|
||||
@@ -33,15 +33,16 @@
|
||||
#include "input.h"
|
||||
#include "Inventory.h"
|
||||
#include "LoadGameHook.h"
|
||||
#include "LoadOrder.h"
|
||||
#include "Logging.h"
|
||||
#include "Message.h"
|
||||
#include "movies.h"
|
||||
#include "Movies.h"
|
||||
#include "Objects.h"
|
||||
#include "PartyControl.h"
|
||||
#include "perks.h"
|
||||
#include "Perks.h"
|
||||
#include "ScriptExtender.h"
|
||||
#include "skills.h"
|
||||
#include "sound.h"
|
||||
#include "Skills.h"
|
||||
#include "Sound.h"
|
||||
#include "SuperSave.h"
|
||||
#include "TalkingHeads.h"
|
||||
#include "version.h"
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* sfall
|
||||
* Copyright (C) 2008-2017 The sfall team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "FalloutEngine.h"
|
||||
|
||||
static std::vector<int> savPrototypes;
|
||||
|
||||
static void __declspec(naked) RemoveDatabase() {
|
||||
__asm {
|
||||
cmp eax, -1;
|
||||
je end;
|
||||
mov ebx, ds:[_paths];
|
||||
mov ecx, ebx;
|
||||
nextPath:
|
||||
mov edx, [esp + 0x104 + 4 + 4]; // path_patches
|
||||
mov eax, [ebx]; // database.path
|
||||
call stricmp_;
|
||||
test eax, eax; // found path?
|
||||
jz skip; // Yes
|
||||
mov ecx, ebx;
|
||||
mov ebx, [ebx + 0xC]; // database.next
|
||||
jmp nextPath;
|
||||
skip:
|
||||
mov eax, [ebx + 0xC]; // database.next
|
||||
mov [ecx + 0xC], eax; // database.next
|
||||
xchg ebx, eax;
|
||||
cmp eax, ecx;
|
||||
jne end;
|
||||
mov ds:[_paths], ebx;
|
||||
end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove master_patches from the chain
|
||||
static void __declspec(naked) game_init_databases_hack1() {
|
||||
__asm {
|
||||
call RemoveDatabase;
|
||||
mov ds:[_master_db_handle], eax; // the pointer of master_patches node will be saved here
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove critter_patches from the chain
|
||||
static void __declspec(naked) game_init_databases_hack2() {
|
||||
__asm {
|
||||
cmp eax, -1;
|
||||
je end;
|
||||
mov eax, ds:[_master_db_handle]; // pointer to master_patches node
|
||||
mov eax, [eax]; // eax = master_patches.path
|
||||
call xremovepath_;
|
||||
dec eax; // remove path (critter_patches == master_patches)?
|
||||
jz end; // Yes (jump if 0)
|
||||
inc eax;
|
||||
call RemoveDatabase;
|
||||
end:
|
||||
mov ds:[_critter_db_handle], eax; // the pointer of critter_patches node will be saved here
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) game_init_databases_hook() {
|
||||
// eax = _master_db_handle
|
||||
__asm {
|
||||
mov ecx, ds:[_critter_db_handle];
|
||||
mov edx, ds:[_paths];
|
||||
test ecx, ecx;
|
||||
jz skip;
|
||||
mov [ecx + 0xC], edx; // critter_patches.next->_paths
|
||||
mov edx, ecx;
|
||||
skip:
|
||||
mov [eax + 0xC], edx; // master_patches.next
|
||||
mov ds:[_paths], eax;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////// SAVE PARTY MEMBER PROTOTYPES //////////////////////////////
|
||||
|
||||
static void __fastcall AddSavPrototype(long pid) {
|
||||
for (std::vector<int>::const_iterator it = savPrototypes.begin(); it != savPrototypes.end(); ++it) {
|
||||
if (*it == pid) return;
|
||||
}
|
||||
savPrototypes.push_back(pid);
|
||||
}
|
||||
|
||||
static long ChangePrototypeExt(char* path) {
|
||||
long len = strlen(path);
|
||||
if (len) {
|
||||
len -= 4;
|
||||
if (path[len] == '.') {
|
||||
path[++len] = 's';
|
||||
path[++len] = 'a';
|
||||
path[++len] = 'v';
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static void __fastcall ExistSavPrototype(long pid, char* path) {
|
||||
if (savPrototypes.empty()) return;
|
||||
for (std::vector<int>::const_iterator it = savPrototypes.begin(); it != savPrototypes.end(); ++it) {
|
||||
if (*it == pid) {
|
||||
ChangePrototypeExt(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static long __fastcall CheckProtoType(long pid, char* path) {
|
||||
if (pid >> 24 != OBJ_TYPE_CRITTER) return 0;
|
||||
return ChangePrototypeExt(path);
|
||||
}
|
||||
|
||||
// saves prototypes (all party members) before saving game or exiting the map
|
||||
static void __declspec(naked) proto_save_pid_hook() {
|
||||
__asm {
|
||||
push ecx;
|
||||
call proto_list_str_;
|
||||
test eax, eax;
|
||||
jnz end;
|
||||
mov ecx, ebx; // party pid
|
||||
mov edx, edi; // path buffer
|
||||
call CheckProtoType;
|
||||
test eax, eax;
|
||||
jz end;
|
||||
mov ecx, ebx; // party pid
|
||||
call AddSavPrototype;
|
||||
end:
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
#define _F_PATHFILE 0x6143F4
|
||||
static void __declspec(naked) GameMap2Slot_hack() { // save party pids
|
||||
__asm {
|
||||
push ecx;
|
||||
mov edx, _F_PATHFILE; // path buffer
|
||||
call CheckProtoType; // ecx - party pid
|
||||
pop ecx;
|
||||
lea eax, [esp + 0x14 + 4];
|
||||
retn 0x14;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) SlotMap2Game_hack() { // load party pids
|
||||
__asm {
|
||||
push edx;
|
||||
mov ecx, edi; // party pid
|
||||
mov edx, _F_PATHFILE; // path buffer
|
||||
call CheckProtoType;
|
||||
test eax, eax;
|
||||
jz end;
|
||||
mov ecx, edi;
|
||||
call AddSavPrototype;
|
||||
end:
|
||||
pop edx;
|
||||
lea eax, [esp + 0x14 + 4];
|
||||
retn 0x14;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) proto_load_pid_hook() {
|
||||
__asm { // eax - party pid
|
||||
push ecx;
|
||||
mov ecx, eax;
|
||||
call proto_list_str_;
|
||||
test eax, eax;
|
||||
jnz end;
|
||||
// check pid type
|
||||
mov edx, ecx;
|
||||
shr edx, 24;
|
||||
cmp edx, OBJ_TYPE_CRITTER;
|
||||
jnz end;
|
||||
mov edx, edi; // path buffer
|
||||
call ExistSavPrototype; // ecx - party pid
|
||||
xor eax, eax;
|
||||
end:
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void ResetReadOnlyAttr() {
|
||||
DWORD attr = GetFileAttributesA((const char*)_F_PATHFILE);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_READONLY)) {
|
||||
SetFileAttributesA((const char*)_F_PATHFILE, (attr & ~FILE_ATTRIBUTE_READONLY));
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) SlotMap2Game_hack_attr() {
|
||||
__asm {
|
||||
cmp eax, -1;
|
||||
je end;
|
||||
cmp ebx, OBJ_TYPE_CRITTER;
|
||||
jne end;
|
||||
call ResetReadOnlyAttr;
|
||||
or eax, 1; // reset ZF
|
||||
end:
|
||||
retn 0x8;
|
||||
}
|
||||
}
|
||||
|
||||
#define _F_SAV (const char*)0x50A480
|
||||
#define _F_PROTO_CRITTERS (const char*)0x50A490
|
||||
|
||||
void RemoveSavFiles() {
|
||||
MapDirErase(_F_PROTO_CRITTERS, _F_SAV);
|
||||
}
|
||||
|
||||
void ClearSavPrototypes() {
|
||||
savPrototypes.clear();
|
||||
RemoveSavFiles();
|
||||
}
|
||||
|
||||
void LoadOrderInit() {
|
||||
if (GetConfigInt("Misc", "DataLoadOrderPatch", 1)) {
|
||||
dlog("Applying data load order patch.", DL_INIT);
|
||||
MakeCall(0x444259, game_init_databases_hack1);
|
||||
MakeCall(0x4442F1, game_init_databases_hack2);
|
||||
HookCall(0x44436D, game_init_databases_hook);
|
||||
SafeWrite8(0x4DFAEC, 0x1D); // error correction (ecx > ebx)
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
dlog("Applying party member protos save/load patch.", DL_INIT);
|
||||
savPrototypes.reserve(25);
|
||||
HookCall(0x4A1CF2, proto_load_pid_hook);
|
||||
HookCall(0x4A1BEE, proto_save_pid_hook);
|
||||
MakeCall(0x47F5A5, GameMap2Slot_hack); // save game
|
||||
MakeCall(0x47FB80, SlotMap2Game_hack); // load game
|
||||
MakeCall(0x47FBBF, SlotMap2Game_hack_attr, 1);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* sfall
|
||||
* Copyright (C) 2008-2017 The sfall team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
void LoadOrderInit();
|
||||
void RemoveSavFiles();
|
||||
void ClearSavPrototypes();
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "Graphics.h"
|
||||
#include "Logging.h"
|
||||
|
||||
#include "movies.h"
|
||||
#include "Movies.h"
|
||||
|
||||
static DWORD MoviePtrs[MaxMovies];
|
||||
char MoviePaths[MaxMovies * 65];
|
||||
@@ -1205,7 +1205,7 @@ static void _stdcall ClearEventsOnMapExit() {
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptExtenderSetup() {
|
||||
void ScriptExtenderInit() {
|
||||
toggleHighlightsKey = GetConfigInt("Input", "ToggleItemHighlightsKey", 0);
|
||||
if (toggleHighlightsKey) {
|
||||
MotionSensorMode = GetConfigInt("Misc", "MotionScannerFlags", 1);
|
||||
|
||||
@@ -43,7 +43,7 @@ typedef struct {
|
||||
char initialized;
|
||||
} sScriptProgram;
|
||||
|
||||
void ScriptExtenderSetup();
|
||||
void ScriptExtenderInit();
|
||||
bool _stdcall IsGameScript(const char* filename);
|
||||
void LoadGlobalScripts();
|
||||
void ClearGlobalScripts();
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "Combat.h"
|
||||
#include "HeroAppearance.h"
|
||||
#include "KillCounter.h"
|
||||
#include "movies.h"
|
||||
#include "Movies.h"
|
||||
#include "PartyControl.h"
|
||||
#include "ScriptExtender.h"
|
||||
|
||||
|
||||
@@ -447,21 +447,12 @@ static void __declspec(naked) op_obj_blocking_at() {
|
||||
|
||||
static void _stdcall op_tile_get_objects2() {
|
||||
DWORD tile = opHandler.arg(0).asInt(),
|
||||
elevation = opHandler.arg(1).asInt(),
|
||||
obj;
|
||||
elevation = opHandler.arg(1).asInt();
|
||||
DWORD arrayId = TempArray(0, 4);
|
||||
__asm {
|
||||
mov eax, elevation;
|
||||
mov edx, tile;
|
||||
call obj_find_first_at_tile_;
|
||||
mov obj, eax;
|
||||
}
|
||||
TGameObj* obj = ObjFindFirstAtTile(elevation, tile);
|
||||
while (obj) {
|
||||
arrays[arrayId].push_back((long)obj);
|
||||
__asm {
|
||||
call obj_find_next_at_tile_;
|
||||
mov obj, eax;
|
||||
}
|
||||
arrays[arrayId].push_back(reinterpret_cast<long>(obj));
|
||||
obj = ObjFindNextAtTile();
|
||||
}
|
||||
opHandler.setReturn(arrayId, DATATYPE_INT);
|
||||
}
|
||||
|
||||
@@ -482,6 +482,18 @@ struct sList {
|
||||
}
|
||||
};
|
||||
|
||||
static DWORD listID = 0xCCCCCC;
|
||||
|
||||
struct ListId {
|
||||
sList* list;
|
||||
DWORD id;
|
||||
|
||||
ListId(sList* lst) : list(lst) {
|
||||
id = ++listID;
|
||||
}
|
||||
};
|
||||
static std::vector<ListId> mList;
|
||||
|
||||
static void FillListVector(DWORD type, std::vector<TGameObj*>& vec) {
|
||||
vec.reserve(100);
|
||||
if (type == 6) {
|
||||
@@ -522,36 +534,28 @@ static void FillListVector(DWORD type, std::vector<TGameObj*>& vec) {
|
||||
} else if (type != 4) {
|
||||
for (int elv = 0; elv < 3; elv++) {
|
||||
for (int tile = 0; tile < 40000; tile++) {
|
||||
TGameObj* obj;
|
||||
__asm {
|
||||
mov edx, tile;
|
||||
mov eax, elv;
|
||||
call obj_find_first_at_tile_;
|
||||
mov obj, eax;
|
||||
}
|
||||
TGameObj* obj = ObjFindFirstAtTile(elv, tile);
|
||||
while (obj) {
|
||||
DWORD otype = obj->pid >> 24;
|
||||
if (type == 9 || (type == 0 && otype == 1) || (type == 1 && otype == 0) || (type >= 2 && type <= 5 && type == otype)) {
|
||||
vec.push_back(obj);
|
||||
}
|
||||
__asm {
|
||||
call obj_find_next_at_tile_;
|
||||
mov obj, eax;
|
||||
}
|
||||
obj = ObjFindNextAtTile();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void* _stdcall list_begin2(DWORD type) {
|
||||
static DWORD _stdcall ListBegin(DWORD type) {
|
||||
std::vector<TGameObj*> vec = std::vector<TGameObj*>();
|
||||
FillListVector(type, vec);
|
||||
sList* list = new sList(&vec);
|
||||
return list;
|
||||
mList.push_back(list);
|
||||
return listID;
|
||||
}
|
||||
|
||||
static DWORD _stdcall list_as_array2(DWORD type) {
|
||||
static DWORD _stdcall ListAsArray(DWORD type) {
|
||||
std::vector<TGameObj*> vec = std::vector<TGameObj*>();
|
||||
FillListVector(type, vec);
|
||||
size_t sz = vec.size();
|
||||
@@ -562,14 +566,20 @@ static DWORD _stdcall list_as_array2(DWORD type) {
|
||||
return id;
|
||||
}
|
||||
|
||||
static TGameObj* _stdcall list_next2(sList* list) {
|
||||
static TGameObj* _stdcall ListNext(sList* list) {
|
||||
if (!list || list->pos == list->len) return 0;
|
||||
else return list->obj[list->pos++];
|
||||
}
|
||||
|
||||
static void _stdcall list_end2(sList* list) {
|
||||
delete[] list->obj;
|
||||
delete list;
|
||||
static void _stdcall ListEnd(DWORD id) {
|
||||
for (std::vector<ListId>::const_iterator it = mList.cbegin(), it_end = mList.cend(); it != it_end; ++it) {
|
||||
if (it->id == id) {
|
||||
delete[] it->list->obj;
|
||||
delete it->list;
|
||||
mList.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) list_begin() {
|
||||
@@ -583,7 +593,7 @@ static void __declspec(naked) list_begin() {
|
||||
cmp di, VAR_TYPE_INT;
|
||||
jnz fail;
|
||||
push eax;
|
||||
call list_begin2;
|
||||
call ListBegin;
|
||||
mov edx, eax;
|
||||
jmp end;
|
||||
fail:
|
||||
@@ -599,6 +609,7 @@ end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) list_as_array() {
|
||||
__asm {
|
||||
pushad;
|
||||
@@ -610,7 +621,7 @@ static void __declspec(naked) list_as_array() {
|
||||
cmp di, VAR_TYPE_INT;
|
||||
jnz fail;
|
||||
push eax;
|
||||
call list_as_array2;
|
||||
call ListAsArray;
|
||||
mov edx, eax;
|
||||
jmp end;
|
||||
fail:
|
||||
@@ -626,33 +637,29 @@ end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void _stdcall list_next2() {
|
||||
const ScriptValue &idArg = opHandler.arg(0);
|
||||
if (idArg.isInt()) {
|
||||
DWORD id = idArg.rawValue();
|
||||
sList* list = nullptr;
|
||||
for (std::vector<ListId>::const_iterator it = mList.cbegin(), it_end = mList.cend(); it != it_end; ++it) {
|
||||
if (it->id == id) {
|
||||
list = it->list;
|
||||
break;
|
||||
}
|
||||
}
|
||||
opHandler.setReturn(ListNext(list));
|
||||
} else {
|
||||
OpcodeInvalidArgs("list_next");
|
||||
opHandler.setReturn(-1);
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) list_next() {
|
||||
__asm {
|
||||
pushad;
|
||||
mov ebp, eax;
|
||||
call interpretPopShort_;
|
||||
mov edi, eax;
|
||||
mov eax, ebp;
|
||||
call interpretPopLong_;
|
||||
cmp di, VAR_TYPE_INT;
|
||||
jnz fail;
|
||||
push eax;
|
||||
call list_next2;
|
||||
mov edx, eax;
|
||||
jmp end;
|
||||
fail:
|
||||
xor edx, edx;
|
||||
dec edx;
|
||||
end:
|
||||
mov eax, ebp;
|
||||
call interpretPushLong_;
|
||||
mov eax, ebp;
|
||||
mov edx, VAR_TYPE_INT;
|
||||
call interpretPushShort_;
|
||||
popad;
|
||||
retn;
|
||||
}
|
||||
_WRAP_OPCODE(list_next2, 1, 1)
|
||||
}
|
||||
|
||||
static void __declspec(naked) list_end() {
|
||||
__asm {
|
||||
pushad;
|
||||
@@ -664,7 +671,7 @@ static void __declspec(naked) list_end() {
|
||||
cmp di, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
push eax;
|
||||
call list_end2;
|
||||
call ListEnd;
|
||||
end:
|
||||
popad;
|
||||
retn;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "Combat.h"
|
||||
#include "Criticals.h"
|
||||
#include "ScriptExtender.h"
|
||||
#include "skills.h"
|
||||
#include "Skills.h"
|
||||
#include "Stats.h"
|
||||
|
||||
const char* invalidStat = "%s() - stat number out of range.";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user