Added "set_town_title" script function

* for displaying custom title in floating text over a town.

Corrected some code.
This commit is contained in:
NovaRain
2020-01-25 15:47:57 +08:00
parent 869b3cf4bd
commit 863a232703
14 changed files with 199 additions and 87 deletions
+8 -7
View File
@@ -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 -------
------------------------
+71 -34
View File
@@ -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) {
+16 -5
View File
@@ -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();
+2
View File
@@ -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)
+4
View File
@@ -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);
+3
View File
@@ -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;
+9 -8
View File
@@ -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
View File
@@ -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&);
}
}
+22 -2
View File
@@ -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();
};
}
+5 -1
View File
@@ -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);