Author Topic: Explorer's XP?  (Read 647 times)

Legacy_Who said that I

  • Hero Member
  • *****
  • Posts: 931
  • Karma: +0/-0
Explorer's XP?
« on: November 28, 2015, 09:12:38 pm »


               

okay I need some help here with a small script I got here. I want to reward players for entering a new area with some XP, though most area's have multiple exits and entrances so wondering if anyone has a fix for me?


 


basically I want to have the xp rewarded given ONLY if the PC has not entered the area before.


 




void main()

{

    // Get the creature who triggered this event.

    object oPC = GetEnteringObject();

 

    // Only fire for (real) PCs.

    if ( !GetIsPC(oPC)  ||  GetIsDMPossessed(oPC) )

        return;

 

    // Only fire once per PC.

    if ( GetLocalInt(oPC, "DO_ONCE__" + GetTag(OBJECT_SELF)) )

        return;

    SetLocalInt(oPC, "DO_ONCE__" + GetTag(OBJECT_SELF), TRUE);

 

    // Give 25 experience to the PC.

    GiveXPToCreature(oPC, 25);

}

 

 



 



thanks in advance! '<img'>



               
               

               
            

Legacy_Tarot Redhand

  • Hero Member
  • *****
  • Posts: 4165
  • Karma: +0/-0
Explorer's XP?
« Reply #1 on: November 28, 2015, 09:26:42 pm »


               

In the OnEnter script for the area check for a flag. If the flag is not set give the award and set the flag otherwise skip that section of code.


 


TR



               
               

               
            

Legacy_Who said that I

  • Hero Member
  • *****
  • Posts: 931
  • Karma: +0/-0
Explorer's XP?
« Reply #2 on: November 28, 2015, 09:42:48 pm »


               


In the OnEnter script for the area check for a flag. If the flag is not set give the award and set the flag otherwise skip that section of code.


 


TR




 


hmm could you help me with how this works since well first of all I am a bit rusty with the scripting and am not entirely sure how you mean. sorry :S


               
               

               
            

Legacy_Pstemarie

  • Hero Member
  • *****
  • Posts: 4368
  • Karma: +0/-0
Explorer's XP?
« Reply #3 on: November 29, 2015, 04:16:56 am »


               

object oPC = GetEnteringObject();


 


if (!GetIsPC(oPC) || GetLocalInt(oPC, "player_awarded") == 1)


     return;


 


else


{


     SetLocalInt(oPC, "player_awarded", 1);


     //award the xp here


}



               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Explorer's XP?
« Reply #4 on: November 29, 2015, 06:35:58 am »


               

I broke it up into separate functions, in case you wanted to store the variable in a different way, but something like this would work:


 



 


// Retrieves the string for storing visited areas.


string GetVisitedAreaList(object oPC);

// Saves the visited area list.

void SetVisitedAreaList(object oPC, string sList);

 

// Checks if the PC has entered that area before.

// returns FALSE if oPC is not a PC, or they aren't in a valid area.

// Area list is updated automatically if the area hasn't been visited before.

int GetPCFirstTimeEnteringArea(object oPC);

 

 

string GetVisitedAreaList(object oPC)

{

    // Using PC skin method for the example.

    object oSkin=GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC);

    return GetLocalString(oSkin, "VISITED_AREA_LIST");

}

 

void SetVisitedAreaList(object oPC, string sList)

{

    // Using PC skin method for the example.

    object oSkin=GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC);

    SetLocalString(oSkin, "VISITED_AREA_LIST", sList);

}

 

 

int GetPCFirstTimeEnteringArea(object oPC)

{

    // Sanity checks.  Must be a PC in a valid area, with a set (non-blank) tag.

    if(!GetIsPC(oPC))return FALSE;

    object oArea=GetArea(oPC);

    if(oArea==OBJECT_INVALID)return FALSE;

    string sTag=GetTag(oArea);

    if(sTag=="")return FALSE;

 

    string sList = GetVisitedAreaList(oPC);

    // This will equal -1 if the area tag isn't found in the list,

    if(FindSubString(sList, sTag)== -1)

    {

        SetVisitedAreaList(oPC, sList+"_"+sTag);

        return TRUE;

    }

    return FALSE;

}

 

 

void main()

{

    object oPC=GetEnteringObject();

 

 

    // PC only exploration XP section.

    // Function cotains PC only sanity check.

    if(GetPCFirstTimeEnteringArea(oPC))

    {

        // Give 25 experience to the PC.

        GiveXPToCreature(oPC, 25);

    }

}


 


The main body would have to go into the area's OnEnter, though the other functions could stay above it in the same script or be moved into an include.



               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Explorer's XP?
« Reply #5 on: November 29, 2015, 07:32:30 am »


               


object oPC = GetEnteringObject();


 


if (!GetIsPC(oPC) || GetLocalInt(oPC, "player_awarded") == 1)


     return;


 


else


{


     SetLocalInt(oPC, "player_awarded", 1);


     //award the xp here


}




this would work only once, PC wouldnt get any XP after entering first area


 




I broke it up into separate functions, in case you wanted to store the variable in a different way, but something like this would work:


 


 


The main body would have to go into the area's OnEnter, though the other functions could stay above it in the same script or be moved into an include.




Generally ok, but your script has two issues.


1) polymorphed creatures can get XP repeatedly


2) in multiplayer server with ILR or ELC on and without CPP 1.71 (or rather without the scrripting solution from 1.71 which usually needs to be merged with own module event scripts), player will get a completely new skin each login and all variables will be deleted.


 


solutions:


- save the exploration datas to module "database item" (eg. id card or whatever)


- or save the exploration datas to database (bioware or nwnx)


- or implement the "losing skin" fix from 1.71 into your module events and then use SKIN_SupportGetSkin function to get skin instead of GetItemInSlot (requires x3_inc_skin)


               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Explorer's XP?
