Added "set_terrain_name" script function

Fixed minor bugs in WorldMapTerrainInfo, TravelMarkerStyles features.

Minor edits to Console.cpp, Logging.cpp.
This commit is contained in:
NovaRain
2020-01-18 17:28:05 +08:00
parent 160a5b6053
commit bf4c47d1c0
13 changed files with 92 additions and 30 deletions
+1
View File
@@ -315,6 +315,7 @@
#define set_outline(obj, color) sfall_func2("set_outline", obj, color) #define set_outline(obj, color) sfall_func2("set_outline", obj, color)
#define set_rest_heal_time(time) sfall_func1("set_rest_heal_time", time) #define set_rest_heal_time(time) sfall_func1("set_rest_heal_time", time)
#define set_rest_mode(mode) sfall_func1("set_rest_mode", mode) #define set_rest_mode(mode) sfall_func1("set_rest_mode", mode)
#define set_terrain_name(x, y, name) sfall_func3("set_terrain_name", x, y, name)
#define set_unique_id(obj) sfall_func1("set_unique_id", obj) #define set_unique_id(obj) sfall_func1("set_unique_id", obj)
#define set_unjam_locks_time(time) sfall_func1("set_unjam_locks_time", time) #define set_unjam_locks_time(time) sfall_func1("set_unjam_locks_time", time)
#define set_window_flag(winID, flag, value) sfall_func3("set_window_flag", winID, flag, value) #define set_window_flag(winID, flag, value) sfall_func3("set_window_flag", winID, flag, value)
@@ -702,6 +702,9 @@ optional argument:
- toCase: 0 - lowercase, 1 - uppercase - toCase: 0 - lowercase, 1 - uppercase
- NOTE: this function works only for English letters of A-Z/a-z - NOTE: this function works only for English letters of A-Z/a-z
> void sfall_func3("set_terrain_name", int x, int y, string name)
- overrides the terrain type name for the sub-tile by the specified coordinates on the world map
------------------------ ------------------------
------ MORE INFO ------- ------ MORE INFO -------
------------------------ ------------------------
-5
View File
@@ -225,11 +225,6 @@ long wmGetCurrentTerrainType() {
return *terrainId; return *terrainId;
} }
// Returns the name of the terrain type at the the player's position on the world map
const char* wmGetCurrentTerrainName() {
return GetMessageStr(&fo::var::wmMsgFile, 1000 + wmGetCurrentTerrainType());
}
//--------------------------------------------------------- //---------------------------------------------------------
// copy the area from the interface buffer to the data array // copy the area from the interface buffer to the data array
void RectCopyToMemory(long fromX, long fromY, long width, long height, long fromWidth, BYTE* fromBuff, BYTE* toMem) { void RectCopyToMemory(long fromX, long fromY, long width, long height, long fromWidth, BYTE* fromBuff, BYTE* toMem) {
-2
View File
@@ -82,8 +82,6 @@ void GetObjectsTileRadius(std::vector<fo::GameObject*> &objs, long sourceTile, l
long wmGetCurrentTerrainType(); long wmGetCurrentTerrainType();
const char* wmGetCurrentTerrainName();
void RectCopyToMemory(long fromX, long fromY, long width, long height, long fromWidth, BYTE* fromBuff, BYTE* toMem); void RectCopyToMemory(long fromX, long fromY, long width, long height, long fromWidth, BYTE* fromBuff, BYTE* toMem);
void MemCopyToWinBuffer(long toX, long toY, long width, long height, long toWidth, BYTE* toBuff, BYTE* fromMem); void MemCopyToWinBuffer(long toX, long toY, long width, long height, long toWidth, BYTE* toBuff, BYTE* fromMem);
+3 -5
View File
@@ -26,10 +26,8 @@
namespace sfall namespace sfall
{ {
using namespace std; static int DebugTypes = 0;
static std::ofstream Log;
static int DebugTypes=0;
static ofstream Log;
void dlog(const std::string& a, int type) { void dlog(const std::string& a, int type) {
if (isDebug && (type == DL_MAIN || (type & DebugTypes))) { if (isDebug && (type == DL_MAIN || (type & DebugTypes))) {
@@ -58,7 +56,7 @@ void dlog_f(const char *fmt, int type, ...) {
} }
void LoggingInit() { void LoggingInit() {
Log.open("sfall-log.txt", ios_base::out | ios_base::trunc); Log.open("sfall-log.txt", std::ios_base::out | std::ios_base::trunc);
if (iniGetInt("Debugging", "Init", 0, ::sfall::ddrawIni)) { if (iniGetInt("Debugging", "Init", 0, ::sfall::ddrawIni)) {
DebugTypes |= DL_INIT; DebugTypes |= DL_INIT;
} }
+7 -9
View File
@@ -25,12 +25,10 @@
namespace sfall namespace sfall
{ {
using namespace std; static std::ofstream consoleFile;
static ofstream consolefile; static void __stdcall ConsoleFilePrint(const char* msg) {
consoleFile << msg << std::endl;
static void _stdcall ConsoleFilePrint(const char* msg) {
consolefile << msg << endl;
} }
static const DWORD ConsoleHookRet = 0x431871; static const DWORD ConsoleHookRet = 0x431871;
@@ -52,16 +50,16 @@ static void __declspec(naked) ConsoleHook() {
void Console::init() { void Console::init() {
auto path = GetConfigString("Misc", "ConsoleOutputPath", "", MAX_PATH); auto path = GetConfigString("Misc", "ConsoleOutputPath", "", MAX_PATH);
if (!path.empty()) { if (!path.empty()) {
consolefile.open(path); consoleFile.open(path);
if (consolefile.is_open()) { if (consoleFile.is_open()) {
MakeJump(0x43186C, ConsoleHook); MakeJump(0x43186C, ConsoleHook);
} }
} }
} }
void Console::exit() { void Console::exit() {
if (consolefile.is_open()) { if (consoleFile.is_open()) {
consolefile.close(); consoleFile.close();
} }
} }
+33 -8
View File
@@ -24,6 +24,7 @@
#include "..\Utils.h" #include "..\Utils.h"
#include "Graphics.h" #include "Graphics.h"
#include "LoadGameHook.h" #include "LoadGameHook.h"
#include "Worldmap.h"
#include "Interface.h" #include "Interface.h"
@@ -471,9 +472,10 @@ enum DotStyleDefault {
}; };
enum TerrainHoverImage { enum TerrainHoverImage {
width = 100, width = 200,
height = 15, height = 15,
size = width * height size = width * height,
x_shift = (width / 4 ) + 25 // adjust x position
}; };
static std::array<unsigned char, TerrainHoverImage::size> wmTmpBuffer; static std::array<unsigned char, TerrainHoverImage::size> wmTmpBuffer;
@@ -563,7 +565,7 @@ static void __declspec(naked) DrawingDots() {
} }
static void PrintTerrainType(long x, long y) { static void PrintTerrainType(long x, long y) {
char* terrainText = (char*)fo::wmGetCurrentTerrainName(); char* terrainText = (char*)Worldmap::GetCurrentTerrainName();
long txtWidth = fo::GetTextWidthFM(terrainText); long txtWidth = fo::GetTextWidthFM(terrainText);
if (txtWidth > TerrainHoverImage::width) txtWidth = TerrainHoverImage::width; if (txtWidth > TerrainHoverImage::width) txtWidth = TerrainHoverImage::width;
@@ -583,7 +585,12 @@ static void __declspec(naked) wmInterfaceRefresh_hook() {
// player stops moving // player stops moving
dots.clear(); dots.clear();
// Reinitialize on next AddNewDot // Reinitialize on next AddNewDot
dotLen = spaceLen = 99; if (terrainCount)
dotLen = spaceLen = 99;
else {
dotLen = DotStyleDefault::DotLen;
spaceLen = DotStyleDefault::SpaceLen;
}
} }
} }
if (isHoveringHotspot && !fo::var::In_WorldMap) { if (isHoveringHotspot && !fo::var::In_WorldMap) {
@@ -594,8 +601,13 @@ static void __declspec(naked) wmInterfaceRefresh_hook() {
} }
static long __fastcall wmDetectHotspotHover(long wmMouseX, long wmMouseY) { static long __fastcall wmDetectHotspotHover(long wmMouseX, long wmMouseY) {
long deltaX = abs((long)fo::var::world_xpos - (wmMouseX - 20 + fo::var::wmWorldOffsetX)); long deltaX = 20, deltaY = 20;
long deltaY = abs((long)fo::var::world_ypos - (wmMouseY - 20 + fo::var::wmWorldOffsetY));
// mouse cursor is out of viewport area (the zero values of wmMouseX and wmMouseY correspond to the top-left corner of the worldmap interface)
if ((wmMouseX < 25 || wmMouseY < 30 || wmMouseX > wmapViewPortWidth + 15 || wmMouseY > wmapViewPortHeight + 15) == false) {
deltaX = abs((long)fo::var::world_xpos - (wmMouseX - deltaX + fo::var::wmWorldOffsetX));
deltaY = abs((long)fo::var::world_ypos - (wmMouseY - deltaY + fo::var::wmWorldOffsetY));
}
bool isHovered = isHoveringHotspot; bool isHovered = isHoveringHotspot;
isHoveringHotspot = deltaX < 8 && deltaY < 6; isHoveringHotspot = deltaX < 8 && deltaY < 6;
@@ -603,12 +615,12 @@ static long __fastcall wmDetectHotspotHover(long wmMouseX, long wmMouseY) {
// upper left corner // upper left corner
long y = fo::var::world_ypos - fo::var::wmWorldOffsetY; long y = fo::var::world_ypos - fo::var::wmWorldOffsetY;
long x = fo::var::world_xpos - fo::var::wmWorldOffsetX; long x = fo::var::world_xpos - fo::var::wmWorldOffsetX;
long x_offset = x - 25; long x_offset = x - TerrainHoverImage::x_shift;
if (!backImageIsCopy) { if (!backImageIsCopy) {
backImageIsCopy = true; backImageIsCopy = true;
// copy image to memory (size 100 x 15) // copy image to memory (size 100 x 15)
fo::RectCopyToMemory(x_offset, y, TerrainHoverImage::width, TerrainHoverImage::height, wmapWinWidth, *(BYTE**)FO_VAR_wmBkWinBuf, wmTmpBuffer.data()); fo::RectCopyToMemory(x_offset, y, TerrainHoverImage::width, TerrainHoverImage::height, wmapWinWidth, *(BYTE**)FO_VAR_wmBkWinBuf, wmTmpBuffer.data());
PrintTerrainType(x, y); PrintTerrainType(x, y); // TODO: fix text being printed over the interface
} else { } else {
// restore saved image // restore saved image
fo::MemCopyToWinBuffer(x_offset, y, TerrainHoverImage::width, TerrainHoverImage::height, wmapWinWidth, *(BYTE**)FO_VAR_wmBkWinBuf, wmTmpBuffer.data()); fo::MemCopyToWinBuffer(x_offset, y, TerrainHoverImage::width, TerrainHoverImage::height, wmapWinWidth, *(BYTE**)FO_VAR_wmBkWinBuf, wmTmpBuffer.data());
@@ -635,12 +647,25 @@ end:
checkHover: checkHover:
cmp dword ptr ds:[FO_VAR_WorldMapCurrArea], -1; cmp dword ptr ds:[FO_VAR_WorldMapCurrArea], -1;
jne end; // player is in a location circle jne end; // player is in a location circle
cmp esi, 328;
je isScroll;
cmp esi, 331;
je isScroll;
cmp esi, 333;
je isScroll;
cmp esi, 336;
je isScroll;
push ecx; push ecx;
mov ecx, [esp + 0x38 - 0x30 + 8]; // x mov ecx, [esp + 0x38 - 0x30 + 8]; // x
mov edx, [esp + 0x38 - 0x34 + 8]; // y mov edx, [esp + 0x38 - 0x34 + 8]; // y
call wmDetectHotspotHover; call wmDetectHotspotHover;
pop ecx; pop ecx;
retn; retn;
isScroll:
mov isHoveringHotspot, 0;
mov backImageIsCopy, 0;
mov eax, dword ptr ds:[FO_VAR_wmWorldOffsetY];
retn;
} }
} }
+1 -1
View File
@@ -91,8 +91,8 @@ private:
HRESULT hr = pAllocNotify->AllocateSurfaceHelper(lpAllocInfo, lpNumBuffers, &surfaces[0]); HRESULT hr = pAllocNotify->AllocateSurfaceHelper(lpAllocInfo, lpNumBuffers, &surfaces[0]);
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
dlog_f(" Height: %d,", DL_INIT, lpAllocInfo->dwHeight);
dlog_f(" Width: %d,", DL_INIT, lpAllocInfo->dwWidth); dlog_f(" Width: %d,", DL_INIT, lpAllocInfo->dwWidth);
dlog_f(" Height: %d,", DL_INIT, lpAllocInfo->dwHeight);
dlog_f(" Format: %d", DL_INIT, lpAllocInfo->Format); dlog_f(" Format: %d", DL_INIT, lpAllocInfo->Format);
hr = surfaces[0]->GetContainer(IID_IDirect3DTexture9, (void**)&pTex); hr = surfaces[0]->GetContainer(IID_IDirect3DTexture9, (void**)&pTex);
@@ -127,6 +127,7 @@ static const SfallMetarule metarules[] = {
{"set_rest_heal_time", sf_set_rest_heal_time, 1, 1, -1, {ARG_INT}}, {"set_rest_heal_time", sf_set_rest_heal_time, 1, 1, -1, {ARG_INT}},
{"set_rest_mode", sf_set_rest_mode, 1, 1, -1, {ARG_INT}}, {"set_rest_mode", sf_set_rest_mode, 1, 1, -1, {ARG_INT}},
{"set_selectable_perk_npc", sf_set_selectable_perk_npc, 5, 5, -1, {ARG_OBJECT, ARG_STRING, ARG_INT, ARG_INT, ARG_STRING}}, {"set_selectable_perk_npc", sf_set_selectable_perk_npc, 5, 5, -1, {ARG_OBJECT, ARG_STRING, ARG_INT, ARG_INT, ARG_STRING}},
{"set_terrain_name", sf_set_terrain_name, 3, 3, -1, {ARG_INT, ARG_INT, ARG_STRING}},
{"set_unique_id", sf_set_unique_id, 1, 2, -1, {ARG_OBJECT, ARG_INT}}, {"set_unique_id", sf_set_unique_id, 1, 2, -1, {ARG_OBJECT, ARG_INT}},
{"set_unjam_locks_time", sf_set_unjam_locks_time, 1, 1, -1, {ARG_INT}}, {"set_unjam_locks_time", sf_set_unjam_locks_time, 1, 1, -1, {ARG_INT}},
{"set_window_flag", sf_set_window_flag, 3, 3, -1, {ARG_INTSTR, ARG_INT, ARG_INT}}, {"set_window_flag", sf_set_window_flag, 3, 3, -1, {ARG_INTSTR, ARG_INT, ARG_INT}},
@@ -257,5 +257,9 @@ void sf_tile_by_position(OpcodeContext& ctx) {
ctx.setReturn(fo::func::tile_num(ctx.arg(0).rawValue(), ctx.arg(1).rawValue())); ctx.setReturn(fo::func::tile_num(ctx.arg(0).rawValue(), ctx.arg(1).rawValue()));
} }
void sf_set_terrain_name(OpcodeContext& ctx) {
Worldmap::SetTerrainTypeName(ctx.arg(0).rawValue(), ctx.arg(1).rawValue(), ctx.arg(2).strValue());
}
} }
} }
@@ -58,5 +58,7 @@ void sf_get_rest_on_map(OpcodeContext&);
void sf_tile_by_position(OpcodeContext&); void sf_tile_by_position(OpcodeContext&);
void sf_set_terrain_name(OpcodeContext&);
} }
} }
+33
View File
@@ -42,6 +42,8 @@ struct levelRest {
}; };
std::unordered_map<int, levelRest> mapRestInfo; std::unordered_map<int, levelRest> mapRestInfo;
std::vector<std::pair<long, std::string>> wmTerrainTypeNames; // pair first: x + y * number of horizontal sub-tiles
static bool restMap; static bool restMap;
static bool restMode; static bool restMode;
static bool restTime; static bool restTime;
@@ -602,6 +604,36 @@ long __fastcall Worldmap::GetRestMapLevel(long elev, int mapId) {
return -1; return -1;
} }
static const char* GetOverrideTerrainName(long x, long y) {
if (wmTerrainTypeNames.empty()) return nullptr;
long subTileID = x + y * (fo::var::wmNumHorizontalTiles * 7);
auto it = std::find_if(wmTerrainTypeNames.crbegin(), wmTerrainTypeNames.crend(),
[=](const std::pair<long, std::string> &el)
{ return el.first == subTileID; }
);
return (it != wmTerrainTypeNames.crend()) ? it->second.c_str() : nullptr;
}
// x, y - position of the sub-tile on the world map
void Worldmap::SetTerrainTypeName(long x, long y, const char* name) {
long subTileID = x + y * (fo::var::wmNumHorizontalTiles * 7);
wmTerrainTypeNames.push_back(std::make_pair(subTileID, name));
}
// TODO: someone might need to know the name of a terrain type?
const char* Worldmap::GetTerrainTypeName(long x, long y) {
//const char* name = GetOverrideTerrainName(x, y);
//return (name) ? name : fo::GetMessageStr(&fo::var::wmMsgFile, 1000 + fo::wmGetTerrainType(x, y));
return nullptr;
}
// Returns the name of the terrain type in the position of the player's marker on the world map
const char* Worldmap::GetCurrentTerrainName() {
const char* name = GetOverrideTerrainName(fo::var::world_xpos / 50, fo::var::world_ypos / 50);
return (name) ? name : fo::GetMessageStr(&fo::var::wmMsgFile, 1000 + fo::wmGetCurrentTerrainType());
}
void Worldmap::init() { void Worldmap::init() {
PathfinderFixInit(); PathfinderFixInit();
StartingStatePatches(); StartingStatePatches();
@@ -616,6 +648,7 @@ void Worldmap::init() {
if (restTime) SetRestHealTime(180); if (restTime) SetRestHealTime(180);
RestRestore(); RestRestore();
mapRestInfo.clear(); mapRestInfo.clear();
wmTerrainTypeNames.clear();
}; };
} }
+4
View File
@@ -42,6 +42,10 @@ public:
static DWORD GetAddedYears(bool isCheck = true); static DWORD GetAddedYears(bool isCheck = true);
static void SetAddedYears(DWORD years); static void SetAddedYears(DWORD years);
static void SetTerrainTypeName(long x, long y, const char* name);
static const char* GetTerrainTypeName(long x, long y);
static const char* GetCurrentTerrainName();
}; };
void _stdcall SetMapMulti(float d); void _stdcall SetMapMulti(float d);