<commit_before>#ifndef __Sinbad_H__
#define __Sinbad_H__

#include "Ogre.h"
#include "OgreInput.h"

using namespace Ogre;
using namespace OgreBites;

#define NUM_ANIMS 13           // number of animations the character has
#define CHAR_HEIGHT 5          // height of character's center of mass above ground
#define CAM_HEIGHT 2           // height of camera above character's center of mass
#define RUN_SPEED 17           // character running speed in units per second
#define TURN_SPEED 500.0f      // character turning in degrees per second
#define ANIM_FADE_SPEED 7.5f   // animation crossfade speed in % of full weight per second
#define JUMP_ACCEL 30.0f       // character jump acceleration in upward units per squared second
#define GRAVITY 90.0f          // gravity in downward units per squared second

class SinbadCharacterController
{
private:

    // all the animations our character has, and a null ID
    // some of these affect separate body parts and will be blended together
    enum AnimID
    {
        ANIM_IDLE_BASE,
        ANIM_IDLE_TOP,
        ANIM_RUN_BASE,
        ANIM_RUN_TOP,
        ANIM_HANDS_CLOSED,
        ANIM_HANDS_RELAXED,
        ANIM_DRAW_SWORDS,
        ANIM_SLICE_VERTICAL,
        ANIM_SLICE_HORIZONTAL,
        ANIM_DANCE,
        ANIM_JUMP_START,
        ANIM_JUMP_LOOP,
        ANIM_JUMP_END,
        ANIM_NONE
    };

public:
    
    SinbadCharacterController(Camera* cam)
    {
        setupBody(cam->getSceneManager());
        setupCamera(cam);
        setupAnimations();
    }

    void addTime(Real deltaTime)
    {
        updateBody(deltaTime);
        updateAnimations(deltaTime);
        updateCamera(deltaTime);
    }

    void injectKeyDown(const KeyboardEvent& evt)
    {
        Keycode key = evt.keysym.sym;
        if (key == 'q' && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP))
        {
            // take swords out (or put them back, since it's the same animation but reversed)
            setTopAnimation(ANIM_DRAW_SWORDS, true);
            mTimer = 0;
        }
        else if (key == 'e' && !mSwordsDrawn)
        {
            if (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)
            {
                // start dancing
                setBaseAnimation(ANIM_DANCE, true);
                setTopAnimation(ANIM_NONE);
                // disable hand animation because the dance controls hands
                mAnims[ANIM_HANDS_RELAXED]->setEnabled(false);
            }
            else if (mBaseAnimID == ANIM_DANCE)
            {
                // stop dancing
                setBaseAnimation(ANIM_IDLE_BASE);
                setTopAnimation(ANIM_IDLE_TOP);
                // re-enable hand animation
                mAnims[ANIM_HANDS_RELAXED]->setEnabled(true);
            }
        }

        // keep track of the player's intended direction
        else if (key == 'w') mKeyDirection.z = -1;
        else if (key == 'a') mKeyDirection.x = -1;
        else if (key == 's') mKeyDirection.z = 1;
        else if (key == 'd') mKeyDirection.x = 1;

