Aller au contenu

Photo

XP Giver - Hard Leveling


  • Veuillez vous connecter pour répondre
51 réponses à ce sujet

#26
WhiZard

WhiZard
  • Members
  • 1 204 messages

oh okay... my mistake

 

is any of these summons accessable for PC ?

 

 

There are summons with domination spells like the vampire mage (which can get a creature and its summons), there are direct summons (like the lesser demilich) and then the PC can dominate creatures to get their summons as well.


  • WhiteTiger aime ceci

#27
WhiteTiger

WhiteTiger
  • Members
  • 479 messages
A player complained that received less XP using Tenser Transformation spell. Is it possible to influence the system?

Instead of gaining 290 XP as usual, he only gained 235 XP.

//EDITED
290 XP because the party penalty (a high level creature iXP = 380)

Modifié par WhiteTiger, 16 juillet 2014 - 04:09 .


#28
Shadooow

Shadooow
  • Members
  • 4 465 messages

anyway you are better to go with some premade XP system that allows easy modification, the current script is pain to read and understand and therefore help you to modify

 

I used PWFXP in past. For some action-oriented PWs I made a 2DA-based xp system which I think I have somewhere on disk, but that wont be good for you I think. And currently no XP systems are on new vault, but maybe someone have the PWFXP?


  • WhiteTiger aime ceci

#29
WhiZard

WhiZard
  • Members
  • 1 204 messages

A player complained that received less XP using Tenser Transformation spell. Is it possible to influence the system?

Instead of gaining 290 XP as usual, he only gained 235 XP.

//EDITED
290 XP because the party penalty (a high level creature iXP = 380)

 

Definitely possible.  You use GiveXPToCreature() which includes the multiclass penalty, and your race is now elf.


  • Shadooow et WhiteTiger aiment ceci

#30
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

Definitely possible.  You use GiveXPToCreature() which includes the multiclass penalty, and your race is now elf.


yeah we use givexptocreature() surely

that's good to know, I like this so
 

anyway you are better to go with some premade XP system that allows easy modification

 

It can be difficult to interpret, but I do not think it would be a good to replace the system. Maybe some adjustments could solve our problem, don't you think?



#31
WhiZard

WhiZard
  • Members
  • 1 204 messages

It can be difficult to interpret, but I do not think it would be a good to replace the system. Maybe some adjustments could solve our problem, don't you think?

 

 

Your system does not care about who in the party makes the kill.  In that sense my suggestion of considering all characters to have the highest HD value for the party is closest to your design, and does fix the problem you have been seeing.  Shadooow is focused on seeing the killing blow as the determining factor for involvement.  This does prevent the PC from gaining significant XP from a high level creature, but if there already is an abuse where players are cooperating to get huge XP dumps, it won't be that long before they figure out that the higher level just fights until the creature is near death, allowing the lower level character to accomplish the killing blow (possibly via a summons).  As far as which system gains the least XP over all, it can vary from situation to situation.  And there is no true fix,  for example, two characters from different parties could cooperate so that the lower level is awarded the killing blow on a high level creature.  This neither of our systems can really fix.


  • WhiteTiger aime ceci

#32
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

Whizard,

 

There, the entire module, secret areas, and areas that only a few players can access. These areas were developed to a greater use of "multi-player". Thus, it is recommended that players organize themselves into groups for the matches. 

The repetition of XP in this case comes in the style of the game, but I did not agree on a level 40 player to party with a level 1 player and the second by the first level up by killing monsters middleman between the two levels.



#33
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

This neither of our systems can really fix.

 

To me they are all excellent solutions. why do you think so?

 

especially that which distributes XP by level difference between the killer and the party - this is the most likely to me

what do you think?



#34
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

Finished script thanks

//EDITED
//too old... =(

Modifié par WhiteTiger, 13 août 2014 - 09:22 .


#35
WhiZard

WhiZard
  • Members
  • 1 204 messages
if((GetHitDice(oKiller) < GetHitDice(oObject)))

 

 

