/** Called at the end of a race. Checks if the current times are worth a new
 *  score, if so it notifies the HighscoreManager so the new score is added 
 *  and saved.
 */
void World::updateHighscores(int* best_highscore_rank, int* best_finish_time, 
                             std::string* highscore_who,
                             StateManager::ActivePlayer** best_player)
{
    *best_highscore_rank = -1;
    *best_player = NULL;
    
    if(!m_use_highscores) return;
    
    // Add times to highscore list. First compute the order of karts,
    // so that the timing of the fastest kart is added first (otherwise
    // someone might get into the highscore list, only to be kicked out
    // again by a faster kart in the same race), which might be confusing
    // if we ever decide to display a message (e.g. during a race)
    unsigned int *index = new unsigned int[m_karts.size()];

    const unsigned int kart_amount = m_karts.size();
    for (unsigned int i=0; i<kart_amount; i++ )
    {
        index[i] = 999; // first reset the contents of the array
    }
    for (unsigned int i=0; i<kart_amount; i++ )
    {
        const int pos = m_karts[i]->getPosition()-1;
        if(pos < 0 || pos >= (int)kart_amount) continue; // wrong position
        index[pos] = i;
    }

    for (unsigned int pos=0; pos<kart_amount; pos++)
    {
        if(index[pos] == 999)
        {
            // no kart claimed to be in this position, most likely means
            // the kart location data is wrong

#ifdef DEBUG
            fprintf(stderr, "Error, incorrect kart positions:\n");
            for (unsigned int i=0; i<m_karts.size(); i++ )
            {
                fprintf(stderr, "i=%d position %d\n",i, 
                        m_karts[i]->getPosition());
            }
#endif
            continue;
        }

        // Only record times for player karts and only if 
        // they finished the race
        if(!m_karts[index[pos]]->getController()->isPlayerController()) 
            continue;
        if (!m_karts[index[pos]]->hasFinishedRace()) continue;

        assert(index[pos] >= 0);
        assert(index[pos] < m_karts.size());
        Kart *k = (Kart*)m_karts[index[pos]];

        Highscores* highscores = getHighscores();

        PlayerController *controller = (PlayerController*)(k->getController());
        
        int highscore_rank = highscores->addData(k->getIdent(),
                              controller->getPlayer()->getProfile()->getName(),
                                                 k->getFinishTime());
        
        if (highscore_rank > 0)
        {
            if (*best_highscore_rank == -1 || 
                highscore_rank < *best_highscore_rank)
            {
                *best_highscore_rank = highscore_rank;
                *best_finish_time = (int)(k->getFinishTime());
                *best_player = controller->getPlayer();
                *highscore_who = k->getIdent();
            }
            
            highscore_manager->saveHighscores();
        }
    } // next position
    delete []index;

}   // updateHighscores
Пример #2
0
void Tool::draw(sf::RenderTarget &render, const PlayerController &event) const
{
    drawRect(render, getPos(), m_dim, sf::Color::Black, 1, m_selected ? getPlayer()->getBaseColor() : (isInside(event.mousePos()) ? sf::Color(150, 150, 150, 255) : sf::Color(100, 100, 100, 255)));
}
Пример #3
0
void GroupCamera::Move(void)
{

	GamePlayer *gp = nullptr;
	PlayerController *cont = nullptr;
	Node *node = nullptr;
	Point3D loc;
	int numPlayers = 0;
	float sumX = 0;
	float xPos = 0;
	//float sumY = 0;
	float yPos = 0;
	float min = 0;
	float max = 0;
	float offset=0;

	//find center of mass, min, and max
	Player *p = TheMessageMgr->GetFirstPlayer();
	if (p)
	{
		gp = static_cast<GamePlayer *>(p);
		cont = gp->GetController();
		if (cont)
		{
			node = cont->GetTargetNode();
			loc = node->GetWorldPosition();
			sumX = sumX + loc.x;
			yPos = loc.y;
			min = sumX;
			max = sumX;
			numPlayers++;
		}

		p = p->Next();
	}
	while (p)
	{
		gp = static_cast<GamePlayer *>(p);
		cont = gp->GetController();
		if (cont)
		{
			node = cont->GetTargetNode();
			loc = node->GetWorldPosition();
			sumX = sumX + loc.x;
			if (loc.y < yPos)
			{
				yPos = loc.y;
			}
			if (loc.x < min){
				min = loc.x;
			}
			else if (loc.x > max)
			{
				max = loc.x;
			}
			numPlayers++;
		}

		p = p->Next();
	}

	xPos = sumX / numPlayers;
	offset = max - min;
	if (offset < 8.0F){
		offset = 8.0F;
	}

	SetNodePosition(Point3D(xPos, yPos - offset, 4.5F));
	LookAtPoint(Point3D(xPos, yPos, 0.0F));
}
Пример #4
0
/** Updates the physics simulation and handles all collisions.
 *  \param dt Time step.
 */
