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

WIP Periods, royalty names & wars

nice xD yeah Ill use the XX dates no problem! and add a desc line, just wanted to make sure I didnt do a lot of work in vain :p could it be simply a word or so for each war, which could then be expanded on in a text doc, to make it a bit easier to get an overview of the code?

Yes we can use translate functions for this. Just make sure it's something unique.
 
what is sleep even

anyway, heres what I dun so far! hope it looks alright, is useful and isnt wrong/broken xD I put it in PROGRAM\NATIONS, but that obviously doesnt matter at this point. Ive added wars from spanish main up to revolutions. early explorers will come later as the wars are still confusing (to me) and I imagine that its the least popular period too, what with the lack of nations. revolutions I just havent had time to look at yet. I also havent done napoleonic yet because I feel ppl are often quite particular about those wars and Im not very familiar with them, so input is welcome :p input is very welcome overall tbh! :type1
 

Attachments

  • RealisticRelations.c
    28.1 KB · Views: 156
mostly putting this here for myself.
In DailyCrewUpdate look for
Code:
    // Fudge Dragon: Changing Face of the Caribbean -->
    if (sti(GetStorylineVar(FindCurrentStoryline(), "CHANGING_RELATIONS")))
    { 
        // Sulan: improved code and moved it to nations.c
        RandomNationsRelationsChange();
    }
    // Fudge Dragon: Changing Face of the Caribbean <--