Huh?  If Shadooow's method encourages high level players to set up kills for low level characters this does even more.  First of all, if there is a team of all equal leveled character's only one is going to get the XP, and if there is a highest level character, he would get just as much XP for going into improved expertise mode and being a meatshield or casting an immobilizing spell, as actually killing the target.  And if he doesn't score any kills, then other characters will get XP as well.  So why should the higher level character even try killing a monster?  The only thing he would get out of killing monsters is depriving others of XP.


  • WhiteTiger aime ceci

#36
Shadooow

Shadooow
  • Members
  • 4 465 messages

I am no longer watching this thread. All these issues you have and those that Whizard warn about has been solved so many times already.

 

Try get some custom XP system (I uploaded mine 2DA based xp system yesterday on vault - but that probably won't be exactly what you need). And modify its settings - will be ten times easier than to incorporate changes you need into this one you got.

 

If my xp system doesn't suit you, then I would suggest PWFXP - unfortunately i don't have in on my disk (only highly customized version which is for no use to you), but if you request it on scripting forum or on vault I am sure someone will upload it.


  • WhiteTiger aime ceci

#37
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

Thank you all for both ideas (about sequencer robe / xp giver). All stuff solved to me.  :)  



#38
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

Huh?  If Shadooow's method encourages high level players to set up kills for low level characters this does even more.  First of all, if there is a team of all equal leveled character's only one is going to get the XP, and if there is a highest level character, he would get just as much XP for going into improved expertise mode and being a meatshield or casting an immobilizing spell, as actually killing the target.  And if he doesn't score any kills, then other characters will get XP as well.  So why should the higher level character even try killing a monster?  The only thing he would get out of killing monsters is depriving others of XP.

 

just to clarify that my script works fine. 
 
This condition if ((GetHitDice (oKiller) <GetHitDice (oObject))) 
 
does not define who receives XP, but the amount of XP of the rest of players in party. this way all will receive XP (low then killer or same value of killer) so you can not level up a weak char by a strong char killing weak creatures


#39
WhiZard

WhiZard
  • Members
  • 1 204 messages

Okay, then it is inconsistent.  If the killer were level 5 and there were level 3 and level 7 characters in the party, then if the level 3 were found before the level 7 he would be treated as level 5, but if he were found after the level 7 then he would be treated as level 7.



#40
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

Okay, then it is inconsistent.  If the killer were level 5 and there were level 3 and level 7 characters in the party, then if the level 3 were found before the level 7 he would be treated as level 5, but if he were found after the level 7 then he would be treated as level 7.

 

not really, my friend

 

If the killer were level 5 and there were level 3 and 7 characters in the party, then level 3 would be treated as level 5 and the level 7 would be treated as level 7.

 

independent which was found first(level 7 or level 3)



#41
WhiZard

WhiZard
  • Members
  • 1 204 messages

not really, my friend

 

If the killer were level 5 and there were level 3 and 7 characters in the party, then level 3 would be treated as level 5 and the level 7 would be treated as level 7.

 

independent which was found first(level 7 or level 3)

 

Nope,  when 7 is considered iXP is set for that.  When 3 crops up later it uses iXP for 7.  The iXP for level 5 is overwritten by level 7.

 

EDIT: In case you were testing order that characters join a party, that is irrelevant.  GetFirst/NextPC() refers to the order that the players log in.



#42
MrZork

MrZork
  • Members
  • 938 messages

