Try to fix that a client collects its own bubble gum in case of

a rewind.
This commit is contained in:
hiker 2018-09-03 18:21:03 +10:00
parent 3d34c2893b
commit 5955166931
4 changed files with 29 additions and 28 deletions

View File

@ -107,11 +107,16 @@ void ItemState::collected(const AbstractKart *kart)
* \param normal The normal upon which the item is placed (so that it can
* be aligned properly with the ground).
* \param mesh The mesh to be used for this item.
* \param owner 'Owner' of this item, i.e. the kart that drops it. This is
* used to deactivate this item for the owner, i.e. avoid that a kart
* 'collects' its own bubble gum. NULL means no owner, and the item
* can be collected immediatley by any kart.
* \param is_predicted True if the creation of the item is predicted by
* a client. Only used in networking.
*/
Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
scene::IMesh* mesh, scene::IMesh* lowres_mesh, bool is_predicted)
scene::IMesh* mesh, scene::IMesh* lowres_mesh,
const AbstractKart *owner, bool is_predicted)
: ItemState(type)
{
assert(type != ITEM_TRIGGER); // use other constructor for that
@ -158,6 +163,11 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
hpr.setHPR(m_original_rotation);
m_node->setRotation(hpr.toIrrHPR());
m_node->grab();
if (owner)
{
m_previous_owner = owner;
ItemState::setDeactivatedTicks(stk_config->time2Ticks(1.5f));
}
} // Item(type, xyz, normal, mesh, lowres_mesh)
//-----------------------------------------------------------------------------
@ -320,17 +330,6 @@ void Item::reset()
}
} // reset
//-----------------------------------------------------------------------------
/** Sets which karts dropped an item. This is used to avoid that a kart is
* affected by its own items.
* \param parent Kart that dropped the item.
*/
void Item::setParent(const AbstractKart* parent)
{
m_previous_owner = parent;
ItemState::setDeactivatedTicks(stk_config->time2Ticks(1.5f));
} // setParent
// ----------------------------------------------------------------------------
/** Updated the item - rotates it, takes care of items coming back into
* the game after it has been collected.

View File

@ -138,7 +138,7 @@ public:
* \param id Index of this item in the array of all items.
* \param kart_id If !=-1 the kart that dropped this item; -1
* indicates an item that's part of the track. */
ItemState(ItemType type, int id=-1, AbstractKart *kart=NULL)
ItemState(ItemType type, int id=-1, const AbstractKart *kart=NULL)
{
setType(type);
m_item_id = id;
@ -150,7 +150,6 @@ public:
void setDisappearCounter();
void update(int ticks);
virtual void collected(const AbstractKart *kart);
// -----------------------------------------------------------------------
void reset()
@ -326,13 +325,13 @@ private:
public:
Item(ItemType type, const Vec3& xyz, const Vec3& normal,
scene::IMesh* mesh, scene::IMesh* lowres_mesh,
const AbstractKart *owner,
bool is_predicted=false);
Item(const Vec3& xyz, float distance,
TriggerItemListener* trigger);
virtual ~Item ();
void updateGraphics(float dt);
virtual void collected(const AbstractKart *kart) OVERRIDE;
void setParent(const AbstractKart* parent);
void reset();
void switchTo(ItemType type, scene::IMesh *mesh, scene::IMesh *lowmesh);
void switchBack();

View File

@ -286,9 +286,7 @@ Item* ItemManager::dropNewItem(ItemState::ItemType type,
}
Item* item = new Item(type, pos, normal, m_item_mesh[mesh_type],
m_item_lowres_mesh[mesh_type]);
if(kart != NULL) item->setParent(kart);
m_item_lowres_mesh[mesh_type], /*prev_owner*/kart);
insertItem(item);
if(m_switch_ticks>=0)
{
@ -318,7 +316,7 @@ Item* ItemManager::placeItem(ItemState::ItemType type, const Vec3& xyz,
ItemState::ItemType mesh_type = type;
Item* item = new Item(type, xyz, normal, m_item_mesh[mesh_type],
m_item_lowres_mesh[mesh_type]);
m_item_lowres_mesh[mesh_type], /*prev_owner*/NULL);
insertItem(item);
if (m_switch_ticks >= 0)

View File

@ -267,6 +267,7 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
// From here the replay can happen.
// 1) Remove predicted items:
// --------------------------
for (unsigned int i=0; i<m_all_items.size(); i++)
{
Item *item = m_all_items[i];
@ -274,20 +275,21 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
{
deleteItem(item);
}
}
} // for i in m_all_items
// 2) Apply all events to current confirmed state:
// -----------------------------------------------
int current_time = m_confirmed_state_time;
bool has_state = count > 0;
while(count > 0)
{
// 1) Decode the event in the message
// ----------------------------------
// 2.1) Decode the event in the message
// ------------------------------------
ItemEventInfo iei(buffer, &count);
// 2) If the event needs to be applied, forward
// the time to the time of this event:
// --------------------------------------------
// 2.2) If the event needs to be applied, forward
// the time to the time of this event:
// ----------------------------------------------
int dt = iei.getTicks() - current_time;
// Skip an event that are 'in the past' (i.e. have been sent again by
// the server because it has not yet received confirmation from all
@ -331,7 +333,9 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
current_time = iei.getTicks();
} // while count >0
// Inform the server which events have been received.
// Inform the server which events have been received (if there has
// been any updates - no need to send messages if nothing has changed)
if (has_state)
{
if (auto gp = GameProtocol::lock())
@ -342,8 +346,8 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
int dt = World::getWorld()->getTicksSinceStart() - current_time;
if(dt>0) forwardTime(dt);
// Restore the state to the current world time:
// ============================================
// 3. Restore the state to the current world time:
// ===============================================
for(unsigned int i=0; i<m_confirmed_state.size(); i++)
{
@ -358,6 +362,7 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
&xyz);
item_new->setPredicted(false);
item_new->setItemId(i);
item_new->setDeactivatedTicks(is->getDeactivatedTicks());
m_all_items[i] = item_new;
*((ItemState*)m_all_items[i]) = *is;
}