• 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 Sea Relations: Change in Nation Relations from Player Actions

I remembered seeing this function at multiple places, but if it isn't called often then there is no problem.
The function is called when:
- You ransom a colony after capturing the fort
- You capture a town and give it to another nation, with an exception for your personal nation (code in Dialog_func.c)
- You capture a town and take it for yourself (code in fortcapture.c interface, though I'm pretty sure this does also call the same function from Dialog_func.c; why is this handled separately???)
- Something involving smuggling while still in the tavern (??? Also... terrible spelling there):
Code:
        Dialog.Text = "We can offer you the sum of " + sum + " gold in exchange of all the smuggling's goods you have in your hold !";
         Link.l1 = "Well. If that can improve relations between me and your country, why not ?";
         Link.l1.go = "accept";
         Link.l2 = "Sorry but for this sum, i prefer to keep my goods ! Farewell !";
         Link.l2.go = "exit";
         Npchar.money = sum;
     break;

     case "accept":
         Dialog.Text = "That's good captain ! The governor will be satisfied with this news and believe well that he will be grateful for that ! Here's your money !";
         Link.l1 = "Thanks.";
         Link.l1.go = "exit";
         sum = Npchar.money;
         PlayStereoSound("INTERFACE\took_item.wav");
         AddMoneyToCharacter(pchar, sti(sum));
         AddMoneyToCharacter(Npchar, -sti(sum));
         float points = stf(sum/4000);
         UpdateRMRelation(GetMainCharacter(), sti(Npchar.nation), -points);
- You sink a ship at sea that is hostile to you (eg. red on the mini-map)
- You capture a ship at sea

None are called in a loop, so impact on performance should not be too horrible.
But there are definitely some curiosities in the related code. :confused:
 
So from the above discussion, I think the following changes are in order:
- You don't lose points with neutral nations by attacking their allies IF you have a valid reason to do so (SINGLE LoM + war on your side)
- Pirates don't immediately turn hostile when you attack them; their points will just decrease if you keep doing it

Does that sound about right?
Another good couple of hours spent and I have now come up with this:
Code:
  // PB: Completely Rewritten -->
   int iActOfPiracy = iNation != PIRATE;
   int ServedNation = GetServedNation();                                 // This may change DURING the below process, but we don't care about that
   float rel  = 0.0
   float relChange  = 0.0;

   // Loop through nations to determine if this was an act of piracy
   for(i = 0; i < NATIONS_QUANTITY; i++)
   {
     if(GetNationRelation(i, iNation) == RELATION_ENEMY && IsInServiceOf(i))               // You are in the service of a nation hostile to the one you attacked
     {
       relChange = fPoints;
       if (GetLetterOfMarqueQuantity() > 1)   relChange = relChange * (1 - GetLetterOfMarqueQuantity()/10); // GR: Reduce points for multiple LoMs
       TraceAndLog("Add " + relChange + " points: You are in the service of " + GetNationNameByType(i) + ", which is at war with " + GetNationNameByType(iNation));
       ChangeRMRelation(char, i, relChange);
       iActOfPiracy = 0;                                       // Cannot be an act of piracy if you have a legal reason
     }
   }

   // Loop through nations to determine how the attacked nation and its allies should respond to this
   for(i = 0; i < NATIONS_QUANTITY; i++)
   {
     if(GetNationRelation(i, iNation) == RELATION_FRIEND)                       // This is the nation you attacked OR an ally
     {
       rel = GetActualRMRelation(i);                                 // Relation between the checked nation and the player
       if (i == iNation)                                       // This is the nation you attacked
       {
         relChange = rel  -  REL_WAR + 1;                             // You may immediately become HOSTILE with this nation!
         if (makeint(rel) <= REL_WAR)                 relChange = fPoints;     // They are already hostile, so just subtract the number
         else                                           // You were friendly with them before, bastard!  
         {
           if (i == PIRATE && !IsInServiceOf(i))           relChange = fPoints;     // The pirates aren't too concerned with you attacking other pirates
           else {if (iActOfPiracy > 0)                 iActOfPiracy += relChange;}   // You had no legal reason for this attack, TRAITOR!
         }
       }
       else                                             // This is an ally
       {
         relChange = rel  -  REL_AFTERATTACK + 1;                         // You may immediately become Wary with this nation
         if (makeint(rel) <= REL_AFTERATTACK)             relChange = fPoints;     // They are already Wary, so just subtract the number
         if (ServedNation != PERSONAL_NATION && iActOfPiracy == 0)                 // Only if you are serving ONE specific nation and committed no act of piracy
         {
           rel = GetNationRelation(i, ServedNation);                       // Relation between the ally and your own served nation
           TraceAndLog("Served Nation = " + GetNationNameByType(ServedNation) + ", relation with " + GetNationNameByType(i) + " = " + rel);
           if(rel == RELATION_NEUTRAL || rel == RELATION_FRIEND)   relChange = 0.0;       // You have a legal reason, so the ally doesn't mind
         }
       }

       if (relChange > 0.0)                                     // There are points to subtract
       {
         if (relChange < fPoints)                   relChange = fPoints;     // Relation change is too small
         TraceAndLog("Remove " + relChange + " points: " + GetNationNameByType(i) + " and " + GetNationNameByType(iNation) + " are allied");
         ChangeRMRelation(char, i, -relChange);
       }
     }
   }

   // You committed and act of piracy, but aren't Friendly with the Pirates
   rel = GetActualRMRelation(PIRATE);                                   // Relation between the pirates and the player
   if (iActOfPiracy > 0 && makeint(rel) < REL_NEUTRAL)
   {
     if (rel + iActOfPiracy > REL_NEUTRAL)                 iActOfPiracy = -rel;     // Prevent becoming MORE than Friendly with the pirates
     TraceAndLog("Add " + iActOfPiracy + " points to Pirates for your actions");
     rel = ChangeRMRelation(char, PIRATE, iActOfPiracy);

     // If you just became Friendly to the pirates through an act of piracy, you are now marked as a TRAITOR
     if (GetServedNation() != PIRATE && makeint(rel) >= REL_NEUTRAL)
     {
       TraceAndLog("Served nation set to pirate, you TRAITOR!");
       SetServedNation(PIRATE);
     }
   }
   // PB: Completely Rewritten <--
This time with comments and based on the suggestions posted today.
Especially the special case when you've got TWO LoMs and therefore are serving PERSONAL_NATION/PIRATE was a tricky one.... :shock

I also reduced the number of repeated function calls to hopefully make it a bit more efficient.
Additionally, I adapted some other functions here and there to update your ServedNation when needed.
This apparently didn't always happen.

Using the following lines in console.c allows you to test a very wide range of possibilities:
Code:
   LeaveService(pchar, ENGLAND, false);
   SetRank(pchar, ENGLAND, GetOldRank(PChar, ENGLAND));
   UpdateRMRelation(pchar, PORTUGAL, 5);
If you leave the service of England, then rejoin with the necessary reputation and points (currently set to 30, which for reputation isn't very much!), then you get your old rank back.
Calling LeaveService is probably better than using LooseLetterOfMarque as that function also control reputation changes and all sorts of extra stuff.
 

Attachments

  • nations.zip
    12.6 KB · Views: 132
Last edited:
Hmm...I will remove the update relations from the smugglers accept dialog. It should only happen if the coastguard appears ....
I will take care of that.
 
Rewritten nation response from player actions is now included in here:
http://www.piratesahoy.net/threads/build-14-beta-3-5-internal-wip-for-testing.24817/

This needs SERIOUS TESTING! Playing the game is, of course, one method.
However, a potentially faster way is using lines like these through console and seeing what happens:
Code:
//   LeaveService(pchar, ENGLAND, false);
//   SetRank(pchar, ENGLAND, GetOldRank(PChar, ENGLAND));
//   UpdateRMRelation(pchar, PORTUGAL, 5);
 
Holy crap, there are SO many different functions for the same thing.

There is a NationsRelations array, which contains the relations between different nations.
There is the pchar.nations.(sNation).Relation attributes, which is apparently stock game code and by now has been completely bypassed.
Plus the FlagRMRelations which is used here and there, but probably doesn't serve much purpose either.

The player nationality is now stored as ServedNation .
PChar.nation is actually the flag you're flying.

Just to make things simple, eh? :facepalm

Anyway, I think just one array with relations between separate nations and another one with relations to the player is enough.
When the player is flying a nation flag, used the nation array for that nation.
When the player flies his own flag, use the player-specific set. Nothing more, nothing less.

I also think nation relations between two nations should be tied.
After all, if Holland is hostile with France, then France should be hostile with Holland too! o_O

Now I'm wondering whether to keep the attribute-based stock game player nation relations or the actual nation relations array that is used at the moment.
I think using the attribute array is probably simpler in the long run, even if it will require reworking quite a substantial amount of code to do it.
There is definitely some danger here of me breaking things for a while..... :wp
 
Actually.... the old attribute-based system could be quite nice because it can be set per character.
So if we want to add other "players" to the game with their own business, they could theoretically get their own relations with nations.
Which means I have to rewrite things a bit further....
 
I also prefer to have the player relations set in the attribute indeed.
good luck with the arrays.
 
Large rewrite for this now included in here: http://www.piratesahoy.net/threads/build-14-beta-3-5-internal-wip-for-testing.24817

There are only two sets of nation relations left: One array with relations between nations and a set of attributes indicating their relation to the player.
Everything else is gone. All functions that made use of other systems have been replaced.

For modders: Any use of pchar.nation is to be replaced by GetCurrentFlag() or GetServedNation() depending on what is needed.
I have already replaced all instances I could find and I hope I did it right.
Technically pchar.nation is exactly what GetCurrentFlag() returns, but it much less confusing for people looking through the code to see the function name

If people want to have a thorough look at the code changes with WinMerge, I would certainly appreciate.
There is probably still some cleaning up of related code yet to be done.
 
Still to be added to this mod:
- Turning a nation hostile will be limited to actually SINKING or CAPTURING a ship (already done)
- Add extra relation loss/served nation to PIRATE if you do that sinking or capturing while still under a flag friendly to the ship you attacked
 
How about this?

Lose all your LoM's. If you have a served nation then you only have one LoM and you've just disgraced it, your nation wants nothing more to do with you - lose the LoM and naval status if you had it. If you have multiple LoM's then you have no served nation and are using them as a cover to legitimise piracy, and you've just blown that cover. (At least, that's how the nations see it. Maybe you've been using multiple LoM's to gain maximum reward for hunting pirates, but now you've effectively become a pirate.)

The nation you attacked and its allies all become hostile. Anyone else becomes wary unless their relation with you was already below wary - they don't care about the ship you attacked but you're untrustworthy and they don't know what you're going to attack next. Pirates, if they were previously hostile, become wary - you've shown yourself to be a pirate but haven't yet joined Pirates, though now they're not hostile so the way is open for you to do so. Meanwhile you have no served nation.
All done!

Since I figure you should definitely lose a substantial amount of points with the nation you attack, I have them going all the way down to REL_MIN.
The points you lose with all the nations through your gross act of piracy are subsequently added to the pirates.
As that number is pretty big, you're pretty much guaranteed to become friendly with the pirates and therefore get your served nation set to PIRATE.

An extra change is to consider ANYTHING you do while under a pirate flag to be an act of piracy.
So even if you had a legal reason as an English privateer to attack a Spanish ship, if you do so under a pirate flag, you gain points with England AND the pirates.

To make this even more fun, I made some extra changes for when you already are in the service of the pirates.
While if you aren't in their service, you cannot gain any positive points with them.
But now, for any act of piracy while you ARE a part of the Brotherhood, that limit no longer applies.
The "act of piracy" number can get pretty huge which means you can get a LOT of points with the pirates in one go.

As an example for the Francis Drake start: I join the Pirates, then attack a Spanish ship under a Spanish flag.
I lose ALL my LoMs, Spain turns MASSIVELY hostile and all other nations turn hostile or neutral depending on their relation with Spain.
Plus I gain 165 points with the pirates in one go! Boosts me right up to rank 7 with them. :cheeky

Does that sound about right?
 
Going further:
- If you manually fire on a ship that appears friendly at sea, that ship remembers you as having betrayed you
- If you are recognized for flying a false flag, this does NOT happen
- You get the above massive penalty if you betrayed them as above OR you are still flying a flag friendly to them when you sink/capture them

So this means that if you are recognized and then hoist a flag hostile to the ships that recognized you,
you get no huge penalty because you admitted being an enemy before sinking/capturing them.
But if you FAIL to hoist a hostile flag, then it WILL happen as, for all they know, you're a genuine traitor.
 
It sounds as though rising through the pirate ranks is now too easy, and that you're being rewarded for attacking a ship while flying a friendly flag.

Perhaps Pirates should give you the same points for attacking the ship regardless of which flag you were flying when you did it. Unlike nations they're not bothered about the legality of attacking under a friendly flag, but they shouldn't actively reward it either. It's a strategem to get you into an advantageous position and, properly used, its main benefit is that you can take on a larger ship more easily than if you approached it honestly. The points you'll get for taking out that larger ship, along with the greater booty, are your rewards for using a friendly flag.
 
It sounds as though rising through the pirate ranks is now too easy, and that you're being rewarded for attacking a ship while flying a friendly flag.
Gaining points with the pirates can be a reward or a penalty, depending on whether you actually want to be a pirate.
Getting your served nation set to pirate is pretty annoying if you don't want to be a pirate.

It only seems fair to me to compensate the player for losing so many points with the various nations by adding those same points to the pirates.
While you can indeed get a large number of points with the pirates in one go, that only works once. And only if you officially joined the pirates prior to that.

If you try the same thing a second time, you've already lost the points you had to lose and therefore will not be gaining huge amounts of points with the pirates again.
So you can't really use it as much of a repeatable exploit. :no
 
Maybe, but going from 0 to 7 in one go is a pretty big exploit already. That's the equivalent of going from nobody to Commodore at once!

Losing the points is supposed to be a punishment for treachery! It no more deserves compensation than losing a lot of reputation for killing a lot of civilians.

Incidentally, as well as losing the LoM, you should also lose any merchant licence you held. The East India Company won't want anything more to do with you if you've switched to freelance pirating. They only tolerate piracy if they're the ones authorising it...
 
Maybe, but going from 0 to 7 in one go is a pretty big exploit already. That's the equivalent of going from nobody to Commodore at once!
Perhaps I can add a limit to the number of points you can gain with the pirates in one go.
For example, limit it to gaining just one rank or so.

Losing the points is supposed to be a punishment for treachery! It no more deserves compensation than losing a lot of reputation for killing a lot of civilians.
True. But why wouldn't the pirates LIKE you committing treachery? It is massively piratey. :wp

Incidentally, as well as losing the LoM, you should also lose any merchant licence you held. The East India Company won't want anything more to do with you if you've switched to freelance pirating. They only tolerate piracy if they're the ones authorising it...
Good point. I'll add that together with losing your LoMs.
So losing your merchant letters will happen ONLY if you capture/sink a ship while under a friendly flag, but not for anything you do under a hostile one.

Alternate approach would be to link it to the moment you switch Served Nation to PIRATE.
Would that make more sense, you reckon?
 
The main concern pirates would have is, if you're that treacherous, what's to prevent you from betraying them too? Beyond that, it's a valid pirate strategy but not one that's going to get you massive recognition, otherwise they'd all be doing it and you'd need to make attacks by apparently friendly ships be common.

As a merchant, you're not really supposed to capture or sink anything, except if it attacked you first. The East India Company arranged LoM's for some of its ships precisely so that they could legally take prizes - possibly something to make happen if you play a merchant career and rise through whatever rank scale applies to EITC. Committing an act of piracy would probably be enough to lose you your merchant's licence, whether or not you then formally join the Pirate nation. (In reality, once you'd committed an act of piracy, if you then went anywhere that the licence was worth anything, you'd be guest of honour at a hanging. You're getting off lightly just losing the licence. :rpirate)
 
The main concern pirates would have is, if you're that treacherous, what's to prevent you from betraying them too? Beyond that, it's a valid pirate strategy but not one that's going to get you massive recognition, otherwise they'd all be doing it and you'd need to make attacks by apparently friendly ships be common.
Very well, I'll add a limit so you'll only gain enough points for one promotion and not more.
That fair enough?

The East India Company arranged LoM's for some of its ships precisely so that they could legally take prizes - possibly something to make happen if you play a merchant career and rise through whatever rank scale applies to EITC.
At the moment.... There are no EITC ranks. Probably won't be for a while. :shrug

Committing an act of piracy would probably be enough to lose you your merchant's licence, whether or not you then formally join the Pirate nation. (In reality, once you'd committed an act of piracy, if you then went anywhere that the licence was worth anything, you'd be guest of honour at a hanging. You're getting off lightly just losing the licence. :rpirate)
True. So I've now set it up so you lose them for ANY act of piracy, even if it is only a minor one.
Would that be OK or is that perhaps a bit too harsh? Those letters are EXPENSIVE! :wp
 
