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

Need help writing some code to test new horizons general

Natzrim

Landlubber
Arrrgggg! I'd like to experiment with and possibly add in some more unique titles for officers in the Player's officer list. Currently, if in game you hire a Carpenter, in the top center of the "Character" tab for that officer, it will just say "Officer" and in the bottom center there will be a "carpenter" tag. I found some code in the Program/NK.c where, if a character or NPC is rank 10 with England (in this case) and has been assigned the "Knighted" tag, instead of the Title "Viscount" it will be overridden to "Lord" or "Lady". I would like some assistance to experiment with this concept for other naval and non naval officer types. For example, a carpenter would have "warrent Officer" for a Naval type and a non naval carpenter would be a "2nd Mate" or something (I've been digging around history for some insights on the titles, bit not that important if it won't work in game). I assume a call could be added to the console.c, or set to run when an officer is hired or assigned during promotions, that would do this. Any insight is appreciated!
 
Have you found which code is run in PROGRAM\INTERFACE\character.c to place that "Officer" text?
 
Have you found which code is run in PROGRAM\INTERFACE\character.c to place that "Officer" text?
I think this is it:
```
// TITLE: Override with Rank if available
int bestRank;
int rankNation = GetBestRank(xi_refCharacter, &bestRank, rankNation); // add return by levis
if (bestRank > 0 && !IsPrisoner(xi_refCharacter)) GameInterface.strings.fakeTitle = TranslateString("", GetRankNameDirect(xi_refCharacter, rankNation, bestrank)); //Fix by Levis

CreateStringCheckCase(true,"fakeTitle",GameInterface.strings.fakeTitle,"interface_title",COLOR_NORMAL,320,5,SCRIPT_ALIGN_CENTER,1.0,true); // MAXIMUS interface MOD

SendMessage(&GameInterface,"lsl",MSG_INTERFACE_MSG_TO_NODE,"exp",0);
oldIndex = -1;
}
```
 
