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

High Priority Change way shared XP works

jsv

Freebooter
Storm Modder
Maybe they could ALWAYS join in the XP joining for their own roles, so that the perk can add them gaining XP in other areas too?
I think that would be logical. Full experience for work they do, regardless the perk. With perk, a fraction of main character' XP (in addition to what they get for doing their work), regardless their role.
 
Sounds like an good idea to me!
 
So.... will you try to make that happen then soon....? :ninja
Before the end of the holliday its working right. Hopefully I can get this to work before next week. But my time is a bit limited this week.
 
Shame. We'll have to make do, I suppose. :shrug

This evening I'll make another EXE, so at least we're all up-to-date again.
If you have anything to include, consider me interested. :cheeky
 
So if I understood right we want all XP by the mainplayer to also go to officers but only if they contribute the skill they will get the XP untill you enabled shared XP this will allow them to Level in other skills also if the main Player receives the XP.
What happens when an officer gets the XP himself. For example by fighting? Should he still get the XP or not? Should this also go to the other officers or the mainchar or not?
 
What happens when an officer gets the XP himself. For example by fighting? Should he still get the XP or not?
I'd think so.

Should this also go to the other officers or the mainchar or not?
Huh... I see two possible answers to that:
  • A logical, but ridiculously complex one: yes, if he himself has Shared XP perk
  • A simple one: no ;)
 
I figure: Without Shared XP, the XP should go ONLY to the player/officer who gained it.
However, in virtually all cases other than Fencing, it is hard to say who should have gained it.
If the player gains Repair, for example, is that because HE oversaw the repairs or because his Carpenter did
I figure it would be fair to have the XP gain for the player AND that Carpenter.

Probably Fencing should not be affected by "Shared XP" in the first place as that is ALWAYS individual.

So without Shared XP:
- Fencing is purely personal and not shared
- Other skills are added ONLY to the characters who gained the skill
- I think it is often ambiguous whether it was the player or an officer, therefore: Do Share XP between officers, BUT multiply it with the "officer skill modifiers"
So if "Repair" is gained, add it to AND the player AND the Carptenter, but NOT the Quartermaster. Multiply by half as appropriate; I recall some officer types have that.
If it is NOT ambiguous, add the skill to ONLY the officer (100%) and NOT the player (0%).

With Shared XP:
- Fencing is still purely personal and not shared
- Certain percentage of ALL skill gains added to ALL officers

Ideally this should mean that officers ALWAYS gain experience in their appropriate fields, even without Shared Experience.
So with Shared Experience, the advantage is that officers gain MORE experience and also in fields that are not their own, which may lead to multi-purpose officers.


Controversial idea:
Only add 50% of the XP to the player without Shared XP instead of 100%. Increase this to 100% when you do have it.
That means that without Shared XP, your officers would gain XP faster than the player does!
I think I may quite like that idea.... :cheeky
 
Okay so trying this in my logic:

When XP is gained every passenger will gain get the XP call.
If the character didn't get the XP self the following check is done:
- Is shared XP active?
>If Yes then give X% of XP to this character
>If NO check if character contributes this skill'
->If Yes add XP multiplied with officermodifier based on contribution
->If No don't add the XP for this character

They should be able to stack up so it wont happens the officer actually getting less XP when shared XP is active.

This means I can get rid of the whole System I had in place with different XP Groups. Where some only went to the Player while other xp also went to the officers (active ones only) and some only went to the passengers.

Also I think this will cause Problems with ships. Because there should be a check when on sea, only the ship which is getting the XP must be checked.
Also what about XP which isn't assigned to a certain skill. should this be split up to different skills first and then still passed on to the officers or not....

I haven't figured it out all yet, sugestions are welcome....
 
I haven't studied XP-related code yet, so my suggestions are probably of little use, but the logic I imagine goes more like this:

Whenever XP received is associated with a particular skill, it's shared between all contributors (mainchar & contributing officers; captain and his officers if there is no mainchar in sight).
If it's something like melee XP, the character that receives it is the sole contributor, so it's not shared.
Independently of this, when the main character receives any XP, is there is Share XP in effect:
  • The main character gets less XP (say, 70%)
  • The remaining 30% are distributed between everyone who is not the main character.
That leaves questions of what to do about XP not associated with any particular skill, and how everything is supposed to work when AUTO_SKILL is off.
 
