1. Firaxis celebrates the "Asian American and Pacific Islander Heritage Month", and offers a give-away of a Civ6 anthology copy (5 in total)! For all the details, please check the thread here. .
    Dismiss Notice
  2. We have selected the winners of the Old World random draw and competition. For the winning entries, please check this thread.
    Dismiss Notice

[UNIT] PPQ unit art and questions thread

Discussion in 'Civ4 - Unit Graphics' started by PPQ_Purple, Dec 13, 2017.

  1. PPQ_Purple

    PPQ_Purple Techpriest Engineer

    Joined:
    Oct 11, 2008
    Messages:
    4,704
    Every other animation works, so that is unlikely.

    This said, I am going to try using KMOD as my base for future unit testing. If that works for me than that solves the issue.
     
  2. MightyToad

    MightyToad Sith Lord

    Joined:
    Sep 11, 2015
    Messages:
    477
    The intercept works with the vanilla game, and warlords.
    Vanilla_Intercept.jpg
    Warlords_Intercept.jpg
    BTS_Intercept.jpg

    I remember it worked with BTS without any patches since thats what I played until relatively recently. I only started playing with a patched game and mods in the last two years.
    The mobile sam was a poor choice as an example since it doesn't have anit-air animations. It just uses a ranged strike for everything.
     
  3. f1rpo

    f1rpo plastics

    Joined:
    May 22, 2014
    Messages:
    1,156
    Location:
    Germany
    Aha, that's good to know. I get the same results as you guys then; K-Mod doesn't make a difference.

    Warlords and BtS 3.03 trigger the animation in CvUnit::interceptTest. v3.13 does it in updateAirCombat (not in CvUnit::updateAirStrike as I had first thought). The code fragment that sets up the CvAirMissionDefinition seems to be the same and v3.13 does play an animation, just not the right one. Since the DLL doesn't choose between a proper anti-air animation and a range-strike fallback, it seems likelier to me that the handling of missions in the EXE was changed around the same time and that something went wrong there. Still, restoring the 3.03 logic in the DLL might be worth a try ...
     
  4. f1rpo

    f1rpo plastics

    Joined:
    May 22, 2014
    Messages:
    1,156
    Location:
    Germany
    ...
    Nope, plugging in the WL/3.03 code
    Spoiler :
    Code:
    void CvUnit::fightInterceptor(const CvPlot *pPlot, bool bQuick)
    {
       FAssert(getCombatTimer() == 0);
       /*setAttackPlot(pPlot, true);
       updateAirCombat(bQuick);*/ // BtS 3.19
       // From CvUnit::interceptTest in WL ...
       CvUnit* pInterceptor = bestInterceptor(pPlot);
       gDLL->getEntityIFace()->RemoveUnitFromBattle(pInterceptor);
       CvAirMissionDefinition kAirMission;
       kAirMission.setMissionType(MISSION_AIRSTRIKE);
       kAirMission.setUnit(BATTLE_UNIT_ATTACKER, this);
       kAirMission.setUnit(BATTLE_UNIT_DEFENDER, pInterceptor);
       // (Skip damage calculation)
       kAirMission.setDamage(BATTLE_UNIT_ATTACKER, 80);
       kAirMission.setDamage(BATTLE_UNIT_DEFENDER, 0);
       kAirMission.setPlot(&kPlot);
       kAirMission.setMissionTime(GC.getMissionInfo(MISSION_AIRSTRIKE).getTime() * gDLL->getSecsPerTurn());
       gDLL->getEntityIFace()->AddMission(&kAirMission);
       changeDamage(80, pInterceptor->getOwner());
       pInterceptor->changeDamage(0, getOwner());
       changeMoves(GC.getMOVE_DENOMINATOR());
       pInterceptor->setMadeInterception(true);
    }
    still shows the wrong animation.

    I guess, in order to swap the animations (so that the EXE will pick the right one), one would have to change the .kfm file at runtime, and then get the game to reload it. That doesn't sound like a workable approach.

    There's CvDLLEntity:: PlayAnimation(AnimationTypes, ...), but a comment in CvEnums.h says that
    "AnimationTypes is depreciated [sic], and will be eventually removed.
    BONUSANIMATION_* and IMPROVEMENTANIMATION_* are still used, and will be left.
    "
    Not reassuring; I've no clue how one would obtain the proper animation id.
     
  5. MightyToad

    MightyToad Sith Lord

    Joined:
    Sep 11, 2015
    Messages:
    477
    Another observation is the mobile sam, and the Sam infantry both play the hurta animation (1023). Which is a melee animation and shouldn't be played at all.
    So, changing the KFM to ranged attack (1032) rather than antiair(1042) wouldn't work. Since that's how the mobile Sam works anyway.
    Probably not helpful but eh. :dunno:
     
  6. PPQ_Purple

    PPQ_Purple Techpriest Engineer

    Joined:
    Oct 11, 2008
    Messages:
    4,704
    Print them all out and see
    Does the DLL support some form of manual log printing?

    Also from my professional experience I can tell you that "will be eventually removed." means that it usually still ain't. So it's worth a try. I'd do it my self but I just can't spare the time these days to set up for DLL compilation.
     
    Last edited: May 20, 2021
  7. f1rpo

    f1rpo plastics

    Joined:
    May 22, 2014
    Messages:
    1,156
    Location:
    Germany
    Well, yes ...
    So, to whom it may concern, logging from the DLL:
    Spoiler :
    In CvDLLUtilityIFaceBase.h (global instance: gDLL) there are
    Code:
    void logMsg(const TCHAR* pLogFileName, const TCHAR* pBuf, bool bWriteToConsole=false, bool bTimeStamp=true);
    void messageControlLog(char* s);
    The former requires LoggingEnabled=1 in CivilizationIV.ini, the latter writes to MPLog.txt and requires MessageLog=1.
    But what to iterate over? There are animation paths in XML, but those don't reference a particular animation. I really don't understand how this stuff works once the EXE has determined the animation path and category.
    Spoiler XML for animations :
    Code:
    <AnimationPath>
       <Type>ANIMATIONPATH_AIRSTRIKE</Type>
       <bMissionPath>1</bMissionPath>
       <PathEntry>
           <Category>ANIMCAT_AIRSTRIKE</Category>
           <Operator/>
           <Parameter/>
       </PathEntry>
    </AnimationPath>
    <AnimationCategory>
       <Type>ANIMCAT_AIRSTRIKE</Type>
       <DefaultTo>ANIMCAT_RANGED_STRIKE</DefaultTo>
       <BaseID>42</BaseID>
    </AnimationCategory>
    <AnimationCategory>
       <Type>ANIMCAT_RANGED_STRIKE</Type>
       <DefaultTo>ANIMCAT_MELEE_STRIKE</DefaultTo>
       <BaseID>32</BaseID>
    </AnimationCategory>
    <AnimationCategory>
       <Type>ANIMCAT_MELEE_STRIKE</Type>
       <DefaultTo>ANIMCAT_RANGED_STRIKE</DefaultTo>
       <BaseID>22</BaseID>
    </AnimationCategory>
    Maybe the AnimationTypes aren't even related to units (anymore, if ever); at any rate, the enumerators are no help:
    Spoiler :
    Code:
    // AnimationTypes is depreciated, and will be eventually removed.
    // BONUSANIMATION_* and IMPROVEMENTANIMATION_* are still used, and will be left.
    enum AnimationTypes
    {
       NONE_ANIMATION = -1,   // NO_ANIMATION is used by FirePlace
    
       BONUSANIMATION_UNIMPROVED = 1,
       BONUSANIMATION_NOT_WORKED,
       BONUSANIMATION_WORKED,
    
       IMPROVEMENTANIMATION_OFF = 2,
       IMPROVEMENTANIMATION_ON,
       IMPROVEMENTANIMATION_OFF_EXTRA,
       IMPROVEMENTANIMATION_ON_EXTRA_1,
       IMPROVEMENTANIMATION_ON_EXTRA_2,
       IMPROVEMENTANIMATION_ON_EXTRA_3,
       IMPROVEMENTANIMATION_ON_EXTRA_4,
    };
    :think: What one could try is call PlayAnimation for all ids from 10 (the first 9 being assigned to resources and improvements) up to ... some number and see what the unit model does. For the ANIMCAT_AIRSTRIKE BaseID of 42, the SAM Infantry just freezes for a few seconds. If I try to play them in a loop
    Code:
    for (int i = 10; i < 50; i++)
        gDLL->getEntityIFace()->PlayAnimation(pInterceptor->getEntity(), (AnimationTypes)i);
    I get the same result. So it seems like each call cancels the previous call ... meaning that testing the IDs this way is pretty tedious.
     
  8. MightyToad

    MightyToad Sith Lord

    Joined:
    Sep 11, 2015
    Messages:
    477
    What does "deprecated" mean in code speak?

    From what I can translate into dummy talk; they were planning to merge air animations with ranged attack for some reason? Then broke it. Then left it like that with no documentation on what they did or how to undo it?
     
  9. PPQ_Purple

    PPQ_Purple Techpriest Engineer

    Joined:
    Oct 11, 2008
    Messages:
    4,704
    Deprecated is programmer talk for:
    We don't like this bit for what ever reason so we want to remove it. But because there is stuff that still depends on it and we need time to trim all that out we can't just delete it without breaking a lot of code. So instead of doing that we are going to slowly start changing every single piece of code that uses that stuff to do things differently. And until that is done (if ever) we are going to mark that piece as [deprecated] so that people don't go around adding new references.

    To use a real world example. When the first commercially viable mass production automobile was invented the horse became deprecated. That was in 1908. But people didn't just shoot all the horses and burn down all the stables. Instead the road from deprecated to obsolete took 50 or so years. That's how long it took for the new code to worm its way into every aspect of the simulation and slowly replace all the old. And if you visit places too remote to have gotten a patch yet you can still run into them.

    That is why I suspect that the method still does something and is used somewhere.

    --------------------------
    As for testing, can't you just add a time delay and loop through the animations that way?
     
    Last edited: May 21, 2021
    MightyToad likes this.
  10. f1rpo

    f1rpo plastics

    Joined:
    May 22, 2014
    Messages:
    1,156
    Location:
    Germany
    I've tried playing a new animation at every 16th game update – that should be every 2 seconds. Still, up to id 100, there is no effect on the unit. I've tried 1042, which is the number shown on the Ctrl+U screen (which appears to be part of the EXE); also no effect. I'm not going to investigate the PlayAnimation function further in this manner. I don't think it has the right parameters to be intended for unit animations:
    Code:
    AnimationTypes eAnim, float fSpeed = 1.0f, bool bQueue = false,
    int iLayer = 0, float fStartPct = 0.0f, float fEndPct = 1.0f
    It gets called on a CvUnitEntity instance. Each unit has only one of those, but an animation should affect only one of the three 3D models in a unit. I don't think iLayer is for selecting the model. Oh, but bQueue=true probably would've made my life easier when trying to call the function in a loop.
    The 3.13 release notes do contain a few bullets about air units:
    Doesn't really sound like it would require the code to be restructured; well, the stack combat thing perhaps. I would assume that Firaxis hadn't noticed that they broke the SAM Infantry. That really seems to be the only Vanilla/BtS unit with special anti-air animations.
    Mobile SAM only has that one hurt animation; so I don't suppose that's an error?
    Spoiler MobileSam directory listing :
    Code:
    MobileSam.kfm
    MobileSam.nif
    MobileSAM_128_damage_all.dds
    MobileSAM_128_Gloss.dds
    MobileSAM_256.dds
    MobileSAM_freeze0000.nif
    MobileSAM_freeze0001.nif
    MobileSam_freeze1000.nif
    MobileSam_freeze1031.nif
    MobileSam_FX.nif
    MobileSam_MD_Damage_BodyGeometry_DamBody1.kf
    MobileSam_MD_Damage_BodyGeometry_DamBody2.kf
    MobileSam_MD_Damage_BodyGeometry_DamBody3.kf
    MobileSam_MD_Damage_BodyGeometry_DamBody4.kf
    MobileSam_MD_Damage_TankTexture_DamTexture1.kf
    MobileSam_MD_Damage_TankTexture_DamTexture2.kf
    MobileSam_MD_Damage_TankTexture_DamTexture3.kf
    MobileSam_MD_Damage_TankTexture_DamTexture4.kf
    MobileSam_MD_Heal.kf
    MobileSam_MD_HurtA.kf
    MobileSam_MD_Idle.kf
    MobileSam_MD_RangedDie.kf
    MobileSam_MD_RangedDie_Fade.kf
    MobileSam_MD_RangedFortify.kf
    MobileSam_MD_RangedStrike.kf
    MobileSam_MD_Ranged_Idle.kf
    MobileSam_MD_Run.kf
    MobileSAM_MD_XFadeIn.kf
    MobileSAM_MD_XFadeOut.kf
     
  11. MightyToad

    MightyToad Sith Lord

    Joined:
    Sep 11, 2015
    Messages:
    477
    This is more anecdotal observation. Code stuff is more like magic spells for me. But ranged units don't use the hurt animation during combat (rifleman). This is because they would have to switch to a melee/idle pose from a ranged pose. Bombardment does trigger it. Anyway, that was my line of thought. It has since occurred to me that is wrong. Mech units do use the hurta in combat. However, in this case the mobile sam should use the ranged attack animation for interception.

    For what it is worth I did a test yesterday. I switched all the air combat event numbers for ranged attack for the jetfighter. There is no equivalent for the patrol. All it does is play a sound. I tested it against the mobile sam. Every thing worked identically as before. No effect.
     
  12. PPQ_Purple

    PPQ_Purple Techpriest Engineer

    Joined:
    Oct 11, 2008
    Messages:
    4,704
    If intercept is ranged attack shouldn't patrol be ranged fortify?
     
  13. SaibotLieh

    SaibotLieh Emperor

    Joined:
    Sep 25, 2009
    Messages:
    1,549
    From what I can see, range units have a hurt animation and use them, but only in melee combat. For pure range units, like the rifleman and the mech units, the hurt animation is made for their ranged stance. The ancient and medieval range units change into a melee combat stance and have their hurt animation for that stance. If you have a combat where both units are pure range, no hurt animation will be triggered.
     
  14. MightyToad

    MightyToad Sith Lord

    Joined:
    Sep 11, 2015
    Messages:
    477
    https://i.imgur.com/qkGi3C1.mp4

    I recorded an extremely low quality mp4 of the jetfighter attacking the mobile sam. You see on the last attack it finally is intercepted. The jet plays the hurta animation like it should. The mobile sam also plays its hurta animation. And not its ranged attack like it should.

    Here is the xml for the KFM I tested:
    Code:
    <KFM>
        <Header>;Gamebryo KFM File Version 2.0.0.0b
    </Header>
        <NIF>JetFighter.nif</NIF>
        <Master>MD</Master>
        <Unknown></Unknown>
        <Animations>
            <Animation>
                <Event>1000</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_Idle.kf</File>
            </Animation>
            <Animation>
                <Event>1020</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_FadeIn_Intercept.kf</File>
            </Animation>
            <Animation>
                <Event>1010</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_Run.kf</File>
            </Animation>
            <Animation>
                <Event>1500</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_Damage_Plane_Texture_DamTexture1.kf</File>
            </Animation>
            <Animation>
                <Event>2500</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_Damage_Plane_Texture_DamTexture2.kf</File>
            </Animation>
            <Animation>
                <Event>3500</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_Damage_Plane_Texture_DamTexture3.kf</File>
            </Animation>
            <Animation>
                <Event>4500</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_Damage_Plane_Texture_DamTexture4.kf</File>
            </Animation>
            <Animation>
                <Event>1022</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_Intercept.kf</File>
            </Animation>
            <Animation>
                <Event>1023</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_Hurt.kf</File>
            </Animation>
            <Animation>
                <Event>1024</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_RunDie.kf</File>
            </Animation>
            <Animation>
                <Event>1510</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_Damage_Smoke_DamSmoke1.kf</File>
            </Animation>
            <Animation>
                <Event>2510</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_Damage_Smoke_DamSmoke2.kf</File>
            </Animation>
            <Animation>
                <Event>3510</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_Damage_Smoke_DamSmoke3.kf</File>
            </Animation>
            <Animation>
                <Event>4510</Event>
                <Variation>0</Variation>
                <File>JetFighter_MD_Damage_Smoke_DamSmoke4.kf</File>
            </Animation>
        </Animations>
    </KFM>
    That would follow... Except you see the intercept uses the melee attack. It is the bomb that is the ranged attack. It seems the "Fadein" intercept is the "fortify" (or the equivalent for planes).

    All I can conclude form all this is the problems aren't caused by the event numbers. :badcomp:
     
  15. PPQ_Purple

    PPQ_Purple Techpriest Engineer

    Joined:
    Oct 11, 2008
    Messages:
    4,704
    At this point I have a suggestion. If you guys can make a diagram of the animations, what should be played and what is actually being played we can go and make new KFM files that address that and fix things that way.

    Like for example, if hurta = intercept aircraft we could create a KFM where the intercept animation is tied to hurta instead.
     
  16. MightyToad

    MightyToad Sith Lord

    Joined:
    Sep 11, 2015
    Messages:
    477
    I'm still hopeful f1rpo will pull a rabbit out of his hat. :please:
     
  17. PPQ_Purple

    PPQ_Purple Techpriest Engineer

    Joined:
    Oct 11, 2008
    Messages:
    4,704
    The typical units in CIV use teamcolor.bmp to paint teamcolor onto a unit. Is there a way to paint both teamcolor1 and teamcolor2 onto a unit?
     
  18. MightyToad

    MightyToad Sith Lord

    Joined:
    Sep 11, 2015
    Messages:
    477
    I've tried to figure something out. One interesting thing I discovered is the game doesn't actually use, or care about "TeamColor.bmp".
    Teamcolor.jpg
    I replaced the "TeamColor.bmp" entry with nothing and it still works. I initially tried "playercolor01.tga" since that's what is used for the secondary color.

    I did manage to get the entire unit to be the secondary color with there settings:
    teamcolor2.jpg
    Not really useable. Unless you make a totally seperate part of the mesh with a different material that has this color.
     
  19. PPQ_Purple

    PPQ_Purple Techpriest Engineer

    Joined:
    Oct 11, 2008
    Messages:
    4,704
    I can work with that. I think.
     
  20. PPQ_Purple

    PPQ_Purple Techpriest Engineer

    Joined:
    Oct 11, 2008
    Messages:
    4,704
    These trucks are driving me insane. Like this is the best I've managed to do so far.
    Civ4ScreenShot0016.JPG Civ4ScreenShot0000.JPG

    What do you guys think? Any ideas or comments? I am half way made up to just give up and publish this.

    And yes, there is a long version as well. This one is just easier to screenshot with multiple civs in one frame.
     
    MightyToad and ramzay1945 like this.

Share This Page