Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Discrepancy in sail damage calculations

A topic by Qwerry, St. created Aug 19, 2021 Views: 331 Replies: 11
Viewing posts 1 to 4
(1 edit)

My goal is to make it possible to repair each fallen mast separately at the shipyard.
At first glance, this is not difficult.
But in practice, it is not possible to correctly calculate the state of the sails (percent) after repair.
=
I make repairs, I count how much damage I removed from sails, 
then I go out to the sea and the engine recalculates ANOTHER percentage of sail condition.
=
Is it possible to add the output of the percentage of sails belonging to a particular mast to scripts?
Or fix the engine recording damage to masts and sails so that there are no discrepancies.

And I cite the results of my research in the script part.
===
1. for the test I shell the ship
2. after shelling, I save all available information about masts and sails:
Engine calculate that ship have 26/100 sails


3. Seems like last digit on reygroup - mastnumber. OK. I just repair damages on broken masts, And result on right side of picture. 
I go out to sea and engine not recalc sail percentage, so... all correct. This holes was on broken masts.
4. I try repair just remaining damage, i.e. holes in the sails, but not restore broken masts.
Sum of damage on this holes: 4.35+12.5+4.63+3.37+15.1 = 40%
26+40 = 66%
Then I go out to sea and engine states that on ship 50/100 sails. NOT 66.

What's wrong? How I can get right percent of repair?

The engine has no concept of .SP or .dmg for sails; that is all handled by the scripts and none of that information resides within the engine.  So if the calculations are done incorrectly, it is the scripts.  The only thing the engine knows about is the number of holes to display, and they are recorded in .hd attribute.  But there is a limit to how many holes can be made, either 10 for triangle sails, or 12 for any other type, so even if damage continues to erode the sail, it cannot put more holes in the sail, even though .SP might continue to decrease.

(2 edits)

I can't agree with this.
I remove from scripts all sails SP recalc and all work even better. All damages correctly update in sea(sail status bar) and in interface tables.
And BattleInterface somehow recalc all damages even not in battle after new damage, but just with ship model loading.
And I don't see in scripts BI code for changing.
-
And on the other hand, if I try to force scripts to set the percentage of the ship's sails to 100% and remove all damage except for broken masts, then, when I go out to sea, the percentage is instantly recalculated by BI depending on the number of broken masts.
-
My question is exactly how I can get this information about how many percent of SP game subtracts for each broken mast.

Upon further review, you are correct that the engine does update .SP attribute.  It calculates .SP as an integer percentage of holes in each sail, relative to the maximum holes allowed for each sail type, as follows:

Triangle maxHole = 10
Other maxHole = 12
Default maxSP = 100
numberholesinsail can never exceed maxHole for sail type

fSP = maxSP * (maxHole - numberholesinsail) / maxHole;

.SP = fSP as integer

The engine does not record the .dmg decimals in the scripts and has no knowledge of those values