        else if (key == SDLK_SPACE && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP))
        {
            // jump if on ground
            setBaseAnimation(ANIM_JUMP_START, true);
            setTopAnimation(ANIM_NONE);
            mTimer = 0;
        }

        if (!mKeyDirection.isZeroLength() && mBaseAnimID == ANIM_IDLE_BASE)
        {
            // start running if not already moving and the player wants to move
            setBaseAnimation(ANIM_RUN_BASE, true);
            if (mTopAnimID == ANIM_IDLE_TOP) setTopAnimation(ANIM_RUN_TOP, true);
        }
    }

    void injectKeyUp(const KeyboardEvent& evt)
    {
        Keycode key = evt.keysym.sym;
        // keep track of the player's intended direction
        if (key == 'w' && mKeyDirection.z == -1) mKeyDirection.z = 0;
        else if (key == 'a' && mKeyDirection.x == -1) mKeyDirection.x = 0;
        else if (key == 's' && mKeyDirection.z == 1) mKeyDirection.z = 0;
        else if (key == 'd' && mKeyDirection.x == 1) mKeyDirection.x = 0;

        if (mKeyDirection.isZeroLength() && mBaseAnimID == ANIM_RUN_BASE)
        {
            // stop running if already moving and the player doesn't want to move
            setBaseAnimation(ANIM_IDLE_BASE);
            if (mTopAnimID == ANIM_RUN_TOP) setTopAnimation(ANIM_IDLE_TOP);
        }
    }

    void injectMouseMove(const MouseMotionEvent& evt)
    {
        // update camera goal based on mouse movement
        updateCameraGoal(-0.05f * evt.xrel, -0.05f * evt.yrel, 0);
    }

    void injectMouseWheel(const MouseWheelEvent& evt)
    {
        // update camera goal based on mouse movement
        updateCameraGoal(0, 0, -0.0005f * evt.y);
    }

    void injectMouseDown(const MouseButtonEvent& evt)
    {
        if (mSwordsDrawn && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP))
        {
            // if swords are out, and character's not doing something weird, then SLICE!
            if (evt.button == BUTTON_LEFT) setTopAnimation(ANIM_SLICE_VERTICAL, true);
            else if (evt.button == BUTTON_RIGHT) setTopAnimation(ANIM_SLICE_HORIZONTAL, true);
            mTimer = 0;
        }
    }