Inside this ifstatement we should have a ifstatement which checks if we want realistic or random relation changes.
If the relatistic option is chosen a new funciton has to be called.
Code:
// STEP 2: Figure out what to do with them
        switch(GetNationRelation(i,j))
        {
            case RELATION_ENEMY:
                logTitle = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" make peace";
                logEntry = "After some time of bloody warfare "+GetNationNameByType(i)+" and "+GetNationNameByType(j)+" have declared a ceasefire.";
                if(GetNationRelation2MainCharacter(i)==RELATION_FRIEND && GetNationRelation2MainCharacter(j)==RELATION_FRIEND) logEntry += " This is good news as it was a very hard time to keep friendly relations with two warfaring parties.";
                if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += "\n \nAlthough good news in general, this is bad news for me. Attacking "+GetNationDescByType(j)+" ships and towns will not raise my reputation with the "+GetNationDescByType(i)+" anymore.";
                if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += "\n \nAlthough good news in general, this is bad news for me. Attacking "+GetNationDescByType(i)+" ships and towns will not raise my reputation with the "+GetNationDescByType(j)+" anymore.";
                WriteNewLogEntry(logTitle, logEntry, "General",false);
                newRelation = RELATION_NEUTRAL;
                break;
            case RELATION_NEUTRAL:
                random = rand(2);
                if(random==0)
                {
                    logTitle = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" have allied";
                    logEntry = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" have formed an alliance. Attacking ships or towns of either nation will also decrease the standing with the ally.";
                    if(GetNationRelation2MainCharacter(i)==RELATION_FRIEND && GetNationRelation2MainCharacter(j)==RELATION_FRIEND) logEntry += " Very good news, indeed. Working for the "+GetNationDescByType(i)+" and the "+GetNationDescByType(j)+", as I currently do, my deeds will raise my standing with both nations.";
                    if(GetNationRelation2MainCharacter(i)==RELATION_ENEMY && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += " Whoops! It seems I have bothered them a little too much. But their alliance won't stop me.";
                    if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += "\n \nThis makes working for the "+GetNationDescByType(i)+" somewhat more difficult, as sinking "+GetNationDescByType(j)+" ships is no longer an option.";
                    if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += "\n \nThis makes working for the "+GetNationDescByType(j)+" somewhat more difficult, as sinking "+GetNationDescByType(i)+" ships is no longer an option.";
                    WriteNewLogEntry(logTitle, logEntry, "General",false);
                    newRelation = RELATION_FRIEND;
                }
                if(random==1)  // i declared war on j
                {
                    logTitle = GetNationNameByType(i)+" is at war with "+GetNationNameByType(j);
                    logEntry = GetNationNameByType(i)+" has declared war on "+GetNationNameByType(j)+". "+GetNationDescByType(i)+" ships have attacked a small "+GetNationDescByType(j)+" settlement, as I was told.";
                    if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += "\n \nIt was about time to show those "+GetNationDescByType(j)+" landlubbers who's in charge in the caribbean!";
                    if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += "\n \nThose bloody cowards! The next "+GetNationDescByType(i)+" ship we encounter will surely pay for this.";
                    WriteNewLogEntry(logTitle, logEntry, "General",false);
                    newRelation = RELATION_ENEMY;
                }
                if(random==2)  // j declared war on i
                {
                    logTitle = GetNationNameByType(j)+" is at war with "+GetNationNameByType(i);
                    logEntry = GetNationNameByType(j)+" has declared war on "+GetNationNameByType(i)+". "+GetNationDescByType(j)+" troops have landed near  "+GetTownByNation(i)+", as I was told.";
                    if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += "\n \nThose bloody cowards! The next "+GetNationDescByType(j)+" ship we encounter will surely pay for this.";
                    if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += "\n \nIt was about time to show those "+GetNationDescByType(i)+" landlubbers who's in charge in the caribbean!";
                    WriteNewLogEntry(logTitle, logEntry, "General",false);
                    newRelation = RELATION_ENEMY;
                }
                break;
            case  RELATION_FRIEND:
                random = rand(2);
                if(random==0)
                {
                    logTitle = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" broke their alliance";
                    logEntry = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" have broken their alliance, but are currently peaceful. Observers report military activity on both sides, but so far an open conflict has been avoided.";
                    newRelation = RELATION_NEUTRAL;
                }
                if(random==1) // i broke the alliance
                {
                    logTitle = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" broke their alliance";
                    logEntry = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" have broken their alliance and are now at war! It was reported that "+GetNationNameByType(i)+" broke the alliance by "+GetBreakAllianceReason(i,j);
                    if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += "\n \nThose treacherous bastards! The "+GetNationDescByType(i)+" will pay for this betrayal. I have ordered to open fire on sight of any "+GetNationDescByType(i)+" ship.";
                    WriteNewLogEntry(logTitle, logEntry, "General",false);
                    newRelation = RELATION_NEUTRAL;
                }
                if(random==2) // j broke the alliance
                {
                    logTitle = GetNationNameByType(j)+" and "+GetNationNameByType(i)+" broke their alliance";
                    logEntry = GetNationNameByType(j)+" and "+GetNationNameByType(i)+" have broken their alliance and are now at war! It was reported that "+GetNationNameByType(j)+" broke the alliance by "+GetBreakAllianceReason(j,i);
                    if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += "\n \nThose treacherous bastards! The "+GetNationDescByType(j)+" will pay for this betrayal. I have ordered to open fire on sight of any "+GetNationDescByType(j)+" ship.";
                    WriteNewLogEntry(logTitle, logEntry, "General",false);
                    newRelation = RELATION_ENEMY;
                }
            break;
        }
This part of the code has to be duplicated at least and maybe it can be reused for both functions if we find an easy way to have the newRelation be determined differently. Maybe still have this piece of code but have the logentries trigger on the newRelation instead in a new function which can be called from both functions. On the other hand we might need to rewrite it completly because the logentries also have to be different.
Code:
        // STEP 3: Change relation and match player if required
        SetNationRelationBoth(i, j, newRelation);
        if(ServedNation != PERSONAL_NATION)                // For any player that serves a specific nation
        {
            if(i == ServedNation || j == ServedNation)
            {
                if(i == ServedNation) i = j;            // Don't change your relation to your OWN nation
                SetNationRelation2MainCharacter(i, newRelation);
            }
        }

        // STEP 4: Notify the player that this happened the first time
        if(!CheckAttribute(PChar, "changing_relations_note"))    // PB: Add clarifying note
        {
            SetQuestHeader("changing_relations");
            AddQuestRecord("changing_relations", "1");
            CloseQuestHeader("changing_relations");
            PChar.changing_relations_note = 1;
        }
This part has to be replicated too and we probably need to change the nationrelations book a bit and has another quest record for this.
 
mostly putting this here for myself.
In DailyCrewUpdate look for
Code:
    // Fudge Dragon: Changing Face of the Caribbean -->
    if (sti(GetStorylineVar(FindCurrentStoryline(), "CHANGING_RELATIONS")))
    {
        // Sulan: improved code and moved it to nations.c
        RandomNationsRelationsChange();
    }
    // Fudge Dragon: Changing Face of the Caribbean <--
Inside this ifstatement we should have a ifstatement which checks if we want realistic or random relation changes.
If the relatistic option is chosen a new funciton has to be called.
Code:
// STEP 2: Figure out what to do with them
        switch(GetNationRelation(i,j))
        {
            case RELATION_ENEMY:
                logTitle = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" make peace";
                logEntry = "After some time of bloody warfare "+GetNationNameByType(i)+" and "+GetNationNameByType(j)+" have declared a ceasefire.";
                if(GetNationRelation2MainCharacter(i)==RELATION_FRIEND && GetNationRelation2MainCharacter(j)==RELATION_FRIEND) logEntry += " This is good news as it was a very hard time to keep friendly relations with two warfaring parties.";
                if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += "\n \nAlthough good news in general, this is bad news for me. Attacking "+GetNationDescByType(j)+" ships and towns will not raise my reputation with the "+GetNationDescByType(i)+" anymore.";
                if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += "\n \nAlthough good news in general, this is bad news for me. Attacking "+GetNationDescByType(i)+" ships and towns will not raise my reputation with the "+GetNationDescByType(j)+" anymore.";
                WriteNewLogEntry(logTitle, logEntry, "General",false);
                newRelation = RELATION_NEUTRAL;
                break;
            case RELATION_NEUTRAL:
                random = rand(2);
                if(random==0)
                {
                    logTitle = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" have allied";
                    logEntry = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" have formed an alliance. Attacking ships or towns of either nation will also decrease the standing with the ally.";
                    if(GetNationRelation2MainCharacter(i)==RELATION_FRIEND && GetNationRelation2MainCharacter(j)==RELATION_FRIEND) logEntry += " Very good news, indeed. Working for the "+GetNationDescByType(i)+" and the "+GetNationDescByType(j)+", as I currently do, my deeds will raise my standing with both nations.";
                    if(GetNationRelation2MainCharacter(i)==RELATION_ENEMY && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += " Whoops! It seems I have bothered them a little too much. But their alliance won't stop me.";
                    if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += "\n \nThis makes working for the "+GetNationDescByType(i)+" somewhat more difficult, as sinking "+GetNationDescByType(j)+" ships is no longer an option.";
                    if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += "\n \nThis makes working for the "+GetNationDescByType(j)+" somewhat more difficult, as sinking "+GetNationDescByType(i)+" ships is no longer an option.";
                    WriteNewLogEntry(logTitle, logEntry, "General",false);
                    newRelation = RELATION_FRIEND;
                }
                if(random==1)  // i declared war on j
                {
                    logTitle = GetNationNameByType(i)+" is at war with "+GetNationNameByType(j);
                    logEntry = GetNationNameByType(i)+" has declared war on "+GetNationNameByType(j)+". "+GetNationDescByType(i)+" ships have attacked a small "+GetNationDescByType(j)+" settlement, as I was told.";
                    if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += "\n \nIt was about time to show those "+GetNationDescByType(j)+" landlubbers who's in charge in the caribbean!";
                    if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += "\n \nThose bloody cowards! The next "+GetNationDescByType(i)+" ship we encounter will surely pay for this.";
                    WriteNewLogEntry(logTitle, logEntry, "General",false);
                    newRelation = RELATION_ENEMY;
                }
                if(random==2)  // j declared war on i
                {
                    logTitle = GetNationNameByType(j)+" is at war with "+GetNationNameByType(i);
                    logEntry = GetNationNameByType(j)+" has declared war on "+GetNationNameByType(i)+". "+GetNationDescByType(j)+" troops have landed near  "+GetTownByNation(i)+", as I was told.";
                    if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += "\n \nThose bloody cowards! The next "+GetNationDescByType(j)+" ship we encounter will surely pay for this.";
                    if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += "\n \nIt was about time to show those "+GetNationDescByType(i)+" landlubbers who's in charge in the caribbean!";
                    WriteNewLogEntry(logTitle, logEntry, "General",false);
                    newRelation = RELATION_ENEMY;
                }
                break;
            case  RELATION_FRIEND:
                random = rand(2);
                if(random==0)
                {
                    logTitle = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" broke their alliance";
                    logEntry = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" have broken their alliance, but are currently peaceful. Observers report military activity on both sides, but so far an open conflict has been avoided.";
                    newRelation = RELATION_NEUTRAL;
                }
                if(random==1) // i broke the alliance
                {
                    logTitle = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" broke their alliance";
                    logEntry = GetNationNameByType(i)+" and "+GetNationNameByType(j)+" have broken their alliance and are now at war! It was reported that "+GetNationNameByType(i)+" broke the alliance by "+GetBreakAllianceReason(i,j);
                    if(IsInServiceOf(j) && GetNationRelation2MainCharacter(i)==RELATION_ENEMY) logEntry += "\n \nThose treacherous bastards! The "+GetNationDescByType(i)+" will pay for this betrayal. I have ordered to open fire on sight of any "+GetNationDescByType(i)+" ship.";
                    WriteNewLogEntry(logTitle, logEntry, "General",false);
                    newRelation = RELATION_NEUTRAL;
                }
                if(random==2) // j broke the alliance
                {
                    logTitle = GetNationNameByType(j)+" and "+GetNationNameByType(i)+" broke their alliance";
                    logEntry = GetNationNameByType(j)+" and "+GetNationNameByType(i)+" have broken their alliance and are now at war! It was reported that "+GetNationNameByType(j)+" broke the alliance by "+GetBreakAllianceReason(j,i);
                    if(IsInServiceOf(i) && GetNationRelation2MainCharacter(j)==RELATION_ENEMY) logEntry += "\n \nThose treacherous bastards! The "+GetNationDescByType(j)+" will pay for this betrayal. I have ordered to open fire on sight of any "+GetNationDescByType(j)+" ship.";
                    WriteNewLogEntry(logTitle, logEntry, "General",false);
                    newRelation = RELATION_ENEMY;
                }
            break;
        }
This part of the code has to be duplicated at least and maybe it can be reused for both functions if we find an easy way to have the newRelation be determined differently. Maybe still have this piece of code but have the logentries trigger on the newRelation instead in a new function which can be called from both functions. On the other hand we might need to rewrite it completly because the logentries also have to be different.
Code:
        // STEP 3: Change relation and match player if required
        SetNationRelationBoth(i, j, newRelation);
        if(ServedNation != PERSONAL_NATION)                // For any player that serves a specific nation
        {
            if(i == ServedNation || j == ServedNation)
            {
                if(i == ServedNation) i = j;            // Don't change your relation to your OWN nation
                SetNationRelation2MainCharacter(i, newRelation);
            }
        }

        // STEP 4: Notify the player that this happened the first time
        if(!CheckAttribute(PChar, "changing_relations_note"))    // PB: Add clarifying note
        {
            SetQuestHeader("changing_relations");
            AddQuestRecord("changing_relations", "1");
            CloseQuestHeader("changing_relations");
            PChar.changing_relations_note = 1;
        }
This part has to be replicated too and we probably need to change the nationrelations book a bit and has another quest record for this.
any progress on this? xD I experimented a bit and tried to get some info from the RealisticRelations.c like the dates with GetSubString() or whatever the function is called, but I couldnt even get that to work cuz Im a doofus :mad:
 
any progress on this? xD I experimented a bit and tried to get some info from the RealisticRelations.c like the dates with GetSubString() or whatever the function is called, but I couldnt even get that to work cuz Im a doofus :mad:
What did you try? What didn't work? And how didn't it work?
 
any progress on this? xD I experimented a bit and tried to get some info from the RealisticRelations.c like the dates with GetSubString() or whatever the function is called, but I couldnt even get that to work cuz Im a doofus :mad:
Not yet, I hope to take a look at it soon ;).
 
What did you try? What didn't work? And how didn't it work?
I #included the file in seadogs I think, then I called the function that adds the wars to the RelationChanges object. then I tried displaying the numbers with the console
Code:
day = GetSubString(CheckAttribute(RelationChanges, "30_years_war.date.start"),".",0);
    month = GetSubString(CheckAttribute(RelationChanges, "30_years_war.date.start"),".",1);
    year = GetSubString(CheckAttribute(RelationChanges, "30_years_war.date.start"),".",2);
LogIt(day + "." + month + "." + year);
I tried some strleft and strright etc too, but I gave up pretty soon to do some other stuff :p

Not yet, I hope to take a look at it soon ;).
no rush, just wanted to know the status :)
 
