mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added optional options to the perks ini file
* to toggle modification sections for perks and traits. Backported ini reading functions from 4.x to main.cpp, and edited related code in Perks.cpp (need to implement to other source later) Added error/warning icons to message boxes.
This commit is contained in:
@@ -27,6 +27,10 @@ WeaponAccurateBonus=20
|
||||
WeaponHandlingBonus=3
|
||||
|
||||
;##############################################################################
|
||||
[Perks]
|
||||
;Set to 1 to enable modifications to perks
|
||||
Enable=0
|
||||
|
||||
;Name=The name of the perk (max 63 characters)
|
||||
;Desc=The description of the perk (max 255 characters)
|
||||
;Image=The line number (0-indexed) of the corresponding FRM in skilldex.lst
|
||||
@@ -78,6 +82,11 @@ INT=0
|
||||
AGL=0
|
||||
LCK=0
|
||||
|
||||
;##############################################################################
|
||||
[Traits]
|
||||
;Set to 1 to enable modifications to traits
|
||||
Enable=0
|
||||
|
||||
;This is a modification to trait 0
|
||||
[t0]
|
||||
NoHardcode=0
|
||||
|
||||
+1
-1
@@ -2369,7 +2369,7 @@ static void __declspec(naked) map_check_state_hook() {
|
||||
void BugFixesInit()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (isDebug && (GetPrivateProfileIntA("Debugging", "BugFixes", 1, ".\\ddraw.ini") == 0)) return;
|
||||
if (isDebug && (GetPrivateProfileIntA("Debugging", "BugFixes", 1, ddrawIniDef) == 0)) return;
|
||||
#endif
|
||||
|
||||
// Fix vanilla negate operator on float values
|
||||
|
||||
+3
-3
@@ -25,7 +25,7 @@
|
||||
static const DWORD ExpectedSize = 0x00122800;
|
||||
static const DWORD ExpectedCRC[] = {0xe1680293, 0xef34f989};
|
||||
|
||||
static void inline Fail(const char* a) { MessageBoxA(0, a, "Error", MB_TASKMODAL); ExitProcess(1); }
|
||||
static void inline Fail(const char* a) { MessageBoxA(0, a, "Error", MB_TASKMODAL | MB_ICONERROR); ExitProcess(1); }
|
||||
|
||||
static const DWORD CRC_table[256] = {
|
||||
0x00000000, 0x0A5F4D75, 0x14BE9AEA, 0x1EE1D79F, 0x14C5EB57, 0x1E9AA622, 0x007B71BD, 0x0A243CC8,
|
||||
@@ -77,7 +77,7 @@ void CRC(const char* filepath) {
|
||||
DWORD size = GetFileSize(h, 0), crc;
|
||||
bool sizeMatch = (size == ExpectedSize);
|
||||
|
||||
if (!sizeMatch && GetPrivateProfileIntA("Debugging", "SkipSizeCheck", 0, ".\\ddraw.ini")) {
|
||||
if (!sizeMatch && GetPrivateProfileIntA("Debugging", "SkipSizeCheck", 0, ddrawIniDef)) {
|
||||
sizeMatch = true;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ void CRC(const char* filepath) {
|
||||
|
||||
bool matchedCRC = false;
|
||||
|
||||
if (GetPrivateProfileStringA("Debugging", "ExtraCRC", "", buf, 512, ".\\ddraw.ini") > 0) {
|
||||
if (GetPrivateProfileStringA("Debugging", "ExtraCRC", "", buf, 512, ddrawIniDef) > 0) {
|
||||
char *TestCRC;
|
||||
TestCRC = strtok(buf, ",");
|
||||
while (TestCRC) {
|
||||
|
||||
@@ -321,7 +321,7 @@ static void __declspec(naked) win_debug_hook() {
|
||||
}
|
||||
|
||||
void DebugModePatch() {
|
||||
DWORD dbgMode = GetPrivateProfileIntA("Debugging", "DebugMode", 0, ".\\ddraw.ini");
|
||||
DWORD dbgMode = GetPrivateProfileIntA("Debugging", "DebugMode", 0, ddrawIniDef);
|
||||
if (dbgMode) {
|
||||
dlog("Applying debugmode patch.", DL_INIT);
|
||||
// If the player is using an exe with the debug patch already applied, just skip this block without erroring
|
||||
@@ -343,7 +343,7 @@ void DebugModePatch() {
|
||||
} else {
|
||||
SafeWrite32(0x4C6D9C, (DWORD)debugGnw);
|
||||
}
|
||||
if (GetPrivateProfileIntA("Debugging", "HideObjIsNullMsg", 0, ".\\ddraw.ini")) {
|
||||
if (GetPrivateProfileIntA("Debugging", "HideObjIsNullMsg", 0, ddrawIniDef)) {
|
||||
MakeJump(0x453FD2, dbg_error_hack);
|
||||
}
|
||||
dlogr(" Done", DL_INIT);
|
||||
@@ -351,7 +351,7 @@ void DebugModePatch() {
|
||||
}
|
||||
|
||||
void DontDeleteProtosPatch() {
|
||||
if (GetPrivateProfileIntA("Debugging", "DontDeleteProtos", 0, ".\\ddraw.ini")) {
|
||||
if (GetPrivateProfileIntA("Debugging", "DontDeleteProtos", 0, ddrawIniDef)) {
|
||||
dlog("Applying permanent protos patch.", DL_INIT);
|
||||
SafeWrite8(0x48007E, 0xEB);
|
||||
dlogr(" Done", DL_INIT);
|
||||
|
||||
@@ -118,7 +118,7 @@ DWORD* ptr_map_elevation = reinterpret_cast<DWORD*>(_map_elevation)
|
||||
DWORD* ptr_map_global_vars = reinterpret_cast<DWORD*>(_map_global_vars);
|
||||
DWORD* ptr_master_db_handle = reinterpret_cast<DWORD*>(_master_db_handle);
|
||||
DWORD* ptr_max = reinterpret_cast<DWORD*>(_max);
|
||||
DWORD* ptr_maxScriptNum = reinterpret_cast<DWORD*>(_maxScriptNum);
|
||||
long* ptr_maxScriptNum = reinterpret_cast<long*>(_maxScriptNum);
|
||||
DWORD* ptr_Meet_Frank_Horrigan = reinterpret_cast<DWORD*>(_Meet_Frank_Horrigan);
|
||||
DWORD* ptr_mouse_hotx = reinterpret_cast<DWORD*>(_mouse_hotx);
|
||||
DWORD* ptr_mouse_hoty = reinterpret_cast<DWORD*>(_mouse_hoty);
|
||||
|
||||
@@ -360,7 +360,7 @@ extern DWORD* ptr_map_elevation;
|
||||
extern DWORD* ptr_map_global_vars;
|
||||
extern DWORD* ptr_master_db_handle;
|
||||
extern DWORD* ptr_max;
|
||||
extern DWORD* ptr_maxScriptNum;
|
||||
extern long* ptr_maxScriptNum;
|
||||
extern DWORD* ptr_Meet_Frank_Horrigan;
|
||||
extern DWORD* ptr_mouse_hotx;
|
||||
extern DWORD* ptr_mouse_hoty;
|
||||
|
||||
+1
-1
@@ -1095,7 +1095,7 @@ void GraphicsInit() {
|
||||
HMODULE h = LoadLibraryEx(_DLL_NAME, 0, LOAD_LIBRARY_AS_DATAFILE);
|
||||
if (!h) {
|
||||
MessageBoxA(0, "You have selected graphics mode 4 or 5, but " _DLL_NAME " is missing.\n"
|
||||
"Switch back to mode 0, or install an up to date version of DirectX.", "Error", 0);
|
||||
"Switch back to mode 0, or install an up to date version of DirectX.", "Error", MB_TASKMODAL | MB_ICONERROR);
|
||||
ExitProcess(-1);
|
||||
} else {
|
||||
FreeLibrary(h);
|
||||
|
||||
@@ -970,7 +970,7 @@ static void FixCritList() {
|
||||
critterListSize = (*(DWORD*)0x510774) / 2;
|
||||
if (critterListSize > 2048) {
|
||||
MessageBoxA(0, "This mod cannot be used because the maximum limit of the FID count in the critters.lst is exceeded.\n"
|
||||
"Please disable the mod and restart the game.", "Hero Appearance mod", 0x10);
|
||||
"Please disable the mod and restart the game.", "Hero Appearance mod", MB_TASKMODAL | MB_ICONERROR);
|
||||
ExitProcess(-1);
|
||||
}
|
||||
critterArraySize = critterListSize * 13;
|
||||
|
||||
@@ -1548,7 +1548,7 @@ void _stdcall RegisterHook(DWORD script, DWORD id, DWORD procNum, bool specReg)
|
||||
}
|
||||
|
||||
static void LoadHookScript(const char* name, int id) {
|
||||
if (id >= numHooks || isGameScript(name)) return;
|
||||
if (id >= numHooks || IsGameScript(name)) return;
|
||||
|
||||
char filename[MAX_PATH];
|
||||
sprintf(filename, "scripts\\%s.int", name);
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
#include "FalloutEngine.h"
|
||||
#include "Imports.h"
|
||||
|
||||
int db_fclose(sFile* file) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
call db_fclose_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
sFile* db_fopen(const char* path, const char* mode) {
|
||||
sFile* result;
|
||||
_asm {
|
||||
mov eax, path;
|
||||
mov edx, mode;
|
||||
call db_fopen_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int db_fgetc(sFile* file) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
call db_fgetc_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
char* db_fgets(char* buf, int max_count, sFile* file) {
|
||||
char* result;
|
||||
_asm {
|
||||
mov eax, buf;
|
||||
mov edx, max_count;
|
||||
mov ebx, file;
|
||||
call db_fgets_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//int db_ungetc(int c, sFile* file);
|
||||
int db_fread(void* buf, int elsize, int count, sFile* file) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, buf;
|
||||
mov edx, elsize;
|
||||
mov ebx, count;
|
||||
mov ecx, file;
|
||||
call db_fread_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int db_fseek(sFile* file, long pos, int origin) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
mov edx, pos;
|
||||
mov ebx, origin;
|
||||
call db_fseek_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//long db_ftell(sFile* file);
|
||||
//void db_rewind(sFile* file);
|
||||
//int db_feof(sFile* file);
|
||||
int db_freadByte(sFile* file, __int8* _out) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
mov edx, _out;
|
||||
call db_freadByte_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int db_freadShort(sFile* file, __int16* _out) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
mov edx, _out;
|
||||
call db_freadShort_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int db_freadInt(sFile* file, __int32* _out) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
mov edx, _out;
|
||||
call db_freadInt_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int db_freadFloat(sFile* file, float* _out) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
mov edx, _out;
|
||||
call db_freadInt_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//int db_freadByteCount(sFile* file, BYTE* ptr, int count);
|
||||
//int db_freadShortCount(sFile* file, WORD* ptr, int count);
|
||||
//int db_freadIntCount(sFile* file, DWORD* ptr, int count);
|
||||
//int db_freadFloatCount(sFile* file, float* ptr, int count);
|
||||
|
||||
int message_init(sMsgFile* file) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
call message_init_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int message_exit(sMsgFile* file) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
call message_exit_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int message_load(sMsgFile* file, char* path) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
mov edx, path
|
||||
call message_load_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int message_search(sMsgFile* file, sMessage* msg) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
mov edx, msg;
|
||||
call message_search_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int message_make_path(char* outpath, char* path) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, outpath;
|
||||
mov edx, path;
|
||||
call message_make_path_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int message_find(sMsgFile* file, DWORD number, DWORD* _out) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
mov edx, number;
|
||||
mov ebx, _out;
|
||||
call message_find_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int message_add(sMsgFile* file, sMessage* msg) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
mov edx, msg;
|
||||
call message_add_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
char* getmsg(sMsgFile* file, sMessage* msg, DWORD num) {
|
||||
char* result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
mov edx, msg;
|
||||
mov ebx, num;
|
||||
call getmsg_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int message_filter(sMsgFile* file) {
|
||||
int result;
|
||||
_asm {
|
||||
mov eax, file;
|
||||
call message_filter_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void get_input() {
|
||||
_asm {
|
||||
call get_input_;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
struct sFile {
|
||||
DWORD fileType;
|
||||
void* handle;
|
||||
};
|
||||
struct sMessage {
|
||||
int number;
|
||||
DWORD flags;
|
||||
char* audio;
|
||||
char* message;
|
||||
};
|
||||
struct sMsgFile {
|
||||
DWORD count;
|
||||
sMessage* messages;
|
||||
};
|
||||
|
||||
int db_fclose(sFile* file);
|
||||
sFile* db_fopen(const char* path, const char* mode);
|
||||
int db_fgetc(sFile* file);
|
||||
char* db_fgets(char* buf, int max_count, sFile* file);
|
||||
int db_ungetc(int c, sFile* file);
|
||||
int db_fread(void* buf, int elsize, int count, sFile* file);
|
||||
int db_fseek(sFile* file, long pos, int origin);
|
||||
long db_ftell(sFile* file);
|
||||
void db_rewind(sFile* file);
|
||||
int db_feof(sFile* file);
|
||||
int db_freadByte(sFile* file, __int8* out);
|
||||
int db_freadShort(sFile* file, __int16* out);
|
||||
int db_freadInt(sFile* file, __int32* out);
|
||||
int db_freadFloat(sFile* file, float* out);
|
||||
int db_freadByteCount(sFile* file, BYTE* ptr, int count);
|
||||
int db_freadShortCount(sFile* file, WORD* ptr, int count);
|
||||
int db_freadIntCount(sFile* file, DWORD* ptr, int count);
|
||||
int db_freadFloatCount(sFile* file, float* ptr, int count);
|
||||
|
||||
int message_init(sMsgFile* file);
|
||||
int message_exit(sMsgFile* file);
|
||||
int message_load(sMsgFile* file, char* path);
|
||||
int message_search(sMsgFile* file, sMessage* msg);
|
||||
int message_make_path(char* outpath, char* path);
|
||||
int message_find(sMsgFile* file, DWORD number, DWORD* out);
|
||||
int message_add(sMsgFile* file, sMessage* msg);
|
||||
char* getmsg(sMsgFile* file, sMessage* msg, DWORD num);
|
||||
int message_filter(sMsgFile* file);
|
||||
|
||||
void get_input();
|
||||
+4
-4
@@ -55,16 +55,16 @@ void dlog_f(const char *fmt, int type, ...) {
|
||||
|
||||
void LoggingInit() {
|
||||
Log.open("sfall-log.txt", ios_base::out | ios_base::trunc);
|
||||
if (GetPrivateProfileIntA("Debugging", "Init", 0, ".\\ddraw.ini")) {
|
||||
if (GetPrivateProfileIntA("Debugging", "Init", 0, ddrawIniDef)) {
|
||||
DebugTypes |= DL_INIT;
|
||||
}
|
||||
if (GetPrivateProfileIntA("Debugging", "Hook", 0, ".\\ddraw.ini")) {
|
||||
if (GetPrivateProfileIntA("Debugging", "Hook", 0, ddrawIniDef)) {
|
||||
DebugTypes |= DL_HOOK;
|
||||
}
|
||||
if (GetPrivateProfileIntA("Debugging", "Script", 0, ".\\ddraw.ini")) {
|
||||
if (GetPrivateProfileIntA("Debugging", "Script", 0, ddrawIniDef)) {
|
||||
DebugTypes |= DL_SCRIPT;
|
||||
}
|
||||
if (GetPrivateProfileIntA("Debugging", "Criticals", 0, ".\\ddraw.ini")) {
|
||||
if (GetPrivateProfileIntA("Debugging", "Criticals", 0, ddrawIniDef)) {
|
||||
DebugTypes |= DL_CRITICALS;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-8
@@ -24,25 +24,19 @@
|
||||
|
||||
ExtraGameMessageListsMap gExtraGameMsgLists;
|
||||
|
||||
int LoadMsgList(MSGList *msgList, const char *msgFilePath) {
|
||||
int retVal;
|
||||
long __stdcall LoadMsgList(MSGList *msgList, const char *msgFilePath) {
|
||||
__asm {
|
||||
mov edx, msgFilePath;
|
||||
mov eax, msgList;
|
||||
call message_load_;
|
||||
mov retVal, eax;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int DestroyMsgList(MSGList *msgList) {
|
||||
int retVal;
|
||||
long __stdcall DestroyMsgList(MSGList *msgList) {
|
||||
__asm {
|
||||
mov eax, msgList;
|
||||
call message_exit_;
|
||||
mov retVal, eax;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
MSGNode *GetMsgNode(MSGList *msgList, int msgRef) {
|
||||
|
||||
+3
-2
@@ -50,8 +50,9 @@ typedef struct MSGList {
|
||||
typedef std::tr1::unordered_map<int, MSGList*> ExtraGameMessageListsMap;
|
||||
extern ExtraGameMessageListsMap gExtraGameMsgLists;
|
||||
|
||||
int LoadMsgList(MSGList *msgList, const char *msgFilePath);
|
||||
int DestroyMsgList(MSGList *msgList);
|
||||
long __stdcall LoadMsgList(MSGList *msgList, const char *msgFilePath);
|
||||
long __stdcall DestroyMsgList(MSGList *msgList);
|
||||
|
||||
MSGNode *GetMsgNode(MSGList *msgList, int msgRef);
|
||||
char* GetMsg(MSGList *msgList, int msgRef, int msgNum);
|
||||
void ReadExtraGameMsgFiles();
|
||||
|
||||
+112
-102
@@ -39,7 +39,9 @@ static char PerkBoxTitle[33];
|
||||
#define check_trait(id) !disableTraits[id] && (pc_trait[0] == id || pc_trait[1] == id)
|
||||
|
||||
static DWORD addPerkMode = 2;
|
||||
|
||||
static bool perksReInit = false;
|
||||
static int perksEnable = 0;
|
||||
|
||||
struct TraitStruct {
|
||||
char* Name;
|
||||
@@ -74,7 +76,7 @@ static PerkStruct Perks[PERK_count];
|
||||
static TraitStruct Traits[TRAIT_count];
|
||||
|
||||
struct FakePerk {
|
||||
int Level;
|
||||
int Level; // current level (max 100)
|
||||
int Image;
|
||||
char Name[maxNameLen];
|
||||
char Desc[maxDescLen];
|
||||
@@ -83,7 +85,7 @@ struct FakePerk {
|
||||
|
||||
std::vector<FakePerk> fakeTraits;
|
||||
std::vector<FakePerk> fakePerks;
|
||||
std::vector<FakePerk> fakeSelectablePerks;
|
||||
std::vector<FakePerk> fakeSelectablePerks; // available perks for selection in the perk selection list
|
||||
|
||||
static long RemoveTraitID = -1;
|
||||
static std::list<int> RemovePerkID;
|
||||
@@ -206,7 +208,7 @@ void _stdcall SetSelectablePerk(const char* name, int active, int image, const c
|
||||
}
|
||||
|
||||
void _stdcall SetFakePerk(const char* name, int level, int image, const char* desc) {
|
||||
if (level < 0 ) return;
|
||||
if (level < 0) return;
|
||||
if (level > 100) level = 100;
|
||||
size_t size = fakePerks.size();
|
||||
if (level == 0) { // remove perk from fakePerks
|
||||
@@ -535,7 +537,7 @@ static void __declspec(naked) GetPerkSNameHook() {
|
||||
jl end;
|
||||
push eax;
|
||||
call GetFakeSPerk;
|
||||
lea eax, ds:[eax + 8];
|
||||
lea eax, ds:[eax + 8]; // Name
|
||||
retn;
|
||||
end:
|
||||
jmp perk_name_;
|
||||
@@ -548,7 +550,7 @@ static void __declspec(naked) GetPerkSDescHook() {
|
||||
jl end;
|
||||
push eax;
|
||||
call GetFakeSPerk;
|
||||
lea eax, ds:[eax + 72];
|
||||
lea eax, ds:[eax + 72]; // Desc
|
||||
retn;
|
||||
end:
|
||||
jmp perk_description_;
|
||||
@@ -701,8 +703,6 @@ static void PerkEngineInit() {
|
||||
}
|
||||
|
||||
static void PerkSetup() {
|
||||
memcpy(Perks, (void*)_perk_data, sizeof(PerkStruct) * PERK_count); // copy vanilla data
|
||||
|
||||
if (!perksReInit) {
|
||||
// _perk_data
|
||||
SafeWrite32(0x496669, (DWORD)Perks);
|
||||
@@ -715,50 +715,52 @@ static void PerkSetup() {
|
||||
SafeWrite32(0x496BF5, (DWORD)Perks + 8);
|
||||
SafeWrite32(0x496AD4, (DWORD)Perks + 12);
|
||||
}
|
||||
if (perksFile[0] != '\0') {
|
||||
memcpy(Perks, (void*)_perk_data, sizeof(PerkStruct) * PERK_count); // copy vanilla data
|
||||
|
||||
if (perksEnable) {
|
||||
char num[4];
|
||||
for (int i = 0; i < PERK_count; i++) {
|
||||
_itoa_s(i, num, 10);
|
||||
if (GetPrivateProfileString(num, "Name", "", &Name[i * maxNameLen], maxNameLen - 1, perksFile)) {
|
||||
if (iniGetString(num, "Name", "", &Name[i * maxNameLen], maxNameLen - 1, perksFile)) {
|
||||
Perks[i].Name = &Name[i * maxNameLen];
|
||||
}
|
||||
if (GetPrivateProfileString(num, "Desc", "", &Desc[i * descLen], descLen - 1, perksFile)) {
|
||||
if (iniGetString(num, "Desc", "", &Desc[i * descLen], descLen - 1, perksFile)) {
|
||||
Perks[i].Desc = &Desc[i * descLen];
|
||||
}
|
||||
int value;
|
||||
value = GetPrivateProfileInt(num, "Image", -99999, perksFile);
|
||||
value = iniGetInt(num, "Image", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Image = value;
|
||||
value = GetPrivateProfileInt(num, "Ranks", -99999, perksFile);
|
||||
value = iniGetInt(num, "Ranks", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Ranks = value;
|
||||
value = GetPrivateProfileInt(num, "Level", -99999, perksFile);
|
||||
value = iniGetInt(num, "Level", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Level = value;
|
||||
value = GetPrivateProfileInt(num, "Stat", -99999, perksFile);
|
||||
value = iniGetInt(num, "Stat", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Stat = value;
|
||||
value = GetPrivateProfileInt(num, "StatMag", -99999, perksFile);
|
||||
value = iniGetInt(num, "StatMag", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].StatMag = value;
|
||||
value = GetPrivateProfileInt(num, "Skill1", -99999, perksFile);
|
||||
value = iniGetInt(num, "Skill1", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Skill1 = value;
|
||||
value = GetPrivateProfileInt(num, "Skill1Mag", -99999, perksFile);
|
||||
value = iniGetInt(num, "Skill1Mag", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Skill1Mag = value;
|
||||
value = GetPrivateProfileInt(num, "Type", -99999, perksFile);
|
||||
value = iniGetInt(num, "Type", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Type = value;
|
||||
value = GetPrivateProfileInt(num, "Skill2", -99999, perksFile);
|
||||
value = iniGetInt(num, "Skill2", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Skill2 = value;
|
||||
value = GetPrivateProfileInt(num, "Skill2Mag", -99999, perksFile);
|
||||
value = iniGetInt(num, "Skill2Mag", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Skill2Mag = value;
|
||||
value = GetPrivateProfileInt(num, "STR", -99999, perksFile);
|
||||
value = iniGetInt(num, "STR", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Str = value;
|
||||
value = GetPrivateProfileInt(num, "PER", -99999, perksFile);
|
||||
value = iniGetInt(num, "PER", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Per = value;
|
||||
value = GetPrivateProfileInt(num, "END", -99999, perksFile);
|
||||
value = iniGetInt(num, "END", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].End = value;
|
||||
value = GetPrivateProfileInt(num, "CHR", -99999, perksFile);
|
||||
value = iniGetInt(num, "CHR", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Chr = value;
|
||||
value = GetPrivateProfileInt(num, "INT", -99999, perksFile);
|
||||
value = iniGetInt(num, "INT", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Int = value;
|
||||
value = GetPrivateProfileInt(num, "AGL", -99999, perksFile);
|
||||
value = iniGetInt(num, "AGL", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Agl = value;
|
||||
value = GetPrivateProfileInt(num, "LCK", -99999, perksFile);
|
||||
value = iniGetInt(num, "LCK", -99999, perksFile);
|
||||
if (value != -99999) Perks[i].Lck = value;
|
||||
}
|
||||
}
|
||||
@@ -924,80 +926,78 @@ static void TraitSetup() {
|
||||
SafeWrite32(0x4B3BA0, (DWORD)Traits + 4);
|
||||
SafeWrite32(0x4B3BC0, (DWORD)Traits + 8);
|
||||
|
||||
if (perksFile[0] != '\0') {
|
||||
char buf[512], num[5] = {'t'};
|
||||
char* num2 = &num[1];
|
||||
for (int i = 0; i < TRAIT_count; i++) {
|
||||
_itoa_s(i, num2, 4, 10);
|
||||
if (GetPrivateProfileString(num, "Name", "", &tName[i * maxNameLen], maxNameLen - 1, perksFile)) {
|
||||
Traits[i].Name = &tName[i * maxNameLen];
|
||||
}
|
||||
if (GetPrivateProfileString(num, "Desc", "", &tDesc[i * descLen], descLen - 1, perksFile)) {
|
||||
Traits[i].Desc = &tDesc[i * descLen];
|
||||
}
|
||||
int value;
|
||||
value = GetPrivateProfileInt(num, "Image", -99999, perksFile);
|
||||
if (value != -99999) Traits[i].Image = value;
|
||||
char buf[512], num[5] = {'t'};
|
||||
char* num2 = &num[1];
|
||||
for (int i = 0; i < TRAIT_count; i++) {
|
||||
_itoa_s(i, num2, 4, 10);
|
||||
if (iniGetString(num, "Name", "", &tName[i * maxNameLen], maxNameLen - 1, perksFile)) {
|
||||
Traits[i].Name = &tName[i * maxNameLen];
|
||||
}
|
||||
if (iniGetString(num, "Desc", "", &tDesc[i * descLen], descLen - 1, perksFile)) {
|
||||
Traits[i].Desc = &tDesc[i * descLen];
|
||||
}
|
||||
int value;
|
||||
value = iniGetInt(num, "Image", -99999, perksFile);
|
||||
if (value != -99999) Traits[i].Image = value;
|
||||
|
||||
if (GetPrivateProfileStringA(num, "StatMod", "", buf, 512, perksFile) > 0) {
|
||||
char *stat, *mod;
|
||||
stat = strtok(buf, "|");
|
||||
if (iniGetString(num, "StatMod", "", buf, 512, perksFile) > 0) {
|
||||
char *stat, *mod;
|
||||
stat = strtok(buf, "|");
|
||||
mod = strtok(0, "|");
|
||||
while (stat&&mod) {
|
||||
int _stat = atoi(stat), _mod = atoi(mod);
|
||||
if (_stat >= 0 && _stat <= STAT_max_derived) TraitStatBonuses[_stat * TRAIT_count + i] = _mod;
|
||||
stat = strtok(0, "|");
|
||||
mod = strtok(0, "|");
|
||||
while (stat&&mod) {
|
||||
int _stat = atoi(stat), _mod = atoi(mod);
|
||||
if (_stat >= 0 && _stat <= STAT_max_derived) TraitStatBonuses[_stat * TRAIT_count + i] = _mod;
|
||||
stat = strtok(0, "|");
|
||||
mod = strtok(0, "|");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GetPrivateProfileStringA(num, "SkillMod", "", buf, 512, perksFile) > 0) {
|
||||
char *stat, *mod;
|
||||
stat = strtok(buf, "|");
|
||||
if (iniGetString(num, "SkillMod", "", buf, 512, perksFile) > 0) {
|
||||
char *stat, *mod;
|
||||
stat = strtok(buf, "|");
|
||||
mod = strtok(0, "|");
|
||||
while (stat&&mod) {
|
||||
int _stat = atoi(stat), _mod = atoi(mod);
|
||||
if (_stat >= 0 && _stat < 18) TraitSkillBonuses[_stat * TRAIT_count + i] = _mod;
|
||||
stat = strtok(0, "|");
|
||||
mod = strtok(0, "|");
|
||||
while (stat&&mod) {
|
||||
int _stat = atoi(stat), _mod = atoi(mod);
|
||||
if (_stat >= 0 && _stat < 18) TraitSkillBonuses[_stat * TRAIT_count + i] = _mod;
|
||||
stat = strtok(0, "|");
|
||||
mod = strtok(0, "|");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GetPrivateProfileInt(num, "NoHardcode", 0, perksFile)) {
|
||||
disableTraits[i] = true;
|
||||
switch (i) {
|
||||
case TRAIT_one_hander:
|
||||
HookCall(0x4245E0, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_finesse:
|
||||
HookCall(0x4248F9, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_fast_shot:
|
||||
HookCall(0x478C8A, BlockedTrait); // fast shot
|
||||
HookCall(0x478E70, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_bloody_mess:
|
||||
HookCall(0x410707, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_jinxed:
|
||||
HookCall(0x42389F, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_drug_addict:
|
||||
HookCall(0x47A0CD, BlockedTrait);
|
||||
HookCall(0x47A51A, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_drug_resistant:
|
||||
HookCall(0x479BE1, BlockedTrait);
|
||||
HookCall(0x47A0DD, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_skilled:
|
||||
HookCall(0x43C295, BlockedTrait);
|
||||
HookCall(0x43C2F3, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_gifted:
|
||||
HookCall(0x43C2A4, BlockedTrait);
|
||||
break;
|
||||
}
|
||||
if (iniGetInt(num, "NoHardcode", 0, perksFile)) {
|
||||
disableTraits[i] = true;
|
||||
switch (i) {
|
||||
case TRAIT_one_hander:
|
||||
HookCall(0x4245E0, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_finesse:
|
||||
HookCall(0x4248F9, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_fast_shot:
|
||||
HookCall(0x478C8A, BlockedTrait); // fast shot
|
||||
HookCall(0x478E70, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_bloody_mess:
|
||||
HookCall(0x410707, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_jinxed:
|
||||
HookCall(0x42389F, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_drug_addict:
|
||||
HookCall(0x47A0CD, BlockedTrait);
|
||||
HookCall(0x47A51A, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_drug_resistant:
|
||||
HookCall(0x479BE1, BlockedTrait);
|
||||
HookCall(0x47A0DD, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_skilled:
|
||||
HookCall(0x43C295, BlockedTrait);
|
||||
HookCall(0x43C2F3, BlockedTrait);
|
||||
break;
|
||||
case TRAIT_gifted:
|
||||
HookCall(0x43C2A4, BlockedTrait);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1040,7 +1040,7 @@ static const DWORD FastShotFixF1[] = {
|
||||
};
|
||||
|
||||
static void FastShotTraitFix() {
|
||||
switch (GetPrivateProfileIntA("Misc", "FastShotFix", 1, ini)) {
|
||||
switch (GetConfigInt("Misc", "FastShotFix", 1)) {
|
||||
case 1:
|
||||
dlog("Applying Fast Shot Trait Fix.", DL_INIT);
|
||||
MakeJump(0x478E75, item_w_called_shot_hack);
|
||||
@@ -1097,6 +1097,8 @@ void PerksReset() {
|
||||
SafeWrite32(0x496880, 0x019078);
|
||||
// Pyromaniac bonus
|
||||
SafeWrite8(0x424AB6, 5);
|
||||
// Swift Learner bonus
|
||||
SafeWrite32(0x4AFAE2, 100);
|
||||
// Restore 'Heave Ho' modify fix
|
||||
if (perkHeaveHoModFix) {
|
||||
SafeWrite8(0x478AC4, 0xBA);
|
||||
@@ -1155,6 +1157,7 @@ void _stdcall AddPerkMode(DWORD mode) {
|
||||
}
|
||||
|
||||
DWORD _stdcall HasFakePerk(const char* name) {
|
||||
if (name[0] == 0) return 0;
|
||||
for (DWORD i = 0; i < fakePerks.size(); i++) {
|
||||
if (!strcmp(name, fakePerks[i].Name)) {
|
||||
return fakePerks[i].Level;
|
||||
@@ -1164,6 +1167,7 @@ DWORD _stdcall HasFakePerk(const char* name) {
|
||||
}
|
||||
|
||||
DWORD _stdcall HasFakeTrait(const char* name) {
|
||||
if (name[0] == 0) return 0;
|
||||
for (DWORD i = 0; i < fakeTraits.size(); i++) {
|
||||
if (!strcmp(name, fakeTraits[i].Name)) {
|
||||
return 1;
|
||||
@@ -1215,27 +1219,33 @@ void PerksInit() {
|
||||
|
||||
PerkEngineInit();
|
||||
HookCall(0x442729, PerkInitWrapper); // game_init_
|
||||
if (GetPrivateProfileString("Misc", "PerksFile", "", &perksFile[2], MAX_PATH - 3, ini)) {
|
||||
|
||||
if (GetConfigString("Misc", "PerksFile", "", &perksFile[2], MAX_PATH - 3)) {
|
||||
perksFile[0] = '.';
|
||||
perksFile[1] = '\\';
|
||||
HookCall(0x44272E, TraitInitWrapper); // game_init_
|
||||
if (GetFileAttributes(perksFile) == INVALID_FILE_ATTRIBUTES) return;
|
||||
|
||||
perksEnable = iniGetInt("Perks", "Enable", 1, perksFile);
|
||||
if (iniGetInt("Traits", "Enable", 1, perksFile)) {
|
||||
HookCall(0x44272E, TraitInitWrapper); // game_init_
|
||||
}
|
||||
|
||||
// Engine perks settings
|
||||
long enginePerkMod = GetPrivateProfileIntA("PerksTweak", "WeaponScopeRangePenalty", -1, perksFile);
|
||||
long enginePerkMod = iniGetInt("PerksTweak", "WeaponScopeRangePenalty", -1, perksFile);
|
||||
if (enginePerkMod >= 0 && enginePerkMod != 8) SafeWrite32(0x42448E, enginePerkMod);
|
||||
enginePerkMod = GetPrivateProfileIntA("PerksTweak", "WeaponScopeRangeBonus", -1, perksFile);
|
||||
enginePerkMod = iniGetInt("PerksTweak", "WeaponScopeRangeBonus", -1, perksFile);
|
||||
if (enginePerkMod >= 2 && enginePerkMod != 5) SafeWrite32(0x424489, enginePerkMod);
|
||||
|
||||
enginePerkMod = GetPrivateProfileIntA("PerksTweak", "WeaponLongRangeBonus", -1, perksFile);
|
||||
enginePerkMod = iniGetInt("PerksTweak", "WeaponLongRangeBonus", -1, perksFile);
|
||||
if (enginePerkMod >= 2 && enginePerkMod != 4) SafeWrite32(0x424474, enginePerkMod);
|
||||
|
||||
enginePerkMod = GetPrivateProfileIntA("PerksTweak", "WeaponAccurateBonus", -1, perksFile);
|
||||
enginePerkMod = iniGetInt("PerksTweak", "WeaponAccurateBonus", -1, perksFile);
|
||||
if (enginePerkMod >= 0 && enginePerkMod != 20) {
|
||||
if (enginePerkMod > 200) enginePerkMod = 200;
|
||||
SafeWrite8(0x42465D, static_cast<BYTE>(enginePerkMod));
|
||||
}
|
||||
|
||||
enginePerkMod = GetPrivateProfileIntA("PerksTweak", "WeaponHandlingBonus", -1, perksFile);
|
||||
enginePerkMod = iniGetInt("PerksTweak", "WeaponHandlingBonus", -1, perksFile);
|
||||
if (enginePerkMod >= 0 && enginePerkMod != 3) {
|
||||
if (enginePerkMod > 10) enginePerkMod = 10;
|
||||
SafeWrite8(0x424636, static_cast<char>(enginePerkMod));
|
||||
|
||||
@@ -1284,7 +1284,7 @@ void ScriptExtenderSetup() {
|
||||
SafeWrite32(0x46CE6C, (DWORD)opcodes); // call that actually jumps to the opcode
|
||||
SafeWrite32(0x46E390, (DWORD)opcodes); // mov that writes to the opcode
|
||||
|
||||
if (GetPrivateProfileIntA("Debugging", "AllowUnsafeScripting", 0, ".\\ddraw.ini")) {
|
||||
if (GetPrivateProfileIntA("Debugging", "AllowUnsafeScripting", 0, ddrawIniDef)) {
|
||||
dlogr(" Unsafe opcodes enabled.", DL_SCRIPT);
|
||||
opcodes[0x1cf] = WriteByte;
|
||||
opcodes[0x1d0] = WriteShort;
|
||||
@@ -1373,7 +1373,7 @@ void ScriptExtenderSetup() {
|
||||
opcodes[0x1a9] = SetViewportY;
|
||||
opcodes[0x1aa] = SetXpMod;
|
||||
opcodes[0x1ab] = SetPerkLevelMod;
|
||||
opcodes[0x1ac] = GetIniSetting;
|
||||
opcodes[0x1ac] = funcGetIniSetting;
|
||||
opcodes[0x1ad] = funcGetShaderVersion;
|
||||
opcodes[0x1ae] = funcSetShaderMode;
|
||||
opcodes[0x1af] = GetGameMode;
|
||||
@@ -1424,7 +1424,7 @@ void ScriptExtenderSetup() {
|
||||
opcodes[0x1e8] = SetApAcEBonus;
|
||||
opcodes[0x1e9] = GetApAcEBonus;
|
||||
opcodes[0x1ea] = InitHook;
|
||||
opcodes[0x1eb] = GetIniString;
|
||||
opcodes[0x1eb] = funcGetIniString;
|
||||
opcodes[0x1ec] = funcSqrt;
|
||||
opcodes[0x1ed] = funcAbs;
|
||||
opcodes[0x1ee] = funcSin;
|
||||
@@ -1634,10 +1634,10 @@ sScriptProgram* GetGlobalScriptProgram(DWORD scriptPtr) {
|
||||
return (it == sfallProgsMap.end()) ? nullptr : &it->second ; // prog
|
||||
}
|
||||
|
||||
bool _stdcall isGameScript(const char* filename) {
|
||||
bool _stdcall IsGameScript(const char* filename) {
|
||||
if (strlen(filename) > 8) return false;
|
||||
for (DWORD i = 0; i < *(DWORD*)_maxScriptNum; i++) {
|
||||
if (strcmp(filename, (char*)(*(DWORD*)_scriptListInfo + i * 20)) == 0) return true;
|
||||
for (int i = 0; i < *ptr_maxScriptNum; i++) {
|
||||
if (strcmp(filename, (char*)(*ptr_scriptListInfo + i * 20)) == 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1663,13 +1663,14 @@ void LoadGlobalScripts() {
|
||||
sScriptProgram prog;
|
||||
for (DWORD i = 0; i < count; i++) {
|
||||
name = _strlwr((char*)filenames[i]);
|
||||
if (name[0] != 'g' || name[1] != 'l') continue; // fix bug in db_get_file_list fuction (if the script name begins with a non-Latin character)
|
||||
|
||||
std::string baseName(name);
|
||||
int lastDot = baseName.find_last_of('.');
|
||||
if ((baseName.length() - lastDot) > 4) continue; // skip files with invalid extension (bug in db_get_file_list fuction)
|
||||
|
||||
baseName = baseName.substr(0, lastDot); // script name without extension
|
||||
if (!isGameScript(baseName.c_str())) {
|
||||
if (!IsGameScript(baseName.c_str())) {
|
||||
dlog("> ", DL_SCRIPT);
|
||||
dlog(name, DL_SCRIPT);
|
||||
isGlobalScriptLoading = 1;
|
||||
|
||||
@@ -44,7 +44,7 @@ typedef struct {
|
||||
} sScriptProgram;
|
||||
|
||||
void ScriptExtenderSetup();
|
||||
bool _stdcall isGameScript(const char* filename);
|
||||
bool _stdcall IsGameScript(const char* filename);
|
||||
void LoadGlobalScripts();
|
||||
void ClearGlobalScripts();
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
* Misc operators
|
||||
*/
|
||||
|
||||
static DWORD dmModelNamePtr=(DWORD)dmModelName;
|
||||
static DWORD dfModelNamePtr=(DWORD)dfModelName;
|
||||
static DWORD MovieNamesPtr=(DWORD)MoviePaths;
|
||||
static DWORD defaultMaleModelNamePtr = (DWORD)defaultMaleModelName;
|
||||
static DWORD defaultFemaleModelNamePtr = (DWORD)defaultFemaleModelName;
|
||||
static DWORD movieNamesPtr = (DWORD)MoviePaths;
|
||||
|
||||
|
||||
//// *** End Helios *** ///
|
||||
@@ -61,7 +61,7 @@ next:
|
||||
mov eax, edi;
|
||||
call interpretGetString_;
|
||||
push eax;
|
||||
push dmModelNamePtr;
|
||||
push defaultMaleModelNamePtr;
|
||||
call strcpy_p;
|
||||
end:
|
||||
pop edi;
|
||||
@@ -91,7 +91,7 @@ next:
|
||||
mov eax, edi;
|
||||
call interpretGetString_;
|
||||
push eax;
|
||||
push dfModelNamePtr;
|
||||
push defaultFemaleModelNamePtr;
|
||||
call strcpy_p;
|
||||
end:
|
||||
pop edi;
|
||||
@@ -137,7 +137,7 @@ next:
|
||||
mov eax, esi;
|
||||
mov esi, 65;
|
||||
mul si;
|
||||
add eax, MovieNamesPtr;
|
||||
add eax, movieNamesPtr;
|
||||
push eax;
|
||||
call strcpy_p;
|
||||
end:
|
||||
@@ -625,7 +625,7 @@ static DWORD _stdcall GetIniSetting2(const char* str, DWORD isString) {
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) GetIniSetting() {
|
||||
static void __declspec(naked) funcGetIniSetting() {
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
@@ -664,7 +664,7 @@ result:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
static void __declspec(naked) GetIniString() {
|
||||
static void __declspec(naked) funcGetIniString() {
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
std::vector<std::string> split(const std::string &s, char delim) {
|
||||
std::vector<std::string> elems;
|
||||
split(s, delim, std::back_inserter(elems));
|
||||
return elems;
|
||||
}
|
||||
|
||||
std::string trim(const std::string& str) {
|
||||
size_t first = str.find_first_not_of(' ');
|
||||
if (std::string::npos == first) {
|
||||
return str;
|
||||
}
|
||||
size_t last = str.find_last_not_of(' ');
|
||||
return str.substr(first, (last - first + 1));
|
||||
}
|
||||
|
||||
void ToLowerCase(std::string& line) {
|
||||
std::transform(line.begin(), line.end(), line.begin(), ::tolower);
|
||||
}
|
||||
|
||||
bool isSpace(char c) {
|
||||
return (c == ' ' || c == '\t' /*|| c == '\n' || c == '\r'*/);
|
||||
}
|
||||
|
||||
void strtrim(char* str) {
|
||||
if (str[0] == 0) return;
|
||||
int len = strlen(str) - 1;
|
||||
|
||||
int i = len;
|
||||
while (len >= 0 && isSpace(str[len])) len--;
|
||||
if (i != len) str[len + 1] = '\0'; // delete all spaces on the right
|
||||
|
||||
i = 0;
|
||||
while (i < len && isSpace(str[i])) i++;
|
||||
if (i > 0) {
|
||||
int j = 0;
|
||||
do {
|
||||
str[j] = str[j + i]; // shift all chars (including null char) to the left
|
||||
} while (++j <= len);
|
||||
}
|
||||
}
|
||||
|
||||
// returns position, find word must be lowercase
|
||||
const char* strfind(const char* source, const char* word) {
|
||||
if (source == 0 || word == 0 || *word == 0) return 0;
|
||||
const char *w_pos, *s_pos;
|
||||
while(*source != 0) {
|
||||
w_pos = word, s_pos = source++;
|
||||
while (tolower(*s_pos) == *w_pos) {
|
||||
s_pos++;
|
||||
if (*++w_pos == 0) return s_pos - (w_pos - word);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
// splits a string by given delimiter
|
||||
// taken from: http://stackoverflow.com/a/236803/4331475
|
||||
template<typename T>
|
||||
void split(const std::string &s, char delim, T result, size_t limit = -1) {
|
||||
std::stringstream ss;
|
||||
ss.str(s);
|
||||
std::string item;
|
||||
size_t i = 0;
|
||||
while (std::getline(ss, item, delim) && (limit == -1 || i < limit)) {
|
||||
*(result++) = item;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Splits a string by given delimiter
|
||||
std::vector<std::string> split(const std::string &s, char delim);
|
||||
|
||||
std::string trim(const std::string& str);
|
||||
|
||||
void ToLowerCase(std::string& line);
|
||||
|
||||
bool isSpace(char c);
|
||||
|
||||
void strtrim(char* str);
|
||||
|
||||
const char* strfind(const char* source, const char* word);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user