Author Topic: GoG AutoAFK/RP Script Issues  (Read 362 times)

Legacy_Evelath

  • Full Member
  • ***
  • Posts: 108
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« on: April 28, 2013, 12:26:26 am »


               Hello everyone,

I am attempting to implement an AutoXP script into my PW that rewards players every 10 minutes for dialogue while playing. I attempt to use GoG's version, however I had a bug occur a few hours into use where the amounts were being given quicker than the pre-set ten minute mark.

CODE SNIP----------------------------------


                             //!!!IMPORTANT!!//
//!!Be sure to "Build" you module after making any changes to this script!!

//Set timer for chat check and movement detection. After this time has expired
//for both checks then the AFK effect type will be applied.
//Default: 600 seconds(10 minutes)
const int TIMER = 600;//Seconds
//If using the RP XP option, decreasing the chat timer will mean that players
//will have to chat more often to recieve the XP reward.
const int CHAT_TIMER = 600;//Seconds

//Available AFK types:
//1 = Repeating floating text on player.
//2 = A visual effect will be applied to the player.
//3 = Transport player to an object in AFK area.
//4 = Boot player.
//5 = Play Animation(looping type only).
const int AFK_TYPE = 1;

//Options for AFK_TYPE 1:
//Enter message that you want to float over the players head when he/she is AFK.
//Default: "AFK"
const string AFK_FLOATING_MESSAGE = "AFK";
//Change the color of the floating text. Options for colors:
//STRING_COLOR_BLACK
//STRING_COLOR_BLUE
//STRING_COLOR_GREEN
//STRING_COLOR_PINK
//STRING_COLOR_RED
//STRING_COLOR_ROSE
//STRING_COLOR_WHITE
const string FLOATY_COLOR = STRING_COLOR_BLUE;
//Allow floaty text with all AFK types. Default: FALSE
const int FLOATY_TEXT_ALWAYS = FALSE;

//Option for AFK_TYPE 2:
//Enter desired VFX number or constant. Default: VFX_DUR_FLAG_GOLD
const int AFK_EFFECT = VFX_DUR_FLAG_GOLD;

//AFK OBJECT. This object is used for AFK_TYPE 2 and AFK_TYPE 3.
//Simply pick any placeable of your choosing and give it the tag below.
//Also make sure the object is checked "plot".If using the object for TYPE 2 you
//can put it in any area. If using it for TYPE 3 place it in the AFK area that
//players will be teleported to.
//Note for AFK_TYPE 3: This option sets a location on the player that they can
//be auto-ported back to. However should the player log out and log back in or
//if the server crashes, this location will be lost. Therefore you should have
//an alternate way of leaving the AKF area.
//Default: "GOGS_AFK_OBJECT"
const string AFK_OBJECT = "GOGS_AFK_OBJECT";
//Additional note for AFK type 3: I have made it so that a player who is in the
//AFK area must type something/anything in the chat bar for them to return to
//their stored location. This is to prevent other players from simply pushing
//the player around and causing a change in location which would teleport them.
//A repeating message is sent to the player until they type something.
//Message:
const string AFK_AREA_MESSAGE = "Type anything in the chat bar to be ported back to saved location.";
//Select color of message. Same color options as above apply.
const string AREA_MESSAGE_COLOR = STRING_COLOR_RED;

//Option for AFK_TYPE 5:
//Enter desired looping animation constant for the AFK animation.
//Default: ANIMATION_LOOPING_SIT_CROSS
const int AFK_ANIMATION = ANIMATION_LOOPING_SIT_CROSS;

//Send a message to the party members of the player that is AFK. This will
//display a message once when the player has gone AFK and once when the player
//is no longer AFK.
//If TRUE, message will be displayed to all party members. DEFAULT: TRUE
const int SEND_FACTION_MESSAGE = TRUE;
//Select color of message. Same color options as above apply.
const string FACTION_MESSAGE_COLOR = STRING_COLOR_PINK;

//Options for awarding RP XP. Basically, if the player is not AFK and has
//chatted within the last timer delay, the player will receive XP.
//Set to TRUE to give RP XP.
const int RP_XP_REWARD = TRUE;
//Set desired amount of XP to give every cycle.
const int XP_AMOUNT = 10;

////////////////////////////END CONFIGURABLE OPTIONS////////////////////////////