Code:
day = GetSubString(CheckAttribute(RelationChanges, "30_years_war.date.start"),".",0);
   month = GetSubString(CheckAttribute(RelationChanges, "30_years_war.date.start"),".",1);
   year = GetSubString(CheckAttribute(RelationChanges, "30_years_war.date.start"),".",2);
LogIt(day + "." + month + "." + year);
Won't work because you use CheckAttribute, this will only return a true or false value ;).
You want to do it like this probably:

Code:
if(CheckAttribute(RelationChanges, "30_years_war.date.start"))
{
   day = GetSubString(RelationChanges.30_years_war.date.start,".",0);
   month = GetSubString(RelationChanges.30_years_war.date.start,".",1);
   year = GetSubString(RelationChanges.30_years_war.date.start,".",2);
   LogIt(day + "." + month + "." + year);
}

You could also start with just doing a DumpAttributes(RelationChanges) to be sure the data is loaded into memory
 
Code:
day = GetSubString(CheckAttribute(RelationChanges, "30_years_war.date.start"),".",0);
   month = GetSubString(CheckAttribute(RelationChanges, "30_years_war.date.start"),".",1);
   year = GetSubString(CheckAttribute(RelationChanges, "30_years_war.date.start"),".",2);
LogIt(day + "." + month + "." + year);
Won't work because you use CheckAttribute, this will only return a true or false value ;).
You want to do it like this probably:

Code:
if(CheckAttribute(RelationChanges, "30_years_war.date.start"))
{
   day = GetSubString(RelationChanges.30_years_war.date.start,".",0);
   month = GetSubString(RelationChanges.30_years_war.date.start,".",1);
   year = GetSubString(RelationChanges.30_years_war.date.start,".",2);
   LogIt(day + "." + month + "." + year);
}

You could also start with just doing a DumpAttributes(RelationChanges) to be sure the data is loaded into memory
ah well, that would explain it :p

while I still think Im not at a programming level to create this function, still gonna ask for learnings sake xD is there any way to get the "30_years_war" part automatically, so to speak? like, making the game check for the dates using a wild card like if(gamedate >= GetSubString(RelationChanges.*.date.start,".",0) && gamedate <= GetSubString(RelationChanges.*.date.end,".",0)) (I realise that code wouldnt work its just as an example:p) but just checking between the same wild card name, so it doesnt use the start date for the Italian_war_1499 and the end date of the napoleonic war, and also return the name so it can be used for the relations and journals etc? dunno if that makes sense
 
ah well, that would explain it :p

while I still think Im not at a programming level to create this function, still gonna ask for learnings sake xD is there any way to get the "30_years_war" part automatically, so to speak? like, making the game check for the dates using a wild card like if(gamedate >= GetSubString(RelationChanges.*.date.start,".",0) && gamedate <= GetSubString(RelationChanges.*.date.end,".",0)) (I realise that code wouldnt work its just as an example:p) but just checking between the same wild card name, so it doesnt use the start date for the Italian_war_1499 and the end date of the napoleonic war, and also return the name so it can be used for the relations and journals etc? dunno if that makes sense