Just out of curiousity, why not a system that tracks the levels of two things: who damaged a creature and the party when a creature is killed? First, whenever a creature is damaged or killed, if the damager was a PC, maintain a pair of variables on it, HIGHEST_LEVEL_PC_ATTACKER and LOWEST_LEVEL_PC_ATTACKER and compare them to the current PC, updating as needed. (If the damager had a master, then use the top master's HP for the update.) Second, when the creature is killed, check that level spread of the PC attackers and also the level spread of the PCs in the party. If either level spread is too high, award whatever minimal XP is the agreed upon penalty, ideally with a message that "The PCs that damaged this creature are too far apart in level. Minimum XP has been awarded for this kill" or "The player characters in your party are too far apart in level. Minimum XP has been awarded for this kill", depending on which spread is too high.

 

Perhaps, no scheme will be perfect. But, wouldn't a system like that pretty much do the right thing? It deals with players letting low-level toons tag along with higher toons to get big XP awards and high level PCs tanking for lower level ones. It deals with a high-level PC from a different party getting a creature to near death and then letting a low-level PC kill it. It doesn't penalize a party of low-level PCs taking on tough creatures if they can. If provides some feedback so that players know why they aren't getting the XP they expect when they are penalized.


  • WhiteTiger aime ceci

#43
WhiZard

WhiZard
  • Members
  • 1 204 messages

Or think of the parties of all damagers/killer as one big party.  Store all damagers and loop through them on death (adding in the killer) to get all the parties involved. 


  • WhiteTiger aime ceci

#44
WhiZard

WhiZard
  • Members
  • 1 204 messages

I've quickly thrown together an XP giving script based on BioWare's model that extends XP gain to all involved parties.  The only major change I made was to consider all characters as possessing the highest HD in the party.

// Gets the Hit Dice based on XP for player characters
int GetTrueHD(object oCreature)
{
int nHD;
if (GetIsPossessedFamiliar(oCreature) || GetIsDMPossessed(oCreature) ||
   (!GetIsPC(oCreature) && !GetIsPossessedFamiliar(GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oCreature))))
  return GetHitDice(oCreature);
else
  return FloatToInt(sqrt(GetXP(oCreature)/500.0 + 0.25) + 0.5);
}

//Checks to see if there was hostility from the creature's faction
int GetIsInHostileParty(object oHostile, object oTarget = OBJECT_SELF)
{
object oHostilePartyMember;
int nNumInvolved = GetLocalInt(oTarget, "nNumEnemies");
int nNum;
for(nNum = 1; nNum <= nNumInvolved; nNum ++)
  {
  if(GetFactionEqual(oHostile, GetLocalObject(oTarget, "nEnemy" + IntToString(nNum))))
   return TRUE;
  }
return FALSE;
}

//Gets the slider setting as a module variable
//The actual slider value cannot be returned by a standard command
float GetXPSliderSetting()
{
return GetLocalFloat(GetModule(), "XP_SLIDER_SETTING");
}

//Gets the Party Size Penalty
float GetPartySizePenalty(int nPartySize)
{
return 4.0/(3 + nPartySize);
}


void main()
{
object oArea = GetArea(OBJECT_SELF);
object oInvolved = GetLastKiller();
object oPC, oFactionMember;
int nNum, nHD;
int nPartySize = 0;
float fXP;
int nHDMax = 0;
int nCR = FloatToInt(GetChallengeRating(OBJECT_SELF));
if(nCR > 40)
 nCR = 40;
int nNumInvolved = GetLocalInt(OBJECT_SELF, "nNumEnemies");
if(!GetIsInHostileParty(oInvolved))
  {
  nNumInvolved++;
  SetLocalObject(OBJECT_SELF, "nEnemy" + IntToString(nNumInvolved), oInvolved);
  SetLocalInt(OBJECT_SELF, "nNumEnemies", nNumInvolved);
  }
for(nNum = 1; nNum <= nNumInvolved; nNum++)
  {
  oInvolved = GetLocalObject(OBJECT_SELF, "nEnemy" + IntToString(nNumInvolved));
  oFactionMember = GetFirstFactionMember(oInvolved);
  while (GetIsObjectValid(oFactionMember))
    {
    if(GetArea(oFactionMember) == oArea && !GetIsDead(oFactionMember))
      {
      nPartySize++;
      nHD = GetTrueHD(oFactionMember);
      if(nHDMax < nHD)
        nHDMax = nHD;
      }
    oFactionMember = GetNextFactionMember(oInvolved);
    }
  }
oInvolved = GetFirstPC();
while(GetIsObjectValid(oInvolved))
  {
  if(GetIsPossessedFamiliar(oInvolved) || GetIsDMPossessed(oInvolved))
    oInvolved = GetMaster(oInvolved);
  if(GetIsInHostileParty(oInvolved) && GetArea(oInvolved) == oArea && !GetIsDead(oInvolved))
   {
   fXP = StringToFloat(Get2DAString("xptable", "C" + IntToString(nCR), nHDMax));
   fXP *= 10.0 * GetXPSliderSetting() * GetPartySizePenalty(nPartySize);
   GiveXPToCreature(oInvolved, FloatToInt(fXP));
   }
  oInvolved = GetNextPC();
  }
}

  • WhiteTiger aime ceci

