diff --git a/_work/data/Scripts/Content/GFA/_intern/collision.d b/_work/data/Scripts/Content/GFA/_intern/collision.d index f886d8d..d3d0956 100644 --- a/_work/data/Scripts/Content/GFA/_intern/collision.d +++ b/_work/data/Scripts/Content/GFA/_intern/collision.d @@ -473,6 +473,35 @@ func void GFA_CC_ProjectileCollisionWithWorld() { }; +/* + * Complete the half-implemented feature in Gothic 1 of fading out the visibility of a projectile before removing it. + * This function hooks oCAIArrowBase::DoAI(), if the collectable feature is not enabled. + */ +func void GFA_CC_FadeProjectileVisibility() { + // Check if AI was already removed + var int destroyed; destroyed = MEM_ReadInt(EDI); + if (destroyed) { + return; + }; + + // Check validity of projectile + var int projectilePtr; projectilePtr = EBX; // oCItem* + if (!projectilePtr) { + return; + }; + var zCVob projectile; projectile = _^(projectilePtr); + + // Check if the projectile stopped moving + if (!(projectile.bitfield[0] & zCVob_bitfield0_physicsEnabled)) { + var int arrowAI; arrowAI = ESI; // oCAIArrow* + var int lifeTime; lifeTime = MEM_ReadInt(arrowAI+oCAIArrowBase_lifeTime_offset); + if (lifeTime == -1082130432) { // -1 + MEM_WriteInt(arrowAI+oCAIArrowBase_lifeTime_offset, FLOATONE); + }; + }; +}; + + /* * Disable collision of projectiles with NPCs once the projectiles have bounced off of another surface. This function is * called from GFA_ExtendCollisionCheck() only if GFA_COLL_PRIOR_NPC == -1. diff --git a/_work/data/Scripts/Content/GFA/_intern/init.d b/_work/data/Scripts/Content/GFA/_intern/init.d index c0290cc..02ce2d1 100644 --- a/_work/data/Scripts/Content/GFA/_intern/init.d +++ b/_work/data/Scripts/Content/GFA/_intern/init.d @@ -173,6 +173,9 @@ func void GFA_InitFeatureCustomCollisions() { HookEngineF(oCAIArrow__ReportCollisionToAI_hitChc, 6, GFA_CC_ProjectileCollisionWithNpc); // Hit reg/coll on NPCs if (GOTHIC_BASE_VERSION == 1) { writeNOP(oCAIArrow__ReportCollisionToAI_destroyPrj, 7); // Disable destroying of projectiles + if (!(GFA_Flags & GFA_REUSE_PROJECTILES)) { + HookEngineF(oCAIArrow__DoAI_rtn, 6, GFA_CC_FadeProjectileVisibility); // Implement fading like in Gothic 2 + }; HookEngineF(oCAIArrow__ReportCollisionToAI_collAll, 8, GFA_CC_ProjectileCollisionWithWorld); // Collision world MemoryProtectionOverride(oCAIArrow__ReportCollisionToAI_keepPlyStrp, 2); // Keep poly strip after coll MEM_WriteByte(oCAIArrow__ReportCollisionToAI_keepPlyStrp, /*EB*/ 235); // jmp