void Physics::update(float dt)
{
    PROFILER_PUSH_CPU_MARKER("Physics", 0, 0, 0);

    m_physics_loop_active = true;
    // Bullet can report the same collision more than once (up to 4
    // contact points per collision). Additionally, more than one internal
    // substep might be taken, resulting in potentially even more
    // duplicates. To handle this, all collisions (i.e. pair of objects)
    // are stored in a vector, but only one entry per collision pair
    // of objects.
    m_all_collisions.clear();

    // Maximum of three substeps. This will work for framerate down to
    // 20 FPS (bullet default frequency is 60 HZ).
    m_dynamics_world->stepSimulation(dt, 3);

    // Now handle the actual collision. Note: flyables can not be removed
    // inside of this loop, since the same flyables might hit more than one
    // other object. So only a flag is set in the flyables, the actual
    // clean up is then done later in the projectile manager.
    std::vector<CollisionPair>::iterator p;
    for(p=m_all_collisions.begin(); p!=m_all_collisions.end(); ++p)
    {
        // Kart-kart collision
        // --------------------
        if(p->getUserPointer(0)->is(UserPointer::UP_KART))
        {
            KartKartCollision(p->getUserPointer(0)->getPointerKart(),
                              p->getContactPointCS(0),
                              p->getUserPointer(1)->getPointerKart(),
                              p->getContactPointCS(1)                );
            Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
            int kartid1 = p->getUserPointer(0)->getPointerKart()->getWorldKartId();
            int kartid2 = p->getUserPointer(1)->getPointerKart()->getWorldKartId();
            script_engine->runFunction("void onKartKartCollision(int, int)",
                [=](asIScriptContext* ctx) {
                    ctx->SetArgDWord(0, kartid1);
                    ctx->SetArgDWord(1, kartid2);
                });
            continue;
        }  // if kart-kart collision

        if(p->getUserPointer(0)->is(UserPointer::UP_PHYSICAL_OBJECT))
        {
            // Kart hits physical object
            // -------------------------
            Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
            AbstractKart *kart = p->getUserPointer(1)->getPointerKart();
            int kartId = kart->getWorldKartId();
            PhysicalObject* obj = p->getUserPointer(0)->getPointerPhysicalObject();
            std::string obj_id = obj->getID();
            std::string scripting_function = obj->getOnKartCollisionFunction();
            if (scripting_function.size() > 0)
            {
                script_engine->runFunction("void " + scripting_function + "(int, const string)",
                    [&](asIScriptContext* ctx) {
                        ctx->SetArgDWord(0, kartId);
                        ctx->SetArgObject(1, &obj_id);
                    });
            }
            if (obj->isCrashReset())
            {
                new RescueAnimation(kart);
            }
            else if (obj->isExplodeKartObject())
            {
                ExplosionAnimation::create(kart);
            }
            else if (obj->isFlattenKartObject())
            {
                const KartProperties* kp = kart->getKartProperties();
                kart->setSquash(kp->getSquashDuration() * kart->getPlayerDifficulty()->getSquashDuration(),
                    kp->getSquashSlowdown() * kart->getPlayerDifficulty()->getSquashSlowdown());
            }
            else if(obj->isSoccerBall() && 
                    race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
            {
                SoccerWorld* soccerWorld = (SoccerWorld*)World::getWorld();
                soccerWorld->setLastKartTohitBall(kartId);
            }
            continue;
        }

        if (p->getUserPointer(0)->is(UserPointer::UP_ANIMATION))
        {
            // Kart hits animation
            ThreeDAnimation *anim=p->getUserPointer(0)->getPointerAnimation();
            if(anim->isCrashReset())
            {
                AbstractKart *kart = p->getUserPointer(1)->getPointerKart();
                new RescueAnimation(kart);
            }
            else if (anim->isExplodeKartObject())
            {
                AbstractKart *kart = p->getUserPointer(1)->getPointerKart();
                ExplosionAnimation::create(kart);
            }
            else if (anim->isFlattenKartObject())
            {
                AbstractKart *kart = p->getUserPointer(1)->getPointerKart();
                const KartProperties* kp = kart->getKartProperties();
                kart->setSquash(kp->getSquashDuration() * kart->getPlayerDifficulty()->getSquashDuration(),
                    kp->getSquashSlowdown() * kart->getPlayerDifficulty()->getSquashSlowdown());
            }
            continue;

        }
        // now the first object must be a projectile
        // =========================================
        if(p->getUserPointer(1)->is(UserPointer::UP_TRACK))
        {
            // Projectile hits track
            // ---------------------
            p->getUserPointer(0)->getPointerFlyable()->hitTrack();
        }
        else if(p->getUserPointer(1)->is(UserPointer::UP_PHYSICAL_OBJECT))
        {
            // Projectile hits physical object
            // -------------------------------
            Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
            Flyable* flyable = p->getUserPointer(0)->getPointerFlyable();
            PhysicalObject* obj = p->getUserPointer(1)->getPointerPhysicalObject();
            std::string obj_id = obj->getID();
            std::string scripting_function = obj->getOnItemCollisionFunction();
            if (scripting_function.size() > 0)
            {
                script_engine->runFunction("void " + scripting_function + "(int, int, const string)",
                        [&](asIScriptContext* ctx) {
                        ctx->SetArgDWord(0, (int)flyable->getType());
                        ctx->SetArgDWord(1, flyable->getOwnerId());
                        ctx->SetArgObject(2, &obj_id);
                    });
            }
            flyable->hit(NULL, obj);

            if (obj->isSoccerBall() && 
                race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
            {
                int kartId = p->getUserPointer(0)->getPointerFlyable()->getOwnerId();
                SoccerWorld* soccerWorld = (SoccerWorld*)World::getWorld();
                soccerWorld->setLastKartTohitBall(kartId);
            }

        }
        else if(p->getUserPointer(1)->is(UserPointer::UP_KART))
        {
            // Projectile hits kart
            // --------------------
            // Only explode a bowling ball if the target is
            // not invulnerable
            AbstractKart* target_kart = p->getUserPointer(1)->getPointerKart();
            PowerupManager::PowerupType type = p->getUserPointer(0)->getPointerFlyable()->getType();
            if(type != PowerupManager::POWERUP_BOWLING || !target_kart->isInvulnerable())
            {
                Flyable *f = p->getUserPointer(0)->getPointerFlyable();
                f->hit(target_kart);

                // Check for achievements
                AbstractKart * kart = World::getWorld()->getKart(f->getOwnerId());
                PlayerController *c = dynamic_cast<PlayerController*>(kart->getController());

                // Check that it's not a kart hitting itself (this can
                // happen at the time a flyable is shot - release too close
                // to the kart, and it's the current player. At this stage
                // only the current player can get achievements.
                if (target_kart != kart && c &&
                    c->getPlayer()->getConstProfile() == PlayerManager::getCurrentPlayer())
                {
                    // Compare the current value of hits with the 'hit' goal value
                    // (otherwise it would be compared with the kart id goal value,
                    // which doesn't exist.
                    PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_ARCH_ENEMY,
                                                       target_kart->getIdent(), 1, "hit");
                    if (type == PowerupManager::POWERUP_BOWLING)
                    {
                        PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_STRIKE,
                                                          "ball", 1);
                    }   // is bowling ball
                }   // if target_kart != kart && is a player kart and is current player
            }

        }
        else
        {
            // Projectile hits projectile
            // --------------------------
            p->getUserPointer(0)->getPointerFlyable()->hit(NULL);
            p->getUserPointer(1)->getPointerFlyable()->hit(NULL);
        }
    }  // for all p in m_all_collisions

    m_physics_loop_active = false;
    // Now remove the karts that were removed while the above loop
    // was active. Now we can safely call removeKart, since the loop
    // is finished and m_physics_world_active is not set anymore.
    for(unsigned int i=0; i<m_karts_to_delete.size(); i++)
        removeKart(m_karts_to_delete[i]);
    m_karts_to_delete.clear();

    PROFILER_POP_CPU_MARKER();
}   // update
Пример #5
0
void GroupCamera2::Move(void)
{

	GamePlayer *gp = nullptr;
	PlayerController *cont = nullptr;
	Node *node = nullptr;
	Point3D loc;
	int numPlayers = 0;
	float sumX = 0;
	float xPos = 0;
	float min = 0;
	float max = 0;


	//find center of mass, min, and max
	Player *p = TheMessageMgr->GetFirstPlayer();
	if (p)
	{
		gp = static_cast<GamePlayer *>(p);
		cont = gp->GetController();
		if (cont)
		{
			node = cont->GetTargetNode();
			loc = node->GetWorldPosition();
			sumX = sumX + loc.x;
			min = sumX;
			max = sumX;
			numPlayers++;
		}

		p = p->Next();
	}
	while (p)
	{
		gp = static_cast<GamePlayer *>(p);
		cont = gp->GetController();
		if (cont)
		{
			node = cont->GetTargetNode();
			loc = node->GetWorldPosition();
			sumX = sumX + loc.x;
			if (loc.x < min){
				min = loc.x;
			}
			else if (loc.x > max)
			{
				max = loc.x;
			}
			numPlayers++;
		}

		p = p->Next();
	}

	xPos = sumX / numPlayers;

	//float offset = -5.0F;
	float yPos = 4.0F;
	float y = 0;

	//find center of mass, min, and max
	p = TheMessageMgr->GetFirstPlayer();
	while (p)
	{
		gp = static_cast<GamePlayer *>(p);
		cont = gp->GetController();
		if (cont)
		{
			node = cont->GetTargetNode();
			loc = node->GetWorldPosition();
			if (loc.x > xPos)
			{
				//use y = 2x
				y = 2.0F*(loc.x - xPos);
			}
			else
			{
				//use y = -2x
				y = 2.0F*(xPos - loc.x);
			}
			//get distance y to loc.y
			y = y - loc.y;
			//check is y is minimum value (negative)
			if (yPos < y){
				yPos = y;
			}
		}

		p = p->Next();
	}

	SetNodePosition(Point3D(xPos, -4.5F - yPos, 3.5F));
	LookAtPoint(Point3D(xPos, 0.0, 0.0F));
}
Пример #6
0
void GuiCommandButton::actionPerformed(const PlayerController &event, Vec pos, Vec dim, Gui* gui)
{
    if(event.pressed(0))
        m_commands++;
}
Пример #7
0
/**
 * Handle the player interacting with the Rotator
 */
void RotatorController::HandleInteractionEvent(InteractionEventType type, const Point3D *position, Node *activator)
{

	PlayerController* sc = TheGame->GetPlayerController();
	sc->SetPlayerAzimuth(sc->GetPlayerAzimuth() + K::pi_over_2);
}
Пример #8
0
void GuiButton::update(const PlayerController &controller, Vec pos, Vec dim)
{
    m_hovered = controller.mousePos().insideRect(pos, dim);
}
Пример #9
0
GameObject* ScriptArguments::getPlayerCharacter(unsigned int player) const {
    auto playerId = parameters->at(player).integerValue();
    PlayerController* controller = getWorld()->players.at(playerId);
    RW_CHECK(controller != nullptr, "No controller for player " << player);
    return controller->getCharacter();
}