Here's another expample:
from NK.c
upon reaching rank 3, if the player character is Theodore Groves, then his rank is set to Commander instead of the typical "Lieutenant" for rank 3:
case 3: // Lieutenant
switch(iNation)
{
case ENGLAND:
switch (GetMySimpleOldName(PChar))
{
case "Francis Drake":
GiveItem2Character(pchar,"bladeFD2");
EquipCharacterByItem(pchar,"bladeFD2");
break;

case "Theodore Groves":
SetRankTitle(PChar, TranslateString("", "Commander")); (color added her to help it show easy)
break;

//default:
GiveItem2Character(pchar,"blade24"+qual); // English Officer's Saber
EquipCharacterByItem(pchar,"blade24"+qual);
}
break;
 
1703519481426.png
 
I started a game as Groves where his starting rank should have been Commander according to the code above, but it doesn't change in game...
 
I think this is it:
```
// TITLE: Override with Rank if available
int bestRank;
int rankNation = GetBestRank(xi_refCharacter, &bestRank, rankNation); // add return by levis
if (bestRank > 0 && !IsPrisoner(xi_refCharacter)) GameInterface.strings.fakeTitle = TranslateString("", GetRankNameDirect(xi_refCharacter, rankNation, bestrank)); //Fix by Levis

CreateStringCheckCase(true,"fakeTitle",GameInterface.strings.fakeTitle,"interface_title",COLOR_NORMAL,320,5,SCRIPT_ALIGN_CENTER,1.0,true); // MAXIMUS interface MOD

SendMessage(&GameInterface,"lsl",MSG_INTERFACE_MSG_TO_NODE,"exp",0);
oldIndex = -1;
}
```
Looks like it indeed. :onya

I started a game as Groves where his starting rank should have been Commander according to the code above, but it doesn't change in game...
I would've been surprised if it did.
As I said before, I'm pretty sure that's not how that function was written to work in the first place.
I wonder who was clever enough to add that line for Mr. Groves.
Probably someone who didn't know what they were doing.
Like me or something. :facepalm
 
void GiveSwordAndPerks(int PlayerRank, int iNation)
{
string PCharTitle; // DeathDaisy
ref pchar = GetMainCharacter();
ref ch;
string qual = "";
if (ENABLE_WEAPONSMOD) qual = "+3";

int PlayerType = 1; // Privateer
if (ProfessionalNavyNation() != UNKNOWN_NATION) PlayerType = 2; // Navy
if (iNation == PIRATE) PlayerType = 3; // Pirate

switch(PlayerRank)
{
-other cases are 1-9-
case 10: // Admiral/Viscount
switch(iNation)
{
case ENGLAND:
if (!CheckAttribute(PChar, "knighted") || sti(GetAttribute(PChar, "knighted")) == iNation)
{
// DeathDaisy -->
if (PChar.sex == "woman") PCharTitle = "Lady";
else PCharTitle = "Lord";
// DeathDaisy <--
SetRankTitle(PChar, TranslateString("", PCharTitle));
PChar.knighted = iNation;
}
break;
}
break;
}
So, This sets the string variable for PCharTitle; a ref to pchar = for main character; then ref ch (that I assume applies the same variable to NPCs, where this will apply to Lord Beckett dispite him not being a Player Character... The Player type distiquishes Privateer/Pirate/Naval Officer character type. Not included here, but at rank 7, the character, if a Privateer or Naval Officer the get "knighted" at that rank. but here at rank 10 the code re-applys the "knighted" tag again? Then this switch checks for the Nation, in this case England, checks if the character is knighted, then applies the Lord/Lady rank title in the RankTitle line on the character tab. So, I figured, using console, when creating a new Officer, I could apply the same logic as here to add a custom Rank Title to an officer, but it doesn't work.
here's an example:
ch = CreateOfficer_Cheat(OFFIC_TYPE_DOCTOR, "PellewX_18", 3, ENGLAND, false);
ch.name = TranslateString("","Edward");
ch.lastname = TranslateString("","Pellew");
ChangeCharacterReputation(ch, 50);
ch.professionalnavy = ch.nation;
SetRank(ch, ENGLAND, 5); // Commander
SetRankTitle(ch, TranslateString("", "Chief Warrant Officer"));
I supposed that using this string SetRankTitle... would replace the default rank 5 title of Commander, and make it "Chief Warrant Officer," But it doen'st work.

Conceptually, I'd like to either add custom rank titles for my own enjoyment and for the storyline I'm working on, or expand it and make it a feature for everyone that will add a bit of RP value. Any help is greatly appreciated, Please keep in mind, I'm very much a novice for writing code and I don't have any formal training at all. I like to understand why a code is what it is not just what it is... Thanks and ARRRGGGG!
 
I'm very much a novice for writing code and I don't have any formal training at all.
That goes for many of the mod contributors over the years.
Myself included.

at rank 7, the character, if a Privateer or Naval Officer the get "knighted" at that rank. but here at rank 10 the code re-applys the "knighted" tag again?
That does surprise and confuse me a bit too.
I don't remember adding that code.
Was it @Grey Roger?
He's usually good with replies, but he's on holiday for a few weeks.

I myself am also with my family for the week and away from my computer, so I can't check things right now either. :facepalm

Right now, I think the result would be that your character would be called:
Chief Warrant Officer Commander Edward Pellew.
Or Commander Chief Warrant Officer Edward Pellew.
One of the two... I'm not sure.

Do you want your rank to be appended to your character full name?
Or do you want it to display separately in an interface somewhere?

In this screenshot, do you want to replace the "Lieutenant" text or the "Naval Captain" one?
I'd suggest picking one of the two and, for starters, just make it display the word "Test" so you know you found the right line.
(Trick: interface files are compiled at the moment an interface is opened, so you can Alt+Tab in/out of the game to make your changes without having to actually reload the full game. Just close the interface and reopen.)
 
First, an explanation of how ranks and titles work. There are two functions:
'SetRank(ref char, int iNation, int newrank)', defined in "PROGRAM\Characters\CharacterUtilite.c", sets the character's actual rank for that nation. Ranks are defined in "PROGRAM\NATIONS\nations_init.c" and copied in "RESOURCE\INI\TEXTS\ENGLISH\common.ini". That is used when you are promoted by talking to a governor, and it can also be used to set an NPC to a particular rank - for example, in "PROGRAM\Characters\init\SideQuest.c", it's used for "Sir Rodney Leighton" to set his rank to 8, Rear Admiral.

"SetRankTitle" is normally used to add a prefix such as "Sir". As you saw, it's used in "NK.c" when you are knighted, and it's also used on "Sir Rodney Leighton" to make him a "Sir". Exactly what that does to a character's name depends on whether the character is a naval officer or not. If he is, the rank goes before the prefix. Play the "Hornblower" storyline and listen to the video in which Captain Pellew introduces himself - or just watch the video directly using something like VLC on "RESOURCE\VIDEOS\Hornblower\Declaration of War.wmv":
Edward Pellew said:
My name is Captain Sir Edward Pellew and I'm here to tell you that your days of idling are over!
It also depends on which version of the character's name is being used. There are several functions in "PROGRAM\Dialog_func.c" to show a character's name with varying levels of formality, ranging from 'GetMySimpleName' which just gives the basic name, up to 'GetMyFullName' which shows the whole lot.

Being given the title "Sir" at level 7 was already in "NK.c". I expanded it a bit, including the title "Lord" for England at level 10, equivalents to "Sir" for other nations at level 7, and some tweaking of "Dialog_func.c" to display titles and ranks correctly. See this thread for more details:Needs Testing - Nobs and Nobility

As for your officer Edward Pellew, you've used 'SetRank(ch, ENGLAND, 5)' to make him a Commander, then used 'SetRankTitle(ch, TranslateString("", "Chief Warrant Officer"))' to give him the prefix "Chief Warrant Officer". Warrant officers are either non-commissioned officers or very junior officers, and a rank 5 Commander is neither. In any case, as you've found, it doesn't work for your purpose. 'GetMyFullName' would call him "Commander Chief Warrant Officer Edward Pellew". 'GetMySimpleName', which appears to be used for the character's name in the interface screen, will simply call him "Edward Pellew". And his rank at the top of the screeen will display his real rank, which is "Commander".

As for Groves, that 'SetRankTitle(PChar, TranslateString("", "Commander"))' will have an interesting effect. As you've seen, it does nothing to his interface screen. But 'GetMyFullName' will show him as "Lieutenant Commander Theodore Groves". And Lieutenant Commander is a Lieutenant in command of a small ship, though according to Wikipedia, the Royal Navy only adopted the term in 1914, rather too late for our purposes! I'll probably remove that line from "NK.c", and Lieutenant Groves can earn his promotions to Commander the same way as any other Lieutenant.
 
Back
Top