You can't use wildcards but you can use variables in these names.
So for example:
Code:
string name = "30_years_war";
string startdate = RelationChanges.(name).date.start;
day = GetSubString(startdate,".",0);
month = GetSubString(startdate,".",1);
year = GetSubString(startdate,".",2);
LogIt(day + "." + month + "." + year);

to loop trough all wars you can do something like this:
Code:
int amount_of_wars= GetAttributesNum(RelationChanges);
for(int i = 0; i < amount_of_wars; i++) 
{
   string war_index = GetAttributeName(GetAttributeN(RelatioinChanges,i));
   string startdate = RelationChanges.(war_index).date.start;
}

I believe this should work. It could be you need to make an aref first because it might not accept object as values.
To explain the functions:
GetAttributesNum will return the amount of attributes below this "thing". So say it would be like:
Code:
Thing
|- Attribute1
|- Attribute2
|- Attribute3
|    |-Sub_Attribute1
|    |-Sub_Attribute2
|- Attribute 4
It will return a value of 4 because there are 4 attributes.
GetAttributeN(ref,int) will return the specific numbered attribute. so in the previous example if you do GetAttributeN(Thing,3) it will return Attribute3
It will return it as an object so it will stil have the sub_attributes etc.
when using GetAttributeName you will get the name of this attribute. so if you do something like this GetAttributeName(GetAttributeN(Thing,3)) it will return a string containing Attribute3.
Hope this helps :).
 
