|
-
G1 AI_StartState - hardcoded ZS states for Player?
Hello folks, (NicoDE!)
I've been trying to 'import' ZS_WhirlWind from G2A to G1 - I have everything setup - and everything works ok when I am using this on NPC. However I cannot use AI_StartState (self, ZS_WhirlWind, 1, ""); on hero.
When I change name ZS_WhirlWind to ZS_MagicSleep (and disable original one) I can run this function on hero !
I was searching for anything that would give me a hint on what is different with ZS_MagicSleep and found out that this state function is mentioned directly in Gothic.exe along with others: ZS_MAGICFEAR, ZS_MAGICSLEEP, ZS_PYRO, ZS_ZAPPED, ZS_SHORTZAPPED, ZS_MAGICFREEZE, ZS_ASSESSSTOPMAGIC, ZS_ASSESSMAGIC.
So I experimented now and changed name of state ZS_WhirlWind to ZS_MagicFear (not used in G1) and again I can run this on hero !
This tells me that states names are restricted and most likely hardcoded - and I can use only these mentioned above on hero.
Is there any way to change this - can I somehow avoid this restriction of ZS_ states when using them with hero instance?
-
As you already found out, the allowed states for the player are hard-coded.
G1
Code:
const int NPC_PLAYER_STATES_ENABLED_MAX = 8;
const zSTRING strPlayerStatesEnabled[NPC_PLAYER_STATES_ENABLED_MAX] = {
"ZS_ASSESSMAGIC",
"ZS_ASSESSSTOPMAGIC",
"ZS_MAGICFREEZE",
"ZS_SHORTZAPPED",
"ZS_ZAPPED",
"ZS_PYRO",
"ZS_MAGICSLEEP",
"ZS_MAGICFEAR"
};
static
int playerStatesEnabled[NPC_PLAYER_STATES_ENABLED_MAX] = {
-1, // [0] checked in oCNpc_States constructor to initialize all others
-1,
-1,
-1,
-1,
-1
// 0
// 0
};
G2A
Code:
const int NPC_PLAYER_STATES_ENABLED_MAX = 9;
const zSTRING strPlayerStatesEnabled[NPC_PLAYER_STATES_ENABLED_MAX] = {
"ZS_ASSESSMAGIC",
"ZS_ASSESSSTOPMAGIC",
"ZS_MAGICFREEZE",
"ZS_WHIRLWIND",
"ZS_SHORTZAPPED",
"ZS_ZAPPED",
"ZS_PYRO",
"ZS_MAGICSLEEP"
// NULL
};
static int playerStatesEnabled[NPC_PLAYER_STATES_ENABLED_MAX] = {
-1, // [0] checked in oCNpc_States constructor to initialize all others
-1,
-1,
-1,
-1,
-1
// 0
// 0
// 0
};
So you might change/hack the symbol indices in the playerStatesEnabled array at runtime. Extending the list would require more effort...
"Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- Connor
-
You don't have any of those addresses which should be manipulated handy, do you?
-
Addresses from http://bendlins.de/nico/gothic/misc/dbg/1.08k_mod/
Code:
.data:0085081C ; int playerStatesEnabled[8]
.data:0085081C playerStatesEnabled dd 6 dup(-1), 2 dup(0)
.data:0085081C ; DATA XREF: oCNpc_States::oCNpc_States(void):loc_006C49FFr
.data:0085081C ; oCNpc_States::oCNpc_States(void)+257o
.data:0085081C ; oCNpc_States::CanPlayerUseAIState(void)+36o
.data:0085081C ; oCNpc_States::DoAIState(void)+2A3o
.data:0085083C `string' db 'ZS_MAGICFEAR',0 ; DATA XREF: strPlayerStatesEnabled__init+69o
.data:0085083C ; oCNpc_States::CanPlayerUseAIState(void)+47o
.data:0085083C ; oCNpc_States::DoAIState(void)+2B3o
.data:00850849 align 4
.data:0085084C `string' db 'ZS_MAGICSLEEP',0 ; DATA XREF: strPlayerStatesEnabled__init+5Ao
.data:0085085A align 4
.data:0085085C `string' db 'ZS_PYRO',0 ; DATA XREF: strPlayerStatesEnabled__init+4Bo
.data:00850864 `string' db 'ZS_ZAPPED',0 ; DATA XREF: strPlayerStatesEnabled__init+3Co
.data:0085086E align 4
.data:00850870 `string' db 'ZS_SHORTZAPPED',0 ; DATA XREF: strPlayerStatesEnabled__init+2Do
.data:0085087F align 4
.data:00850880 `string' db 'ZS_MAGICFREEZE',0 ; DATA XREF: strPlayerStatesEnabled__init+1Eo
.data:0085088F align 4
.data:00850890 `string' db 'ZS_ASSESSSTOPMAGIC',0
.data:00850890 ; DATA XREF: strPlayerStatesEnabled__init+Fo
.data:008508A3 align 4
.data:008508A4 `string' db 'ZS_ASSESSMAGIC',0 ; DATA XREF: strPlayerStatesEnabled__inito
.data:008508B3 align 4
Code:
.data:008DC0E0 ; zSTRING strPlayerStatesEnabled[8]
.data:008DC0E0 strPlayerStatesEnabled zSTRING 8 dup(<?>)
.data:008DC0E0 ; DATA XREF: strPlayerStatesEnabled__init+5o
.data:008DC0E0 ; strPlayerStatesEnabled__exit+9o
.data:008DC0E0 ; oCNpc_States::oCNpc_States(void)+25Co
"Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- Connor
Geändert von NicoDE (08.02.2019 um 08:52 Uhr)
-
G1 control player zs_states
Thank you NicoDe!
I was unfortunatelly not able to use potential hidden in these addresses. However I found an alternative way:
I have hooked _HOOK_NPC_STATES_DOAISTATE - and here I am checking npc.state_nextState_name,
if (npc.state_nextState_name == "ZS_WHIRLWIND") I will repoint npc.state_nextState_index to ZS_ASSESSMAGIC.
In ZS_ASSESSMAGIC I will call intended function, which is still stored in npc.state_nextState_name and will overwrite npc.state_nextState_loop & npc.state_nextState_end to match npc.state_nextState_name function.
Code:
//Cannibalized from Ikarus 1.2.1 oCNPC class definition:
class oCNpc_States {
var int state_vfptr; // 0x0470
var string state_name; // 0x0474 zSTRING
var int state_npc; // 0x0488 oCNpc*
// TNpcAIState curState {
var int state_curState_index; // 0x048C int
var int state_curState_loop; // 0x0490 int
var int state_curState_end; // 0x0494 int
var int state_curState_timeBehaviour; // 0x0498 int
var int state_curState_restTime; // 0x049C zREAL
var int state_curState_phase; // 0x04A0 int
var int state_curState_valid; // 0x04A4 zBOOL
var string state_curState_name; // 0x04A8 zSTRING
var int state_curState_stateTime; // 0x04BC zREAL
var int state_curState_prgIndex; // 0x04C0 int
var int state_curState_isRtnState; // 0x04C4 zBOOL
// }
// TNpcAIState nextState {
var int state_nextState_index; // 0x04C8 int
var int state_nextState_loop; // 0x04CC int
var int state_nextState_end; // 0x04D0 int
var int state_nextState_timeBehaviour; // 0x04D4 int
var int state_nextState_restTime; // 0x04D8 zREAL
var int state_nextState_phase; // 0x04DC int
var int state_nextState_valid; // 0x04E0 zBOOL
var string state_nextState_name; // 0x04E4 zSTRING
var int state_nextState_stateTime; // 0x04F8 zREAL
var int state_nextState_prgIndex; // 0x04FC int
var int state_nextState_isRtnState; // 0x0500 zBOOL
};
/*
ZS_ASSESSMAGIC is allowed state for player, but it is not defined in G1 -> we can reserve it for ourselves
When this function will be called by _HOOK_NPC_STATES_DOAISTATE on player - it will
call npc.state_nextState_name (intended function)
overwrite npc.state_nextState_loop with npc.state_nextState_name_LOOP
overwrite npc.state_nextState_end with npc.state_nextState_name_END
*/
FUNC VOID ZS_ASSESSMAGIC ()
{
var oCNPC npc;
npc = Hlp_GetNPC (self);
//Disable further calls
npc.state_nextState_index = -1;
//Call npc.state_nextState_name (ZS_WHIRLWIND or others, if specified in _HOOK_NPC_STATES_DOAISTATE)
MEM_CallByString (npc.state_nextState_name);
//Overwrite npc.state_nextState_loop with npc.state_nextState_name_LOOP
var string fNameLoop;
fNameLoop = ConcatStrings (npc.state_nextState_name, "_LOOP");
npc.state_nextState_loop = MEM_FindParserSymbol (fNameLoop);
//Overwrite npc.state_nextState_end with npc.state_nextState_name_END
var string fNameEnd;
fNameEnd = ConcatStrings (npc.state_nextState_name, "_END");
npc.state_nextState_end = MEM_FindParserSymbol (fNameEnd);
};
FUNC INT ZS_ASSESSMAGIC_Loop () {};
FUNC VOID ZS_ASSESSMAGIC_End () {};
//006C5C60 .text Debug data ?DoAIState@oCNpc_States@@QAEHXZ
const int oCNpc_States__DoAIState_G1 = 7101536;
//0x0076D1A0 public: int __thiscall oCNpc_States::DoAIState(void)
const int oCNpc_States__DoAIState_G2 = 7786912;
FUNC VOID _HOOK_NPC_STATES_DOAISTATE ()
{
var oCNpc_States state;
state = _^ (ECX);
var oCNPC npc;
npc = _^ (state.state_npc);
if (NPC_IsPlayer (npc))
{
if (state.state_nextState_index != 0)
&& (state.state_nextState_index != -1)
{
//Here you can specify what states are allowed for player
if (Hlp_StrCmp (state.state_nextState_name, "ZS_WHIRLWIND"))
{
//Overwrite state_nextState_index - this will point to function ZS_ASSESSMAGIC
//npc.state_nextState_name will still contain string "ZS_WHIRLWIND")
npc.state_nextState_index = MEM_FindParserSymbol ("ZS_ASSESSMAGIC");
};
};
};
};
Hook:
Code:
HookEngine (MEMINT_SwitchG1G2 (oCNpc_States__DoAIState_G1, oCNpc_States__DoAIState_G2), 6, "_HOOK_NPC_STATES_DOAISTATE");
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
|
|