This is how it's divded now:
Code:
bool AddXP(ref chref, string expName, int _exp, string group)
{
    bool LevelUp = false;
    //First catch some weird cases which shouldn't happen in the first place. let log if they do happen.
    if(!CheckAttribute(chref,"index")) { return false; if(DEBUG_EXPERIENCE>0) Trace("XP ERROR: Character "+GetMySimpleName(chref)+" has no index");}
    if(sti(chref.index)<0) { return false; if(DEBUG_EXPERIENCE>0){ Trace("XP ERROR: Character "+GetMySimpleName(chref)+" has index smaller than 0");} }
    if(_exp <= 0)
    {
        _exp = -(_exp);
        if(DEBUG_EXPERIENCE>0) { Trace("XP ERROR: NEGATIVE OR ZERO XP");}
    }
    if(_exp == 0) return false;
   
    //Check for shared experience
    bool SharedXP = GetOfficersPerkUsing(chref,"SharedExperience");
   
    if(DEBUG_EXPERIENCE>1) Trace("XP LOG: Called AddXP for "+GetMySimpleName(chref)+" with skill: "+expName+" and xp: "+_exp+" and group: "+group);
    if(DEBUG_EXPERIENCE>1) { if(SharedXP) Trace("XP LOG: SharedXP is active"); }
   
    //Add a difficulty multiplier
    float diffmult = 1.0-((GetDifficulty()-1.0) / 6.0); //Let's make it a bit less dependent on difficulty

    //First handle the character which gets the XP
    float xpmult = GetXPmult(expName);
    int xp = makeint(makefloat(_exp)*xpmult);
    if(AddXPtoChar(chref, expName, makeint(diffmult*xp))) LevelUp = true;
   
    //Now handle the officers
    int cn;
    if(SharedXP || group == XP_GROUP_OFFIC || group == XP_GROUP_PARTY)
    {
        if(FindCaptainIndex(chref) >= 0)
        {
            //If this character is part of a party we want to have the whole party.
            ref captain = GetCharacter(FindCaptainIndex(chref));
            if(DEBUG_EXPERIENCE>1) Trace("XP LOG: Checking officers for captain "+GetMySimpleName(captain));
            //Check if the captain has got the XP already
            if(captain.index != chref.index)
            {
                xpmult = XP_GAIN_OFFIC_ACTIVE;
                if(SharedXP) xpmult += XP_PERCENTAGE_SHARED;
                xp = makeint(_exp*xpmult);
                if(AddXPtoChar(captain, expName, makeint(diffmult*xp))) LevelUp = true;
            }
            if(DEBUG_EXPERIENCE>1) Trace("XP LOG: Start checking officers");
            for(int i=0; i < GetPassengersQuantity(captain); i++)
            {
                cn = GetPassenger(chref, i);
                //Filter the original character and prisoned characters
                if(cn < 0 || cn == chref.index) continue;
                if(CheckAttribute(Characters[cn],"prisoned") && sti(Characters[cn].prisoned)) continue;
                //Set the percentage of xp given.
                xpmult = 0;
                if(SharedXP) xpmult = XP_PERCENTAGE_SHARED;
                if(group == XP_GROUP_OFFIC)
                {
                    if (IsOfficer(Characters[cn]))
                    {
                        xpmult += XP_GAIN_OFFIC_ACTIVE;
                    }
                    else
                    {
                        xpmult += XP_GAIN_OFFIC_INACTIVE;
                    }
                }
                xp = makeint(_exp*xpmult);
                //Add the experience
                if(AddXPtoChar(&Characters[cn], expName, makeint(diffmult*xp))) LevelUp = true;
            }
        }
    }
   
    //Now handle the companions
    if(SharedXP || group == XP_GROUP_PARTY)
    {
        if(DEBUG_EXPERIENCE>1) Trace("XP LOG: Checking companions");
        if(GetCompanionQuantity(chref) > 1)
        {
            for(i=1; i < 4; i++)
            {
                cn = GetCompanionIndex(chref, i);
                //Filter the original character and prisoned characters
                if(cn < 0 || cn == chref.index) continue;
                if(CheckAttribute(Characters[cn],"prisoned") && sti(Characters[cn].prisoned)) continue;
                //Set the percentage of xp given.
                xpmult = 0;
                if(SharedXP) xpmult = XP_PERCENTAGE_SHARED;
                if(group == XP_GROUP_PARTY) xpmult += XP_GAIN_COMPANION;
                xp = makeint(_exp*xpmult);
                //The companion might have officers also so call self to manage this but with less XP already.
                if(AddXP(&Characters[cn], expName, xp, XP_GROUP_OFFIC)) LevelUp = true;;
            }
        }
    }
    //returns true if there is a levelup somewhere
    return LevelUp;
}

And this is how they are called:

Code:
//Old XP functions, now all redirect to the new one

