fillig the GameEventsProtocol with events that concern powerup collect

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13419 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hilnius
2013-08-06 19:10:33 +00:00
parent 9ec58bbcb1
commit 9151770aa0
16 changed files with 216 additions and 101 deletions

View File

@@ -32,7 +32,7 @@
#include "karts/explosion_animation.hpp"
#include "karts/kart_properties.hpp"
#include "modes/three_strikes_battle.hpp"
#include "modes/world.hpp"
#include "modes/world.hpp"
#include "utils/constants.hpp"
/** Initialises the attachment each kart has.

View File

@@ -29,6 +29,8 @@
#include "io/file_manager.hpp"
#include "karts/abstract_kart.hpp"
#include "modes/linear_world.hpp"
#include "network/network_manager.hpp"
#include "network/network_world.hpp"
#include "tracks/quad_graph.hpp"
#include "tracks/track.hpp"
#include "utils/string_utils.hpp"
@@ -305,7 +307,11 @@ void ItemManager::checkItemHit(AbstractKart* kart)
// we pass the kart and the position separately.
if((*i)->hitKart(kart->getXYZ(), kart))
{
collectedItem(*i, kart);
// if we're not playing online, pick the item.
if (!NetworkWorld::getInstance()->isRunning())
collectedItem(*i, kart);
else if (NetworkManager::getInstance()->isServer())
NetworkWorld::getInstance()->collectedItem(*i, kart);
} // if hit
} // for m_all_items
} // checkItemHit

View File

@@ -406,6 +406,12 @@ void Powerup::use()
*/
void Powerup::hitBonusBox(const Item &item, int add_info)
{
if (add_info>=0)
{
PowerupManager::PowerupType id = (PowerupManager::PowerupType)((add_info>>4)&0x0f); // highest 4 bits for the type
uint8_t quantity = (add_info&0x0f); // last 4 bits for the amount
set(id,quantity);
}
// Position can be -1 in case of a battle mode (which doesn't have
// positions), but this case is properly handled in getRandomPowerup.
int position = m_owner->getPosition();

View File

@@ -270,7 +270,7 @@ public:
* \param add_info Additional info, used in networking games to force
* a specific item to be used (instead of a random item) to keep
* all karts in synch. */
virtual void collectedItem(Item *item, int random_attachment) = 0;
virtual void collectedItem(Item *item, int add_info) = 0;
// ------------------------------------------------------------------------
/** Returns the current position of this kart in the race. */
virtual int getPosition() const = 0;

View File

@@ -120,7 +120,7 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
m_jump_time = 0;
m_is_jumping = false;
m_min_nitro_time = 0.0f;
m_view_blocked_by_plunger = 0;
m_has_caught_nolok_bubblegum = false;
@@ -852,19 +852,19 @@ void Kart::collectedItem(Item *item, int add_info)
break;
case Item::ITEM_BONUS_BOX :
{
m_powerup->hitBonusBox(*item, add_info);
m_powerup->hitBonusBox(*item, add_info); // selects the powerup
break;
}
case Item::ITEM_BUBBLEGUM:
m_has_caught_nolok_bubblegum = (item->getEmitter() != NULL &&
m_has_caught_nolok_bubblegum = (item->getEmitter() != NULL &&
item->getEmitter()->getIdent() == "nolok");
// slow down
m_bubblegum_time = m_kart_properties->getBubblegumTime();
m_bubblegum_torque = (rand()%2)
m_bubblegum_torque = (rand()%2)
? m_kart_properties->getBubblegumTorque()
: -m_kart_properties->getBubblegumTorque();
m_max_speed->setSlowdown(MaxSpeed::MS_DECREASE_BUBBLE,
m_max_speed->setSlowdown(MaxSpeed::MS_DECREASE_BUBBLE,
m_kart_properties->getBubblegumSpeedFraction(),
m_kart_properties->getBubblegumFadeInTime(),
m_bubblegum_time);
@@ -1152,7 +1152,8 @@ void Kart::update(float dt)
} // if there is material
// Check if any item was hit.
ItemManager::get()->checkItemHit(this);
if (!m_controller->isNetworkController()) // no need in network
ItemManager::get()->checkItemHit(this);
static video::SColor pink(255, 255, 133, 253);
static video::SColor green(255, 61, 87, 23);
@@ -1198,7 +1199,7 @@ void Kart::update(float dt)
// take the same time again to reach the bottom
float t = 2.0f * v/force;
// Jump if either the jump is estimated to be long enough, or
// Jump if either the jump is estimated to be long enough, or
// the texture has the jump property set.
if(t>getKartProperties()->getJumpAnimationTime() ||
last_m->isJumpTexture() )
@@ -1211,13 +1212,13 @@ void Kart::update(float dt)
{
// Kart touched ground again
m_is_jumping = false;
HitEffect *effect = new Explosion(getXYZ(), "jump",
HitEffect *effect = new Explosion(getXYZ(), "jump",
"jump_explosion.xml");
projectile_manager->addHitEffect(effect);
m_kart_model->setAnimation(KartModel::AF_DEFAULT);
m_jump_time = 0;
}
if( (!isOnGround() || emergency) && m_shadow_enabled)
{
m_shadow_enabled = false;
@@ -1226,7 +1227,7 @@ void Kart::update(float dt)
if(!m_shadow_enabled && isOnGround() && !emergency)
{
m_shadow->enableShadow();
m_shadow_enabled = true;
m_shadow_enabled = true;
}
} // update
@@ -1255,7 +1256,7 @@ void Kart::setSquash(float time, float slowdown)
return;
}
m_node->setScale(core::vector3df(1.0f, 0.5f, 1.0f));
m_max_speed->setSlowdown(MaxSpeed::MS_DECREASE_SQUASH, slowdown,
m_max_speed->setSlowdown(MaxSpeed::MS_DECREASE_SQUASH, slowdown,
0.1f, time);
m_squash_time = time;
} // setSquash
@@ -1522,13 +1523,13 @@ void Kart::updateNitro(float dt)
if (m_min_nitro_time > 0.0f)
{
m_min_nitro_time -= dt;
// when pressing the key, don't allow the min time to go under zero.
// If it went under zero, it would be reset
if (m_controls.m_nitro && m_min_nitro_time <= 0.0f)
m_min_nitro_time = 0.1f;
}
bool increase_speed = (m_controls.m_nitro && isOnGround());
if (!increase_speed && m_min_nitro_time <= 0.0f)
{
@@ -1540,7 +1541,7 @@ void Kart::updateNitro(float dt)
m_collected_energy = 0;
return;
}
if (increase_speed)
{
m_max_speed->increaseMaxSpeed(MaxSpeed::MS_INCREASE_NITRO,
@@ -2300,7 +2301,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_NITRO2, 0);
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_NITROSMOKE1, 0);
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_NITROSMOKE2, 0);
}
m_kart_gfx->resizeBox(KartGFX::KGFX_NITRO1, getSpeed(), dt);
m_kart_gfx->resizeBox(KartGFX::KGFX_NITRO2, getSpeed(), dt);