You can't use wildcards but you can use variables in these names.
So for example:
Code:
string name = "30_years_war";
string startdate = RelationChanges.(name).date.start;
day = GetSubString(startdate,".",0);
month = GetSubString(startdate,".",1);
year = GetSubString(startdate,".",2);
LogIt(day + "." + month + "." + year);

to loop trough all wars you can do something like this:
Code:
int amount_of_wars= GetAttributesNum(RelationChanges);
for(int i = 0; i < amount_of_wars; i++)
{
   string war_index = GetAttributeName(GetAttributeN(RelatioinChanges,i));
   string startdate = RelationChanges.(war_index).date.start;
}

I believe this should work. It could be you need to make an aref first because it might not accept object as values.
To explain the functions:
GetAttributesNum will return the amount of attributes below this "thing". So say it would be like:
Code:
Thing
|- Attribute1
|- Attribute2
|- Attribute3
|    |-Sub_Attribute1
|    |-Sub_Attribute2
|- Attribute 4
It will return a value of 4 because there are 4 attributes.
GetAttributeN(ref,int) will return the specific numbered attribute. so in the previous example if you do GetAttributeN(Thing,3) it will return Attribute3
It will return it as an object so it will stil have the sub_attributes etc.
when using GetAttributeName you will get the name of this attribute. so if you do something like this GetAttributeName(GetAttributeN(Thing,3)) it will return a string containing Attribute3.
Hope this helps :).
definitely does xD it still makes my head spin, but with some more thinking and a bit of experimenting I think Ill understand it soon enough :p
 
so for a bit of fun and learning, I tried to write some object code. I havent spellchecked or ran it in game etc, but conceptually, would something like this work?
Code:
int dateDay,dateMonth,dateYear;
    ref PChar = GetMainCharacter();
    
    dateDay = GetDataDay();
    dateMonth = GetDataMonth();
    dateYear = GetDataYear();
    
    int amount_of_wars = GetAttributeNum(RelationChanges);
    for(int i = 0; i < amount_of_wars; i++){
        string war_name = GetAttributeName(GetAttributeN(RelationChanges,i));
        
        int startDay = sti(GetSubString(GetAttribute(RelationChanges,(war_name).date.start),".",0));
        int startMonth = sti(GetSubString(GetAttribute(RelationChanges,(war_name).date.start),".",1));
        int startYear = sti(GetSubString(GetAttribute(RelationChanges,(war_name).date.start),".",2));
        
        int endDay = sti(GetSubString(GetAttribute(RelationChanges,(war_name).date.end),".",0));
        int endMonth = sti(GetSubString(GetAttribute(RelationChanges,(war_name).date.end),".",1));
        int endYear = sti(GetSubString(GetAttribute(RelationChanges,(war_name).date.end),".",2));
        
        if(startDay >= dateDay && startMonth >= dateMonth && startYear >= dateYear && endDay <= dateDay && endMonth <= dateMonth && endYear <= dateYear){
            RealisticRelations.(war_name).war_active = "true";
            amount_of_relation_changes = GetAttributeNum(GetAttributeN(RelationChanges,i).relations)/3;
            for(int j = 0; j < amount_of_relation_changes; j++){
                string relnum = "rel" + j;
                string Nation1 = RelationChanges.(war_name).relations.(relnum).nation1;
                string Nation2 = RelationChanges.(war_name).relations.(relnum).nation2;
                string RelationState = RelationChanges.(war_name).relations.(relnum).state;
                SetNationRelationBoth(Nation1,Nation2,RelationState);
            }
            string logStartTitle = GetAttribute(RelationChanges,(war_name).desc.start) + "_Title";
            string logStartEntry = GetAttribute(RelationChanges,(war_name).desc.start) + "_Entry";
            if(RelationChanges.(war_name).desc_start != "done"){
                RelationChanges.(war_name).desc_start = "done";
                WriteNewLogEntry(TranslateString(logStartTitle),TranslateString(logStartEntry),"General",true);
            }
        }
        else{
            if(CheckAttribute(RelationChanges.(war_name).war_active, "true")){
                string logEndTitle = GetAttribute(RelationChanges,(war_name).desc.end) + "_Title";
                string logEndEntry = GetAttribute(RelationChanges,(war_name).desc.end) + "_Entry";
                WriteNewLogEntry(TranslateString(logEndTitle),TranslateString(logEndEntry),"General",true);
                RelationChanges.(war_name).war_active = "false";
                DeleteAttribute(RelationChanges,(war_name).desc_start);
            }
        }
    }
 
