Updated the code for party order attack

This commit is contained in:
NovaRain
2021-01-22 14:18:55 +08:00
parent 9e403e0e6b
commit 671065baed
15 changed files with 71 additions and 17 deletions
+4
View File
@@ -12,6 +12,10 @@ PartyACMsg=AC:
PartyAddictMsg=Addict PartyAddictMsg=Addict
NPCPickupFail=%s cannot pick up the item. NPCPickupFail=%s cannot pick up the item.
PartyOrderAttackHuman=I'll take care of it.|Okay, I got it.|Sounds like a plan.
PartyOrderAttackCreature=::Growl::
PartyOrderAttackRobot=::Beep::
[AppearanceMod] [AppearanceMod]
RaceText=Race RaceText=Race
StyleText=Style StyleText=Style
+1 -1
View File
@@ -35,7 +35,7 @@ MotionScanner=0
;Set to 0 to disable ;Set to 0 to disable
;Set to 1 to control all critters in combat ;Set to 1 to control all critters in combat
;Set to 2 to control all party members ;Set to 2 to control all party members
;Set to 3 to order party members to attack a specified target instead of controlling them by yourself ;Set to 3 to let you order party members to attack a specified target instead of controlling them directly after your first attack
Mode=0 Mode=0
;If you want to control only specific critters, uncomment the PIDList line and set a comma delimited list of PIDs ;If you want to control only specific critters, uncomment the PIDList line and set a comma delimited list of PIDs
;PIDList=62,89,97,107,160,161 ;PIDList=62,89,97,107,160,161
Binary file not shown.
+12
View File
@@ -366,6 +366,11 @@ void DrawToSurface(long width, long height, long fromX, long fromY, long fromWid
} }
} }
//void TranslucentDarkFill(BYTE* surface, long x, long y, long width, long height, long surfWidth) {
// BYTE* surf = surface + (y * surfWidth) + x;
// fo::func::wmInterfaceDrawSubTileRectFogged(surf, width, height, surfWidth);
//}
// Fills the specified interface window with index color // Fills the specified interface window with index color
void WinFillRect(long winID, long x, long y, long width, long height, BYTE indexColor) { void WinFillRect(long winID, long x, long y, long width, long height, BYTE indexColor) {
fo::Window* win = fo::func::GNW_find(winID); fo::Window* win = fo::func::GNW_find(winID);
@@ -388,6 +393,13 @@ void ClearWindow(long winID, bool refresh) {
} }
//--------------------------------------------------------- //---------------------------------------------------------
void PrintFloatText(fo::GameObject* object, const char* text, long colorText, long colorOutline, long font) {
fo::BoundRect rect;
if (!fo::func::text_object_create(object, text, font, colorText, colorOutline, &rect)) {
fo::func::tile_refresh_rect(&rect, object->elevation);
}
}
// print text to surface // print text to surface
void PrintText(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface) { void PrintText(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface) {
DWORD posOffset = yPos * toWidth + xPos; DWORD posOffset = yPos * toWidth + xPos;
+2
View File
@@ -121,6 +121,8 @@ void WinFillRect(long winID, long x, long y, long width, long height, BYTE index
// Fills the specified interface window with index color 0 (black color) // Fills the specified interface window with index color 0 (black color)
void ClearWindow(long winID, bool refresh = true); void ClearWindow(long winID, bool refresh = true);
void PrintFloatText(fo::GameObject* object, const char* text, long colorText, long colorOutline = 207, long font = 101);
// Print text to surface // Print text to surface
void PrintText(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface); void PrintText(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface);
void PrintTextFM(const char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface); void PrintTextFM(const char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface);
+2
View File
@@ -49,6 +49,7 @@ WRAP_WATCOM_FFUNC4(long, register_object_move_to_object, GameObject*, source, Ga
WRAP_WATCOM_FFUNC4(long, register_object_run_to_object, GameObject*, source, GameObject*, target, long, distance, long, delay) WRAP_WATCOM_FFUNC4(long, register_object_run_to_object, GameObject*, source, GameObject*, target, long, distance, long, delay)
WRAP_WATCOM_FFUNC3(long, scr_get_local_var, long, sid, long, varId, long*, value) WRAP_WATCOM_FFUNC3(long, scr_get_local_var, long, sid, long, varId, long*, value)
WRAP_WATCOM_FFUNC3(long, scr_set_local_var, long, sid, long, varId, long, value) WRAP_WATCOM_FFUNC3(long, scr_set_local_var, long, sid, long, varId, long, value)
WRAP_WATCOM_FFUNC6(long, text_object_create, GameObject*, object, const char*, text, long, font, long, colorText, long, colorOutline, BoundRect*, rect)
WRAP_WATCOM_FFUNC3(long, tile_num_in_direction, long, tile, long, rotation,long, distance) WRAP_WATCOM_FFUNC3(long, tile_num_in_direction, long, tile, long, rotation,long, distance)
WRAP_WATCOM_FFUNC8(void, trans_cscale, void*, fromBuff, long, width, long, height, long, fromPitch, void*, toBuff, long, toWidth, long, toHeight, long, toPitch) WRAP_WATCOM_FFUNC8(void, trans_cscale, void*, fromBuff, long, width, long, height, long, fromPitch, void*, toBuff, long, toWidth, long, toHeight, long, toPitch)
WRAP_WATCOM_FFUNC3(void, win_clip, Window*, window, RectList**, rects, void*, buffer) WRAP_WATCOM_FFUNC3(void, win_clip, Window*, window, RectList**, rects, void*, buffer)
@@ -105,6 +106,7 @@ WRAP_WATCOM_FUNC1(void, dbase_close, void*, dbPtr)
WRAP_WATCOM_FUNC1(void, display_print, const char*, msg) // Displays message in main UI console window WRAP_WATCOM_FUNC1(void, display_print, const char*, msg) // Displays message in main UI console window
WRAP_WATCOM_FUNC0(void, display_stats) WRAP_WATCOM_FUNC0(void, display_stats)
WRAP_WATCOM_FUNC2(long, combat_turn, GameObject*, critter, long, isDudeTurn) // Perform combat turn for a given critter WRAP_WATCOM_FUNC2(long, combat_turn, GameObject*, critter, long, isDudeTurn) // Perform combat turn for a given critter
WRAP_WATCOM_FUNC1(long, critter_body_type, GameObject*, critter)
WRAP_WATCOM_FUNC1(long, critter_is_dead, GameObject*, critter) WRAP_WATCOM_FUNC1(long, critter_is_dead, GameObject*, critter)
WRAP_WATCOM_FUNC1(void, EndLoad, DbFile*, file) WRAP_WATCOM_FUNC1(void, EndLoad, DbFile*, file)
// Execute script proc by internal proc number (from script's proc table, basically a sequential number of a procedure as defined in code, starting from 1) // Execute script proc by internal proc number (from script's proc table, basically a sequential number of a procedure as defined in code, starting from 1)
+2 -2
View File
@@ -28,6 +28,7 @@
#define FO_VAR_btncnt 0x43EA1C #define FO_VAR_btncnt 0x43EA1C
#define FO_VAR_carCurrentArea 0x672E68 #define FO_VAR_carCurrentArea 0x672E68
#define FO_VAR_carGasAmount 0x672E6C #define FO_VAR_carGasAmount 0x672E6C
#define FO_VAR_card_old_fid1 0x5709EC
#define FO_VAR_character_points 0x518538 #define FO_VAR_character_points 0x518538
#define FO_VAR_cmap 0x51DF34 #define FO_VAR_cmap 0x51DF34
#define FO_VAR_colorTable 0x6A38D0 #define FO_VAR_colorTable 0x6A38D0
@@ -178,7 +179,6 @@
#define FO_VAR_num_game_global_vars 0x5186C4 #define FO_VAR_num_game_global_vars 0x5186C4
#define FO_VAR_num_map_global_vars 0x519574 #define FO_VAR_num_map_global_vars 0x519574
#define FO_VAR_num_windows 0x6ADF24 #define FO_VAR_num_windows 0x6ADF24
#define FO_VAR_card_old_fid1 0x5709EC
#define FO_VAR_obj_dude 0x6610B8 #define FO_VAR_obj_dude 0x6610B8
#define FO_VAR_obj_seen 0x662445 #define FO_VAR_obj_seen 0x662445
#define FO_VAR_obj_seen_check 0x6610BC #define FO_VAR_obj_seen_check 0x6610BC
@@ -217,8 +217,8 @@
#define FO_VAR_pipmesg 0x664338 #define FO_VAR_pipmesg 0x664338
#define FO_VAR_preload_list_index 0x519640 #define FO_VAR_preload_list_index 0x519640
#define FO_VAR_procTableStrs 0x51C758 // table of procId (from define.h) => procName map #define FO_VAR_procTableStrs 0x51C758 // table of procId (from define.h) => procName map
#define FO_VAR_proto_msg_files 0x6647AC
#define FO_VAR_proto_main_msg_file 0x6647FC #define FO_VAR_proto_main_msg_file 0x6647FC
#define FO_VAR_proto_msg_files 0x6647AC
#define FO_VAR_ptable 0x59E934 #define FO_VAR_ptable 0x59E934
#define FO_VAR_pud 0x59E960 #define FO_VAR_pud 0x59E960
#define FO_VAR_quest_count 0x51C12C #define FO_VAR_quest_count 0x51C12C
+2
View File
@@ -120,6 +120,7 @@ VAR_(master_volume, DWORD)
VAR_(max, DWORD) VAR_(max, DWORD)
VAR_(maxScriptNum, long) VAR_(maxScriptNum, long)
VAR_(Meet_Frank_Horrigan, bool) VAR_(Meet_Frank_Horrigan, bool)
VAR_(mouse_buttons, DWORD)
VAR_(mouse_hotx, DWORD) VAR_(mouse_hotx, DWORD)
VAR_(mouse_hoty, DWORD) VAR_(mouse_hoty, DWORD)
VAR_(mouse_is_hidden, DWORD) VAR_(mouse_is_hidden, DWORD)
@@ -224,6 +225,7 @@ VARA(trait_data, fo::TraitInfo, fo::TRAIT_count)
VAR_(view_page, DWORD) VAR_(view_page, DWORD)
VAR_(wd_obj, DWORD) VAR_(wd_obj, DWORD)
VARA(window, fo::Window*, 50) VARA(window, fo::Window*, 50)
VARA(window_index, DWORD, 50)
VAR_(WhiteColor, BYTE) VAR_(WhiteColor, BYTE)
VAR_(wmAreaInfoList, DWORD) VAR_(wmAreaInfoList, DWORD)
VARC(wmBkWin, DWORD) VARC(wmBkWin, DWORD)
+1 -1
View File
@@ -64,7 +64,7 @@ static long __fastcall op_metarule3_ext(long metafunc, long* args) {
__asm call fo::funcoffs::kb_clear_; __asm call fo::funcoffs::kb_clear_;
break; break;
case MetaruleFunction::EXT_PARTY_ORDER_ATTACK: case MetaruleFunction::EXT_PARTY_ORDER_ATTACK:
PartyControl::MemberOrderAttackPatch(); PartyControl::OrderAttackPatch();
break; break;
default: default:
fo::func::debug_printf("\nOPCODE ERROR: metarule3(%d, ...) - metarule function number does not exist.\n > Script: %s, procedure %s.", fo::func::debug_printf("\nOPCODE ERROR: metarule3(%d, ...) - metarule function number does not exist.\n > Script: %s, procedure %s.",
+30 -12
View File
@@ -18,6 +18,7 @@
#include "..\main.h" #include "..\main.h"
#include "..\FalloutEngine\Fallout2.h" #include "..\FalloutEngine\Fallout2.h"
#include "..\Utils.h"
#include "HookScripts\InventoryHs.h" #include "HookScripts\InventoryHs.h"
#include "Drugs.h" #include "Drugs.h"
#include "HookScripts.h" #include "HookScripts.h"
@@ -627,7 +628,7 @@ static void __declspec(naked) gdControlUpdateInfo_hook() {
} }
static bool partyOrderPickTargetLoop; static bool partyOrderPickTargetLoop;
static char partyOrderAttackMsg[33]; static std::vector<std::string> partyOrderAttackMsg;
// disables the display of the hit chance value when picking a target // disables the display of the hit chance value when picking a target
static void __declspec(naked) gmouse_bk_process_hack() { static void __declspec(naked) gmouse_bk_process_hack() {
@@ -670,22 +671,22 @@ static void __fastcall action_attack_to(long unused, fo::GameObject* partyMember
if (underObject->critter.IsNotDead()) { if (underObject->critter.IsNotDead()) {
outlineColor = underObject->outline; outlineColor = underObject->outline;
if (underObject->critter.combatState) { if (fo::var::combatNumTurns || underObject->critter.combatState) {
underObject->outline = 254 << 8; underObject->outline = 254 << 8; // flashing red
validTarget = underObject; validTarget = underObject;
} else { } else {
underObject->outline = 10 << 8; underObject->outline = 10 << 8; // grey
} }
fo::func::obj_bound(underObject, &rect); fo::func::obj_bound(underObject, &rect);
fo::func::tile_refresh_rect(&rect, fo::var::map_elevation); fo::func::tile_refresh_rect(&rect, fo::var::map_elevation);
targetObject = underObject; targetObject = underObject;
} }
} }
if (validTarget && *(DWORD*)FO_VAR_mouse_buttons == 1) break; // left mouse button if (validTarget && fo::var::mouse_buttons == 1) break; // left mouse button
} while (*(DWORD*)FO_VAR_mouse_buttons != 2 && fo::func::get_input() != 27); // 27 - escape code } while (fo::var::mouse_buttons != 2 && fo::func::get_input() != 27); // 27 - escape code
if (validTarget && *(DWORD*)FO_VAR_mouse_buttons == 1) { if (validTarget && fo::var::mouse_buttons == 1) {
partyMember->critter.whoHitMe = validTarget; partyMember->critter.whoHitMe = validTarget;
validTarget->outline = outlineColor; validTarget->outline = outlineColor;
@@ -693,12 +694,26 @@ static void __fastcall action_attack_to(long unused, fo::GameObject* partyMember
if (cap->disposition == fo::AIpref::disposition::custom) { if (cap->disposition == fo::AIpref::disposition::custom) {
cap->attack_who = (long)fo::AIpref::attack_who::whomever; cap->attack_who = (long)fo::AIpref::attack_who::whomever;
} }
std::strcpy((char*)FO_VAR_attack_str, partyOrderAttackMsg);
fo::func::ai_print_msg(partyMember, 0); // float message // floating text messages
const char* message;
switch (fo::func::critter_body_type(partyMember)) {
case fo::BodyType::Quadruped: // creatures
message = partyOrderAttackMsg[0].c_str();
break;
case fo::BodyType::Robotic:
message = partyOrderAttackMsg[1].c_str();
break;
default: // biped
long max = partyOrderAttackMsg.size() - 1;
long rnd = (max > 2) ? GetRandom(2, max) : 2;
message = partyOrderAttackMsg[rnd].c_str();
}
fo::PrintFloatText(partyMember, message, cap->color, cap->outline_color, cap->font);
} }
partyOrderPickTargetLoop = false; partyOrderPickTargetLoop = false;
//*(DWORD*)FO_VAR_mouse_buttons = 0; fo::var::mouse_buttons = 0;
fo::func::gmouse_set_cursor(0); fo::func::gmouse_set_cursor(0);
fo::func::gmouse_3d_set_mode(1); fo::func::gmouse_3d_set_mode(1);
@@ -739,7 +754,7 @@ static void __declspec(naked) gmouse_handle_event_hook_restore() {
} }
} }
void PartyControl::MemberOrderAttackPatch() { void PartyControl::OrderAttackPatch() {
MakeCall(0x44C4A7, gmouse_handle_event_hack, 2); MakeCall(0x44C4A7, gmouse_handle_event_hack, 2);
HookCall(0x44C75F, gmouse_handle_event_hook); HookCall(0x44C75F, gmouse_handle_event_hook);
HookCall(0x44C69A, gmouse_handle_event_hook_restore); HookCall(0x44C69A, gmouse_handle_event_hook_restore);
@@ -788,7 +803,10 @@ void PartyControl::init() {
dlogr(" Done", DL_INIT); dlogr(" Done", DL_INIT);
} }
Translate("sfall", "PartyOrderAttack", "I'll take care of it.", partyOrderAttackMsg, 33); partyOrderAttackMsg.push_back(std::move(Translate("sfall", "PartyOrderAttackCreature", "::Growl::", 33)));
partyOrderAttackMsg.push_back(std::move(Translate("sfall", "PartyOrderAttackRobot", "::Beep::", 33)));
auto msgs = TranslateList("sfall", "PartyOrderAttackHuman", "I'll take care of it.|Okay, I got it.", '|', 512);
partyOrderAttackMsg.insert(partyOrderAttackMsg.cend(), msgs.cbegin(), msgs.cend());
} }
void PartyControl::exit() { void PartyControl::exit() {
+1 -1
View File
@@ -38,7 +38,7 @@ public:
// Returns pointer to "real" dude, which is different from "dude_obj" when controlling another critter // Returns pointer to "real" dude, which is different from "dude_obj" when controlling another critter
static fo::GameObject* RealDudeObject(); static fo::GameObject* RealDudeObject();
static void MemberOrderAttackPatch(); static void OrderAttackPatch();
}; };
extern bool npcAutoLevelEnabled; extern bool npcAutoLevelEnabled;
+5
View File
@@ -69,4 +69,9 @@ void StrNormalizePath(char* path) {
} while (*(++path) != 0); } while (*(++path) != 0);
} }
// max range 0-32767
long GetRandom(long min, long max) {
return (min + (std::rand() % (max - (min - 1))));
}
} }
+2
View File
@@ -36,4 +36,6 @@ const char* strfind(const char* source, const char* word);
void StrNormalizePath(char* path); void StrNormalizePath(char* path);
long GetRandom(long min, long max);
} }
+5
View File
@@ -149,6 +149,10 @@ std::vector<std::string> GetConfigList(const char* section, const char* setting,
return GetIniList(section, setting, defaultValue, bufSize, ',', ini); return GetIniList(section, setting, defaultValue, bufSize, ',', ini);
} }
std::vector<std::string> TranslateList(const char* section, const char* setting, const char* defaultValue, char delimiter, size_t bufSize) {
return GetIniList(section, setting, defaultValue, bufSize, delimiter, translationIni);
}
std::string Translate(const char* section, const char* setting, const char* defaultValue, size_t bufSize) { std::string Translate(const char* section, const char* setting, const char* defaultValue, size_t bufSize) {
return GetIniString(section, setting, defaultValue, bufSize, translationIni); return GetIniString(section, setting, defaultValue, bufSize, translationIni);
} }
@@ -346,6 +350,7 @@ defaultIni:
} }
} }
} }
std::srand(GetTickCount());
InitModules(); InitModules();
} }
+2
View File
@@ -104,6 +104,8 @@ size_t GetConfigString(const char* section, const char* setting, const char* def
// Parses the comma-separated list from the settings from Sfall configuration INI file. // Parses the comma-separated list from the settings from Sfall configuration INI file.
std::vector<std::string> GetConfigList(const char* section, const char* setting, const char* defaultValue, size_t bufSize = 128); std::vector<std::string> GetConfigList(const char* section, const char* setting, const char* defaultValue, size_t bufSize = 128);
std::vector<std::string> TranslateList(const char* section, const char* setting, const char* defaultValue, char delimiter, size_t bufSize = 256);
// Translates given string using Sfall translation INI file. // Translates given string using Sfall translation INI file.
std::string Translate(const char* section, const char* setting, const char* defaultValue, size_t bufSize = 128); std::string Translate(const char* section, const char* setting, const char* defaultValue, size_t bufSize = 128);