• 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!

Perks questions relating to perks_init.c

Tingyun

Corsair
Storm Modder
EDIT: Some of the included ideas (but not perk locks) now implemented here: Mod Release - Experiment 1: Skilled AI Captains and fair sea battles | PiratesAhoy!

@Levis @Pieter Boelen

Could I ask, do either of you know any way to set a prerequisite minimum skill requirement to purchase a perk?


So, for example, to the perk for maneuverability:

ChrPerksList.list.ShipTurnRateUp.descr = "perkShipTurnRateUp";
ChrPerksList.list.ShipTurnRateUp.disable.iRealismMode = 2; //Levis
ChrPerksList.list.ShipTurnRateUp.disable.REALISTIC_ABILITIES = 2; //Levis
ChrPerksList.list.ShipTurnRateUp.cost = 1; // Levis
ChrPerksList.list.ShipTurnRateUp.type = PERK_TYPE_SAILING; //Levis

I want to add something like:

ChrPerksList.list.ShipTurnRateUp.condition.______ = true, and make it sailing > 4;

But of course that doesn't work just plugging in sailing > 4. I'm wondering if there is some way of rephrasing it so that it does? Or some other thing I could do elsewhere to enable that?


As part of broader experiments, I am currently experimenting with possible ways to resolve two issues:

1) AI captains cannot purchase enough perks even at high level to cover all the roles the player can get officers for, meaning they inevitably fall behind

2) there is some odd parts of officers, like low level officers with only a couple points of cannons being able to max out all the perks, high level officers with near perfect cannons lacking many relevant perks

The best solution I've thought of involves reducing perk cost to 1 for all sea perks (keeping combat perks high cost, and raising noncontributing chance), and then implementing requirements for the skill itself.

In this way I'd tie each perk up the chain to more advanced sailing perks to an increasing level of sailing, but make them only cost 1. Then high level AI captains would be able to purchase what they need provided their skills are calibrated right, and have a good perklist to compete with the player. And the most powerful perks would be properly limited.

I could just tie it to level, which would mostly work, only I am afraid then the Player character will just be purchasing all the now cheap perks that his guys are missing...
 
Last edited:
Just so you know, as far as I'm aware AI characters, including NPC captains, are bound by the exact same limitations that apply to the player.
Though I'm not 100% certain of that. @Levis could confirm.

I want to add something like:

ChrPerksList.list.ShipTurnRateUp.condition.______ = true, and make it sailing > 4;
Currently that is not possible. Maybe @Levis could add it though.
 
Ok, for now I'll go with level locks then, I know Levis has a lot on his plate. :)

Pieter, yep, I understand that--this is mostly aimed at HELPING AI captains!

Let me explain further, here is the way it currently goes, as far as I can tell:

AI captain selects from his character type perk list and combat perks. Picks a bunch of perks that don't really help him, and even at level 40 he isn't going to come close to buying all the sea combat perks (actually, his perk list is filled with perks that don't help him at all, and he is missing alot that do, even navy captains are missing many valuable sea warfare perks). And he gets no officers to help him.

Meanwhile, a player of level 20, half his level, will have officers covering all the useful sea combat perks. So the AI always comes out behind, and the deck is stacked in favor of the player.

The way I am addressing this for everything but the merchant captain (as an experiment):

1) Clean up AI captain perk lists, get them all the useful combat perks as possibilities, and delete all the perks that won't help them in combat. Remove their noncontributing perk chance. This means they will only spend their valuable perk points on sea combat, and personal combat.

2) Lower the cost of perks useful in sea combat. Now the AI will have the perk points to actually buy many, even if they get distracted by the combat perks.

3) Ability lock or level lock the perks away. Won't be a problem for the ai captains, it will just cause them at low level to spend their limited points on other useful perks from the new list I give them. At high level, they will then buy the more advanced perks. Means they won't specilize in one branch of sea warfare perks, but will spread out, as probably makes sense for a captain.

4) Also, I will be ability locking or level locking the combat perks. So low level AI captains won't blow all their perk points on combat perks, they'll be buying at least some sea ones.