Looks good. But I would personally first check for the attribute war_active inside your loop. if this is true you want to check for the enddate to be true.
If war_active isn't true you want to check if the start date is true, and if so you want to set the relations.
I think that would make your logic easier.

if it works you want to make it a function and call it from:
DailyCrewUpdate()

that way the function will be called each day.
 
Looks good. But I would personally first check for the attribute war_active inside your loop. if this is true you want to check for the enddate to be true.
If war_active isn't true you want to check if the start date is true, and if so you want to set the relations.
I think that would make your logic easier.
Im not sure I follow, but Ill see if I can work it out
if it works you want to make it a function and call it from:
DailyCrewUpdate()

that way the function will be called each day.
since the wars start dates are set to the exact day they were declared, when that info is available atleast, Im thinking if daily is maybe too often? its probably doesnt matter that much tbh cuz whos gonna notice or care, but for pseudorealism it could maybe check every 1-3 weeks? just putting it in the dailycrewupdate is probably the easiest way tho
 
Im not sure I follow, but Ill see if I can work it out

some pseudo code:
Code:
forloop
{
  if(war_active = true)
  {
    if(enddate is here)
    {
      Set relation back to neutral
      Make log entry
      Set war_active = false
    }
  }
  else
  {
      if(startdate is here)
      {
        Set relations to right setting
        make log entry
        set war_active = true
      }
  }
}

since the wars start dates are set to the exact day they were declared, when that info is available atleast, Im thinking if daily is maybe too often? its probably doesnt matter that much tbh cuz whos gonna notice or care, but for pseudorealism it could maybe check every 1-3 weeks? just putting it in the dailycrewupdate is probably the easiest way tho
Purely for testing purposes ;) eventually it should be incorperated in the function which does the relation changes so it's all together there and a check has to be added to see which settings are used etc :).
 
some pseudo code:
Code:
forloop
{
  if(war_active = true)
  {
    if(enddate is here)
    {
      Set relation back to neutral
      Make log entry
      Set war_active = false
    }
  }
  else
  {
      if(startdate is here)
      {
        Set relations to right setting
        make log entry
        set war_active = true
      }
  }
}
wont that turn into a loop that activates and deactivates every past war everytime its run? since if the war is ended and war_active is false, it will check if its after the start date, which it is, and activate the war again? or am I reading that wrong?
 
wont that turn into a loop that activates and deactivates every past war everytime its run? since if the war is ended and war_active is false, it will check if its after the start date, which it is, and activate the war again? or am I reading that wrong?
depens on how you check for the date. If you run it each day and only check if the date is there exactly it wont happen.
if you check for the date less accurate that's possible.
 