int AddCharacterExpChar(ref chref, string expName, int _exp) {return makeint(AddXP(chref, expName, _exp, XP_GROUP_PLAYER));}
int AddCharacterExp(ref chref,int _exp) { return makeint(AddXP(chref, "", _exp, XP_GROUP_OFFIC)); }
void Ship_AddCharacterExpChar(ref rCharacter, string expName, int iExpQuantity) { AddXP(rCharacter, expName, iExpQuantity, XP_GROUP_OFFIC); }
int AddCharacterExpNSChar(ref chref, string expName, int _exp) { return makeint(AddXP(chref, expName, _exp, XP_GROUP_PLAYER)); }
int AddCharacterExpNS(ref chref,int _exp) { return makeint(AddXP(chref, "", _exp, XP_GROUP_PLAYER)); }
void AddPartyExpChar(ref chref, string expName, int _exp) { AddXP(chref, expName, _exp, XP_GROUP_PARTY); }
void AddPartyExp(ref chref, int _exp) { AddXP(chref, "", _exp, XP_GROUP_PARTY); }
void AddExpAndShow(ref chref, int _exp)
{
	AddXP(chref, "", _exp, XP_GROUP_PLAYER);
	Log_SetStringToLog("+" + _exp + XI_ConvertString("add experience"));
}
 
Looking at this a bit more I think the first one should mazbe be GROUP_OFFICER instead of Player .... I believe i changed that in the past already ...
 
Also I think this will cause Problems with ships. Because there should be a check when on sea, only the ship which is getting the XP must be checked.
True, that.

Also what about XP which isn't assigned to a certain skill. should this be split up to different skills first and then still passed on to the officers or not....
Does that happen? If so, where and when? Do we even want that at all?

Independently of this, when the main character receives any XP, is there is Share XP in effect:
  • The main character gets less XP (say, 70%)
  • The remaining 30% are distributed between everyone who is not the main character.
So "Shared XP" would give a NEGATIVE effect on the player, but a POSITIVE one on the officers?
I'm not sure that change would be met with much enthusiasm by the players.... Especially since it cannot be reversed....

When XP is gained every passenger will gain get the XP call.
Would it be more efficient to ONLY call it for those characters who will actually get something done?
So quick loop to determine if the characters are contributing officers for that specific skill before applying the XP gain to only those characters?
 
Does that happen? If so, where and when? Do we even want that at all?
Yes it happens for example when someone gets a fake levelup or when someone is initialized. Also there might be cases where this happens because someone didn't specify the skill. Also if you are playing without Auto Level it now happens a lot still unless I remove all those checks. And then still how should no-Auto Level work?

So "Shared XP" would give a NEGATIVE effect on the player, but a POSITIVE one on the officers?
I'm not sure that change would be met with much enthusiasm by the players.... Especially since it cannot be reversed....
Not what we want indeed

Would it be more efficient to ONLY call it for those characters who will actually get something done?
So quick loop to determine if the characters are contributing officers for that specific skill before applying the XP gain to only those characters?
with the call I mean mostly Looping trough them indeed, its not applying the XP. Just checking if the Person actually gets the XP.
 
Yes it happens for example when someone gets a fake levelup or when someone is initialized.
I think in those specific cases, any "Shared XP" functionality can safely be skipped.
If you do (Fake?) Level-Up on a character, it is only on that character. Same for the initialization process.

Also there might be cases where this happens because someone didn't specify the skill.
In that case, we should find those instances and change them so they DO specify the skill.

Also if you are playing without Auto Level it now happens a lot still unless I remove all those checks. And then still how should no-Auto Level work?
I figure for Auto Level System OFF, any call to a skill-specific function should be re-routed to a generic one.
Then for sharing, the same "contributing skills" logic can be used for Auto Skill System ON, I imagine.

That way we could get rid of all the if-statements for "Auto Skill System" and keep it purely within the functions themselves.
 
you can already get rid of the Auto skill Switches. I just was to lazy to Change it. and left it for now in case we decided to Change things again etc.

But I prefer to Keep the ability to assign XP to a character without defining which skill it is. This is also used at the Moment for the character Progression over time (NPC's) this is a function which has been there for very Long already. I haven't touched it yet, after build 14 I want to Change this too).
 
But I prefer to Keep the ability to assign XP to a character without defining which skill it is. This is also used at the Moment for the character Progression over time (NPC's) this is a function which has been there for very Long already.
Fine by me. But I think Shared XP doesn't need to be considered for that specific functionality.
Might save you some work. :cheeky
 
Fine by me. But I think Shared XP doesn't need to be considered for that specific functionality.
Might save you some work. :cheeky
I think it does.
Say someone did a quest, you might want to reward him some General XP and some specific one. Then the shared XP should work I think. But I will look into tonight/tomorrow and see if I can come up with a better logic as we have now....
 
think it does.
Say someone did a quest, you might want to reward him some General XP and some specific one. Then the shared XP should work I think.
I think General XP simply shouldn't be awarded like that. So if there ARE such instances, I'd suggest changing them to be for some specific skill.

No need making things more complicated than they need to be. :shrug
 
Back
Top