private:

    void setupBody(SceneManager* sceneMgr)
    {
        // create main model
        mBodyNode = sceneMgr->getRootSceneNode()->createChildSceneNode(Vector3::UNIT_Y * CHAR_HEIGHT);
        mBodyEnt = sceneMgr->createEntity("SinbadBody", "Sinbad.mesh");
        mBodyNode->attachObject(mBodyEnt);

        // create swords and attach to sheath
        LogManager::getSingleton().logMessage("Creating swords");
        mSword1 = sceneMgr->createEntity("SinbadSword1", "Sword.mesh");
        mSword2 = sceneMgr->createEntity("SinbadSword2", "Sword.mesh");
        mBodyEnt->attachObjectToBone("Sheath.L", mSword1);
        mBodyEnt->attachObjectToBone("Sheath.R", mSword2);

        LogManager::getSingleton().logMessage("Creating the chains");
        // create a couple of ribbon trails for the swords, just for fun
        NameValuePairList params;
        params["numberOfChains"] = "2";
        params["maxElements"] = "80";
        mSwordTrail = (RibbonTrail*)sceneMgr->createMovableObject("RibbonTrail", &params);
        mSwordTrail->setMaterialName("Examples/LightRibbonTrail");
        mSwordTrail->setTrailLength(20);
        mSwordTrail->setVisible(false);
        sceneMgr->getRootSceneNode()->attachObject(mSwordTrail);


        for (int i = 0; i < 2; i++)
        {
            mSwordTrail->setInitialColour(i, 1, 0.8, 0);
            mSwordTrail->setColourChange(i, 0.75, 1.25, 1.25, 1.25);
            mSwordTrail->setWidthChange(i, 1);
            mSwordTrail->setInitialWidth(i, 0.5);
        }

        mKeyDirection = Vector3::ZERO;
        mVerticalVelocity = 0;
    }

    void setupAnimations()
    {
        // this is very important due to the nature of the exported animations
        mBodyEnt->getSkeleton()->setBlendMode(ANIMBLEND_CUMULATIVE);

        String animNames[] =
        {"IdleBase", "IdleTop", "RunBase", "RunTop", "HandsClosed", "HandsRelaxed", "DrawSwords",
        "SliceVertical", "SliceHorizontal", "Dance", "JumpStart", "JumpLoop", "JumpEnd"};

        // populate our animation list
        for (int i = 0; i < NUM_ANIMS; i++)
        {
            mAnims[i] = mBodyEnt->getAnimationState(animNames[i]);
            mAnims[i]->setLoop(true);
            mFadingIn[i] = false;
            mFadingOut[i] = false;
        }

        // start off in the idle state (top and bottom together)
        setBaseAnimation(ANIM_IDLE_BASE);
        setTopAnimation(ANIM_IDLE_TOP);
<commit_msg>Samples: SinbadCharacterController - initialise m*AnimID<commit_after>#ifndef __Sinbad_H__
#define __Sinbad_H__

#include "Ogre.h"
#include "OgreInput.h"

using namespace Ogre;
using namespace OgreBites;

#define NUM_ANIMS 13           // number of animations the character has
#define CHAR_HEIGHT 5          // height of character's center of mass above ground
#define CAM_HEIGHT 2           // height of camera above character's center of mass
#define RUN_SPEED 17           // character running speed in units per second
#define TURN_SPEED 500.0f      // character turning in degrees per second
#define ANIM_FADE_SPEED 7.5f   // animation crossfade speed in % of full weight per second
#define JUMP_ACCEL 30.0f       // character jump acceleration in upward units per squared second
#define GRAVITY 90.0f          // gravity in downward units per squared second

class SinbadCharacterController
{
private:

    // all the animations our character has, and a null ID
    // some of these affect separate body parts and will be blended together
    enum AnimID
    {
        ANIM_IDLE_BASE,
        ANIM_IDLE_TOP,
        ANIM_RUN_BASE,
        ANIM_RUN_TOP,
        ANIM_HANDS_CLOSED,
        ANIM_HANDS_RELAXED,
        ANIM_DRAW_SWORDS,
        ANIM_SLICE_VERTICAL,
        ANIM_SLICE_HORIZONTAL,
        ANIM_DANCE,
        ANIM_JUMP_START,
        ANIM_JUMP_LOOP,
        ANIM_JUMP_END,
        ANIM_NONE
    };

public:
    
    SinbadCharacterController(Camera* cam) : mBaseAnimID(ANIM_NONE), mTopAnimID(ANIM_NONE)
    {
        setupBody(cam->getSceneManager());
        setupCamera(cam);
        setupAnimations();
    }

    void addTime(Real deltaTime)
    {
        updateBody(deltaTime);
        updateAnimations(deltaTime);
        updateCamera(deltaTime);
    }

    void injectKeyDown(const KeyboardEvent& evt)
    {
        Keycode key = evt.keysym.sym;
        if (key == 'q' && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP))
        {
            // take swords out (or put them back, since it's the same animation but reversed)
            setTopAnimation(ANIM_DRAW_SWORDS, true);
            mTimer = 0;
        }
        else if (key == 'e' && !mSwordsDrawn)
        {
            if (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)
            {
                // start dancing
                setBaseAnimation(ANIM_DANCE, true);
                setTopAnimation(ANIM_NONE);
                // disable hand animation because the dance controls hands
                mAnims[ANIM_HANDS_RELAXED]->setEnabled(false);
            }
            else if (mBaseAnimID == ANIM_DANCE)
            {
                // stop dancing
                setBaseAnimation(ANIM_IDLE_BASE);
                setTopAnimation(ANIM_IDLE_TOP);
                // re-enable hand animation
                mAnims[ANIM_HANDS_RELAXED]->setEnabled(true);
            }
        }

        // keep track of the player's intended direction
        else if (key == 'w') mKeyDirection.z = -1;
        else if (key == 'a') mKeyDirection.x = -1;
        else if (key == 's') mKeyDirection.z = 1;
        else if (key == 'd') mKeyDirection.x = 1;

        else if (key == SDLK_SPACE && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP))
        {
            // jump if on ground
            setBaseAnimation(ANIM_JUMP_START, true);
            setTopAnimation(ANIM_NONE);
            mTimer = 0;
        }

        if (!mKeyDirection.isZeroLength() && mBaseAnimID == ANIM_IDLE_BASE)
        {
            // start running if not already moving and the player wants to move
            setBaseAnimation(ANIM_RUN_BASE, true);
            if (mTopAnimID == ANIM_IDLE_TOP) setTopAnimation(ANIM_RUN_TOP, true);
        }
    }

    void injectKeyUp(const KeyboardEvent& evt)
    {
        Keycode key = evt.keysym.sym;
        // keep track of the player's intended direction
        if (key == 'w' && mKeyDirection.z == -1) mKeyDirection.z = 0;
        else if (key == 'a' && mKeyDirection.x == -1) mKeyDirection.x = 0;
        else if (key == 's' && mKeyDirection.z == 1) mKeyDirection.z = 0;
        else if (key == 'd' && mKeyDirection.x == 1) mKeyDirection.x = 0;

        if (mKeyDirection.isZeroLength() && mBaseAnimID == ANIM_RUN_BASE)
        {
            // stop running if already moving and the player doesn't want to move
            setBaseAnimation(ANIM_IDLE_BASE);
            if (mTopAnimID == ANIM_RUN_TOP) setTopAnimation(ANIM_IDLE_TOP);
        }
    }

    void injectMouseMove(const MouseMotionEvent& evt)
    {
        // update camera goal based on mouse movement
        updateCameraGoal(-0.05f * evt.xrel, -0.05f * evt.yrel, 0);
    }

    void injectMouseWheel(const MouseWheelEvent& evt)
    {
        // update camera goal based on mouse movement
        updateCameraGoal(0, 0, -0.0005f * evt.y);
    }

    void injectMouseDown(const MouseButtonEvent& evt)
    {
        if (mSwordsDrawn && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP))
        {
            // if swords are out, and character's not doing something weird, then SLICE!
            if (evt.button == BUTTON_LEFT) setTopAnimation(ANIM_SLICE_VERTICAL, true);
            else if (evt.button == BUTTON_RIGHT) setTopAnimation(ANIM_SLICE_HORIZONTAL, true);
            mTimer = 0;
        }
    }

