Author Topic: How does code on playertypes work?  (Read 1432 times)

I want to make a playertype that changes its view direction to be closer to the direction it's moving. This seems pretty simple logic-wise, I can probably make code for an event that does this when you run it on a loop but I don't know how to make this code run on the player and not as part of an event. It doesn't really make sense as an event; it's better to put it on the player because it's entirely a player-based thing.

How does code on playertypes work? All the documentation I can find is on modelling them... I need something either running on a loop all the time or while the player is moving under their own power.
« Last Edit: June 06, 2017, 07:38:46 PM by Super Suit 12 »

normally playertype code is just simple things
either attribute changes so the player jumps higher/is slower/has more health/goes super fast while crouching
or is things to modify functions like being damaged

I'm not even sure how you'd go about changing the player aim over time without a loop, which you could do regardless of having a playertype
the only thing having a playertype would add is to only change players aim if they're the playertype (could just be a variable set instead though)

PlayerstandardArmor.dump();

Checking movement is a little hacky without client scripts, the best thing you can do is use Player::getVelocity(); to help with that.

Here's an example player loop:

function Player::moveloop(%this)
{
       announce(%this.getVelocity());
       %this.moveloop = %this.schedule(1000,moveloop);
}


if you want to cancel it type cancel(findclientbyname(yourname).player.moveloop); in console
« Last Edit: June 07, 2017, 07:10:47 AM by PhantOS »

if you want to call something when a player spawns as a particular datablock, you can define a function as SomePlayerArmor::onAdd(%datablock, %obj) (replace SomePlayerArmor with your datablock's name)

there's also SomePlayerArmor::onNewDatablock(%datablock, %obj) it seems and i'm not sure what the practical difference between the two is, or if there is one, i'm just looking at some old code i made and for some reason i used both so i figured i'd mention this one too. i feel like onAdd should catch all cases tho

edit: onNewDatablock is called when you change datablocks, while onAdd is just a callback for when an object is created with that datablock. when you use onNewDatablock make sure to call the parent tho (ie parent::onNewDatablock(%datablock, %obj); ) since Armor::onNewDatablock actually has default functionality

Here's an example player loop:

function Player::moveloop(%this)
{
       announce(%this.getVelocity());
       %this.moveloop = %this.schedule(1000,moveloop);
}


if you want to cancel it type cancel(findclientbyname(yourname).player.moveloop); in console
to add onto this, it's generally good practice to cancel the loop at the beginning of the loop function:

function Player::moveloop(%this)
{
       if(isEventPending(%this.moveloop)) //not sure if this if statement is really considered necessary, just force of habit for me
              cancel(%this.moveloop);

       announce(%this.getVelocity());
       %this.moveloop = %this.schedule(1000,moveloop);
}


that way you can only ever be running one loop at a time. without this, if moveloop were called a second time, it would begin another loop, and if called again, a third loop, and so on, and you would only ever be able to keep track of one of these loops at a time. as you might imagine, this can cause unexpected and wrong behavior and really make things generally difficult to deal with
« Last Edit: June 07, 2017, 02:08:39 PM by otto-san »

You don't need the pending thing.

if(isEventPending(%this.moveloop)) //not sure if this if statement is really considered necessary, just force of habit for me
    cancel(%this.moveloop);

It's not, by calling isEventPending you're effectively just walking the event list an extra time.

Code: [Select]
void cancelEvent(U32 eventSequence)
{
    Mutex::lockMutex(gEventQueueMutex);

    SimEvent **walk = &gEventQueue;
    SimEvent *current;

    while((current = *walk) != NULL)
    {
        if(current->sequenceCount == eventSequence)
        {
            *walk = current->nextEvent;
            delete current;
            Mutex::unlockMutex(gEventQueueMutex);
            return;
        }
        else
            walk = &(current->nextEvent);
    }

    Mutex::unlockMutex(gEventQueueMutex);
}

bool isEventPending(U32 eventSequence)
{
    Mutex::lockMutex(gEventQueueMutex);

    for(SimEvent *walk = gEventQueue; walk; walk = walk->nextEvent)
    {
        if(walk->sequenceCount == eventSequence)
        {
            Mutex::unlockMutex(gEventQueueMutex);
            return true;
        }
    }
        
    Mutex::unlockMutex(gEventQueueMutex);
    
    return false;
}
« Last Edit: June 07, 2017, 02:28:50 PM by SUSHI »

Thanks, everyone. I'm currently working with onTrigger to use the jet key. Blockland Content Creators discord was faster.
« Last Edit: June 08, 2017, 01:02:17 PM by Super Suit 12 »

Of course it is, the forums are awfully slow because not everyone is checking every topic