View File

@@ -18,8 +18,11 @@
#include "network/game_setup.hpp"
#include "karts/abstract_kart.hpp"
#include "modes/world.hpp"
#include "utils/log.hpp"
//-----------------------------------------------------------------------------
GameSetup::GameSetup()
@@ -110,6 +113,39 @@ void GameSetup::setPlayerKart(uint8_t id, std::string kart_name)
//-----------------------------------------------------------------------------
void GameSetup::bindKartsToProfiles()
{
World::KartList karts = World::getWorld()->getKarts();
for (unsigned int i = 0; i < m_players.size(); i++)
{
Log::info("GameSetup", "Player %d has id %d and kart %s", i, m_players[i]->race_id, m_players[i]->kart_name.c_str());
}
for (unsigned int i = 0; i < karts.size(); i++)
{
Log::info("GameSetup", "Kart %d has id %d and kart %s", i, karts[i]->getWorldKartId(), karts[i]->getIdent().c_str());
}
for (unsigned int j = 0; j < m_players.size(); j++)
{
bool found = false;
for (unsigned int i = 0 ; i < karts.size(); i++)
{
if (karts[i]->getIdent() == m_players[j]->kart_name)
{
m_players[j]->world_kart_id = karts[i]->getWorldKartId();
found = true;
break;
}
}
if (!found)
{
Log::error("GameSetup", "Error while binding world kart ids to players profiles.");
}
}
}
//-----------------------------------------------------------------------------
const NetworkPlayerProfile* GameSetup::getProfile(uint32_t id)
{
for (unsigned int i = 0; i < m_players.size(); i++)
@@ -138,6 +174,20 @@ const NetworkPlayerProfile* GameSetup::getProfile(uint8_t id)
//-----------------------------------------------------------------------------
const NetworkPlayerProfile* GameSetup::getProfile(std::string kart_name)
{
for (unsigned int i = 0; i < m_players.size(); i++)
{
if (m_players[i]->kart_name == kart_name)
{
return m_players[i];
}
}
return NULL;
}
//-----------------------------------------------------------------------------
bool GameSetup::isKartAvailable(std::string kart_name)
{
for (unsigned int i = 0; i < m_players.size(); i++)

View File

@@ -39,6 +39,7 @@ class NetworkPlayerProfile
uint8_t race_id; //!< The id of the player for the race
std::string kart_name; //!< The selected kart.
Online::User* user_profile; //!< Pointer to the lobby profile
uint8_t world_kart_id; //!< the kart id in the World class (pointer to AbstractKart)
};
/*! \class GameSetup
@@ -55,11 +56,13 @@ class GameSetup
bool removePlayer(uint32_t id); //!< Remove a player by id.
bool removePlayer(uint8_t id); //!< Remove a player by local id.
void setPlayerKart(uint8_t id, std::string kart_name); //!< Set the kart of a player
void bindKartsToProfiles();
std::vector<NetworkPlayerProfile*> getPlayers() { return m_players; }
int getPlayerCount() { return m_players.size(); }
const NetworkPlayerProfile* getProfile(uint32_t id); //!< Get a profile by database id
const NetworkPlayerProfile* getProfile(uint8_t id); //!< Get the profile by the lobby id
const NetworkPlayerProfile* getProfile(std::string kart_name);
bool isKartAvailable(std::string kart_name);
bool isKartAllowed(std::string kart_name) {return true; }

View File

@@ -1,8 +1,10 @@
#include "network/network_world.hpp"
#include "network/network_manager.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/synchronization_protocol.hpp"
#include "network/protocols/controller_events_protocol.hpp"
#include "network/protocols/game_events_protocol.hpp"
#include "modes/world.hpp"
#include "karts/controller/controller.hpp"
@@ -40,6 +42,21 @@ void NetworkWorld::update(float dt)
}
}
bool NetworkWorld::isRaceOver()
{
if (!World::getWorld())
return false;
return (World::getWorld()->getPhase() >= WorldStatus::RESULT_DISPLAY_PHASE);
}
void NetworkWorld::collectedItem(Item *item, AbstractKart *kart)
{
assert(NetworkManager::getInstance()->isServer()); // this is only called in the server
GameEventsProtocol* protocol = static_cast<GameEventsProtocol*>(
ProtocolManager::getInstance()->getProtocol(PROTOCOL_GAME_EVENTS));
protocol->collectedItem(item,kart);
}
void NetworkWorld::controllerAction(Controller* controller, PlayerAction action, int value)
{
ControllerEventsProtocol* protocol = static_cast<ControllerEventsProtocol*>(
@@ -48,9 +65,3 @@ void NetworkWorld::controllerAction(Controller* controller, PlayerAction action,
protocol->controllerAction(controller, action, value);
}
bool NetworkWorld::isRaceOver()
{
if (!World::getWorld())
return false;
return (World::getWorld()->getPhase() >= WorldStatus::RESULT_DISPLAY_PHASE);
}

View File

@@ -8,6 +8,7 @@
class Controller;
class KartUpdateProtocol;
class AbstractKart;
class Item;
/*! \brief Manages the world updates during an online game
* This function's update is to be called instead of the normal World update
@@ -23,6 +24,7 @@ class NetworkWorld : public Singleton<NetworkWorld>
bool isRunning() { return m_running; }
bool isRaceOver();
void collectedItem(Item *item, AbstractKart *kart);
void controllerAction(Controller* controller, PlayerAction action, int value);
std::string m_self_kart;

View File

@@ -1,5 +1,12 @@
#include "network/protocols/game_events_protocol.hpp"
#include "karts/abstract_kart.hpp"
#include "items/item.hpp"
#include "items/item_manager.hpp"
#include "items/powerup.hpp"
#include "modes/world.hpp"
#include "network/network_manager.hpp"
GameEventsProtocol::GameEventsProtocol() : Protocol(NULL, PROTOCOL_GAME_EVENTS)
{
}
@@ -8,6 +15,50 @@ GameEventsProtocol::~GameEventsProtocol()
{
}
bool GameEventsProtocol::notifyEvent(Event* event)
{
if (event->type != EVENT_TYPE_MESSAGE)
return true;
NetworkString data = event->data();
if (data.size() < 5) // for token and type
{
Log::warn("GameEventsProtocol", "Too short message.");
return true;
}
if ( (*event->peer)->getClientServerToken() != data.gui32())
{
Log::warn("GameEventsProtocol", "Bad token.");
return true;
}
int8_t type = data.gui8(4);
data.removeFront(5);
switch (type)
{
case 0x01: // item picked
{
if (data.size() < 6)
{
Log::warn("GameEventsProtocol", "Too short message.");
return true;
}
uint32_t item_id = data.gui32();
uint8_t powerup_type = data.gui8(4);
uint8_t kart_race_id = data.gui8(5);
// now set the kart powerup
AbstractKart* kart = World::getWorld()->getKart(
NetworkManager::getInstance()->getGameSetup()->getProfile(kart_race_id)->world_kart_id);
ItemManager::get()->collectedItem(
ItemManager::get()->getItem(item_id),
kart,
powerup_type);
} break;
default:
Log::warn("GameEventsProtocol", "Unkown message type.");
break;
}
return true;
}
void GameEventsProtocol::setup()
{
}
@@ -15,3 +66,20 @@ void GameEventsProtocol::setup()
void GameEventsProtocol::update()
{
}
void GameEventsProtocol::collectedItem(Item* item, AbstractKart* kart)
{
NetworkString ns;
GameSetup* setup = NetworkManager::getInstance()->getGameSetup();
assert(setup);
const NetworkPlayerProfile* player_profile = setup->getProfile(kart->getIdent()); // use kart name
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
for (unsigned int i = 0; i < peers.size(); i++)
{
ns.ai32(peers[i]->getClientServerToken());
// 0x01 : item picked : send item id, powerup type and kart race id
ns.ai8(0x01).ai32(item->getItemId()).ai8((int)(kart->getPowerup()->getType())).ai8(player_profile->race_id); // send item,
m_listener->sendMessage(this, peers[i], ns, true); // reliable
}
}

View File

@@ -3,6 +3,8 @@
#include "network/protocol.hpp"
class AbstractKart;
class Item;
class GameEventsProtocol : public Protocol
{
@@ -10,12 +12,14 @@ class GameEventsProtocol : public Protocol
GameEventsProtocol();
virtual ~GameEventsProtocol();
virtual bool notifyEvent(Event* event) { return true; }
virtual bool notifyEventAsynchronous(Event* event) { return true; }
virtual bool notifyEvent(Event* event);
virtual bool notifyEventAsynchronous(Event* event) { return false; }
virtual void setup();
virtual void update();
virtual void asynchronousUpdate() {}
void collectedItem(Item* item, AbstractKart* kart);
protected:
};

View File

@@ -193,6 +193,8 @@ void StartGameProtocol::ready() // on clients, means the loading is finished
ns.ai32(NetworkManager::getInstance()->getPeers()[0]->getClientServerToken()).ai8(1);
Log::info("StartGameProtocol", "Player ready, notifying server.");
m_listener->sendMessage(this, ns, true);
// set karts into the network game setup
NetworkManager::getInstance()->getGameSetup()->bindKartsToProfiles();
m_state = READY;
m_ready = true;
return;

View File

@@ -3,6 +3,7 @@
#include "network/network_manager.hpp"
#include "network/protocols/kart_update_protocol.hpp"
#include "network/protocols/controller_events_protocol.hpp"
#include "network/protocols/game_events_protocol.hpp"
#include "utils/time.hpp"
//-----------------------------------------------------------------------------
@@ -133,6 +134,7 @@ void SynchronizationProtocol::asynchronousUpdate()
Log::info("SynchronizationProtocol", "Countdown finished. Starting now.");
m_listener->requestStart(new KartUpdateProtocol());
m_listener->requestStart(new ControllerEventsProtocol());
m_listener->requestStart(new GameEventsProtocol());
m_listener->requestTerminate(this);
return;
}

View File

@@ -832,75 +832,7 @@ void KartHoverListener::onSelectionChanged(DynamicRibbonWidget* theWidget,
return;
}
// Update the displayed model
ModelViewWidget* w3 = m_parent->m_kart_widgets[playerID].m_model_view;
assert( w3 != NULL );
if (selectionID == RANDOM_KART_ID)
{
// Random kart
scene::IMesh* model =
ItemManager::getItemModel(Item::ITEM_BONUS_BOX);
w3->clearModels();
w3->addModel( model, Vec3(0.0f, -12.0f, 0.0f),
Vec3(35.0f, 35.0f, 35.0f) );
w3->update(0);
m_parent->m_kart_widgets[playerID].m_kart_name
->setText( _("Random Kart"), false );
}
// selectionID contains the name of the kart, so check only for substr
else if (StringUtils::startsWith(selectionID, ID_LOCKED))
{
w3->clearModels();
w3->addModel(irr_driver->getAnimatedMesh(
file_manager->getDataDir() + "/models/chest.b3d" )->getMesh(20),
Vec3(0,0,0), Vec3(15.0f, 15.0f, 15.0f) );
w3->update(0);
if (m_parent->m_multiplayer)
{
m_parent->m_kart_widgets[playerID].m_kart_name
->setText(_("Locked"), false );
}
else
{
m_parent->m_kart_widgets[playerID].m_kart_name
->setText(_("Locked : solve active challenges to gain "
"access to more!"), false );
}
}
else
{
const KartProperties *kp =
kart_properties_manager->getKart(selectionID);
if (kp != NULL)
{
const KartModel &kart_model = kp->getMasterKartModel();
w3->clearModels();
w3->addModel( kart_model.getModel(), Vec3(0,0,0),
Vec3(35.0f, 35.0f, 35.0f),
kart_model.getBaseFrame() );
w3->addModel( kart_model.getWheelModel(0),
kart_model.getWheelGraphicsPosition(0) );
w3->addModel( kart_model.getWheelModel(1),
kart_model.getWheelGraphicsPosition(1) );
w3->addModel( kart_model.getWheelModel(2),
kart_model.getWheelGraphicsPosition(2) );
w3->addModel( kart_model.getWheelModel(3),
kart_model.getWheelGraphicsPosition(3) );
w3->update(0);
m_parent->m_kart_widgets[playerID].m_kart_name
->setText( selectionText.c_str(), false );
}
else
{
fprintf(stderr, "[KartSelectionScreen] WARNING: could not "
"find a kart named '%s'\n",
selectionID.c_str());
}
}
m_parent->updateKartWidgetModel(playerID, selectionID, selectionText);
m_parent->m_kart_widgets[playerID].setKartInternalName(selectionID);
m_parent->validateKartChoices();
@@ -1506,8 +1438,11 @@ void KartSelectionScreen::playerConfirm(const int playerID)
// ----------------------------------------------------------------------------
void KartSelectionScreen::considerKartHovered(uint8_t widget_id, std::string selection)
void KartSelectionScreen::updateKartWidgetModel(uint8_t widget_id,
const std::string& selection,
const irr::core::stringw& selectionText)
{
// Update the displayed model
ModelViewWidget* w3 = m_kart_widgets[widget_id].m_model_view;
assert( w3 != NULL );
@@ -1520,8 +1455,29 @@ void KartSelectionScreen::considerKartHovered(uint8_t widget_id, std::string sel
w3->addModel( model, Vec3(0.0f, -12.0f, 0.0f),
Vec3(35.0f, 35.0f, 35.0f) );
w3->update(0);
m_kart_widgets[widget_id].m_kart_name->setText(
_("Random Kart"), false );
m_kart_widgets[widget_id].m_kart_name
->setText( _("Random Kart"), false );
}
// selection contains the name of the kart, so check only for substr
else if (StringUtils::startsWith(selection, ID_LOCKED))
{
w3->clearModels();
w3->addModel(irr_driver->getAnimatedMesh(
file_manager->getDataDir() + "/models/chest.b3d" )->getMesh(20),
Vec3(0,0,0), Vec3(15.0f, 15.0f, 15.0f) );
w3->update(0);
if (m_multiplayer)
{
m_kart_widgets[widget_id].m_kart_name
->setText(_("Locked"), false );
}
else
{
m_kart_widgets[widget_id].m_kart_name
->setText(_("Locked : solve active challenges to gain "
"access to more!"), false );
}
}
else
{
@@ -1545,8 +1501,8 @@ void KartSelectionScreen::considerKartHovered(uint8_t widget_id, std::string sel
kart_model.getWheelGraphicsPosition(3) );
w3->update(0);
m_kart_widgets[widget_id].m_kart_name->setText(
selection.c_str(), false );
m_kart_widgets[widget_id].m_kart_name
->setText( selectionText.c_str(), false );
}
else
{

View File

@@ -104,6 +104,10 @@ protected:
void setKartsFromCurrentGroup();
virtual void playerConfirm(const int playerID);
/** updates model of a kart widget, to have the good selection when the user validates */
void updateKartWidgetModel(uint8_t widget_id,
const std::string& selection,
const irr::core::stringw& selectionText);
/** Stores a pointer to the current selection screen */
static KartSelectionScreen* m_instance_ptr;

View File

@@ -144,7 +144,7 @@ void NetworkKartSelectionScreen::playerSelected(uint8_t race_id, std::string kar
assert(widget_id>=0 && widget_id < m_kart_widgets.size());
considerKartHovered(widget_id,kart_name);
KartSelectionScreen::updateKartWidgetModel(widget_id, kart_name, irr::core::stringw(kart_name.c_str()));
m_kart_widgets[widget_id].setKartInternalName(kart_name);
m_kart_widgets[widget_id].markAsReady(); // mark player ready
}