At the same time, I think slowing the player down in getting all the combat perks will be good, slowing down officers from maxing out their role perks as well. Basically, I think this will create better balance throughout. More growth potential for the player, as they strive to get their gunner to level 25 or whatever to buy the last perk maxing out his list.

The only reason I don't like level locking the perks is the player might later be able to purchase them for himself, even with low skills. Locking them to minimum skills would avoid that. But it isn't bad as a temporary measure.

But we'll see how it works out as an experiment. :)
 
Last edited:
AI captain selects from his character type perk list and combat perks. Picks a bunch of perks that don't really help him, and even at level 40 he isn't going to come close to buying all the sea combat perks (actually, his perk list is filled with perks that don't help him at all, and he is missing alot that do, even navy captains are missing many valuable sea warfare perks). And he gets no officers to help him.
@Levis, can that not be sorted by setting the "noncontribchance" to 0 or something?
 
Pieter, I can answer that, that is only the first step to a solution, and one which I have already implemented--but it is only a first step. Let me explain.

For example, the old Pirate Captain had this:

OfficerTypes.(type).noncontribchance = 30;
OfficerTypes.(type).crewtype = OFFIC_TYPE_PIRATE;
if(isPerkExisting("DefendPoison")) {OfficerTypes.(type).perks.DefendPoison = 1};
if(isPerkExisting("ShipTurnRateUp")) {OfficerTypes.(type).perks.ShipTurnRateUp = 1};
if(isPerkExisting("ShipSpeedUp")) {OfficerTypes.(type).perks.ShipSpeedUp = 1};
if(isPerkExisting("StormProfessional")) {OfficerTypes.(type).perks.StormProfessional = 1};
if(isPerkExisting("SailsDamageUp")) {OfficerTypes.(type).perks.SailsDamageUp = 1};
if(isPerkExisting("CrewDamageUp")) {OfficerTypes.(type).perks.CrewDamageUp = 1};
if(isPerkExisting("LongRangeShoot")) {OfficerTypes.(type).perks.LongRangeShoot = 1};
if(isPerkExisting("LongRangeGrappling")) {OfficerTypes.(type).perks.LongRangeGrappling = 1};
if(isPerkExisting("MusketsShoot")) {OfficerTypes.(type).perks.MusketsShoot = 1};
if(isPerkExisting("GrapplingProfessional")) {OfficerTypes.(type).perks.GrapplingProfessional = 1};
if(isPerkExisting("LightRepair")) {OfficerTypes.(type).perks.LightRepair = 1};
if(isPerkExisting("Disguiser")) {OfficerTypes.(type).perks.Disguiser = 1};
if(isPerkExisting("ImproveSmuggling")) {OfficerTypes.(type).perks.ImproveSmuggling = 1};
if(isPerkExisting("Brander")) {OfficerTypes.(type).perks.Brander = 1};
if(isPerkExisting("SharedExperience")) {OfficerTypes.(type).perks.SharedExperience = 1};

I changed him to this

OfficerTypes.(type).crewtype = OFFIC_TYPE_PIRATE;
if(isPerkExisting("ShipSpeedUp")) {OfficerTypes.(type).perks.ShipSpeedUp = 1};
if(isPerkExisting("ShipTurnRateUp")) {OfficerTypes.(type).perks.ShipTurnRateUp = 1};
if(isPerkExisting("StormProfessional")) {OfficerTypes.(type).perks.StormProfessional = 1};
if(isPerkExisting("SandbankManeuver")) {OfficerTypes.(type).perks.SandbankManeuver = 1};
if(isPerkExisting("SailingProfessional")) {OfficerTypes.(type).perks.SailingProfessional = 1};
if(isPerkExisting("BasicBattleState")) {OfficerTypes.(type).perks.BasicBattleState = 1};
if(isPerkExisting("AdvancedBattleState")) {OfficerTypes.(type).perks.AdvancedBattleState = 1};
if(isPerkExisting("ShipDefenceProfessional")) {OfficerTypes.(type).perks.ShipDefenceProfessional = 1};
if(isPerkExisting("FastReload")) {OfficerTypes.(type).perks.FastReload = 1};
if(isPerkExisting("HullDamageUp")) {OfficerTypes.(type).perks.HullDamageUp = 1};
if(isPerkExisting("SailsDamageUp")) {OfficerTypes.(type).perks.SailsDamageUp = 1};
if(isPerkExisting("CrewDamageUp")) {OfficerTypes.(type).perks.CrewDamageUp = 1};
if(isPerkExisting("CriticalShoot")) {OfficerTypes.(type).perks.CriticalShoot = 1};
if(isPerkExisting("LongRangeShoot")) {OfficerTypes.(type).perks.LongRangeShoot = 1};
if(isPerkExisting("CannonProfessional")) {OfficerTypes.(type).perks.CannonProfessional = 1};
if(isPerkExisting("LongRangeGrappling")) {OfficerTypes.(type).perks.LongRangeGrappling = 1};
if(isPerkExisting("MusketsShoot")) {OfficerTypes.(type).perks.MusketsShoot = 1};
if(isPerkExisting("LightRepair")) {OfficerTypes.(type).perks.LightRepair = 1};
if(isPerkExisting("IronWill")) {OfficerTypes.(type).perks.IronWill = 1};

(I'm assuming ironwill works to help morale for AI players...I might have to look into that one to check)

So now he has the full sea combat perk list and can get all the good ones, and I deleted the distracting perks like poison resistance and shared XP that will only consume his valuable points. And his noncontributing chance is at 0 now, so he won't waste points there.

But think about this--even with all of that, he will be better, but still TERRIBLE compared to the player. At level 20 the player will be getting pretty much all the sea perks from his officers.

What can a level 20 AI captain get? Well, he will probably buy a couple of combat perks, and maybe only 6 or so sea combat perks even with getting the improved list I gave him. And the player will absolutelly and unfairly have the advantage.

So I thought of two solutions:

The first one it outlined above--drop costs and lock the perks to skill or level requirement, which will allow them to purchase more, and also fix some things with how the player advances.

Or two, make a mirror duplicate AI captain that has three times (400%) normal perk points for his level and only exists during the sea battle, representing the influence of his officers, and then he gets replaced with a normal sea captain after sea combat.

The first solution I know how to do, so I'm trying it out for my experiment, the second would need someone far more talented than I ;)

EDIT (I will probably also delete some perk prereqs like sandbank manuver and storm profesional being required for sea wolf, and just ability or level lock it instead. Then the AI won't have to purchase prereqs that don't help it, and I can further trim down their list)
 
Do note that any changes to perks will be applied to all characters so if you lower the costs for perks the main character can progress quicker too. For now its set up that even at level 100 you can't have all perks.
The captains where missing certain perks for different reasons. 1 to make them more diverse, a pirate captain was specilized in boarding etc.
I'm still planning on adding officers to captains to overcome the problem of them being weaker then the character. Also do mind they need combat perks because they will be fighting the player if he boards them.
Locking perks for certain skills is possible but I'm not sure yet it's worth it.
 
Levis,

Yep, anything to allow the AI player to have officers, or give him an alternate version with more perks would be better.

I understand why they had the list they currently do--it is very thematic to their role. But it was absolutely killing their combat capability. A pirate with disguiser, smuggling skills, and such is just not going to be able to sail his ship or fight.

I'm not denying them combat perks, I'm locking them to level so a low level AI does not spend ALL of his on combat (instead, he will be spreading them between combat and sea warfare). I think this will help with the player getting a more gradual increase in ability as well.

Basically, adding non contributing perks, thematic but not useful contributing perks, and combat perks, a current level 20 pirate captain is completely terrible at sailing. ;)

The advancement issue is why I would prefer to ability score lock it up. The player would then presumably not be able to max out most things beyond sailing, leadership, and combat.

Once AI captains have officers, I would prefer that. What I am experimenting with is a way of making them have a fighting chance in the meantime.

The truth is even under the current system though I'd love to set skill requirements for perks. Makes sense a level 5 in cannon officer cannot be a professional cannoner and eliminate further advancement. ;)

Do you mean there is some code I could currently use to lock perks by minimum ability score? Or that you would have to add something? If there currently is something, please let me know what it is, otherwise I'll rely on the second-best level locking solution. ;)
 
there is no code to lock it for a skilllevel.
But if you for example lock the profesional fencer to level 20 also all officers and the main character won't be able to get it untill that level. that will cause a lot of problems because not everyone wants to play in the same way.

you could take a look at the function
InitPerkTypes
in officers.c (in the characters folder).
This is how the perks ar chosen.
All perks are set to a specific category. When an officer wants to pick a perk it will go trough all of these categories and multiplies its skilllevel with the provided weight in this function.
The category which has the highest totalweight will be used to pick a perk from. If the officers has a noncontribchance there is a possebility that it will pick from another category instead.
When picking a perk it will look at different aspects and score the avaible perks.
It will look at the price of the perk, if the perk unlocks other perks and some other variables. Based on this each perk is scored and the highest scoring perk will be picked.
 
Levis,

I think the issue isn't really in perk selection, it is in perk points (unless we want to block the AI captains from getting any personal combat abilities, which as you already said they do need some). Until Captains have officers, then can't possibly afford everything they need. Even with cleaned up perk lists and 0 noncontributing, when the player can spread the cost of 40 perk points of sea warfare perks among the entire officer crew, the AI captain just can't keep up at current perk costs.

On level limits, we already do this for some perks anyway, just inconsistently. Sea Wolf is locked to level 20. One of the gun use perks is locked to level 15.

It is sad it can't be done with ability score though--requiring cannon ability 8 for professional cannoner makes so much more sense than requiring a certain level. At any rate, since this is just an initial experiment with Eskhol and me, I'm inclined to try out the sea wolf formula of requiring minimum levels for the officer sea combat oerks

I think I will try experimenting with only limiting non combat perks by level, so like seawolf i will limit the gunnery perks and such, but I won't limit any of the personal combat ones, and remove the currently present limit on the personal gun combat one. As you suggest, it might limit players too much to limit the personal combat ones
 
Last edited:
For reference, here is the basic perklist I am now using for the combat captains (I checked and it does seem the AI ship stuff makes use of fire ship, club hauling, and iron will). Some slight changes for specific types, like adding master of boarding to pirate captains, but mostly avoiding anything else that could divide their perk attention.

if(isPerkExisting("ShipSpeedUp")) {OfficerTypes.(type).perks.ShipSpeedUp = 1};
if(isPerkExisting("ShipTurnRateUp")) {OfficerTypes.(type).perks.ShipTurnRateUp = 1};
if(isPerkExisting("SailingProfessional")) {OfficerTypes.(type).perks.SailingProfessional = 1};
if(isPerkExisting("BasicBattleState")) {OfficerTypes.(type).perks.BasicBattleState = 1};
if(isPerkExisting("AdvancedBattleState")) {OfficerTypes.(type).perks.AdvancedBattleState = 1};
if(isPerkExisting("ShipDefenceProfessional")) {OfficerTypes.(type).perks.ShipDefenceProfessional = 1};
if(isPerkExisting("FastReload")) {OfficerTypes.(type).perks.FastReload = 1};
if(isPerkExisting("HullDamageUp")) {OfficerTypes.(type).perks.HullDamageUp = 1};
if(isPerkExisting("SailsDamageUp")) {OfficerTypes.(type).perks.SailsDamageUp = 1};
if(isPerkExisting("CrewDamageUp")) {OfficerTypes.(type).perks.CrewDamageUp = 1};
if(isPerkExisting("CriticalShoot")) {OfficerTypes.(type).perks.CriticalShoot = 1};
if(isPerkExisting("LongRangeShoot")) {OfficerTypes.(type).perks.LongRangeShoot = 1};
if(isPerkExisting("CannonProfessional")) {OfficerTypes.(type).perks.CannonProfessional = 1};
if(isPerkExisting("LongRangeGrappling")) {OfficerTypes.(type).perks.LongRangeGrappling = 1};
if(isPerkExisting("MusketsShoot")) {OfficerTypes.(type).perks.MusketsShoot = 1};
if(isPerkExisting("LightRepair")) {OfficerTypes.(type).perks.LightRepair = 1};
if(isPerkExisting("IronWill")) {OfficerTypes.(type).perks.IronWill = 1};
if(isPerkExisting("Brander")) {OfficerTypes.SuperOfficer.perks.Brander = 1};
if(isPerkExisting("Turn180")) {OfficerTypes.(type).perks.Turn180 = 1};

This is with Sea Wolf now having prereqs of maneuverability and speed, so the AI can skip those otherwise less usefule perks of storm professional and reducing reef damage.

Total cost is over 35 perk points. Combat perks add up to 15 perk points.

So with these streamlined (and sadly less thematic, but needed until AI gets officers) perk lists, an AI captain at level 25 will have around half the sea combat perks, and they will max out at level 50 getting everything.

With these changes maybe the streamlined perk lists are enough even without reduced perk costs. We are still stacking the deck in favor of the player at anything short of a tier 1, because the player will have all the perks by then, but the AI will still be much better than before.

But that's the question, whether the rank bonus will operate or not to give them that many perks.

Can I ask that Levis? If a level 40 captain is generated for a tier 1 ship, does he get 50 perk points because of OfficerTypes.(type).rankbonus = 10;?

I know that in LAi_Create Officer it is like this
int rank = (8-shipclass)*7;
rank = rank*0.8 + 0.3*rand(rank);
rank += GetOfficTypeRankBonus(SCaptain.quest.officertype);
So with the random amount this looks like average level of 46 for a class 1 ship before the bonus.

Is that rank += GetOfficTypeRankBonus(SCaptain.quest.officertype); adding in the bonus rank from OfficerTypes.(type).rankbonus = 10;?

If so then It looks pretty good with the new perk lists. Tier 1 and tier 2 officers would get around 50 perk points if the +10 rank bonus is operating, as they should, and now with the streamlined perks and expanded ship combat perks they would actually be able to purchase all the sea warfare and combat perks, and be able to match the player officer team.

I think then the new perk lists would be enough to make the ai captains pretty competitive, without any of the lowering of perk cost I was considering. At least, worthy of experimenting and seeing.
 
Last edited:
Every character should get as many perkpoints as his level permits. So depending on which level they become they will have so many perkpoints.

I'm pretty sure I we are not going to include this in the mainmod because it will destroy any balance we have now. but for a personal test its no problem ofcourse :) and it's a good excercise in modding.

Adding officers to captains shouldn't be that hard anymore and its on my todolist. But I would like to have them some more use also and have them show up during boarding. And that stage I'm still figuring out. I haven't yet found where the boarding decks are called etc. maybe @Pieter Boelen knows this. The same goes for fortcommanders, they should be able to have officers too. Does someone know where its determined which area's you go trough when sacking the town etc?
 
But I would like to have them some more use also and have them show up during boarding. And that stage I'm still figuring out.
Maybe that is something that can be added later?
Might not be necessary to do it all in one go.

I haven't yet found where the boarding decks are called etc. maybe @Pieter Boelen knows this.
Good place to start is the usual LAi_boarding.c file.

The same goes for fortcommanders, they should be able to have officers too.
What for? Forts basically only use cannons. You might as well put a Gunner in charge. ;)