private:

    void setupBody(SceneManager* sceneMgr)
    {
        // create main model
        mBodyNode = sceneMgr->getRootSceneNode()->createChildSceneNode(Vector3::UNIT_Y * CHAR_HEIGHT);
        mBodyEnt = sceneMgr->createEntity("SinbadBody", "Sinbad.mesh");
        mBodyNode->attachObject(mBodyEnt);

        // create swords and attach to sheath
        LogManager::getSingleton().logMessage("Creating swords");
        mSword1 = sceneMgr->createEntity("SinbadSword1", "Sword.mesh");
        mSword2 = sceneMgr->createEntity("SinbadSword2", "Sword.mesh");
        mBodyEnt->attachObjectToBone("Sheath.L", mSword1);
        mBodyEnt->attachObjectToBone("Sheath.R", mSword2);

        LogManager::getSingleton().logMessage("Creating the chains");
        // create a couple of ribbon trails for the swords, just for fun
        NameValuePairList params;
        params["numberOfChains"] = "2";
        params["maxElements"] = "80";
        mSwordTrail = (RibbonTrail*)sceneMgr->createMovableObject("RibbonTrail", &params);
        mSwordTrail->setMaterialName("Examples/LightRibbonTrail");
        mSwordTrail->setTrailLength(20);
        mSwordTrail->setVisible(false);
        sceneMgr->getRootSceneNode()->attachObject(mSwordTrail);


        for (int i = 0; i < 2; i++)
        {
            mSwordTrail->setInitialColour(i, 1, 0.8, 0);
            mSwordTrail->setColourChange(i, 0.75, 1.25, 1.25, 1.25);
            mSwordTrail->setWidthChange(i, 1);
            mSwordTrail->setInitialWidth(i, 0.5);
        }

        mKeyDirection = Vector3::ZERO;
        mVerticalVelocity = 0;
    }

    void setupAnimations()
    {
        // this is very important due to the nature of the exported animations
        mBodyEnt->getSkeleton()->setBlendMode(ANIMBLEND_CUMULATIVE);

        String animNames[NUM_ANIMS] =
        {"IdleBase", "IdleTop", "RunBase", "RunTop", "HandsClosed", "HandsRelaxed", "DrawSwords",
        "SliceVertical", "SliceHorizontal", "Dance", "JumpStart", "JumpLoop", "JumpEnd"};

        // populate our animation list
        for (int i = 0; i < NUM_ANIMS; i++)
        {
            mAnims[i] = mBodyEnt->getAnimationState(animNames[i]);
            mAnims[i]->setLoop(true);
            mFadingIn[i] = false;
            mFadingOut[i] = false;
        }

        // start off in the idle state (top and bottom together)
        setBaseAnimation(ANIM_IDLE_BASE);
        setTopAnimation(ANIM_IDLE_TOP);

{'fraction_non_alphanumeric': 0.10310147936672723, 'fraction_numerical': 0.010770827926291202, 'mean_word_length': 2.3039657020364417, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4225085', 'n_tokens_mistral': 5043, 'n_tokens_neox': 4821, 'n_words': 1137}