#45
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

Nope,  when 7 is considered iXP is set for that.  When 3 crops up later it uses iXP for 7.  The iXP for level 5 is overwritten by level 7.

 

EDIT: In case you were testing order that characters join a party, that is irrelevant.  GetFirst/NextPC() refers to the order that the players log in.

 

this makes sense  :o

I'll check soon



#46
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

well whizard, to solve it we can add this (line 142)

 

if((GetHitDice(oKiller) < GetHitDice(oObject))) iHD = GetHitDice(oObject);
else iHD = GetHitDice(oKiller);

and remove this condition (line 150)

if((GetHitDice(oKiller) < GetHitDice(oObject))) {}

I think that now it's all

Again a great by whizard. thank you very much  ^_^ 


Modifié par WhiteTiger, 18 juillet 2014 - 09:03 .


#47
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

Take a look to my finished code, Whizard and Shadooow.

//:://////////////////////////////////////////////////
//:: Code by WhiteTiger
//:: a_xp_giver
/*
  Script Padrao de recebimento de XP Amnesia
  Aplica dois tipos de penalidades no valor bruto.
 */
//:://////////////////////////////////////////////////

#include "amnesia_include"
#include "x2_inc_compon"
#include "x0_i0_spawncond"

int setPP(int iDN, int iNumParty)
{
    if(iNumParty == 2 && iDN >= 5) return 11;
    if(iNumParty == 2 && iDN == 4) return 13;
    if(iNumParty == 2 && iDN == 3) return 12;
    if(iNumParty == 2 && (iDN == 1 || iDN == 2)) return 14;
    if(iNumParty == 2 && (iDN == -1 || iDN == 0)) return 20;
    if(iNumParty == 2 && iDN == -2) return 25;
    if(iNumParty == 3 && iDN >= 5) return 14;
    if(iNumParty == 3 && iDN == 4) return 16;
    if(iNumParty == 3 && iDN == 3) return 15;
    if(iNumParty == 3 && iDN == 2) return 19;
    if(iNumParty == 3 && iDN == 1) return 20;
    if(iNumParty == 3 && iDN == 0) return 28;
    if(iNumParty == 3 && (iDN == -2 || iDN == -1)) return 25;
    if(iNumParty == 4 && iDN >= 5) return 16;
    if(iNumParty == 4 && (iDN == 3 || iDN == 4)) return 19;
    if(iNumParty == 4 && iDN == 2) return 23;
    if(iNumParty == 4 && iDN == 1) return 27;
    if(iNumParty == 4 && iDN == 0) return 37;
    if(iNumParty == 4 && iDN == -1) return 34;
    if(iNumParty == 4 && iDN == -2) return 25;

    return 10;
}

int setXP(int iDN)
{
    if (iDN >= 05) return 380;
    if (iDN == 04) return 330;
    if (iDN == 03) return 270;
    if (iDN == 02) return 220;
    if (iDN == 01) return 160;
    if (iDN == 00) return 110;
    if (iDN == -1) return 60;
    if (iDN == -2) return 40;
    if (iDN == -3) return 20;
    if (iDN == -4) return 10;

    return 1;
}