Does someone know where its determined which area's you go trough when sacking the town etc?
PROGRAM\Towns\init_towns.c has a list of locations for each town.
 
Maybe that is something that can be added later?
Might not be necessary to do it all in one go.
true...
I first want to make sure captains work properly and we have the captain generation down so we know how it works. It's getting better and better, and there are only 2 place now where it happens. I want to try to bring this into 1 function and make sure that during boarding the captain doesn't have to be made with a twin character (these are both bugs which are open about captains). once this is done adding officers to him is a simple matter of calling the create officer function X times and assigning them to the captain.
I might have to expand the characters array a bit to make room for these officers but thats not that hard.
 
I first want to make sure captains work properly and we have the captain generation down so we know how it works. It's getting better and better, and there are only 2 place now where it happens. I want to try to bring this into 1 function and make sure that during boarding the captain doesn't have to be made with a twin character (these are both bugs which are open about captains). once this is done adding officers to him is a simple matter of calling the create officer function X times and assigning them to the captain.
I might have to expand the characters array a bit to make room for these officers but thats not that hard.
Sounds like a good plan!
 
it will destroy any balance we have now

Levis, I agree it is an early experiment, but curious why you think that.

Basically, the main thing I am doing with the perks lists (locked perks is a seperate experiment) is allowing AI captains to get the same sea combat perks the player does. The balance we have now is the player has all the sea warfare perks, the AI doesn't, and the player gets to do extra damage/take less damage/go faster than even high level AI ships. Even level 45 navy captains right now are blocked from some sea combat perks!

