diff --git a/_work/data/Scripts/Content/freeAim/_intern/init.d b/_work/data/Scripts/Content/freeAim/_intern/init.d index d33f8ea..a2a648f 100644 --- a/_work/data/Scripts/Content/freeAim/_intern/init.d +++ b/_work/data/Scripts/Content/freeAim/_intern/init.d @@ -42,6 +42,7 @@ func void freeAimInitFeatureFreeAiming() { HookEngineF(oCAIHuman__BowMode_696296, 5, freeAimAnimation); // Interpolate aiming animation HookEngineF(oCAIArrow__SetupAIVob, 6, freeAimSetupProjectile); // Setup projectile trajectory (shooting) HookEngineF(oCAIArrowBase__DoAI_6A06D8, 6, freeAimResetGravity); // Reset gravity of projectile on collision + // HookEngineF(oCAIHuman__BowMode_6962A4, 6, freeAimRangedStrafing); // Strafing while aiming. NOT WORKING // Gothic 2 controls if (GOTHIC_BASE_VERSION == 2) { diff --git a/_work/data/Scripts/Content/freeAim/_intern/offsets_G2.d b/_work/data/Scripts/Content/freeAim/_intern/offsets_G2.d index 6a44f83..73a9748 100644 --- a/_work/data/Scripts/Content/freeAim/_intern/offsets_G2.d +++ b/_work/data/Scripts/Content/freeAim/_intern/offsets_G2.d @@ -61,10 +61,12 @@ const int projectileDeflectOffNpcAddr = 6949734; //0x6A0B66 const int oCAIHuman__BowMode_695F2B = 6905643; //0x695F2B const int oCAIHuman__BowMode_6962F2 = 6906610; //0x6962F2 const int oCAIHuman__PC_ActionMove_69A0BB = 6922427; //0x69A0BB +const int oCAIHuman__PC_Strafe = 6925440; //0x69AC80 const int zCWorld__AdvanceClock = 6447328; //0x6260E0 // Hook length 10 const int cGameManager__ApplySomeSettings_rtn = 4362867; //0x429273 // Hook length 5 const int oCAIHuman__BowMode = 6905600; //0x695F00 // Hook length 6 const int oCAIHuman__BowMode_696296 = 6906518; //0x696296 // Hook length 5 +const int oCAIHuman__BowMode_6962A4 = 6906532; //0x6962A4 // Hook length 6 const int oCAIHuman__BowMode_69633B = 6906683; //0x69633B // Hook length 6 const int oCAIArrow__SetupAIVob = 6951136; //0x6A10E0 // Hook length 6 const int oCAIArrow__CanThisCollideWith = 6952080; //0x6A1490 // Hook length 7 diff --git a/_work/data/Scripts/Content/freeAim/_intern/rangedAiming.d b/_work/data/Scripts/Content/freeAim/_intern/rangedAiming.d index b725d15..193b811 100644 --- a/_work/data/Scripts/Content/freeAim/_intern/rangedAiming.d +++ b/_work/data/Scripts/Content/freeAim/_intern/rangedAiming.d @@ -112,3 +112,43 @@ func void freeAimAnimation() { MEM_WriteInt(ESP+20, FLOATHALF); // First argument: Always aim at center (azimuth) (esp+44h-30h) ECX = angleY; // Second argument: New elevation }; + + +/* + * Enable strafing while aiming. This function hooks oCAIHuman::BowMode() at an offset, where the player is aiming. + * + * CAUTION: This is just an attempt or more of a test to realize strafing. This is not ready to be used, and thus its + * hook is not initialized (commented out int _intern\init.d). So far it also only works with Gothic 2 controls, as + * there is another key press condition in oCAIHuman::PC_Strafe(), preventing strafing on action key press. + * This function has been deliberately left in the scripts to inspire, in case somebody wants to finish this feature. + * + * Here is an explanation of this attempt: + * Strafing can simply be injected into oCAIHuman::BowMode, resulting in fully functioning strafing while aiming. Of + * course, the bow is not maintaining the aiming animation, and when stopping to strafe the bow is drawn again. + * What can be done now, is to create an animation, in which the bow is drawn and centered (that is where the bow always + * is while aiming) while strafing and figuring out a way to prevent redrawing the bow after strafing. The latter is not + * guaranteed to work. + */ +func void freeAimRangedStrafing() { + var oCNpc her; her = Hlp_GetNpc(hero); + + // Call strafing function. It handles button presses and directions + const int call = 0; + var int herAIPtr; herAIPtr = her.human_ai; + var int zero; zero = 1; + var int ret; + if (CALL_Begin(call)) { + CALL_IntParam(_@(zero)); // Argument ignored by function + CALL_PutRetValTo(_@(ret)); + CALL__thiscall(_@(herAIPtr), oCAIHuman__PC_Strafe); + call = CALL_End(); + }; + + // The return value specifies whether the player is currently strafing or not + if (ret) { + MEM_Info("Strafing now"); // Debug + + // Exchange animation or something like that (actually needs to be done before starting to strafe) + // her.anictrl._t_strafel = aniID; // zTModelAniID* of new animation + }; +};