Very well, I'll add a limit so you'll only gain enough points for one promotion and not more.
That fair enough?
I reconsidered: The code is much cleaner and simpler if I set the limit on the number of points the ship is actually worth.
So you WILL get a lot of points if you weren't already friendly with the pirates, but you'll only go up to Friendly then.
Otherwise, a ship is a ship and you don't get bonus points above zero.
 
At the moment.... There are no EITC ranks. Probably won't be for a while. :shrug
Fair enough. It was just a suggestion so that advanced merchant characters could get a LoM. Otherwise if you want to play as a privateer, get a LoM; if you want to play as a peaceful merchant, get a merchant's licence; and if you've declared yourself a peaceful merchant by getting a licence, behave accordingly!

True. So I've now set it up so you lose them for ANY act of piracy, even if it is only a minor one.
Would that be OK or is that perhaps a bit too harsh? Those letters are EXPENSIVE! :wp
Another possibility might be to drop your relations heavily with any nation with whom you have a LoM. Demote accordingly. If the drop takes you below 0 then you lose the LoM.

Have you remembered also to strip the player of professional navy status if he switches to Served Nation Pirates? If not, this could be the way to try out those naval promotion rewards for pirates which I added for completion when I was doing them for all nations... ;)
 
Fair enough. It was just a suggestion so that advanced merchant characters could get a LoM. Otherwise if you want to play as a privateer, get a LoM; if you want to play as a peaceful merchant, get a merchant's licence; and if you've declared yourself a peaceful merchant by getting a licence, behave accordingly!
What you CAN do is get a LoM and a merchant letter. That is quite possible and basically makes you a Privateer who doesn't need to worry about signing articles with his crew.
You shouldn't lose your merchant letter as long as you don't commit any actual acts of piracy.

Another possibility might be to drop your relations heavily with any nation with whom you have a LoM. Demote accordingly. If the drop takes you below 0 then you lose the LoM.
Demotion for navy officer is currently a bit of a tricky thing; needs to be looked in further. Some time.....

Have you remembered also to strip the player of professional navy status if he switches to Served Nation Pirates? If not, this could be the way to try out those naval promotion rewards for pirates which I added for completion when I was doing them for all nations... ;)
The function that makes you loose a LoM also removes your professional navy status. :yes

Even if it didn't, if you're an English navy officer, you wouldn't become a "pirate navy officer" ever.
At the moment that just cannot happen.
 
Back
Top