OK
Now I realize that you completly didn't understand what I need. 
:(

Well I'm not going to change how the engine calculates and updates Ship.Sail.SP value.

The scripts update that number using .dmg, in function CalculateShipSP.  The engine uses a percentage based on numHoles/maxHoles; both of those are available in the .hc and .mhc attributes of the sails.  You can either change CalculateShipSP to use the same calculation I provided, instead of .dmg, so they will always match.  Or, you can store CalculateShipSP in a different attribute within your scripts (example Ship.Sail.SP2) and use that new attribute everywhere in your scripts when you repair, but then adjust the engines hole count to match your desired SP value that you calculate in the scripts, by using DeleteOneSailHole, to inform the engine to adjust the hole count that will cause the engine to calculate a similar Ship.Sail.SP value when it employs holes/maxHoles.

discrepancies occur when the mast falls.

 all information about how many sails are considered attributed to this fallen mast is not available in the script part

but nevertheless, when mast falls, chr.ship.sp data is instantly updated in BattleInterface and this is not done by the calculateshipsp function.

I need information about what percentage of all ship sails the engine subtracts when the mast falls. and how I can get this persent in scripts. 

just  forget about sail holes. 

(1 edit)

You can't ignore sail holes because that is precisely the measurement the engine is using to set the .SP value and you want to know how to arrive at that figure.  The engine will send each sail through event "DoSailHole" (function ProcessSailDamage()).  During a mast fall, sMastName will not equal "*" and holeCount will equal maxHoleCount. You could possibly record the number of holes for each fallen mast.

An idea that might work in ProcessSailDamage:

if(sMastName!="#")    {
  arSail.mastFall = sMastName;
if(CheckAttribute(chref, "mastFalls." + sMastName))
    chref.mastFalls.(sMastName) = sti(chref.mastFalls.(sMastName)) + holeCount;
else
    chref.mastFalls.(sMastName) = holeCount;
}

With that information, plus the example to arrive at the same engine .SP value below, should hopefully help.

Also, an example to arrive at the same .SP the engine calculates:

float CalculateShipSP(ref chref)
{
    float fSP = GetCharacterShipSP(chref);
    aref arRoot,arGroup,arSail;
    int q,n,i,j;
    int hc = 0;

    makearef(arRoot, chref.ship.sails);
    q = GetAttributesNum(arRoot);
    for(i=0; i<q; i++)
    {
        arGroup = GetAttributeN(arRoot,i);
        n = GetAttributesNum(arGroup);
        for(j=0; j<n; j++)
        {
            arSail = GetAttributeN(arGroup,j);
            if(!CheckAttribute(arSail, "dmg"))
            {
                arSail.dmg = 0.0;
            }
            if(CheckAttribute(arSail, "hc")) //Added for test to accumulate holeCount for each sail
            {
                hc += sti(arSail.hc);
            }
            fSP -= stf(arSail.dmg);
        }
    }

    if(fSP<0.0) fSP = 0.0;
    int st = GetCharacterShipType(GetCharacter(sti(chref.index)));
    ref shref = GetRealShip(st); //This is .maxSP sent to engine in BI_objRetValue.maxSP from procGetSailTextureData() event
    int ssP = sti(chref.ship.sails); //Engine stores cumulative maxHoles in .ship.sails root attribute
    trace("ship.sails " + chref.ship.sails); //Engine stores cumulative maxHoles in .ship.sails root attribute
    trace("hc " + hc); //Accumulated holeCount
    trace("RSP = " + shref.sp); //This is the maxSP the engine will use to figure .SP
    trace("CSP = " + chref.ship.sp); //This is engine recorded .SP
   //ssP - hc is maxHoles - holecount
    trace("SPtest = " + sti(shref.sp) * (ssP - hc) / ssP);
    trace("fSP = " + fSP);
    return fSP;
}

I just tested the following, by calling: CalculateShipSP(pchar);

This was the output in compile.log:

ship.sails 126
hc 9
RSP = 350
CSP = 325
SPtest = 325
fSP = 311.4

CSP is the engine recorded ship.SP
SPTest is figured from realship.SP * (chref.ship.sails - cumulative .hc) / chref.ship.sails

as expected, it didn't work when the mast fell.
=
if (sMastName!="#")    
{
arSail.mastFall = sMastName;
if(CheckAttribute(chref, "mastFalls." + sMastName))
chref.mastFalls.(sMastName) = sti(chref.mastFalls.(sMastName)) + holeCount;
else   chref.mastFalls.(sMastName) = holeCount;
}
code doesn't work at all. Probably the name of the mast is never different from *.
I checked breakage of mast with another ship collision and from shelling. And this section of code has never been executed.

So I don't have any new information for recalculations.

You appear frustrated, but this exchange of information has proved useful.  What I described in my previous post is what I saw when I mentally traced the engine source code logic and that event should be called when a mast falls.  However, given your claim that event does not fire properly, I physically traced the logic during actual execution and found you are correct, that the event does not execute during mast fall.  But it should execute, and I found where the original developers intended it to perform, but they made a mistake, which I was able to correct.

I just updated Maelstrom, and now during a mast fall, the information for the fallen mast, and its relevant sails, will now be sent to this event.

(3 edits)

OK. I'll check tomorrow, but I'm pretty sure it won't work.
Because after mast falling, when recalculating SP - all sails and ropes that were assigned to that mast are considered completely destroyed.
And in the ProcessSailDamage function, I can remember only one last element that was hit.
So, if I don't have information about all sails, rigs, ropes... holes/triangles quantity, then I can't correctly calculate SP.

=

just remind you that you can break the bowsprit against another ship or land
There will be no holes on it, but the ship will lose a significant part of the SP immediately