IE, until the better solution of AI officers is implemented, "the balance we have now" is that sea combat cheats for the player, and gives him huge statistical bonuses, even on swashbuckler. ;) How could allowing the AI to have a better perklist not be an improvement to balance?
 
Last edited:
In truth, we won't know how this will work out until you try it.
Which is exactly what you're doing, so I'll be curious to find out how it goes! :cheers
 
Yes, I'm pretty sure 80% of what I do will end up being not a good idea. ;) I am going to seperate out my experiments as much as the files allow, so that the feedback becomes more useful in seeing if there is any small part of the experiment thst makes sense.

Levis is right that the perk locking will probably annoy people, so I'm seperating that one out of the perk list experiment. :)
 
I don't usually change things, but I was trying to recruit a First Mate to turn into a Captain that doesn't automatically select a bunch of useless perks. I changed the noncontrib to 0 and put all the skills I want him to prioritize right below the following:

//First Mate
type = OFFIC_TYPE_FIRSTMATE;
OfficerTypes.(type).skills.Leadership = 2;
OfficerTypes.(type).skills.Leadership.importance = 10;
OfficerTypes.(type).skills.Fencing = 0;
OfficerTypes.(type).skills.Fencing.importance = 5;
OfficerTypes.(type).skills.Sailing = 1;
OfficerTypes.(type).skills.Sailing.importance = 6;
OfficerTypes.(type).skills.Accuracy = 1; // Set to 1 to balance for few perks
OfficerTypes.(type).skills.Accuracy.importance = 5;
OfficerTypes.(type).skills.Cannons = 0;
OfficerTypes.(type).skills.Grappling = 0;
OfficerTypes.(type).skills.Repair = 0;
OfficerTypes.(type).skills.Defence = 0;
OfficerTypes.(type).skills.Commerce = 0;
OfficerTypes.(type).skills.Sneak = 0;
OfficerTypes.(type).usableoffictype = true;
OfficerTypes.(type).rankbonus = 2;
OfficerTypes.(type).hpbasebonus = 10;
OfficerTypes.(type).hplevelbonus = 1;
OfficerTypes.(type).pricemod = 1.02;
OfficerTypes.(type).noncontribchance = 0;
if(isPerkExisting("FastReload")) {OfficerTypes.(type).perks.FastReload = 1};

I changed the list of perks for the Captains to be the same.
Problem is... It's not doing anything. A first mate I already had still reflects the same contributory skills, and all new prospects are coming in with Shared Experience which I have removed from the list.


Edit: Figured out that it works if I make a new save game. I assume there's no way to make my old save work with the new settings?
 
Last edited:
You need to download Levis's officer types reinitilization fix, which is in the bug reports section of the forum and can be downloaded, install it, and then press f11 to reinitilize.

Then, the changes you made will work. :)
 
Back
Top