void main()
{
    object oKiller = GetLastKiller();

    //Set oKiller as a player
    if(GetAssociateType(oKiller) != ASSOCIATE_TYPE_NONE) oKiller = GetMaster(oKiller);

    //============== Starting Variables ===============
    int iNumParty;
    int iXP;
    float fXPPenalt;
    int iXPPenalt;
    int iNewXP;
    int iPenal;
    int iPenal2;
    int iCR = FloatToInt(GetChallengeRating(OBJECT_SELF));
    int iHD1 = GetHitDice(oKiller);
    int iHD2;
    int iDN1 = iCR - iHD1;
    int iDN2;
    object oAreaPC;

    //============== Starting Countdown ===========================
    object oArea = GetArea(OBJECT_SELF);
    object oObject = GetFirstObjectInArea(oArea);
    int iDead = GetIsDead (oObject);
    int iSameFaction = GetFactionEqual (oKiller, oObject);
    while (GetIsObjectValid(oObject))
    {
        if ((GetIsPC(oObject)) && (iSameFaction == TRUE) && (iDead == FALSE))
            {
                iNumParty = iNumParty + 1;
            }
        oObject = GetNextObjectInArea(oArea);
        iDead = GetIsDead (oObject);
        iSameFaction = GetFactionEqual (oKiller, oObject);
    }

    //========== Applying XP (oKiller) ====================================
            int iCurrentXP = GetXP(oKiller);
            int iXPMax = ((iHD1 * 1000) + (iHD1 * (iHD1 - 1) * 500));
            iDead = GetIsDead (oKiller);

            //Set the XP Proporcion
            iXP = setXP(iDN1);

            //Set the correct penalty according the XP
            iPenal = setPP(iDN1, iNumParty);

            //Set penalty if there is 5 players in party
            if(iNumParty >= 5) iXP = iXP/2;

                if  ((iDead == FALSE) && (iCurrentXP < iXPMax))
                {
                        if (!HasSanctuary(oKiller))
                        {
                            fXPPenalt = (iXP/10) * (iPenal/100.0);
                            iXPPenalt = FloatToInt(fXPPenalt); //Important Conversion.
                            iNewXP = iXP - (iXPPenalt*10);

                            if(((iCurrentXP + iNewXP) >= iXPMax))
                            {
                                SetXP(oKiller, (iXPMax));
                                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(GetMaxHitPoints(oKiller) - GetCurrentHitPoints(oKiller)), oKiller);
                                SendMessageToPC(oKiller, "Level Up!");
                            } else
                            if(iNewXP <= 1)
                            {
                            iNewXP = 1;
                            SetXP(oKiller, (iCurrentXP + iNewXP));
                            } else GiveXPToCreature(oKiller, iNewXP);
                        }
                        else
                        {
                            FloatingTextStringOnCreature ("No XP in Sanctuary!", oKiller);
                        }
                } else
                if((iCurrentXP >= iXPMax) && (iCurrentXP < 780000))
                    {
                        FloatingTextStringOnCreature ("Level Up!", oKiller);
                    }

    //========== Applying XP (oObject) ====================================
    oObject = GetFirstPC();
    while (GetIsObjectValid(oObject))
    {
        iHD2 = GetHitDice(oObject);
        iDN2 = iCR - iHD2;

        //Extra Party Penalty
        iPenal2 = ((iHD1 - iHD2) - iDN1)*10;
        if(iPenal2 <= 0) iPenal2 = 0;

        iDead = GetIsDead (oObject);
        iSameFaction = GetFactionEqual (oKiller, oObject);
        oAreaPC = GetArea(oObject);
        if ((iSameFaction == TRUE) && (iDead == FALSE) && (oAreaPC == oArea) && (oObject != oKiller))
        {
            //Set the XP Proporcion
            iXP = setXP(iDN2);

            //Set the correct penalty according the XP
            iPenal = setPP(iDN2, iNumParty);

            //Set penalty if there is 5 players in party
            if(iNumParty >= 5) iXP = iXP/2;

            int iCurrentXP = GetXP(oObject);
            int iXPMax = ( (iHD2 * 1000) + (iHD2 * (iHD2 - 1) * 500) );
            if  (iCurrentXP < iXPMax)
            {
                    if (!HasSanctuary(oObject))
                    {
                        fXPPenalt = (iXP/10) * (iPenal/100.0);
                        iXPPenalt = FloatToInt(fXPPenalt); //Important conversion
                        iNewXP = (iXP - (iXPPenalt*10)) - iPenal2;

                        if(((iCurrentXP + iNewXP) >= iXPMax))
                            {
                                SetXP(oObject, (iXPMax));
                                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(GetMaxHitPoints(oObject) - GetCurrentHitPoints(oObject)), oObject);
                                SendMessageToPC(oObject, "Level Up!");
                            } else
                        if(iNewXP <= 1)
                            {
                            iNewXP = 1;
                            SetXP(oObject, (iCurrentXP + iNewXP));
                            } else GiveXPToCreature(oObject, iNewXP);
                    }
                    else
                    {
                        FloatingTextStringOnCreature ("No XP in Sanctuary!", oObject);
                    }
            } else
            if((iCurrentXP >= iXPMax) && (iCurrentXP < 780000))
                    {
                        FloatingTextStringOnCreature ("Level Up!", oObject);
                    }
        }
    oObject = GetNextPC();
    }
}