it just straight up refuses to recognize that war_active is an attribute, even after I added it to the wars themselves in their function :mad:
Code:
void RealisticNationsRelationsChange(){
   
    int dateDay,dateMonth,dateYear;
    ref PChar = GetMainCharacter();
   
    dateDay = GetDataDay();
    dateMonth = GetDataMonth();
    dateYear = GetDataYear();
   
    int amount_of_wars = GetAttributesNum(RelationChanges);
    for(int i = 0; i < amount_of_wars; i++){
        string war_name = GetAttributeName(GetAttributeN(RelationChanges,i));
        trace("Checking " + war_name);
       
       
        int startDay = sti(GetSubString(GetAttribute(RelationChanges,(war_name)+".date.start"),".",0));
        int startMonth = sti(GetSubString(GetAttribute(RelationChanges,(war_name)+".date.start"),".",1));
        int startYear = sti(GetSubString(GetAttribute(RelationChanges,(war_name)+".date.start"),".",2));
        trace("Start = " + startDay+"."+startMonth+"."+startYear);
       
        int endDay = sti(GetSubString(GetAttribute(RelationChanges,(war_name)+".date.end"),".",0));
        int endMonth = sti(GetSubString(GetAttribute(RelationChanges,(war_name)+".date.end"),".",1));
        int endYear = sti(GetSubString(GetAttribute(RelationChanges,(war_name)+".date.end"),".",2));
        trace("End = " + endDay+"."+endMonth+"."+endYear);
       
        int amount_of_relation_changes = GetAttributesNum(GetAttributeN(RelationChanges,i)+".relations")/3;
        if(RelationChanges.(war_name).war_active != "true" && startDay >= dateDay && startMonth >= dateMonth && startYear >= dateYear && endDay <= dateDay && endMonth <= dateMonth && endYear <= dateYear){
            RelationChanges.(war_name).war_active = "true";
            trace(war_name + " is active");
            for(int j = 0; j < amount_of_relation_changes; j++){
                string relnum = "rel" + j;
                string Nation1 = GetAttribute(RelationChanges,(war_name)+".relations."+(relnum)+".nation1");
                string Nation2 = GetAttribute(RelationChanges,(war_name)+".relations."+(relnum)+".nation2");
                string RelationState = GetAttribute(RelationChanges,(war_name)+".relations."+(relnum)+".state");
                SetNationRelationBoth(Nation1,Nation2,RelationState);
                trace("Nation 1 = " + Nation1 + " Nation 2 = " + Nation2 + " Relation = " + RelationState)
            }
            string logStartTitle = GetAttribute(RelationChanges,(war_name)+".desc.start") + "_Title";
            string logStartEntry = GetAttribute(RelationChanges,(war_name)+".desc.start") + "_Entry";
            WriteNewLogEntry(logStartTitle,logStartEntry,"General",true);
        }
        else{
            if(RelationChanges.(war_name).war_active == "true" && endDay > dateDay && endMonth > dateMonth && endYear > dateYear){
                trace(war_name + " has ended");
                string logEndTitle = GetAttribute(RelationChanges,(war_name)+".desc.end") + "_Title";
                string logEndEntry = GetAttribute(RelationChanges,(war_name)+".desc.end") + "_Entry";
                WriteNewLogEntry(logEndTitle,logEndEntry,"General",true);
                RelationChanges.(war_name).war_active = "tralse";
                for(int k = 0; k < amount_of_relation_changes; k++){
                    string relnumEnd = "rel" + k;
                    string Nation1End = GetAttribute(RelationChanges,(war_name)+".relations."+(relnumEnd)+".nation1");
                    string Nation2End = GetAttribute(RelationChanges,(war_name)+".relations."+(relnumEnd)+".nation2");
                    SetNationRelationBoth(Nation1End,Nation2End,RELATION_NEUTRAL);
                }
            }
        }
    }
}
seems to work alright otherwise

EDIT: jk, when removing the war_active check it runs thru the wars should in theory end all wars before the current date. it sure does end a lot of wars, but it doesnt end the right wars, it ends random wars from all over time and space and doesnt start the current war (30 years war in this case). no idea whats going on, guess theres some way left to go
 
Last edited:
You can use the DumpAttributes(RelationChanges) to see what is going on.
Could it be you maybe also call the init function again somewhere and therefore overwrite the attribute for war_active?
 
Back
Top