Reload Animations and No Fire Through Friendly Units.

Discussion in 'Modding' started by Ftoomsh, Jan 14, 2020.

  1. Ftoomsh

    Ftoomsh Well-Known Member

    Has anybody done any work on reload animations for muskets? I am not an artist or animator so I am just wondering if anyone is trying such things. Also wonderful would be a kneeling front rank.

    I believe my 3 rank firing system (in OCMOD4) would work well with such graphics. As I have said before, I achieve 3 rank fire by lifting friendonline musket-shot (ray) detection in the y-axis just enough that 3 ranks and no more can fire at a target at full range. The smoke puff is not lifted. The system is pretty accurate. Deeper ranks on rising ground (forward slopes) also get to fire. It looks quite realistic except for lack of animations and one technical flaw.

    My system adjusts for the unit-box heights of infantry muskets and cavalry drags. It does not adjust for enemy units coming closer. The declension of the ray leads to a greater angle so the second rank and then the third rank do not fire subsequent volleys as the enemy closes in (which melee units do). This is a flaw but in most engagements the flaw is not noticed in the heat of battle when the lines become ragged (which in turn they do unless on stand ground).

    Theoretically, I could adjust for this flaw by modifying the y-axis lift compared to the range. It's just geometry I guess but I have forgotten most of my high school geometry. I'll see if I can get my mathematician son to give me the required formula.

    If I could add this tweak and then re-introduce General WVPM's range damage system to increase head-shots and/or damage at closer ranges, then I would have a pretty good fire system I think. But without the reload and kneel animations it would never be complete.

    I've been thinking that volley control (holding a volley for closer range) should only be available for formations on stand ground (so not for units not in formation and not for formations marching on attack). However, it would be nice to give the player an option to set a default volley range before the start of the game. Units at idle or on attack would use default volley range. The player should probably be able to set a default volley range to suit his playing style and micro skills (or lack of them). The options would be:

    (1) auto volley at 100% range.
    (2) auto volley at 75% range.
    (3 auto volley at 50% range.

    This last idea is a bit of a dream at this point but I will start work on modifying the y-axis lift and on introducing General WVPM's range damage system to OCMOD4. Now, if only some good elves will start working on reload and kneeling animations. ;)
     
    Loner likes this.
  2. Ftoomsh

    Ftoomsh Well-Known Member

    I've secondarily adjusted the raising of shot height in my Testbed mod to get rank 2 and rank 3 (partially) to fire at close range. If I don't add this second adjustment, the shot ray declines too much as units get close and ranks 2 and 3 stop firing. The second adjustment is very small as the angle in the y plane begins to get very acute. This makes it difficult to make an accurate adjustment at so fine a level. I am still testing it.

    The key line is;

    UnitBoxAdjustment := UnitBoxAdjustment + (UnitBoxAdjustment*((distRatio*distRatio)/1200000));

    You'll see I have to square the distance ratio (TObjProp(pobjprop).weapon.detectradiusmax)/shotdist) and divide it by 1.2 million to get the effect I want without allowing ranks deeper than 3 to fire. Even so, a few odd units fire sporadically from ranks 4 and 5. In a live game this would hardly ever be noticed. On undulating ground one could attribute the firing to the undulating ground. At close range this method gets rank 2 to fire and a few from rank 3. This is better than only rank 1 firing at close range.
    The complete code is:

    var FriendOnLine : Integer;
    FriendOnLine := 0; //Ftoomsh initialises
    var UnitBoxAdjustment: float; // Ftoomsh
    var unittype : Integer = _misc_GetUnitType(goHnd); // Ftoomsh
    UnitBoxAdjustment := 0.93; // Ftoomsh for infantry three rank fire
    if (unittype=gc_result_unittype_cav) then
    UnitBoxAdjustment := 1.0; // Ftoomsh for cavalry three rank fire
    var shotdist : Float = VectorDistance(px, 0, pz, tx, 0, tz);
    var distRatio : Float; // Ftoomsh
    distRatio := (TObjProp(pobjprop).weapon.detectradiusmax{+rbonus})/shotdist; // Ftoomsh
    UnitBoxAdjustment := UnitBoxAdjustment + (UnitBoxAdjustment*((distRatio*distRatio)/1200000)); // Ftoomsh testing not finished yet.
    if (TObjProp(pobjprop).weapon[weapon].weaponid=0) or (not gWeapons[TObjProp(pobjprop).weapon[weapon].weaponid].bcheckfriendonline) then
    FriendOnLine := 0
    else
    FriendOnLine := _misc_IsBuildingInRay(goHnd, px, py+UnitBoxAdjustment, pz, tx, ty+0.5, tz); // Ftoomsh test changes py from 0.5 t0 0.935 for infantry
    if (FriendOnLine = 0) and ((TObjProp(pobjprop).weapon[weapon].weaponid=0) or (gWeapons[TObjProp(pobjprop).weapon[weapon].weaponid].bcheckfriendonline)) then
    FriendOnLine := _misc_IsBuildingInRay2(goHnd, px, py+0.5, pz, tx, ty+0.5, tz);

    Any suggestions on how to refine this method would be much appreciated. It seems to me this method with my current formula is always going to be hard to calibrate accurately. The second adjustment to the unitbox height is so tiny and yet needs to be very accurate.
     
    Last edited: Jan 15, 2020
    Loner likes this.
  3. Awar

    Awar Well-Known Member

    You can achieve a ban on shooting through your units in another way.

    misc.script

    We add a unit, gc_obj_material_body, to the check mask of the obstacle in the path of the shot.

    var mmask : Integer = (1 shl gc_obj_material_body) or (1 shl gc_obj_material_building) or (1 shl gc_obj_material_wood) or (1 shl gc_obj_material_stonewall) or (1 shl gc_obj_material_woodwall);

    We add a friendly unit to the check of buildings, ships.

    if (gObjProp[cid, id].bBuilding) or (gObjProp[cid, id].media=gc_obj_media_water) or ( (enemyplmask and gPlayer[TObj(pObj).pl].myplmask)=0) then

    As a result, only the first rank shoots.
    To prevent the second and third lines from making a shot.
    We add a variable.
    var findunit : Integer = 0;

    Now, if the check found a unit that interferes with shooting
    We change the variable to findunit := findunit+1;

    if GetGameObjectRayCastAABBByHandle(goHnd, x1, tmpy1, z1, x2, tmpy2, z2) then
    begin
    if (gObjProp[cid, id].bBuilding) or (gObjProp[cid, id].media=gc_obj_media_water) or (findunit>1) then
    begin
    Result := goHnd;
    break(MAIN);
    end else
    findunit := findunit+1;


    If an obstacle occurs again during a new check and findunit>1, we cancel the shooting
    So, our squad is firing from the first three rows.
    I need to test everything again. Then this option can be used.
    The full version of the code will be placed later.
    [​IMG]
     
    Loner likes this.
  4. Awar

    Awar Well-Known Member

    Ftoomsh and Foeurdr like this.
  5. Ftoomsh

    Ftoomsh Well-Known Member

    I liked your post Awar because it details a neater and more logical method than my approach. I suspect it also requires less processing so that it will be more optimized. It should cause less calculation load I think. However, one point in favor of my approach (derived from Cavalli originally) is that deeper ranks on a forward slope get to fire too. I had one game in OCMOD4 where two sides of three rank fire came from a square on a hill (forward slope) plus some troops right at the back corner of the square were up on the highest point of the hill and because of the high terrain point and the long weapon range I give, they were firing too! That was a nice effect. They wouldn't have been able to fire on flat ground of course.

    The only question I have is this. How will it perform when other friendly troops are in front of the formation in question? I mean a different friendly formation or possibly unformed friendly troops like hussars galloping in front of the shooting formation. Is the test limited to the formation that is shooting or is the test applied globally as it were and thus affected by all friendly troops in front? I have looked at all the examples above and there doesn't seen to be an example to answer that question.

    I have a lot of game testing experience of what a ban on shooting through friendlies does to general tactics and especially to flank attacks by cavalry. It makes flank attacks much more deadly especially by fast horse. It takes of lot of testing to get the balance you want in this situation. Some players might not like the fact that cavalry flanking becomes so effective. Other players will love it. Offering the option on the ban on shooting through friendlies is a good idea. As I said elsewhere too, I found that a ban on shooting through friendlies really means that longer musket ranges are required so that the units can get in two or three volleys before melee enemy troops close in except of course that hussars close in too fast for the extra volleys. That's okay, that's the hussars' "superpower" but it makes combat balancing even more tricky.

    With cavalry flanking becoming more effective, it would be totally amazing if you could mod the AI to take advantage of that. :)

    I allow three rank fire because I have slowed fire rate. I need to get enough fire into approaching enemy melee troops. On flat ground, inaccuracies in my system (and inaccuracies in how well the ranks line up) mean an occasional fourth ranker fires. I have to tolerate that because if I tweak it the other way, half of the third rank won't fire. Also, due to inaccuracies in calculations in my system it means that when melee enemy get close only two ranks fire. Maybe the third rankers are poorer troops and have fumbled the next reload, lol.
     
    Last edited: Jan 21, 2020
  6. Awar

    Awar Well-Known Member

    The physical model remains the same, only the height of the shot is 0.5
    You can add a little height to get the desired effect.
    Formula for checking the unit along the bullet path
    GetGameObjectRayCastAABBByHandle(goHnd, x1, tmpy1, z1, x2, tmpy2, z2)

    it is applied globally

    Thank you for your advice.
     
    Last edited: Jan 21, 2020
    Ftoomsh likes this.
  7. Ftoomsh

    Ftoomsh Well-Known Member

    All of this means;

    (a) The new State vs Country "ban fire through friendlies" option will be an excellent fire system. :)
    (b) Some options may need to be tied together. Thus "No firing though friendlies" and "Muskets get 50% extra range" will need to be tied together in one option like "Ranked Fire and Longer Ranges".
    (c) At the same time, (b) will work better with reload times being doubled compared to vanilla (in my opinion) .
    (d) Doubling reload times works against (b) and (c), this is true. However, I deal with that by lifting the head-shot value to get more kills.

    Items (b) and (c) would be my ballpark recommendations. Obviously, testing will still be required within your total game balancing model. What you do with reload times and the head-shot chance will depend on your balance testing I think, plus the general playing experience you want to achieve.

    Following on from the above;

    (d) Cavalry needs to be balanced so that it suffers badly (usually) if it gallops straight into a firing line as it will take a lot of fire. But if it flanks the infantry and then "crosses the T", meaning attacking the end of a firing line from a right angle then it will do well and often enough can roll up and destroy the whole firing line. Even attacking the end of a line from 45 degrees the cavalry can do well. This is all true when thin formation firing lines are created. Maybe it's not quite so true when you have deep firing lines of 8 ranks (4x4) but even then you will notice the effect is significant. In OCMOD4, 72 man and 120 man line formations are just 3 ranks. The 196 man line formation is 4 ranks and the 400 man line formation is 6 ranks.

    Another nice attacking strategy is to fix an enemy infantry firing line with your infantry firing line and then attack it with cavalry while it is all aiming at your infantry.

    In turn, all of these effects mean cavalry handling by the player (and AI) becomes more challenging. Quite possibly players will find it best to employ cavalry at the flanks of the infantry army in most cases. There will be tactical exceptions though.
     
    Last edited: Jan 21, 2020
    Awar likes this.
  8. Ftoomsh

    Ftoomsh Well-Known Member

    More thoughts. During ongoing balancing of OCMOD4, and its ban on firing through friendlies, I have found a number of interesting effects.

    (a) Long lines deliver more fire. This is obvious and to be expected.
    (b) A big square delivers better fire power than a column, usually.
    (c) Columns (called "square" in formations.cfg) deliver the most concentrated bayonet power.
    (d Squares (called "Kare" in formations.cfg) don't concentrate bayonet power as well as columns.
    (e) Bayonets do better when troops are moving, not on stand ground, unless the stand ground bonuses are very large. (Hence squares need a large stand ground bonus which leads to a possible player exploit. See note 1 below.)

    Points (c), (d) and (e) occur because moving infantry can really concentrate and thus they concentrate all their bayonets in a very small space. Lines get badly defeated by cavalry attacking from their flank (crossing the T) and this effect is exaggerated in OCMOD4 because of the very long, thin line formations I use. This effect will be less exaggerated in State vs Country if it keeps its current deeper line formations. I have found that if a line in OCMOD4 is threatened by melee cavalry from the flank (and it has no cavalry support of its own) it should immediately be set to column and allowed to concentrate. Even if it only gets half concentrated by the time the enemy cavalry charge arrives it is still a lot better off. It still takes a lot of casualties but it delivers more casualties to the enemy cavalry at the same time.

    Note 1. Exploiting stand ground bonus for the true square (Kare). If the player clicks to change from line to true square and then hits Ctrl-S to stop the formation and then hits stand ground command, then when the stand ground progress bar completes the formation which is still much more a line than a square gets the square hold ground bonus. This problem is worsened in OCMOD4 because I made stand ground progress very quick. Perhaps I need to make it slow again. After all, charging cavalry gets in range quickly and then the stand ground progress bar won't complete. Another fix might be to not permit stand ground to be an option after a Ctrl-S on a formation. Easier might be just removing Ctrl-S for formations. I note these issues because they might affect State vs Country balancing but in general the deeper lines (more ranks) of SvC line formations will reduce these kind of problems a bit anyway. But deeper lines also make it difficult to deliver a wide front of fire with all the units firing. There are pros and cons (arguments for and arguments against). It is worth keeping a watch on these effects when balancing.
     
    Last edited: Jan 21, 2020
    Awar likes this.
  9. Awar

    Awar Well-Known Member

    Ftoomsh, note the file
    \data\objects\ref\refunit.prop

    collisionmeshproperty : section.begin
    .........
    CustomBoundingAABBMin : struct.begin
    X = -0.25
    Y = -0.1
    Z = -0.25
    struct.end
    CustomBoundingAABBMax : struct.begin
    X = 0.25
    Y = 0.90
    Z = 0.25
    struct.end

    Dimensions of the unit X and Y directly depend on the shooting
    Y = 0.90
    Is this the height of the unit when firing?
     
  10. Ftoomsh

    Ftoomsh Well-Known Member

    Awar,

    Yes, the infantry man is 0.90 high. That's the height of his unit box. The standard rays check is 0.5 to 0.5 which is like a shot from waist to waist.

    I originally got my lift of the shot height correct simply by experimentation. I kept raising it until it worked the way I wanted it to for infantry. The value I settled on for infantry 3 rank fire (at long range) was 0.93. I had no real idea why that worked until Ebel told me in a conversation that the custom bounding box for infantry had a Y height of 0.90 as you say. Then it became obvious to me why my lift of 0.93 worked. In the same conversation she showed me that the Y height for cavalry was 0.95. My experiments showed that a Y lift of 1.00 was fairly good for cavalry. Their unit box is longer (horses are long) so that might be why they need a higher y lift.

    I do not change the units' true heights (custom bounding) of course. These remain constant at 0.90 for infantry and 0.95 for cavalry. I just change the height the ray check originates from. This is why I use the code:

    var FriendOnLine : Integer;
    FriendOnLine := 0; //Ftoomsh initialises
    var UnitBoxAdjustment: float; // Ftoomsh
    var unittype : Integer = _misc_GetUnitType(goHnd); // Ftoomsh
    UnitBoxAdjustment := 0.93; // Ftoomsh for infantry three rank fire
    if (unittype=gc_result_unittype_cav) then
    UnitBoxAdjustment := 1.0; // Ftoomsh for cavalry three rank fire
    var shotdist : Float = VectorDistance(px, 0, pz, tx, 0, tz);
    var distRatio : Float; // Ftoomsh
    distRatio := (TObjProp(pobjprop).weapon.detectradiusmax)/shotdist; // Ftoomsh
    UnitBoxAdjustment := UnitBoxAdjustment + (UnitBoxAdjustment*((distRatio*distRatio)/1200000)); // Ftoomsh kludge
    if (TObjProp(pobjprop).weapon[weapon].weaponid=0) or (not gWeapons[TObjProp(pobjprop).weapon[weapon].weaponid].bcheckfriendonline) then
    FriendOnLine := 0
    else
    FriendOnLine := _misc_IsBuildingInRay(goHnd, px, py+UnitBoxAdjustment, pz, tx, ty+0.5, tz); // Ftoomsh test changes py from 0.5 to 0.935 for infantry
    if (FriendOnLine = 0) and ((TObjProp(pobjprop).weapon[weapon].weaponid=0) or (gWeapons[TObjProp(pobjprop).weapon[weapon].weaponid].bcheckfriendonline)) then
    FriendOnLine := _misc_IsBuildingInRay2(goHnd, px, py+0.5, pz, tx, ty+0.5, tz);



    You will notice I adjust the firing height based on how close the enemy is. At close range, the ray check origin gets a bit higher as per the rough formula:
    UnitBoxAdjustment := UnitBoxAdjustment + (UnitBoxAdjustment*((distRatio*distRatio)/1200000));

    This allows a 2nd rank shot to clear the front rank unit box at closer range (because the ray declines as the enemy get closer). It's straight geometry of course. The final effect in testing and in-game is that at full range 3 ranks fire (plus the odd extra fourth ranker because the formula isn't perfect). But at close range only two ranks get to fire plus the odd third ranker. I am happy enough with that effect. Of course, the musket shot graphics (spark and puff of smoke) are not lifted so to the player it all looks perfectly good, like a normal shot.

    My musket weapon is set up differently from yours, I think, so I apply the two tests IsBuildingInRay and IsBuildingInRay2 with different logic. You will notice I don't bother lifting the Y origin of the ray for the test IsBuildingInRay2. It's not necessary. It's always going to block the shot if a building or stone wall is in the way. For the time being I have taken wooden fences out of my mod so I don't have to test for them.

    It sounds like you are going to combine the two methods (your rank counting and my ray lift) in some manner. That might work better than either single method on its own. I await what you do with great interest. I am sure you can make the final result more accurate than my test.

    Footnote:

    Volley fire was achieved in various ways in the 16th and 17th C according to sources. Here are two key methods:

    "I have discovered … a method of getting the musketeers and soldiers armed with arquebuses not only to keep firing very well but to do it effectively in battle order … in the following manner: as soon as the first rank has fired together, then by the drill [they have learned] they will march to the back. The second rank, either marching forward or standing still, [will next] fire together [and] then march to the back. After that, the third and following ranks will do the same. Thus before the last ranks have fired, the first will have reloaded." - William Louis, Count of Nassau-Dillenberg in a letter to his cousin Maurice in 1594.


    A later method in the 18th C was;

    "After the command to make ready was given, the first rank knelt down, whilst the third rank stepped slightly to the right, in order to level their muskets past the men in front of them." - Wikipedia.

    Sometimes double ranks and triple ranks would fire sequentially along the line squad by squad so that fire was always coming from some section along the line. I imagine this was useful especially if the enemy line was advancing on the oblique or had lost shape and was advancing unevenly. The squads closest to the advancing enemy would fire first at optimum range and then the fire would ripple along the line on officers' orders. That's a bit of a guess on my part though.

    My favorite movie battle scene. It's from "War and Peace" - Sergei Bondarchuk.

     
    Last edited: Jan 23, 2020
    Awar likes this.
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice