• New Horizons on Maelstrom
    Maelstrom New Horizons


    Visit our website www.piratehorizons.com to quickly find download links for the newest versions of our New Horizons mods Beyond New Horizons and Maelstrom New Horizons!

Fixed Possible to Lose LoM if Relation < 0

Pieter Boelen

Navigation Officer
Administrator
Storm Modder
Hearts of Oak Donator
As mentioned in Assassin vs. Version 4.1 | PiratesAhoy!, @Grey Roger lost his Spanish LoM when attacking what should have been a valid target.
The reason was because the nation relation at the time was -45 for storyline reasons, which is of course an uncommon (and normally impossible) situation.
A simple and perfectly feasible work-around is to simply not have the relation lower than 0 if you have a LoM.

I still want to double-check the related code though to allow this to work even WITH a relation of -45.
If I recall, I've had a similar unintentional effect in the past. If it is the same time this, it might be a quick fix.
 
I think this is the correct savegame. Try it. If it is the right one then you're on the worldmap, and in front of you is a battle in progress, Spanish merchants against Portuguese merchants. Join in, load up with grapeshot, attack and board a Portuguese ship, and see what happens.
 

Attachments

  • -=Player=- Open Sea December 1st, 1662.zip
    723.1 KB · Views: 129
I think this is the correct savegame. Try it. If it is the right one then you're on the worldmap, and in front of you is a battle in progress, Spanish merchants against Portuguese merchants. Join in, load up with grapeshot, attack and board a Portuguese ship, and see what happens.
Thanks! :cheers

I was just going to be lazy and "fake" the relation effects through console. :oops:
 
I think I may have found it. Look at "nations.c", specifically the definition of 'ChangeRMRelation':
Code:
float ChangeRMRelation(ref char, int iNation, float relch)
{
   float relorg = GetRMRelation(char, iNation);
   if (relch > 0.0 && !IsInServiceOf(iNation))         // If GAINING points when not in their service
   {
     relch += relorg;
     if (relch >= REL_NEUTRAL)   relch = REL_NEUTRAL;   // Prevent becoming MORE than Friendly
     if (relch < relorg)       relch = relorg;       // But don't ever LOSE points while you're meant to be gaining them!
   }
   else                           // Losing points OR in the service
   {
     relch += relorg;                   // Simple behaviour, no extra checks
   }
   SetRMRelation(char, iNation, relch);
   if (IsMainCharacter(char) && relch < 0) LooseLetterOfMarque(iNation); // KK

   //log new relation
   if (iRealismMode == 0 && LogsToggle == LOG_VERBOSE) Log_SetStringToLog(XI_ConvertString(GetNationNameByType(iNation))+ " - " + TranslateString("",GetRMRelationName(char, iNation)) + "."); // KK
   return relch;
}

And in particular, that line 'if (IsMainCharacter(char) && relch < 0) LooseLetterOfMarque(iNation);'. This ties in with what I observed - I gained a couple of points with Spain (started off at -45, ended up at -43) and lost the LoM because my relation after the change was negative. The line is probably supposed to take your LoM if you attacked something which you weren't supposed to attack, causing your relation to drop below 0; it doesn't take account of the possibility that you might have started out with relation less than 0 for reasons other than invalid attacks.
 
I think I may have found it.
You hit the nail squarely on the head there. :onya

This is indeed what I suspected. I had a similar effect before, which is the reason for those if (relch > 0.0 and if (relch < relorg) parts near the top.
I could probably come up with a "quick fix" for it, but I should really think it through a bit more to avoid that function becoming needlessly cluttered.
 
The logical solution would be to change that condition. If you can have a LoM while the nation is Wary then change it to:
Code:
if (IsMainCharacter(char) && relch < REL_AFTERATTACK) LooseLetterOfMarque(iNation);
So if you've started out Wary then you'd better behave because the first invalid attack will cost you the LoM. On the other hand, if you started out at 0 then a few mistakes aren't going to ruin you, as long as you don't make a habit of it.

Or move the line up inside the main condition which checks if 'relch' is positive - put it in the 'else' block, so you only lose the LoM if you attacked something which cost you relation points.
Code:
else // Losing points OR in the service
{
     relch += relorg; // Simple behaviour, no extra checks
     if (IsMainCharacter(char) && relch < 0) LooseLetterOfMarque(iNation); // KK
}
 
The logical solution would be to change that condition. If you can have a LoM while the nation is Wary then change it to:
Code:
if (IsMainCharacter(char) && relch < REL_AFTERATTACK) LooseLetterOfMarque(iNation);
So if you've started out Wary then you'd better behave because the first invalid attack will cost you the LoM. On the other hand, if you started out at 0 then a few mistakes aren't going to ruin you, as long as you don't make a habit of it.
I reckon you should lose your LoM for any invalid attack that makes your relation drop to 0 or below.
In this case though, you lost your LoM for a valid attack and that should not happen.

Or move the line up inside the main condition which checks if 'relch' is positive - put it in the 'else' block, so you only lose the LoM if you attacked something which cost you relation points.
Code:
else // Losing points OR in the service
{
relch += relorg; // Simple behaviour, no extra checks
if (IsMainCharacter(char) && relch < 0) LooseLetterOfMarque(iNation); // KK
}
That is indeed closer to what I think is needed.
But just that won't work, because that 'else' always gets triggered if you are in their service.

Probably the if (relch < relorg) check is needed so you can't lose a LoM when you're supposed to be gaining points.
 
I think this rewritten logic might do the trick:
Code:
float ChangeRMRelation(ref char, int iNation, float relch)
{
   float relorg = GetRMRelation(char, iNation);
   float newrel = relorg + relch;
   if (relch > 0.0)                                 // GAINING points
   {
     if (!IsInServiceOf(iNation))                         // If not in the service
     {
       if (newrel >= REL_NEUTRAL)   newrel = REL_NEUTRAL;             // Prevent becoming MORE than Friendly
       if (newrel < relorg)     newrel = relorg;               // But don't ever LOSE points while you're meant to be gaining them!
     }
   }
   else                                       // Losing points
   {
     if (IsMainCharacter(char)  && newrel <  REL_NEUTRAL)             // If dropping below Friendly
       LooseLetterOfMarque(iNation);                       // Lose any Letter of Marque
   }
   SetRMRelation(char, iNation, newrel);

   //log new relation
   if (iRealismMode == 0 && LogsToggle == LOG_VERBOSE) Log_SetStringToLog(XI_ConvertString(GetNationNameByType(iNation))+ " - " + TranslateString("",GetRMRelationName(char, iNation)) + "."); // KK
   return newrel;
}

@Grey Roger and @Mere_Mortal: Could you have a look at this to check if I am forgetting anything?
I think I covered all bases:
- Cannot gain points above Friendly without a LoM
- If you already had those points somehow, you should keep them
- Only lose LoM when points are being subtracted
 
The only change I might make is to change 'if (relch > 0.0)' to 'if (relch >= 0.0)'. If it's possible to attack a ship and get "relch" equal to 0.0 then it's a ship which "iNation" doesn't care about one way or the other, so sinking it shouldn't cost you your LoM.

Is the line 'if (newrel < relorg) newrel = relorg' necessary? I can't see how it's ever going to happen. By definition "newrel" is "relorg" plus a positive number, otherwise the code hasn't gone down this branch(it had to pass 'if (relch > 0.0)' to get here). How can "newrel" then possibly be less than "relorg"? Did anyone actually manage to lose relation points by attacking something legitimate, and if so, did that line have an effect?
 
The only change I might make is to change 'if (relch > 0.0)' to 'if (relch >= 0.0)'. If it's possible to attack a ship and get "relch" equal to 0.0 then it's a ship which "iNation" doesn't care about one way or the other, so sinking it shouldn't cost you your LoM.
Technically I don't think ChangeRMRelation should ever get called with 0.0, but you never do know.
Good idea; it certainly can't hurt. :doff

Is the line 'if (newrel < relorg) newrel = relorg' necessary? I can't see how it's ever going to happen. By definition "newrel" is "relorg" plus a positive number, otherwise the code hasn't gone down this branch(it had to pass 'if (relch > 0.0)' to get here). How can "newrel" then possibly be less than "relorg"? Did anyone actually manage to lose relation points by attacking something legitimate, and if so, did that line have an effect?
Imagine having relation points with a nation, but NOT a LoM. At the moment I think that isn't possible in normal play, but it isn't completely impossible.
The if (newrel >= REL_NEUTRAL) newrel = REL_NEUTRAL; line could then bring your relation DOWN to Friendly.
That if (newrel < relorg) line is purely to prevent that.
Then if you gain points, you shouldn't get any (because you have no LoM) but still keep whatever points you had before.
 
This is a new piece of code to me, I’d have to spend an hour looking at it to understand what it’s doing, then probably another hour to figure out what was wrong on if it’s now right. ;)
 
This is a new piece of code to me, I’d have to spend an hour looking at it to understand what it’s doing, then probably another hour to figure out what was wrong on if it’s now right. ;)
No worries then. :doff
 
Yes, and I think I've just figured out where it's going to happen. And it should have occured to me sooner because where it's going to happen is "Hornblower"! :facepalm The storyline gives you ranks, therefore relation points, with Britain. But you have no LoM so that you can't earn promotions except where the story gives them to you. That line prevents you from getting demoted down to rank 0 when you do your duty as a British naval officer and attack a French ship.
 
Yes, and I think I've just figured out where it's going to happen. And it should have occured to me sooner because where it's going to happen is "Hornblower"! :facepalm The storyline gives you ranks, therefore relation points, with Britain. But you have no LoM so that you can't earn promotions except where the story gives them to you. That line prevents you from getting demoted down to rank 0 when you do your duty as a British naval officer and attack a French ship.
Actually, Hornblower should remain unaffected.
IsInServiceOf(ENGLAND) will return TRUE for Hornblower despite him not technically having a LoM because he is still a professional navy officer in the service of England.

Hornblower should gain points with England from his actions during regular play even during the main storyline.
As long as you he doesn't have a LoM though, he can gain all the points he wants, but won't ever get the "promotion dialog" at the governors.
So the lack of LoM just prevents the actual promotions, but nothing else.

In the past, it was possible to gain positive relation points even without having a LoM.
That check is a result from me testing a lot of my development last year from a savegame of yours (I think) where you had points with France, but not a LoM with them.
This should not ever happen anymore.

However, if for storyline purposes you want to give a player plus points with a nation despite not being in the service, there is now nothing preventing you from doing so.
The player should keep those points and can get plenty promotions straight away if they decide to get a LoM, provided they don't do anything specifically to lose them.
Not sure if that serves much of a purpose, but the option is there.

I've got some vague ideas about having nation relations affect things throughout the game.
That might be a reason for a storyline writer to give such extra points to give their player a "bonus" with a certain nation.
This used to be the case for Jean Lafitte as well as he'd start with 30 points with the US to encourage players to get a LoM from them.
I can't remember if that is still the case, now that he has a Smuggler start instead of his former Agent type.
 
Back
Top