mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
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:
@@ -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 -------
|
||||||
------------------------
|
------------------------
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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&);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user