« Reply #6 on: November 29, 2015, 08:38:47 am »


               

A database item or actual database usage would definitely have advantages over PC skin, yes.  Most servers tend to have their own skin scripts, so I never considered the terrible way that the vanilla scripts handle them, but polymorphing would be an issue regardless.


A quasi IC item like a "Travel journal", that the variable was stored to, and that could even be used to list all areas visited, would be pretty easy to implement.  The ability to fine tune the storage method was a large part of why I wrote the script up as multiple small functions.


 


Changing these:



 


string GetVisitedAreaList(object oPC)


{

    // Using PC skin method for the example.

    object oSkin=GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC);

    return GetLocalString(oSkin, "VISITED_AREA_LIST");

}

 

void SetVisitedAreaList(object oPC, string sList)

{

    // Using PC skin method for the example.

    object oSkin=GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC);

    SetLocalString(oSkin, "VISITED_AREA_LIST", sList);

}


to:



 


string GetVisitedAreaList(object oPC)


{

    // Using a DB item

    object oDB=GetItemPossessedBy(oPC, "TRAVEL_DB_BOOK");

    return GetLocalString(oDB, "VISITED_AREA_LIST");

}

 

void SetVisitedAreaList(object oPC, string sList)

{

    

    // Using a DB item
    object oDB=GetItemPossessedBy(oPC, "TRAVEL_DB_BOOK");

    SetLocalString(oDB, "VISITED_AREA_LIST", sList);

}


would be enough to change it to look for an item instead.


It's still not ideal, since a module with hundreds of areas would lead to a very long string, but short of numbering every area, stored onto it by variable, and making a pseudo bitwise string to check against, it's as good a method as most would need.



               
               

               
            

Legacy_Who said that I

  • Hero Member
  • *****
  • Posts: 931
  • Karma: +0/-0
Explorer's XP?
« Reply #7 on: November 29, 2015, 09:34:23 am »


               


A database item or actual database usage would definitely have advantages over PC skin, yes.  Most servers tend to have their own skin scripts, so I never considered the terrible way that the vanilla scripts handle them, but polymorphing would be an issue regardless.


A quasi IC item like a "Travel journal", that the variable was stored to, and that could even be used to list all areas visited, would be pretty easy to implement.  The ability to fine tune the storage method was a large part of why I wrote the script up as multiple small functions.


 


Changing these:


to:


would be enough to change it to look for an item instead.


It's still not ideal, since a module with hundreds of areas would lead to a very long string, but short of numbering every area, stored onto it by variable, and making a pseudo bitwise string to check against, it's as good a method as most would need.




awesome, I totally appreciate this guys, been struggling with this for a while now and well been out of the scripting for a bit (If I do not do scripting for a few months it takes some time for me to get back into it)  


 


anyway regarding the storage item....I already have so many items that store data of the character in their inventory, I am kinda wanting not to add any more items to it otherwise the inventory is already full at the beginning of the game XD  


 


So could I switch TRAVEL_DB_BOOK" to anything I want?


 


so far the module has around 30+ area's and more coming up, this will be a big PW by the time we are done with it. So would totally appreciate the one with the least issues XD


               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Explorer's XP?
« Reply #8 on: November 29, 2015, 10:22:35 am »


               


 


So could I switch TRAVEL_DB_BOOK" to anything I want?




Absolutely, you can store all informations in single item - just make sure player cant lose it. (make it undroppable and not equippable)


               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Explorer's XP?
« Reply #9 on: November 29, 2015, 10:22:39 am »


               


 


So could I switch TRAVEL_DB_BOOK" to anything I want?




Absolutely, you can store all informations in single item - just make sure player cant lose it. (make it undroppable and not equippable)


               
               

               
            

Legacy_Pstemarie

  • Hero Member
  • *****
  • Posts: 4368
  • Karma: +0/-0
Explorer's XP?
« Reply #10 on: November 29, 2015, 10:47:59 am »


               


this would work only once, PC wouldnt get any XP after entering first area


 




 


True, I missed in the OP's post about being useful for multiple areas. Thanks Shadooow.


 


@ WhoSaid...In this case you'd want to use a string variable and store it directly on a PC item - like FailedBard and Shadooow suggests. For the data stored just use the area tag (make sure all areas have different tags).



               
               

               
            

Legacy_Who said that I

  • Hero Member
  • *****
  • Posts: 931
  • Karma: +0/-0
Explorer's XP?
« Reply #11 on: November 30, 2015, 04:36:27 pm »


               

thank you all for the info! I am so happy with this! '<img'>



               
               

               
            

Legacy_Who said that I

  • Hero Member
  • *****
  • Posts: 931
  • Karma: +0/-0
Explorer's XP?
« Reply #12 on: December 01, 2015, 06:25:27 pm »


               

hm apparently its not entirely working....it does not seem to save it on the item and the pc keeps getting the xp each time entering the area.....


 


anything I did wrong perhapa? Put it on enterarea and honestly only changed the database section and changed the item it should store the item on. I miss something here?



               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Explorer's XP?
« Reply #13 on: December 01, 2015, 11:17:02 pm »


               

It should work using an item, so long as you changed the "TRAVEL_DB_BOOK" tag to the tag of a possessed item, bearing in mind that tags are case sensitive, so have to match exactly.



               
               

               
            

Legacy_Who said that I

  • Hero Member
  • *****
  • Posts: 931
  • Karma: +0/-0
Explorer's XP?
« Reply #14 on: December 02, 2015, 03:05:46 pm »


               I did, i simply copy pasted the tag of the new item over where the "TRAVEL_DB_BOOK" is supposed to be. I got no errors but it does not matter what I do I keep getting xp entering the area