mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Updated the code for party order attack
This commit is contained in:
@@ -12,6 +12,10 @@ PartyACMsg=AC:
|
||||
PartyAddictMsg=Addict
|
||||
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]
|
||||
RaceText=Race
|
||||
StyleText=Style
|
||||
|
||||
@@ -35,7 +35,7 @@ MotionScanner=0
|
||||
;Set to 0 to disable
|
||||
;Set to 1 to control all critters in combat
|
||||
;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
|
||||
;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
|
||||
|
||||
Binary file not shown.
@@ -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
|
||||
void WinFillRect(long winID, long x, long y, long width, long height, BYTE indexColor) {
|
||||
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
|
||||
void PrintText(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface) {
|
||||
DWORD posOffset = yPos * toWidth + xPos;
|
||||
|
||||
@@ -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)
|
||||
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
|
||||
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);
|
||||
|
||||
@@ -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_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_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_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)
|
||||
@@ -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_FUNC0(void, display_stats)
|
||||
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(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)
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define FO_VAR_btncnt 0x43EA1C
|
||||
#define FO_VAR_carCurrentArea 0x672E68
|
||||
#define FO_VAR_carGasAmount 0x672E6C
|
||||
#define FO_VAR_card_old_fid1 0x5709EC
|
||||
#define FO_VAR_character_points 0x518538
|
||||
#define FO_VAR_cmap 0x51DF34
|
||||
#define FO_VAR_colorTable 0x6A38D0
|
||||
@@ -178,7 +179,6 @@
|
||||
#define FO_VAR_num_game_global_vars 0x5186C4
|
||||
#define FO_VAR_num_map_global_vars 0x519574
|
||||
#define FO_VAR_num_windows 0x6ADF24
|
||||
#define FO_VAR_card_old_fid1 0x5709EC
|
||||
#define FO_VAR_obj_dude 0x6610B8
|
||||
#define FO_VAR_obj_seen 0x662445
|
||||
#define FO_VAR_obj_seen_check 0x6610BC
|
||||
@@ -217,8 +217,8 @@
|
||||
#define FO_VAR_pipmesg 0x664338
|
||||
#define FO_VAR_preload_list_index 0x519640
|
||||
#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_msg_files 0x6647AC
|
||||
#define FO_VAR_ptable 0x59E934
|
||||
#define FO_VAR_pud 0x59E960
|
||||
#define FO_VAR_quest_count 0x51C12C
|
||||
|
||||
@@ -120,6 +120,7 @@ VAR_(master_volume, DWORD)
|
||||
VAR_(max, DWORD)
|
||||
VAR_(maxScriptNum, long)
|
||||
VAR_(Meet_Frank_Horrigan, bool)
|
||||
VAR_(mouse_buttons, DWORD)
|
||||
VAR_(mouse_hotx, DWORD)
|
||||
VAR_(mouse_hoty, DWORD)
|
||||
VAR_(mouse_is_hidden, DWORD)
|
||||
@@ -224,6 +225,7 @@ VARA(trait_data, fo::TraitInfo, fo::TRAIT_count)
|
||||
VAR_(view_page, DWORD)
|
||||
VAR_(wd_obj, DWORD)
|
||||
VARA(window, fo::Window*, 50)
|
||||
VARA(window_index, DWORD, 50)
|
||||
VAR_(WhiteColor, BYTE)
|
||||
VAR_(wmAreaInfoList, DWORD)
|
||||
VARC(wmBkWin, DWORD)
|
||||
|
||||
@@ -64,7 +64,7 @@ static long __fastcall op_metarule3_ext(long metafunc, long* args) {
|
||||
__asm call fo::funcoffs::kb_clear_;
|
||||
break;
|
||||
case MetaruleFunction::EXT_PARTY_ORDER_ATTACK:
|
||||
PartyControl::MemberOrderAttackPatch();
|
||||
PartyControl::OrderAttackPatch();
|
||||
break;
|
||||
default:
|
||||
fo::func::debug_printf("\nOPCODE ERROR: metarule3(%d, ...) - metarule function number does not exist.\n > Script: %s, procedure %s.",
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "..\main.h"
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
#include "..\Utils.h"
|
||||
#include "HookScripts\InventoryHs.h"
|
||||
#include "Drugs.h"
|
||||
#include "HookScripts.h"
|
||||
@@ -627,7 +628,7 @@ static void __declspec(naked) gdControlUpdateInfo_hook() {
|
||||
}
|
||||
|
||||
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
|
||||
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()) {
|
||||
outlineColor = underObject->outline;
|
||||
|
||||
if (underObject->critter.combatState) {
|
||||
underObject->outline = 254 << 8;
|
||||
if (fo::var::combatNumTurns || underObject->critter.combatState) {
|
||||
underObject->outline = 254 << 8; // flashing red
|
||||
validTarget = underObject;
|
||||
} else {
|
||||
underObject->outline = 10 << 8;
|
||||
underObject->outline = 10 << 8; // grey
|
||||
}
|
||||
fo::func::obj_bound(underObject, &rect);
|
||||
fo::func::tile_refresh_rect(&rect, fo::var::map_elevation);
|
||||
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;
|
||||
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) {
|
||||
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;
|
||||
//*(DWORD*)FO_VAR_mouse_buttons = 0;
|
||||
fo::var::mouse_buttons = 0;
|
||||
|
||||
fo::func::gmouse_set_cursor(0);
|
||||
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);
|
||||
HookCall(0x44C75F, gmouse_handle_event_hook);
|
||||
HookCall(0x44C69A, gmouse_handle_event_hook_restore);
|
||||
@@ -788,7 +803,10 @@ void PartyControl::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() {
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
// Returns pointer to "real" dude, which is different from "dude_obj" when controlling another critter
|
||||
static fo::GameObject* RealDudeObject();
|
||||
|
||||
static void MemberOrderAttackPatch();
|
||||
static void OrderAttackPatch();
|
||||
};
|
||||
|
||||
extern bool npcAutoLevelEnabled;
|
||||
|
||||
@@ -69,4 +69,9 @@ void StrNormalizePath(char* path) {
|
||||
} while (*(++path) != 0);
|
||||
}
|
||||
|
||||
// max range 0-32767
|
||||
long GetRandom(long min, long max) {
|
||||
return (min + (std::rand() % (max - (min - 1))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,4 +36,6 @@ const char* strfind(const char* source, const char* word);
|
||||
|
||||
void StrNormalizePath(char* path);
|
||||
|
||||
long GetRandom(long min, long max);
|
||||
|
||||
}
|
||||
|
||||
@@ -149,6 +149,10 @@ std::vector<std::string> GetConfigList(const char* section, const char* setting,
|
||||
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) {
|
||||
return GetIniString(section, setting, defaultValue, bufSize, translationIni);
|
||||
}
|
||||
@@ -346,6 +350,7 @@ defaultIni:
|
||||
}
|
||||
}
|
||||
}
|
||||
std::srand(GetTickCount());
|
||||
|
||||
InitModules();
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
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.
|
||||
std::string Translate(const char* section, const char* setting, const char* defaultValue, size_t bufSize = 128);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user