Modifié par WhiteTiger, 16 août 2014 - 04:36 .


#48
Shadooow

Shadooow
  • Members
  • 4 465 messages

havent studied very deeply, but a small suggestion - learn to use and exploit "switch" statement

 

see this

 

int setXP(int iDN)
{
if (iDN >= 05) return 380; // 350, 340, 330, 320
if (iDN == 04) return 330; // 300, 290, 280, 270
if (iDN == 03) return 270; // 250, 240, 230, 220
if (iDN == 02) return 220; // 200, 190, 180, 170
if (iDN == 01) return 160; // 150, 140, 130, 120
if (iDN == 00) return 110; // 100, 090, 080, 070
if (iDN == -1) return 60; // 060, 050, 050, 040
if (iDN == -2) return 50; // 050, 040, 040, 030
if (iDN == -3) return 40; // 040, 040, 030
if (iDN == -4) return 20; // 020, 020, 020

return 1;
}

 

to

 

int setXP(int iDN)
{

 switch(iDN)

 {

 case 5: return 380;

 case 4: return 330;

 case 3: return 270;

 case 2: return 220;

 case 1: return 160;

 case 0: return 110;

 case -1: return 60;
 case -2: return 50;

 case -3: return 40;

 case -4: return 20;

 }
return 1;
}

 

especially useable it is if you would need to declare a variable like this

 

int n = GetLocalInt(something);

if(n == 2)

if(n == 6)

 

vs

 

switch(GetLocalInt(something))

{

 case 2:

 case 6:

}

 

More here.

 

EDIT: not saying your way is wrong, just offering an alternative and sometimes better way to do this.


Modifié par Shadooow, 13 août 2014 - 09:32 .

  • WhiteTiger aime ceci

#49
WhiteTiger

WhiteTiger
  • Members
  • 479 messages

int setXP(int iDN)

{

 switch(iDN)

 {

 case 5: return 380;

 case 4: return 330;

 case 3: return 270;

 case 2: return 220;

 case 1: return 160;

 case 0: return 110;

 case -1: return 60;
 case -2: return 50;

 case -3: return 40;

 case -4: return 20;

 }
return 1;
}

 

Good, haha... 

I have visited the link. And the default statement in switch? 

Is possible to set cases >4 = 380?  :P



#50
Shadooow

Shadooow
  • Members
  • 4 465 messages

Good, haha... 

I have visited the link. And the default statement in switch? 

Is possible to set cases >4 = 380?  :P

not directly but yes usign the default statement

basically you cover all other cases such as 0 1 2 3 (or negatives)

then the default is everything else than these cases which should be 4 5 6 7 and more