////////////////////////////////////////////////////////////////////////////////
void SendAFKFactionMessage(object oPC)
{
int iActive = GetLocalInt(oPC, "AFK_ACTIVE");
string sName = GetName(oPC);
string sMessage;
if (iActive == TRUE) sMessage = sName + " has gone AFK.";
else sMessage = sName + " is no longer AFK.";
object oMember = GetFirstFactionMember(oPC);
while (GetIsObjectValid(oMember))
    {
    SendMessageToPC(oMember, StringToRGBString(sMessage, FACTION_MESSAGE_COLOR));
    oMember = GetNextFactionMember(oPC);
    }
}
////////////////////////////////////////////////////////////////////////////////
void CheckNoAFK(object oPC)
{
location lPC = GetLocation(oPC);
location lCheck = GetLocalLocation(oPC, "AFK_LOC_CHECK");
int iChatty = GetLocalInt(oPC, "CHATTY");
if (iChatty == TRUE || lPC != lCheck)
    {
    if (AFK_TYPE == 1)
        {
        SetLocalInt(oPC, "AFK_ACTIVE", FALSE);
        if (SEND_FACTION_MESSAGE == TRUE) SendAFKFactionMessage(oPC);
        }
    if (AFK_TYPE == 2)
        {
        effect eEffect = GetFirstEffect(oPC);
        while (GetIsEffectValid(eEffect))
            {
            if (GetEffectCreator(eEffect)== GetObjectByTag("GOGS_AFK_OBJECT"))
                {
                RemoveEffect(oPC, eEffect);
                }
            eEffect = GetNextEffect(oPC);
            }
        SetLocalInt(oPC, "AFK_ACTIVE", FALSE);
        if (SEND_FACTION_MESSAGE == TRUE) SendAFKFactionMessage(oPC);
        }
    if (AFK_TYPE == 3)
        {
        location lLoc = GetLocalLocation(oPC, "AFK_RETURN_LOC");
        if (iChatty == TRUE)
            {
            SetLocalInt(oPC, "AFK_ACTIVE", FALSE);
            if (SEND_FACTION_MESSAGE == TRUE) SendAFKFactionMessage(oPC);
            DelayCommand(2.0, AssignCommand(oPC, ActionJumpToLocation(lLoc)));
            }
        else
            {
            SendMessageToPC(oPC, StringToRGBString(AFK_AREA_MESSAGE, AREA_MESSAGE_COLOR));
            DelayCommand(3.0, CheckNoAFK(oPC));
            }
        }
    if (AFK_TYPE == 5)
        {
        SetLocalInt(oPC, "AFK_ACTIVE", FALSE);
        if (SEND_FACTION_MESSAGE == TRUE) SendAFKFactionMessage(oPC);
        }
    }
else
    {
    DelayCommand(3.0, CheckNoAFK(oPC));
    if (AFK_TYPE == 1 || FLOATY_TEXT_ALWAYS == TRUE)
        {
        string sAFK = StringToRGBString(AFK_FLOATING_MESSAGE, FLOATY_COLOR);
        FloatingTextStringOnCreature(sAFK, oPC);
        }
    }
}
////////////////////////////////////////////////////////////////////////////////
void RunAFKType(object oPC)
{
if (AFK_TYPE == 1)
    {
    //
    }
if (AFK_TYPE == 2)
    {
    object oAFKObject = GetObjectByTag(AFK_OBJECT);
    AssignCommand(oAFKObject, ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectVisualEffect(AFK_EFFECT)), oPC));
    }
if (AFK_TYPE == 3)
    {
    SetLocalLocation(oPC, "AFK_RETURN_LOC", GetLocation(oPC));
    AssignCommand(oPC, ActionJumpToObject(GetObjectByTag(AFK_OBJECT)));
    }
if (AFK_TYPE == 4)
    {
    //SendMessageToPC(oPC, "Boot!");//Used for testing in single player.
    BootPC(oPC);
    }
if (AFK_TYPE == 5)
    {
    AssignCommand(oPC, ActionPlayAnimation(AFK_ANIMATION, 1.0, 10000.0));
    }
SetLocalInt(oPC, "AFK_ACTIVE", TRUE);
if (SEND_FACTION_MESSAGE == TRUE) SendAFKFactionMessage(oPC);
CheckNoAFK(oPC);
}
////////////////////////////////////////////////////////////////////////////////
void ChatCheck(object oPC)
{
int iChatty = GetLocalInt(oPC, "CHATTY");
if (iChatty != TRUE)
    {
    SetLocalInt(oPC, "CHATTY", TRUE);
    DelayCommand(IntToFloat(CHAT_TIMER), SetLocalInt(oPC, "CHATTY", FALSE));
    }
}
////////////////////////////////////////////////////////////////////////////////
void RunAFKDetection(object oPC)
{
location lPC = GetLocation(oPC);
location lCheck = GetLocalLocation(oPC, "AFK_LOC_CHECK");
int iAFKActive = GetLocalInt(oPC, "AFK_ACTIVE");
int iChatty = GetLocalInt(oPC, "CHATTY");

if (lPC == lCheck && iChatty != TRUE && iAFKActive != TRUE)
    {
    RunAFKType(oPC);
    }
SetLocalLocation(oPC, "AFK_LOC_CHECK", lPC);
if (iChatty == TRUE && RP_XP_REWARD == TRUE) GiveXPToCreature(oPC, XP_AMOUNT);
DelayCommand(IntToFloat(TIMER), RunAFKDetection(oPC));
}
////////////////////////////////////////////////////////////////////////////////
void GOGsAFKDetector(object oPC)
{
DelayCommand(10.0, RunAFKDetection(oPC));
}

