mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added "set_town_title" script function
* for displaying custom title in floating text over a town. Corrected some code.
This commit is contained in:
@@ -77,13 +77,6 @@
|
||||
#define LIST_SPATIAL (6)
|
||||
#define LIST_ALL (9)
|
||||
|
||||
//Valid flags for force_encounter_with_flags
|
||||
#define ENCOUNTER_FLAG_NO_CAR (0x1)
|
||||
#define ENCOUNTER_FLAG_LOCK (0x2) // block new forced encounter by the next function call until the current specified encounter occurs
|
||||
#define ENCOUNTER_FLAG_NO_ICON (0x4) // disable displaying the flashing icon
|
||||
#define ENCOUNTER_FLAG_ICON_SP (0x8) // use special encounter icon
|
||||
#define ENCOUNTER_FLAG_FADEOUT (0x10) // fade out the screen on encounter (Note: you yourself should restore the fade screen when entering the encounter)
|
||||
|
||||
//Valid window types for get_window_attribute
|
||||
#define WINTYPE_INVENTORY (0) // any inventory window
|
||||
#define WINTYPE_DIALOG (1)
|
||||
@@ -94,6 +87,13 @@
|
||||
#define WINTYPE_SKILLDEX (6)
|
||||
#define WINTYPE_ESCMENU (7) // escape menu
|
||||
|
||||
//Valid flags for force_encounter_with_flags
|
||||
#define ENCOUNTER_FLAG_NO_CAR (0x1)
|
||||
#define ENCOUNTER_FLAG_LOCK (0x2) // block new forced encounter by the next function call until the current specified encounter occurs
|
||||
#define ENCOUNTER_FLAG_NO_ICON (0x4) // disable displaying the flashing icon
|
||||
#define ENCOUNTER_FLAG_ICON_SP (0x8) // use special encounter icon
|
||||
#define ENCOUNTER_FLAG_FADEOUT (0x10) // fade out the screen on encounter (Note: you yourself should restore the fade screen when entering the encounter)
|
||||
|
||||
//The attack types returned by get_attack_type
|
||||
#define ATKTYPE_LWEP1 (0)
|
||||
#define ATKTYPE_LWEP2 (1)
|
||||
@@ -332,6 +332,7 @@
|
||||
#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_terrain_name(x, y, name) sfall_func3("set_terrain_name", x, y, name)
|
||||
#define set_town_title(areaID, title) sfall_func2("set_town_title", areaID, title)
|
||||
#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_window_flag(winID, flag, value) sfall_func3("set_window_flag", winID, flag, value)
|
||||
|
||||
@@ -710,6 +710,10 @@ int sfall_func2("get_window_attribute", int winType, int attrType)
|
||||
- winType: the type number of the interface window (see WINTYPE_* constants in sfall.h)
|
||||
- attrType: 0 - X position, 1 - Y position (relative to the top-left corner of the game screen)
|
||||
|
||||
> void sfall_func2("set_town_title", int areaID, string title)
|
||||
- sets a floating text for a town on the world map when hovering the cursor over the player's marker
|
||||
- areaID: the ID number of the town from city.txt
|
||||
|
||||
------------------------
|
||||
------ MORE INFO -------
|
||||
------------------------
|
||||
|
||||
@@ -207,7 +207,7 @@ enum WinNameType {
|
||||
};
|
||||
|
||||
fo::Window* GetWindow(long winType) {
|
||||
long winID = -1;
|
||||
long winID = 0;
|
||||
switch (winType) {
|
||||
case WinNameType::Inventory:
|
||||
winID = fo::var::i_wid;
|
||||
@@ -236,7 +236,7 @@ fo::Window* GetWindow(long winType) {
|
||||
default:
|
||||
return (fo::Window*)-1;
|
||||
}
|
||||
return (winID != -1) ? fo::func::GNW_find(winID) : nullptr;
|
||||
return (winID > 0) ? fo::func::GNW_find(winID) : nullptr;
|
||||
}
|
||||
|
||||
// Returns an array of objects within the specified radius from the source tile
|
||||
@@ -271,26 +271,62 @@ long wmGetCurrentTerrainType() {
|
||||
|
||||
//---------------------------------------------------------
|
||||
// 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) {
|
||||
fromBuff += fromY * fromWidth + fromX;
|
||||
void SurfaceCopyToMem(long fromX, long fromY, long width, long height, long fromWidth, BYTE* fromSurface, BYTE* toMem) {
|
||||
fromSurface += fromY * fromWidth + fromX;
|
||||
long i = 0;
|
||||
for (long h = 0; h < height; h++) {
|
||||
for (long w = 0; w < width; w++) {
|
||||
toMem[i++] = fromBuff[w];
|
||||
toMem[i++] = fromSurface[w];
|
||||
}
|
||||
fromBuff += fromWidth;
|
||||
fromSurface += fromWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// copy data from memory to the area of the interface buffer
|
||||
void MemCopyToWinBuffer(long toX, long toY, long width, long height, long toWidth, BYTE* toBuff, BYTE* fromMem) {
|
||||
toBuff += toY * toWidth + toX;
|
||||
void DrawToSurface(long toX, long toY, long width, long height, long toWidth, long toHeight, BYTE* toSurface, BYTE* fromMem) {
|
||||
BYTE* _toSurface = toSurface + (toY * toWidth + toX);
|
||||
BYTE* endToSurf = (toWidth * toHeight) + toSurface;
|
||||
long i = 0;
|
||||
for (long h = 0; h < height; h++) {
|
||||
for (long w = 0; w < width; w++) {
|
||||
toBuff[w] = fromMem[i++];
|
||||
if (_toSurface + w > endToSurf) return;
|
||||
if (_toSurface >= toSurface) _toSurface[w] = fromMem[i++];
|
||||
}
|
||||
toBuff += toWidth;
|
||||
_toSurface += toWidth;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawToSurface(long width, long height, long fromX, long fromY, long fromWidth, BYTE* fromSurf,
|
||||
long toX, long toY, long toWidth, long toHeight, BYTE* toSurf, int maskRef)
|
||||
{
|
||||
BYTE* _fromSurf = fromSurf + (fromY * fromWidth + fromX);
|
||||
BYTE* _toSurf = toSurf + (toY * toWidth + toX);
|
||||
BYTE* endToSurf = (toWidth * toHeight) + toSurf;
|
||||
|
||||
for (long h = 0; h < height; h++) {
|
||||
for (long w = 0; w < width; w++) {
|
||||
if (_toSurf + w > endToSurf) return;
|
||||
if (_toSurf >= toSurf && _fromSurf[w] != maskRef) _toSurf[w] = _fromSurf[w];
|
||||
}
|
||||
_fromSurf += fromWidth;
|
||||
_toSurf += toWidth;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawToSurface(long width, long height, long fromX, long fromY, long fromWidth, BYTE* fromSurf,
|
||||
long toX, long toY, long toWidth, long toHeight, BYTE* toSurf)
|
||||
{
|
||||
BYTE* _fromSurf = fromSurf + (fromY * fromWidth + fromX);
|
||||
BYTE* _toSurf = toSurf + (toY * toWidth + toX);
|
||||
BYTE* endToSurf = (toWidth * toHeight) + toSurf;
|
||||
|
||||
for (long h = 0; h < height; h++) {
|
||||
for (long w = 0; w < width; w++) {
|
||||
if (_toSurf + w > endToSurf) return;
|
||||
if (_toSurf >= toSurf) _toSurf[w] = _fromSurf[w];
|
||||
}
|
||||
_fromSurf += fromWidth;
|
||||
_toSurf += toWidth;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,74 +365,75 @@ void PrintTextFM(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWO
|
||||
//---------------------------------------------------------
|
||||
//gets the height of the currently selected font
|
||||
DWORD GetTextHeight() {
|
||||
DWORD TxtHeight;
|
||||
// DWORD TxtHeight;
|
||||
__asm {
|
||||
call dword ptr ds:[FO_VAR_text_height]; //get text height
|
||||
mov TxtHeight, eax;
|
||||
// mov TxtHeight, eax;
|
||||
}
|
||||
return TxtHeight;
|
||||
// return TxtHeight;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//gets the length of a string using the currently selected font
|
||||
DWORD GetTextWidth(const char *TextMsg) {
|
||||
DWORD GetTextWidth(const char* TextMsg) {
|
||||
__asm {
|
||||
mov eax, TextMsg;
|
||||
call dword ptr ds:[FO_VAR_text_width]; //get text width
|
||||
}
|
||||
}
|
||||
|
||||
DWORD GetTextWidthFM(const char *TextMsg) {
|
||||
__asm {
|
||||
mov eax, TextMsg;
|
||||
call fo::funcoffs::FMtext_width_; //get text width
|
||||
}
|
||||
DWORD GetTextWidthFM(const char* TextMsg) {
|
||||
return fo::func::FMtext_width(TextMsg); //get text width
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//get width of Char for current font
|
||||
DWORD GetCharWidth(char CharVal) {
|
||||
DWORD charWidth;
|
||||
DWORD GetCharWidth(char charVal) {
|
||||
__asm {
|
||||
mov al, CharVal;
|
||||
mov al, charVal;
|
||||
call dword ptr ds:[FO_VAR_text_char_width];
|
||||
mov charWidth, eax;
|
||||
}
|
||||
return charWidth;
|
||||
}
|
||||
|
||||
DWORD GetCharWidthFM(char charVal) {
|
||||
__asm {
|
||||
mov al, charVal;
|
||||
call fo::funcoffs::FMtext_char_width_;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//get maximum string length for current font - if all characters were maximum width
|
||||
DWORD GetMaxTextWidth(char *TextMsg) {
|
||||
DWORD msgWidth;
|
||||
DWORD GetMaxTextWidth(const char* TextMsg) {
|
||||
// DWORD msgWidth;
|
||||
__asm {
|
||||
mov eax, TextMsg;
|
||||
call dword ptr ds:[FO_VAR_text_mono_width];
|
||||
mov msgWidth, eax;
|
||||
// mov msgWidth, eax;
|
||||
}
|
||||
return msgWidth;
|
||||
// return msgWidth;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//get number of pixels between characters for current font
|
||||
DWORD GetCharGapWidth() {
|
||||
DWORD gapWidth;
|
||||
// DWORD gapWidth;
|
||||
__asm {
|
||||
call dword ptr ds:[FO_VAR_text_spacing];
|
||||
mov gapWidth, eax;
|
||||
// mov gapWidth, eax;
|
||||
}
|
||||
return gapWidth;
|
||||
// return gapWidth;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//get maximum character width for current font
|
||||
DWORD GetMaxCharWidth() {
|
||||
DWORD charWidth = 0;
|
||||
// DWORD charWidth = 0;
|
||||
__asm {
|
||||
call dword ptr ds:[FO_VAR_text_max];
|
||||
mov charWidth, eax;
|
||||
// mov charWidth, eax;
|
||||
}
|
||||
return charWidth;
|
||||
// return charWidth;
|
||||
}
|
||||
|
||||
void RedrawObject(GameObject* obj) {
|
||||
|
||||
@@ -84,24 +84,35 @@ void GetObjectsTileRadius(std::vector<fo::GameObject*> &objs, long sourceTile, l
|
||||
|
||||
long wmGetCurrentTerrainType();
|
||||
|
||||
void RectCopyToMemory(long fromX, long fromY, long width, long height, long fromWidth, BYTE* fromBuff, BYTE* toMem);
|
||||
void SurfaceCopyToMem(long fromX, long fromY, long width, long height, long fromWidth, BYTE* fromSurface, BYTE* toMem);
|
||||
|
||||
void MemCopyToWinBuffer(long toX, long toY, long width, long height, long toWidth, BYTE* toBuff, BYTE* fromMem);
|
||||
void DrawToSurface(long toX, long toY, long width, long height, long toWidth, long toHeight, BYTE* toSurface, BYTE* fromMem);
|
||||
|
||||
void DrawToSurface(long width, long height, long fromX, long fromY, long fromWidth, BYTE* fromSurf, long toX, long toY, long toWidth, long toHeight, BYTE* toSurf, int maskRef);
|
||||
|
||||
void DrawToSurface(long width, long height, long fromX, long fromY, long fromWidth, BYTE* fromSurf, long toX, long toY, long toWidth, long toHeight, BYTE* toSurf);
|
||||
|
||||
// Print text to surface
|
||||
void PrintText(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface);
|
||||
void PrintTextFM(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface);
|
||||
|
||||
// gets the height of the currently selected font
|
||||
DWORD GetTextHeight();
|
||||
|
||||
// gets the length of a string using the currently selected font
|
||||
DWORD GetTextWidth(const char *textMsg);
|
||||
DWORD GetTextWidthFM(const char *textMsg);
|
||||
DWORD GetTextWidth(const char* textMsg);
|
||||
DWORD GetTextWidthFM(const char* textMsg);
|
||||
|
||||
// get width of Char for current font
|
||||
DWORD GetCharWidth(char charVal);
|
||||
DWORD GetCharWidthFM(char charVal);
|
||||
|
||||
// get maximum string length for current font - if all characters were maximum width
|
||||
DWORD GetMaxTextWidth(char *textMsg);
|
||||
DWORD GetMaxTextWidth(const char* textMsg);
|
||||
|
||||
// get number of pixels between characters for current font
|
||||
DWORD GetCharGapWidth();
|
||||
|
||||
// get maximum character width for current font
|
||||
DWORD GetMaxCharWidth();
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ WRAP_WATCOM_FUNC1(long, critter_is_dead, GameObject*, critter)
|
||||
WRAP_WATCOM_FUNC1(void, EndLoad, DbFile*, file)
|
||||
WRAP_WATCOM_FUNC1(long, folder_print_line, const char*, text)
|
||||
WRAP_WATCOM_FUNC1(long, folder_print_seperator, const char*, text)
|
||||
WRAP_WATCOM_FUNC1(long, FMtext_width, const char*, text)
|
||||
WRAP_WATCOM_FUNC1(long, game_get_global_var, long, globalVar)
|
||||
WRAP_WATCOM_FUNC1(void, gdialogDisplayMsg, const char*, message)
|
||||
WRAP_WATCOM_FUNC0(long, gmouse_3d_get_mode)
|
||||
@@ -180,5 +181,6 @@ WRAP_WATCOM_FUNC1(void, win_delete, DWORD, winRef)
|
||||
WRAP_WATCOM_FUNC0(long, windowWidth)
|
||||
WRAP_WATCOM_FUNC1(void, wmCarUseGas, long, gasAmount)
|
||||
WRAP_WATCOM_FUNC0(void, wmPartyWalkingStep)
|
||||
WRAP_WATCOM_FUNC1(void, wmRefreshInterfaceOverlay, long, isRedraw)
|
||||
WRAP_WATCOM_FUNC2(DbFile*, xfopen, const char*, fileName, const char*, flags)
|
||||
WRAP_WATCOM_FUNC3(long, xfseek, DbFile*, file, long, fOffset, long, origin)
|
||||
|
||||
@@ -29,6 +29,10 @@ namespace var
|
||||
#define VAR_(name, type) \
|
||||
type &name = *reinterpret_cast<type*>(FO_VAR_##name);
|
||||
|
||||
// defines reference to a constant variable (value can't be changed from sfall)
|
||||
#define VARC(name, type) \
|
||||
const type& name = *reinterpret_cast<type*>(FO_VAR_##name);
|
||||
|
||||
// defines reference to static array
|
||||
#define VARA(name, type, size) \
|
||||
ArrayWrapper<type, size> &name = *reinterpret_cast<ArrayWrapper<type, size>*>(FO_VAR_##name);
|
||||
|
||||
@@ -55,6 +55,9 @@ struct ArrayWrapper {
|
||||
#define VAR_(name, type) \
|
||||
extern type& name;
|
||||
|
||||
#define VARC(name, type) \
|
||||
extern const type& name;
|
||||
|
||||
// defines reference to static array
|
||||
#define VARA(name, type, size) \
|
||||
extern ArrayWrapper<type, size> &name;
|
||||
|
||||
@@ -41,10 +41,10 @@ VAR_(dialog_target, GameObject*)
|
||||
VAR_(dialog_target_is_party, DWORD)
|
||||
VAR_(dialogue_state, DWORD)
|
||||
VAR_(dialogue_switch_mode, DWORD)
|
||||
VAR_(dialogueBackWindow, DWORD)
|
||||
VARC(dialogueBackWindow, DWORD)
|
||||
VAR_(dropped_explosive, DWORD)
|
||||
VARA(drugInfoList, DrugInfoList, 9)
|
||||
VAR_(edit_win, DWORD)
|
||||
VARC(edit_win, DWORD)
|
||||
VAR_(editor_message_file, MessageList)
|
||||
VAR_(Educated, DWORD)
|
||||
VAR_(elevation, DWORD)
|
||||
@@ -77,12 +77,12 @@ VAR_(hot_line_count, DWORD)
|
||||
VAR_(i_fid, DWORD)
|
||||
VAR_(i_lhand, GameObject*)
|
||||
VAR_(i_rhand, GameObject*)
|
||||
VAR_(i_wid, DWORD)
|
||||
VARC(i_wid, DWORD)
|
||||
VAR_(i_worn, GameObject*)
|
||||
VAR_(idle_func, DWORD)
|
||||
VAR_(In_WorldMap, DWORD) // moving on WorldMap
|
||||
VAR_(info_line, DWORD)
|
||||
VAR_(interfaceWindow, DWORD)
|
||||
VARC(interfaceWindow, DWORD)
|
||||
VAR_(intfaceEnabled, DWORD)
|
||||
VAR_(intotal, DWORD)
|
||||
VAR_(inven_dude, GameObject*)
|
||||
@@ -136,7 +136,7 @@ VAR_(optionsButtonDownKey, DWORD)
|
||||
VAR_(optionsButtonUp, DWORD)
|
||||
VAR_(optionsButtonUp1, DWORD)
|
||||
VAR_(optionsButtonUpKey, DWORD)
|
||||
VAR_(optnwin, DWORD)
|
||||
VARC(optnwin, DWORD)
|
||||
VAR_(outlined_object, GameObject*)
|
||||
VAR_(partyMemberAIOptions, DWORD)
|
||||
VAR_(partyMemberCount, DWORD)
|
||||
@@ -154,7 +154,7 @@ VARA(pc_trait, long, 2) // 2 of them
|
||||
VAR_(PeanutButter, BYTE)
|
||||
VARA(perk_data, PerkInfo, PERK_count)
|
||||
VAR_(perkLevelDataList, long*) // dynamic array, limited to PERK_Count
|
||||
VAR_(pip_win, DWORD)
|
||||
VARC(pip_win, DWORD)
|
||||
VAR_(pipboy_message_file, MessageList)
|
||||
VAR_(pipmesg, DWORD)
|
||||
VAR_(preload_list_index, DWORD)
|
||||
@@ -173,7 +173,7 @@ VAR_(script_path_base, const char*)
|
||||
VAR_(scr_size, BoundRect)
|
||||
VAR_(scriptListInfo, ScriptListInfoItem*) // dynamic array
|
||||
VARA(skill_data, SkillInfo, SKILL_count)
|
||||
VAR_(skldxwin, DWORD)
|
||||
VARC(skldxwin, DWORD)
|
||||
VAR_(slot_cursor, DWORD)
|
||||
VAR_(sneak_working, DWORD) // DWORD var
|
||||
VAR_(sound_music_path1, char*)
|
||||
@@ -210,7 +210,7 @@ VAR_(wd_obj, DWORD)
|
||||
VARA(window, fo::Window*, 50)
|
||||
VAR_(WhiteColor, BYTE)
|
||||
VAR_(wmAreaInfoList, DWORD)
|
||||
VAR_(wmBkWin, DWORD)
|
||||
VARC(wmBkWin, DWORD)
|
||||
VAR_(wmBkWinBuf, BYTE*)
|
||||
VAR_(wmLastRndTime, DWORD)
|
||||
VAR_(wmMaxTileNum, DWORD)
|
||||
@@ -226,6 +226,7 @@ VAR_(WorldMapCurrArea, DWORD)
|
||||
VAR_(YellowColor, BYTE)
|
||||
|
||||
#undef VAR_
|
||||
#undef VARC
|
||||
#undef VARP
|
||||
#undef VARA
|
||||
#undef VAR2
|
||||
|
||||
+48
-30
@@ -191,6 +191,7 @@ static void __declspec(naked) wmInterfaceInit_text_font_hook() {
|
||||
static DWORD wmTownMapSubButtonIds[WMAP_TOWN_BUTTONS + 1]; // replace _wmTownMapSubButtonIds (index 0 - unused element)
|
||||
static int worldmapInterface;
|
||||
static long wmapWinWidth = 640;
|
||||
static long wmapWinHeight = 480;
|
||||
static long wmapViewPortWidth = 450;
|
||||
static long wmapViewPortHeight = 443;
|
||||
|
||||
@@ -353,6 +354,7 @@ static void WorldmapViewportPatch() {
|
||||
dlog("Applying expanded world map interface patch.", DL_INIT);
|
||||
|
||||
wmapWinWidth = WMAP_WIN_WIDTH;
|
||||
wmapWinHeight = WMAP_WIN_HEIGHT;
|
||||
mapSlotsScrollMax -= 216;
|
||||
if (mapSlotsScrollMax < 0) mapSlotsScrollMax = 0;
|
||||
|
||||
@@ -465,6 +467,7 @@ static void WorldmapViewportPatch() {
|
||||
}
|
||||
|
||||
///////////////////////// FALLOUT 1 WORLD MAP FEATURES /////////////////////////
|
||||
static bool showTerrainType = false;
|
||||
|
||||
enum DotStyleDefault {
|
||||
DotLen = 2,
|
||||
@@ -564,17 +567,40 @@ static void __declspec(naked) DrawingDots() {
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintTerrainType(long x, long y) {
|
||||
char* terrainText = (char*)Worldmap::GetCurrentTerrainName();
|
||||
long txtWidth = fo::GetTextWidthFM(terrainText);
|
||||
static bool PrintHotspotText(long x, long y, bool backgroundCopy = false) {
|
||||
long area = fo::var::WorldMapCurrArea;
|
||||
char* text = (area != -1 || !showTerrainType) ? (char*)Worldmap::GetCustomAreaTitle(area) : (char*)Worldmap::GetCurrentTerrainName();
|
||||
if (!text) return false;
|
||||
|
||||
if (backgroundCopy) { // copy background image to memory (size 200 x 15)
|
||||
backImageIsCopy = true;
|
||||
fo::SurfaceCopyToMem(x - TerrainHoverImage::x_shift, y, TerrainHoverImage::width, TerrainHoverImage::height, wmapWinWidth, fo::var::wmBkWinBuf, wmTmpBuffer.data());
|
||||
}
|
||||
|
||||
long txtWidth = fo::GetTextWidthFM(text);
|
||||
if (txtWidth > TerrainHoverImage::width) txtWidth = TerrainHoverImage::width;
|
||||
|
||||
// offset position
|
||||
// offset text position
|
||||
y += 4;
|
||||
x += 25 - (txtWidth / 2);
|
||||
|
||||
fo::PrintTextFM(terrainText, 228, x, y, txtWidth, wmapWinWidth, fo::var::wmBkWinBuf); // text shadow
|
||||
fo::PrintTextFM(terrainText, 215, x - 1, y - 1, txtWidth, wmapWinWidth, fo::var::wmBkWinBuf);
|
||||
// prevent printing text outside of viewport
|
||||
/*if ((x + txtWidth) > wmapViewPortWidth - 20) {
|
||||
txtWidth -= (x + txtWidth) - wmapViewPortWidth - 20;
|
||||
} else if (x < 20) {
|
||||
long x_cut = abs(20 - x);
|
||||
long width = 0;
|
||||
do {
|
||||
width += fo::GetCharWidthFM(*text++);
|
||||
} while (width < x_cut);
|
||||
x += x_cut;
|
||||
}*/
|
||||
|
||||
fo::PrintTextFM(text, 228, x, y, txtWidth, wmapWinWidth, fo::var::wmBkWinBuf); // shadow
|
||||
fo::PrintTextFM(text, 215, x - 1, y - 1, txtWidth, wmapWinWidth, fo::var::wmBkWinBuf);
|
||||
|
||||
if (backgroundCopy) fo::func::wmRefreshInterfaceOverlay(0); // prevent printing text over the interface
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmInterfaceRefresh_hook() {
|
||||
@@ -594,17 +620,19 @@ static void __declspec(naked) wmInterfaceRefresh_hook() {
|
||||
}
|
||||
}
|
||||
if (isHoveringHotspot && !fo::var::In_WorldMap) {
|
||||
PrintTerrainType(fo::var::world_xpos - fo::var::wmWorldOffsetX, fo::var::world_ypos - fo::var::wmWorldOffsetY);
|
||||
PrintHotspotText(fo::var::world_xpos - fo::var::wmWorldOffsetX, fo::var::world_ypos - fo::var::wmWorldOffsetY);
|
||||
isHoveringHotspot = backImageIsCopy = false;
|
||||
}
|
||||
__asm jmp fo::funcoffs::wmDrawCursorStopped_;
|
||||
}
|
||||
|
||||
static long __fastcall wmDetectHotspotHover(long wmMouseX, long wmMouseY) {
|
||||
static void __fastcall wmDetectHotspotHover(long wmMouseX, long wmMouseY) {
|
||||
if (!showTerrainType && Worldmap::AreaTitlesIsEmpty()) return;
|
||||
|
||||
long deltaX = 20, deltaY = 20;
|
||||
|
||||
// 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) {
|
||||
if ((wmMouseX < 20 || wmMouseY < 20 || wmMouseX > wmapViewPortWidth + 15 || wmMouseY > wmapViewPortHeight + 20) == 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));
|
||||
}
|
||||
@@ -617,13 +645,10 @@ static long __fastcall wmDetectHotspotHover(long wmMouseX, long wmMouseY) {
|
||||
long x = fo::var::world_xpos - fo::var::wmWorldOffsetX;
|
||||
long x_offset = x - TerrainHoverImage::x_shift;
|
||||
if (!backImageIsCopy) {
|
||||
backImageIsCopy = true;
|
||||
// copy image to memory (size 100 x 15)
|
||||
fo::RectCopyToMemory(x_offset, y, TerrainHoverImage::width, TerrainHoverImage::height, wmapWinWidth, fo::var::wmBkWinBuf, wmTmpBuffer.data());
|
||||
PrintTerrainType(x, y); // TODO: fix text being printed over the interface
|
||||
if (!PrintHotspotText(x, y, true)) return;
|
||||
} else {
|
||||
// restore saved image
|
||||
fo::MemCopyToWinBuffer(x_offset, y, TerrainHoverImage::width, TerrainHoverImage::height, wmapWinWidth, fo::var::wmBkWinBuf, wmTmpBuffer.data());
|
||||
// restore background image
|
||||
fo::DrawToSurface(x_offset, y, TerrainHoverImage::width, TerrainHoverImage::height, wmapWinWidth, wmapWinHeight, fo::var::wmBkWinBuf, wmTmpBuffer.data());
|
||||
backImageIsCopy = false;
|
||||
}
|
||||
// redraw rectangle on worldmap interface
|
||||
@@ -634,19 +659,15 @@ static long __fastcall wmDetectHotspotHover(long wmMouseX, long wmMouseY) {
|
||||
rect.bottom = y + TerrainHoverImage::height;
|
||||
fo::func::win_draw_rect(fo::var::wmBkWin, &rect);
|
||||
}
|
||||
return fo::var::wmWorldOffsetY; // overwritten code
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmWorldMap_hack() {
|
||||
__asm {
|
||||
cmp ds:[FO_VAR_In_WorldMap], 1; // player is moving
|
||||
jne checkHover;
|
||||
end:
|
||||
mov eax, dword ptr ds:[FO_VAR_wmWorldOffsetY];
|
||||
mov eax, dword ptr ds:[FO_VAR_wmWorldOffsetY]; // overwritten code
|
||||
retn;
|
||||
checkHover:
|
||||
cmp dword ptr ds:[FO_VAR_WorldMapCurrArea], -1;
|
||||
jne end; // player is in a location circle
|
||||
cmp esi, 328;
|
||||
je isScroll;
|
||||
cmp esi, 331;
|
||||
@@ -660,6 +681,7 @@ checkHover:
|
||||
mov edx, [esp + 0x38 - 0x34 + 8]; // y
|
||||
call wmDetectHotspotHover;
|
||||
pop ecx;
|
||||
mov eax, dword ptr ds:[FO_VAR_wmWorldOffsetY];
|
||||
retn;
|
||||
isScroll:
|
||||
mov isHoveringHotspot, 0;
|
||||
@@ -733,9 +755,8 @@ static void WorldMapInterfacePatch() {
|
||||
}
|
||||
}
|
||||
|
||||
// Fallout 1 features, travel markers and displaying terrain types
|
||||
bool showTravelMarkers, showTerrainType;
|
||||
if (showTravelMarkers = GetConfigInt("Interface", "WorldMapTravelMarkers", 0) != 0) {
|
||||
// Fallout 1 features, travel markers and displaying terrain types or town titles
|
||||
if (GetConfigInt("Interface", "WorldMapTravelMarkers", 0)) {
|
||||
dlog("Applying world map travel markers patch.", DL_INIT);
|
||||
|
||||
int color = GetConfigInt("Interface", "TravelMarkerColor", 134); // color index in palette: R = 224, G = 0, B = 0
|
||||
@@ -769,12 +790,9 @@ static void WorldMapInterfacePatch() {
|
||||
};
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
if (showTerrainType = GetConfigInt("Interface", "WorldMapTerrainInfo", 0) != 0) {
|
||||
dlog("Applying display terrain types patch.", DL_INIT);
|
||||
MakeCall(0x4BFE84, wmWorldMap_hack);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
if (showTravelMarkers || showTerrainType) HookCall(0x4C3C7E, wmInterfaceRefresh_hook); // when calling wmDrawCursorStopped_
|
||||
showTerrainType = (GetConfigInt("Interface", "WorldMapTerrainInfo", 0) != 0);
|
||||
HookCall(0x4C3C7E, wmInterfaceRefresh_hook); // when calling wmDrawCursorStopped_
|
||||
MakeCall(0x4BFE84, wmWorldMap_hack);
|
||||
|
||||
// Car fuel gauge graphics patch
|
||||
MakeCall(0x4C528A, wmInterfaceRefreshCarFuel_hack_empty);
|
||||
@@ -841,7 +859,7 @@ static long gmouse_handle_event_hook() {
|
||||
// if IFACE_BAR_MODE is not enabled, check the display_win window area
|
||||
win = fo::func::GNW_find(*(DWORD*)FO_VAR_display_win);
|
||||
RECT *rect = &win->wRect;
|
||||
return fo::func::mouse_click_in(rect->left, rect->top, rect->right, rect->bottom); // 1 - click in the display_win area
|
||||
return fo::func::mouse_click_in(rect->left, rect->top, rect->right, rect->bottom); // 1 - click in the display window area
|
||||
}
|
||||
|
||||
static void __declspec(naked) gmouse_bk_process_hook() {
|
||||
|
||||
@@ -129,6 +129,7 @@ static const SfallMetarule metarules[] = {
|
||||
{"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_terrain_name", sf_set_terrain_name, 3, 3, -1, {ARG_INT, ARG_INT, ARG_STRING}},
|
||||
{"set_town_title", sf_set_town_title, 2, 2, -1, {ARG_INT, ARG_STRING}},
|
||||
{"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_window_flag", sf_set_window_flag, 3, 3, -1, {ARG_INTSTR, ARG_INT, ARG_INT}},
|
||||
|
||||
@@ -283,5 +283,9 @@ void sf_set_terrain_name(OpcodeContext& ctx) {
|
||||
Worldmap::SetTerrainTypeName(ctx.arg(0).rawValue(), ctx.arg(1).rawValue(), ctx.arg(2).strValue());
|
||||
}
|
||||
|
||||
void sf_set_town_title(OpcodeContext& ctx) {
|
||||
Worldmap::SetCustomAreaTitle(ctx.arg(0).rawValue(), ctx.arg(1).strValue());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,5 +60,7 @@ void sf_tile_by_position(OpcodeContext&);
|
||||
|
||||
void sf_set_terrain_name(OpcodeContext&);
|
||||
|
||||
void sf_set_town_title(OpcodeContext&);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ struct levelRest {
|
||||
std::unordered_map<int, levelRest> mapRestInfo;
|
||||
|
||||
std::vector<std::pair<long, std::string>> wmTerrainTypeNames; // pair first: x + y * number of horizontal sub-tiles
|
||||
std::vector<std::pair<long, std::string>> wmAreaHotSpotTitle;
|
||||
|
||||
static bool restMap;
|
||||
static bool restMode;
|
||||
@@ -615,20 +616,38 @@ 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());
|
||||
}
|
||||
|
||||
bool Worldmap::AreaTitlesIsEmpty() {
|
||||
return wmAreaHotSpotTitle.empty();
|
||||
}
|
||||
|
||||
void Worldmap::SetCustomAreaTitle(long areaID, const char* msg) {
|
||||
wmAreaHotSpotTitle.push_back(std::make_pair(areaID, msg));
|
||||
}
|
||||
|
||||
const char* Worldmap::GetCustomAreaTitle(long areaID) {
|
||||
if (wmAreaHotSpotTitle.empty()) return nullptr;
|
||||
|
||||
auto it = std::find_if(wmAreaHotSpotTitle.crbegin(), wmAreaHotSpotTitle.crend(),
|
||||
[=](const std::pair<long, std::string> &el)
|
||||
{ return el.first == areaID; }
|
||||
);
|
||||
return (it != wmAreaHotSpotTitle.crend()) ? it->second.c_str() : nullptr;
|
||||
}
|
||||
|
||||
void Worldmap::init() {
|
||||
PathfinderFixInit();
|
||||
StartingStatePatches();
|
||||
@@ -646,6 +665,7 @@ void Worldmap::init() {
|
||||
RestRestore();
|
||||
mapRestInfo.clear();
|
||||
wmTerrainTypeNames.clear();
|
||||
wmAreaHotSpotTitle.clear();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,12 @@ public:
|
||||
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* GetTerrainTypeName(long x, long y);
|
||||
static const char* GetCurrentTerrainName();
|
||||
|
||||
static bool AreaTitlesIsEmpty();
|
||||
static const char* GetCustomAreaTitle(long areaId);
|
||||
static void SetCustomAreaTitle(long areaId, const char* msg);
|
||||
};
|
||||
|
||||
void _stdcall SetMapMulti(float value);
|
||||
|
||||
Reference in New Issue
Block a user