/*

Example "OnPlayerChat" script:

//::////////////////////////////////////////////////////////////////////////////
//::A bunch of stuff here.....
//:://///////////////////////////////////////////////////////////////////////////

#include "???????????"
#include "gogs_afk_inc"  <------Add this line to your script!

void main()
{
    object oPC = GetPCChatSpeaker();
    ChatCheck(oPC)       <------Add this line to your script!
    OtherStuff.......
    Ect........
    Ect...........

}


Example "OnClientEnter" script:

//::////////////////////////////////////////////////////////////////////////////
//::A bunch of stuff here.....
//:://///////////////////////////////////////////////////////////////////////////

#include "???????????"
#include "gogs_afk_inc"        <------Add this line to your script!

void main()
{
    object oPC = GetEnteringObject();
    GOGsAFKDetector(oPC)       <------Add this line to your script!
    OtherStuff.......
    Ect........
    Ect...........

}

*/

---------------------CODE SNIP

If there are any suggestions please let me know.
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #1 on: April 29, 2013, 07:25:11 am »


               Pretty sure It's because I'm a horrible scripter. '<img'>
I haven't looked at this script in a very long time. But looking over it and thinking about it now I believe the problem may be that the pseudo heartbeat is running on the module rather than the player. Does this bug happen to players who log out and back in? I suspect that what's happening is that when a player logs in, the pseudo HB kicks in and does what it's supposed to, then a player logs out and back in and a second pseudo HB starts up for that player and so on and so on. So in the line that you add to the OnClientEnter change it from:

GOGsAFKDetector(oPC);

to

AssignCommand(oPC,  GOGsAFKDetector(oPC));

If you would be so kind as to let me know if that fixes it I would really appreciate it. I will change it on the vault as well. Thanks for trying out my system and I apologize for my lack of super duper scriptyness. '=]'
               
               

               


                     Modifié par GhostOfGod, 29 avril 2013 - 06:26 .
                     
                  


            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #2 on: April 29, 2013, 11:57:59 pm »


               How about just keeping track of time & counting the characters from total dialogue (talk / party etc)...

Then rewarding based upon total # of characters in X Time?

Obviously this would have to work from the OnPlayerChat module event script....
You could probably store the variable on the module using the player's name...
Obviously these variables would be lost every module reset, or you should reset them every hour...

A Strong Piece of Advice while coding is....

KISS...

Keep It Simple Silly  =)
               
               

               


                     Modifié par _Guile, 29 avril 2013 - 10:58 .
                     
                  


            

Legacy_Evelath

  • Full Member
  • ***
  • Posts: 108
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #3 on: April 30, 2013, 04:35:17 am »


               @GOG -- I will make that attempt and monitor it.

@_Guile -- How would you go about determining the the total dialogue? Sorry, I am a basic scripter but still have trouble determining the many paths to the ending conclusion.
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #4 on: April 30, 2013, 06:51:40 am »


               @_Guile: I just don't think that whoever chats the most = the best RPer. So keeping it simple would be just to give everyone who is RPing an equal opportunity to gain similar XP.

And just for the record the system I posted is more an AFK system. I just threw the RP XP in as an optional thing to go along with the system since it is already tracking chats and location changes. I'm sure there are more complex RP XP rewarding systems out there.
               
               

               
            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #5 on: April 30, 2013, 06:18:15 pm »


               

GhostOfGod wrote...

@_Guile: I just don't think that whoever chats the most = the best RPer. So keeping it simple would be just to give everyone who is RPing an equal opportunity to gain similar XP.

And just for the record the system I posted is more an AFK system. I just threw the RP XP in as an optional thing to go along with the system since it is already tracking chats and location changes. I'm sure there are more complex RP XP rewarding systems out there.


This is true, but there is NO substitute for a DM either, not really... =)
               
               

               
            

Legacy_Evelath

  • Full Member
  • ***
  • Posts: 108
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #6 on: April 30, 2013, 09:11:26 pm »


               @GoG --

I am getting reports that the issues are persistent; in one instance a player received two ticks of the XP bonus spaced 2 minutes apart. (Honestly I really like the system in terms of how simple it is to configure, so good job '<img'>) Also, are there any systems you could suggest?

@Guile --

You are correct there is no subtitute, however I am trying to set-up some form of reward for Roleplay when a DM is not able to be present.

Thank you both for your help thus far '<img'>
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #7 on: May 01, 2013, 01:04:34 am »


               Hmm...And just to confirm you are using it in the mods "OnClientEnter" and not an area's or trigger's "OnEnter"? And you also rebuilt the module after the change above?
               
               

               
            

Legacy_lovellin

  • Newbie
  • *
  • Posts: 28
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #8 on: May 01, 2013, 07:11:50 pm »


               The script seems to have a general issue. Whenever a PC logs in, a sequence of AFK checks is started (call GOGsAFKDetector() in OnClientEnter). However, after the PC logged off, the sequence of delayed commands doesn't stop. RunAFKDetection() should exit as soon as its argument oPC has become invalid.
               
               

               
            

Legacy_lovellin

  • Newbie
  • *
  • Posts: 28
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #9 on: May 01, 2013, 07:22:59 pm »


               If I understand your intention correctly, you're checking each 600s whether a player has sent a chat message in the last 600s. In ChatCheck(), you delay a command to reset variable CHATTY after 600s. This method incurs 2 problems: 1. Maintenance of flag CHATTY is imprecise. Asuume a player chats once and then after 550s. The delayed command from the first chat event will run nonetheless after 600s, i.e. CHATTY is reset 50s after the second event. 2. Timeout of CHATTY is not synchronized with AFK check where you have included the XP award.
I suggest another solution: record the last time a chat event has occurred in a timestamp format. In the AFK check, test whether the recorded time is more than 600s ago.
               
               

               
            

Legacy_Evelath

  • Full Member
  • ***
  • Posts: 108
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #10 on: May 01, 2013, 10:08:23 pm »


               @GoG - Yes; OnClientEnter

@lovellin - How would this be done? Can you give me a basic example?
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #11 on: May 02, 2013, 02:09:53 am »


               

lovellin wrote...

The script seems to have a general issue. Whenever a PC logs in, a sequence of AFK checks is started (call GOGsAFKDetector() in OnClientEnter). However, after the PC logged off, the sequence of delayed commands doesn't stop. RunAFKDetection() should exit as soon as its argument oPC has become invalid.


Hmm. I was under the assumption that once a player logged out (or object is destroyed), any recursive script on them would no longer apply. Which was the reason I suggested (due to my terrible mistake) that the pseudo HB run on the player rather than the module by assigning the command. If this is incorrect then I'm not entirely sure how you could "return" out of the HB before the delay has finished...delaying. Unless I run a second pseudo HB inside that runs every few seconds to make sure the player is still a valid object. That might get a bit too pseudo sloppy though. Hmmm...I will definitely give this some thought.


lovellin wrote...

If I understand your intention
correctly, you're checking each 600s whether a player has sent a chat
message in the last 600s. In ChatCheck(), you delay a command to reset
variable CHATTY after 600s. This method incurs 2 problems: 1.
Maintenance of flag CHATTY is imprecise. Asuume a player chats once and
then after 550s. The delayed command from the first chat event will run
nonetheless after 600s, i.e. CHATTY is reset 50s after the second event.
2. Timeout of CHATTY is not synchronized with AFK check where you have
included the XP award.
I suggest another solution: record the last
time a chat event has occurred in a timestamp format. In the AFK check,
test whether the recorded time is more than 600s ago.


Yeah I've been aware of this since I made it. Definitely not a very precise way of doing it. And I had been meaning to implement what you suggest. But I just kinda but it on the back burner so to speak. It's been on that burner for a few years now which is why the script is all crusty and burnt, ':lol:'
               
               

               


                     Modifié par GhostOfGod, 02 mai 2013 - 01:11 .
                     
                  


            

Legacy_lovellin

  • Newbie
  • *
  • Posts: 28
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #12 on: May 02, 2013, 08:47:55 pm »


               I'd simply insert a return statement at the beginning of the function:

void RunAFKDetection(object oPC)
{
if (!GetIsObjectValid(oPC)) return;

location lPC = GetLocation(oPC);
location lCheck = GetLocalLocation(oPC, "AFK_LOC_CHECK");
...

This will stop the chain of delayed commands as soon as the PC no longer exists in the module.
               
               

               
            

Legacy_Evelath

  • Full Member
  • ***
  • Posts: 108
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #13 on: May 15, 2013, 12:28:58 am »


               Thanks for the responses. I have run into an issue where the 10minute clock seems to be off if a player relogs. Also, 10XP is given each time they log in and out; which is prone to abuse.

Thoughts?
               
               

               
            

Legacy_Evelath

  • Full Member
  • ***
  • Posts: 108
  • Karma: +0/-0
GoG AutoAFK/RP Script Issues
« Reply #14 on: July 03, 2013, 04:38:01 am »


               Just bringing this up again; the issue was never fully resolved and was curious if anyone has any advice.