Merge remote-tracking branch 'origin/network-item-debugging'
This commit is contained in:
commit
abd3a79526
@ -37,6 +37,25 @@
|
|||||||
#include <ISceneManager.h>
|
#include <ISceneManager.h>
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Constructor.
|
||||||
|
* \param type Type of the item.
|
||||||
|
* \param owner If not NULL it is the kart that dropped this item; NULL
|
||||||
|
* indicates an item that's part of the track.
|
||||||
|
* \param id Index of this item in the array of all items.
|
||||||
|
*/
|
||||||
|
ItemState::ItemState(ItemType type, const AbstractKart *owner, int id)
|
||||||
|
{
|
||||||
|
setType(type);
|
||||||
|
m_item_id = id;
|
||||||
|
m_previous_owner = owner;
|
||||||
|
m_used_up_counter = -1;
|
||||||
|
if (owner)
|
||||||
|
setDeactivatedTicks(stk_config->time2Ticks(1.5f));
|
||||||
|
else
|
||||||
|
setDeactivatedTicks(0);
|
||||||
|
} // ItemState(ItemType)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Sets the disappear counter depending on type. */
|
/** Sets the disappear counter depending on type. */
|
||||||
void ItemState::setDisappearCounter()
|
void ItemState::setDisappearCounter()
|
||||||
@ -52,9 +71,23 @@ void ItemState::setDisappearCounter()
|
|||||||
} // switch
|
} // switch
|
||||||
} // setDisappearCounter
|
} // setDisappearCounter
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
/** Initialises an item.
|
||||||
|
* \param type Type for this item.
|
||||||
|
*/
|
||||||
|
void ItemState::initItem(ItemType type, const Vec3& xyz)
|
||||||
|
{
|
||||||
|
m_xyz = xyz;
|
||||||
|
m_original_type = ITEM_NONE;
|
||||||
|
m_ticks_till_return = 0;
|
||||||
|
setDisappearCounter();
|
||||||
|
} // initItem
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Update the state of the item, called once per physics frame.
|
/** Update the state of the item, called once per physics frame.
|
||||||
* \param ticks Number of ticks to simulate (typically 1).
|
* \param ticks Number of ticks to simulate. While this value is 1 when
|
||||||
|
* called during the normal game loop, during a rewind this value
|
||||||
|
* can be (much) larger than 1.
|
||||||
*/
|
*/
|
||||||
void ItemState::update(int ticks)
|
void ItemState::update(int ticks)
|
||||||
{
|
{
|
||||||
@ -107,12 +140,17 @@ void ItemState::collected(const AbstractKart *kart)
|
|||||||
* \param normal The normal upon which the item is placed (so that it can
|
* \param normal The normal upon which the item is placed (so that it can
|
||||||
* be aligned properly with the ground).
|
* be aligned properly with the ground).
|
||||||
* \param mesh The mesh to be used for this item.
|
* \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
|
* \param is_predicted True if the creation of the item is predicted by
|
||||||
* a client. Only used in networking.
|
* a client. Only used in networking.
|
||||||
*/
|
*/
|
||||||
Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
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,
|
||||||
: ItemState(type)
|
const AbstractKart *owner, bool is_predicted)
|
||||||
|
: ItemState(type, owner)
|
||||||
{
|
{
|
||||||
assert(type != ITEM_TRIGGER); // use other constructor for that
|
assert(type != ITEM_TRIGGER); // use other constructor for that
|
||||||
|
|
||||||
@ -190,7 +228,6 @@ Item::Item(const Vec3& xyz, float distance, TriggerItemListener* trigger)
|
|||||||
void Item::initItem(ItemType type, const Vec3 &xyz)
|
void Item::initItem(ItemType type, const Vec3 &xyz)
|
||||||
{
|
{
|
||||||
ItemState::initItem(type, xyz);
|
ItemState::initItem(type, xyz);
|
||||||
m_previous_owner = NULL;
|
|
||||||
m_rotate = (getType()!=ITEM_BUBBLEGUM) &&
|
m_rotate = (getType()!=ITEM_BUBBLEGUM) &&
|
||||||
(getType()!=ITEM_TRIGGER );
|
(getType()!=ITEM_TRIGGER );
|
||||||
// Now determine in which quad this item is, and its distance
|
// Now determine in which quad this item is, and its distance
|
||||||
@ -334,17 +371,6 @@ void Item::reset()
|
|||||||
}
|
}
|
||||||
} // 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
|
/** Updated the item - rotates it, takes care of items coming back into
|
||||||
* the game after it has been collected.
|
* the game after it has been collected.
|
||||||
|
@ -122,35 +122,25 @@ private:
|
|||||||
* and then converting this value to a Vec3. */
|
* and then converting this value to a Vec3. */
|
||||||
Vec3 m_xyz;
|
Vec3 m_xyz;
|
||||||
|
|
||||||
protected:
|
|
||||||
/** The 'owner' of the item, i.e. the kart that dropped this item.
|
/** The 'owner' of the item, i.e. the kart that dropped this item.
|
||||||
* Is NULL if the item is part of the track. */
|
* Is NULL if the item is part of the track. */
|
||||||
const AbstractKart *m_previous_owner;
|
const AbstractKart *m_previous_owner;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
friend class ItemManager;
|
friend class ItemManager;
|
||||||
friend class NetworkItemManager;
|
friend class NetworkItemManager;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual void setType(ItemType type) { m_type = type; }
|
virtual void setType(ItemType type) { m_type = type; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Constructor.
|
ItemState(ItemType type, const AbstractKart *owner=NULL, int id = -1);
|
||||||
* \param type Type of the item.
|
void initItem(ItemType type, const Vec3& xyz);
|
||||||
* \param id Index of this item in the array of all items.
|
void update(int ticks);
|
||||||
* \param kart_id If !=-1 the kart that dropped this item; -1
|
void setDisappearCounter();
|
||||||
* indicates an item that's part of the track. */
|
virtual void collected(const AbstractKart *kart);
|
||||||
ItemState(ItemType type, int id=-1, AbstractKart *kart=NULL)
|
|
||||||
{
|
|
||||||
setType(type);
|
|
||||||
m_item_id = id;
|
|
||||||
m_previous_owner = kart;
|
|
||||||
} // ItemState(ItemType)
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual ~ItemState() {}
|
virtual ~ItemState() {}
|
||||||
void setDisappearCounter();
|
|
||||||
void update(int ticks);
|
|
||||||
virtual void collected(const AbstractKart *kart);
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
void reset()
|
void reset()
|
||||||
@ -166,19 +156,6 @@ public:
|
|||||||
}
|
}
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
/** Initialises an item.
|
|
||||||
* \param type Type for this item.
|
|
||||||
*/
|
|
||||||
void initItem(ItemType type, const Vec3& xyz)
|
|
||||||
{
|
|
||||||
m_xyz = xyz;
|
|
||||||
m_original_type = ITEM_NONE;
|
|
||||||
m_deactive_ticks = 0;
|
|
||||||
m_ticks_till_return = 0;
|
|
||||||
setDisappearCounter();
|
|
||||||
} // initItem
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Switches an item to be of a different type. Used for the switch
|
/** Switches an item to be of a different type. Used for the switch
|
||||||
* powerup.
|
* powerup.
|
||||||
@ -329,19 +306,18 @@ private:
|
|||||||
public:
|
public:
|
||||||
Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
||||||
scene::IMesh* mesh, scene::IMesh* lowres_mesh,
|
scene::IMesh* mesh, scene::IMesh* lowres_mesh,
|
||||||
|
const AbstractKart *owner,
|
||||||
bool is_predicted=false);
|
bool is_predicted=false);
|
||||||
Item(const Vec3& xyz, float distance,
|
Item(const Vec3& xyz, float distance,
|
||||||
TriggerItemListener* trigger);
|
TriggerItemListener* trigger);
|
||||||
virtual ~Item ();
|
virtual ~Item ();
|
||||||
void updateGraphics(float dt);
|
void updateGraphics(float dt);
|
||||||
virtual void collected(const AbstractKart *kart) OVERRIDE;
|
virtual void collected(const AbstractKart *kart) OVERRIDE;
|
||||||
void setParent(const AbstractKart* parent);
|
|
||||||
void reset();
|
void reset();
|
||||||
void switchTo(ItemType type, scene::IMesh *mesh, scene::IMesh *lowmesh);
|
void switchTo(ItemType type, scene::IMesh *mesh,
|
||||||
|
scene::IMesh *lowmesh);
|
||||||
void switchBack();
|
void switchBack();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns true if the Kart is close enough to hit this item, the item is
|
/** Returns true if the Kart is close enough to hit this item, the item is
|
||||||
* not deactivated anymore, and it wasn't placed by this kart (this is
|
* not deactivated anymore, and it wasn't placed by this kart (this is
|
||||||
@ -352,7 +328,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool hitKart(const Vec3 &xyz, const AbstractKart *kart=NULL) const
|
bool hitKart(const Vec3 &xyz, const AbstractKart *kart=NULL) const
|
||||||
{
|
{
|
||||||
if (m_previous_owner == kart && getDeactivatedTicks() > 0)
|
if (getPreviousOwner() == kart && getDeactivatedTicks() > 0)
|
||||||
return false;
|
return false;
|
||||||
Vec3 lc = quatRotate(m_original_rotation, xyz - getXYZ());
|
Vec3 lc = quatRotate(m_original_rotation, xyz - getXYZ());
|
||||||
// Don't be too strict if the kart is a bit above the item
|
// Don't be too strict if the kart is a bit above the item
|
||||||
@ -373,7 +349,8 @@ protected:
|
|||||||
bool hitLine(const core::line3df &line,
|
bool hitLine(const core::line3df &line,
|
||||||
const AbstractKart *kart=NULL) const
|
const AbstractKart *kart=NULL) const
|
||||||
{
|
{
|
||||||
if (m_previous_owner == kart && getDeactivatedTicks() >0) return false;
|
if (getPreviousOwner() == kart && getDeactivatedTicks() > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
Vec3 closest = line.getClosestPoint(getXYZ().toIrrVector());
|
Vec3 closest = line.getClosestPoint(getXYZ().toIrrVector());
|
||||||
return hitKart(closest, kart);
|
return hitKart(closest, kart);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
ItemEventInfo::ItemEventInfo(BareNetworkString *buffer, int *count)
|
ItemEventInfo::ItemEventInfo(BareNetworkString *buffer, int *count)
|
||||||
{
|
{
|
||||||
|
m_ticks_till_return = 0;
|
||||||
m_type = (EventType)buffer->getUInt8();
|
m_type = (EventType)buffer->getUInt8();
|
||||||
m_ticks = buffer->getTime();
|
m_ticks = buffer->getTime();
|
||||||
m_kart_id = buffer->getInt8();
|
m_kart_id = buffer->getInt8();
|
||||||
@ -41,7 +42,11 @@ ItemEventInfo::ItemEventInfo(BareNetworkString *buffer, int *count)
|
|||||||
m_xyz = buffer->getVec3();
|
m_xyz = buffer->getVec3();
|
||||||
*count -= 12;
|
*count -= 12;
|
||||||
}
|
}
|
||||||
|
else if (m_type == IEI_COLLECT)
|
||||||
|
{
|
||||||
|
m_ticks_till_return = buffer->getUInt16();
|
||||||
|
*count -= 2;
|
||||||
|
}
|
||||||
} // ItemEventInfo(BareNetworkString, int *count)
|
} // ItemEventInfo(BareNetworkString, int *count)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -55,7 +60,6 @@ void ItemEventInfo::saveState(BareNetworkString *buffer)
|
|||||||
.addUInt16(m_index);
|
.addUInt16(m_index);
|
||||||
if(m_type == IEI_NEW)
|
if(m_type == IEI_NEW)
|
||||||
buffer->add(m_xyz);
|
buffer->add(m_xyz);
|
||||||
|
else if (m_type == IEI_COLLECT)
|
||||||
|
buffer->addUInt16(m_ticks_till_return);
|
||||||
} // saveState
|
} // saveState
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -51,13 +51,20 @@ private:
|
|||||||
/** In case of new items the position of the new item. */
|
/** In case of new items the position of the new item. */
|
||||||
Vec3 m_xyz;
|
Vec3 m_xyz;
|
||||||
|
|
||||||
|
/** Ticks for the item to return, atm used by collecting banana
|
||||||
|
* with bomb to delay the return for banana. */
|
||||||
|
int16_t m_ticks_till_return;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Constructor for collecting an existing item.
|
/** Constructor for collecting an existing item.
|
||||||
* \param ticks Time of the event.
|
* \param ticks Time of the event.
|
||||||
* \param item_id The index of the item that was collected.
|
* \param item_id The index of the item that was collected.
|
||||||
* \param kart_id the kart that collected the item. */
|
* \param kart_id the kart that collected the item.
|
||||||
ItemEventInfo(int ticks, int index, int kart_id)
|
* \param ttr Ticks till return after being collected. */
|
||||||
: m_ticks(ticks), m_index(index), m_kart_id(kart_id)
|
|
||||||
|
ItemEventInfo(int ticks, int index, int kart_id, int16_t ttr)
|
||||||
|
: m_ticks(ticks), m_index(index), m_kart_id(kart_id),
|
||||||
|
m_ticks_till_return(ttr)
|
||||||
{
|
{
|
||||||
m_type = IEI_COLLECT;
|
m_type = IEI_COLLECT;
|
||||||
} // ItemEventInfo(collected existing item)
|
} // ItemEventInfo(collected existing item)
|
||||||
@ -69,14 +76,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
ItemEventInfo(int ticks, ItemState::ItemType type, int index,
|
ItemEventInfo(int ticks, ItemState::ItemType type, int index,
|
||||||
int kart_id, const Vec3 &xyz)
|
int kart_id, const Vec3 &xyz)
|
||||||
: m_ticks(ticks), m_index(index), m_kart_id(kart_id), m_xyz(xyz)
|
: m_ticks(ticks), m_index(index), m_kart_id(kart_id), m_xyz(xyz),
|
||||||
|
m_ticks_till_return(0)
|
||||||
{
|
{
|
||||||
m_type = IEI_NEW;
|
m_type = IEI_NEW;
|
||||||
} // ItemEventInfo(new item)
|
} // ItemEventInfo(new item)
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
/** Constructor for switching items. */
|
/** Constructor for switching items. */
|
||||||
ItemEventInfo(int ticks) : m_ticks(ticks)
|
ItemEventInfo(int ticks) : m_ticks(ticks), m_ticks_till_return(0)
|
||||||
{
|
{
|
||||||
m_type = IEI_SWITCH;
|
m_type = IEI_SWITCH;
|
||||||
} // ItemEventInfo(switch)
|
} // ItemEventInfo(switch)
|
||||||
@ -116,6 +124,9 @@ public:
|
|||||||
return m_xyz;
|
return m_xyz;
|
||||||
} // getXYZ
|
} // getXYZ
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
/** Returns the ticks till return, used only by collection events. */
|
||||||
|
int getTicksTillReturn() const { return m_ticks_till_return; }
|
||||||
|
// --------------------------------------------------------------------
|
||||||
/** Returns the type of this item. Note at this stage only bubble gums
|
/** Returns the type of this item. Note at this stage only bubble gums
|
||||||
* can be created during a race. */
|
* can be created during a race. */
|
||||||
ItemState::ItemType getNewItemType() const
|
ItemState::ItemType getNewItemType() const
|
||||||
|
@ -226,13 +226,15 @@ unsigned int ItemManager::insertItem(Item *item)
|
|||||||
// previously deleted entry, otherwise at the end.
|
// previously deleted entry, otherwise at the end.
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for(index=(int)m_all_items.size()-1; index>=0 && m_all_items[index]; index--) {}
|
for(index=(int)m_all_items.size()-1; index>=0 && m_all_items[index]; index--) {}
|
||||||
|
if (index == -1)
|
||||||
if(index==-1) index = (int)m_all_items.size();
|
{
|
||||||
|
index = (int)m_all_items.size();
|
||||||
if(index<(int)m_all_items.size())
|
|
||||||
m_all_items[index] = item;
|
|
||||||
else
|
|
||||||
m_all_items.push_back(item);
|
m_all_items.push_back(item);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_all_items[index] = item;
|
||||||
|
}
|
||||||
item->setItemId(index);
|
item->setItemId(index);
|
||||||
|
|
||||||
// Now insert into the appropriate quad list, if there is a quad list
|
// Now insert into the appropriate quad list, if there is a quad list
|
||||||
@ -286,9 +288,7 @@ Item* ItemManager::dropNewItem(ItemState::ItemType type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item* item = new Item(type, pos, normal, m_item_mesh[mesh_type],
|
Item* item = new Item(type, pos, normal, m_item_mesh[mesh_type],
|
||||||
m_item_lowres_mesh[mesh_type]);
|
m_item_lowres_mesh[mesh_type], /*prev_owner*/kart);
|
||||||
|
|
||||||
if(kart != NULL) item->setParent(kart);
|
|
||||||
insertItem(item);
|
insertItem(item);
|
||||||
if(m_switch_ticks>=0)
|
if(m_switch_ticks>=0)
|
||||||
{
|
{
|
||||||
@ -318,7 +318,7 @@ Item* ItemManager::placeItem(ItemState::ItemType type, const Vec3& xyz,
|
|||||||
ItemState::ItemType mesh_type = type;
|
ItemState::ItemType mesh_type = type;
|
||||||
|
|
||||||
Item* item = new Item(type, xyz, normal, m_item_mesh[mesh_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);
|
insertItem(item);
|
||||||
if (m_switch_ticks >= 0)
|
if (m_switch_ticks >= 0)
|
||||||
@ -354,7 +354,7 @@ Item* ItemManager::placeTrigger(const Vec3& xyz, float distance,
|
|||||||
* \param item The item that was collected.
|
* \param item The item that was collected.
|
||||||
* \param kart The kart that collected the item.
|
* \param kart The kart that collected the item.
|
||||||
*/
|
*/
|
||||||
void ItemManager::collectedItem(Item *item, AbstractKart *kart)
|
void ItemManager::collectedItem(ItemState *item, AbstractKart *kart)
|
||||||
{
|
{
|
||||||
assert(item);
|
assert(item);
|
||||||
// Spare tire karts don't collect items
|
// Spare tire karts don't collect items
|
||||||
|
@ -133,7 +133,7 @@ public:
|
|||||||
void updateGraphics (float dt);
|
void updateGraphics (float dt);
|
||||||
void checkItemHit (AbstractKart* kart);
|
void checkItemHit (AbstractKart* kart);
|
||||||
void reset ();
|
void reset ();
|
||||||
virtual void collectedItem (Item *item, AbstractKart *kart);
|
virtual void collectedItem (ItemState *item, AbstractKart *kart);
|
||||||
void switchItems ();
|
void switchItems ();
|
||||||
bool areItemSwitched() { return (m_switch_ticks > 0); }
|
bool areItemSwitched() { return (m_switch_ticks > 0); }
|
||||||
bool randomItemsForArena(const AlignedArray<btTransform>& pos);
|
bool randomItemsForArena(const AlignedArray<btTransform>& pos);
|
||||||
|
@ -95,17 +95,18 @@ void NetworkItemManager::initClientConfirmState()
|
|||||||
* \param item The item that was collected.
|
* \param item The item that was collected.
|
||||||
* \param kart The kart that collected the item.
|
* \param kart The kart that collected the item.
|
||||||
*/
|
*/
|
||||||
void NetworkItemManager::collectedItem(Item *item, AbstractKart *kart)
|
void NetworkItemManager::collectedItem(ItemState *item, AbstractKart *kart)
|
||||||
{
|
{
|
||||||
if(NetworkConfig::get()->isServer())
|
if(NetworkConfig::get()->isServer())
|
||||||
{
|
{
|
||||||
|
ItemManager::collectedItem(item, kart);
|
||||||
// The server saves the collected item as item event info
|
// The server saves the collected item as item event info
|
||||||
m_item_events.lock();
|
m_item_events.lock();
|
||||||
m_item_events.getData().emplace_back(World::getWorld()->getTicksSinceStart(),
|
m_item_events.getData().emplace_back(World::getWorld()->getTicksSinceStart(),
|
||||||
item->getItemId(),
|
item->getItemId(),
|
||||||
kart->getWorldKartId());
|
kart->getWorldKartId(),
|
||||||
|
item->getTicksTillReturn());
|
||||||
m_item_events.unlock();
|
m_item_events.unlock();
|
||||||
ItemManager::collectedItem(item, kart);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -142,7 +143,7 @@ Item* NetworkItemManager::dropNewItem(ItemState::ItemType type,
|
|||||||
kart->getXYZ() );
|
kart->getXYZ() );
|
||||||
m_item_events.unlock();
|
m_item_events.unlock();
|
||||||
return item;
|
return item;
|
||||||
} // newItem
|
} // dropNewItem
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Called by the GameProtocol when a confirmation for an item event is
|
/** Called by the GameProtocol when a confirmation for an item event is
|
||||||
@ -237,9 +238,9 @@ void NetworkItemManager::forwardTime(int ticks)
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Restores the state of the items to the current world time. It takes the
|
/** Restores the state of the items to the current world time. It takes the
|
||||||
* last saved
|
* last saved confirmed state, applies any updates from the server, and
|
||||||
|
* then syncs up the confirmed state to the in-race items.
|
||||||
* using exactly 'count' bytes of the message.
|
* It uses exactly 'count' bytes of the message.
|
||||||
* \param buffer the state content.
|
* \param buffer the state content.
|
||||||
* \param count Number of bytes used for this state.
|
* \param count Number of bytes used for this state.
|
||||||
*/
|
*/
|
||||||
@ -267,6 +268,7 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
// From here the replay can happen.
|
// From here the replay can happen.
|
||||||
|
|
||||||
// 1) Remove predicted items:
|
// 1) Remove predicted items:
|
||||||
|
// --------------------------
|
||||||
for (unsigned int i=0; i<m_all_items.size(); i++)
|
for (unsigned int i=0; i<m_all_items.size(); i++)
|
||||||
{
|
{
|
||||||
Item *item = m_all_items[i];
|
Item *item = m_all_items[i];
|
||||||
@ -274,20 +276,22 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
{
|
{
|
||||||
deleteItem(item);
|
deleteItem(item);
|
||||||
}
|
}
|
||||||
}
|
} // for i in m_all_items
|
||||||
|
|
||||||
// 2) Apply all events to current confirmed state:
|
// 2) Apply all events to current confirmed state:
|
||||||
|
// -----------------------------------------------
|
||||||
|
World *world = World::getWorld();
|
||||||
int current_time = m_confirmed_state_time;
|
int current_time = m_confirmed_state_time;
|
||||||
bool has_state = count > 0;
|
bool has_state = count > 0;
|
||||||
while(count > 0)
|
while(count > 0)
|
||||||
{
|
{
|
||||||
// 1) Decode the event in the message
|
// 2.1) Decode the event in the message
|
||||||
// ----------------------------------
|
// ------------------------------------
|
||||||
ItemEventInfo iei(buffer, &count);
|
ItemEventInfo iei(buffer, &count);
|
||||||
|
|
||||||
// 2) If the event needs to be applied, forward
|
// 2.2) If the event needs to be applied, forward
|
||||||
// the time to the time of this event:
|
// the time to the time of this event:
|
||||||
// --------------------------------------------
|
// ----------------------------------------------
|
||||||
int dt = iei.getTicks() - current_time;
|
int dt = iei.getTicks() - current_time;
|
||||||
// Skip an event that are 'in the past' (i.e. have been sent again by
|
// 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
|
// the server because it has not yet received confirmation from all
|
||||||
@ -297,13 +301,35 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
// Forward the saved state:
|
// Forward the saved state:
|
||||||
if (dt>0) forwardTime(dt);
|
if (dt>0) forwardTime(dt);
|
||||||
|
|
||||||
// TODO: apply the various events types, atm only collection is supported:
|
// TODO: apply the various events types, atm only collection
|
||||||
|
// and new items are supported.
|
||||||
if(iei.isItemCollection())
|
if(iei.isItemCollection())
|
||||||
{
|
{
|
||||||
int index = iei.getIndex();
|
int index = iei.getIndex();
|
||||||
// An item on the track was collected:
|
// An item on the track was collected:
|
||||||
AbstractKart *kart = World::getWorld()->getKart(iei.getKartId());
|
AbstractKart *kart = world->getKart(iei.getKartId());
|
||||||
m_confirmed_state[index]->collected(kart);
|
|
||||||
|
// The world clock was set by the RewindManager to be the time
|
||||||
|
// of the state we are rewinding to. But this confirmed collection
|
||||||
|
// event happened in the past (we are replaying item events since
|
||||||
|
// the last confirmed state in order to get a new confirmed state).
|
||||||
|
// So we need to reset the clock to the time at which this event
|
||||||
|
// happened so that (e.g.) kart can use the right time (for
|
||||||
|
// example, bubble gum torque depends on time, and would be wrong
|
||||||
|
// otherwise resulting in stuttering).
|
||||||
|
int old_time = world->getTicksSinceStart(); // Save time we rewind to
|
||||||
|
world->setTicksForRewind(iei.getTicks()); // Set time of event
|
||||||
|
|
||||||
|
if (m_confirmed_state[index] != NULL)
|
||||||
|
{
|
||||||
|
m_confirmed_state[index]->collected(kart);// Collect item
|
||||||
|
// Reset till ticks return from state (required for eating banana with bomb)
|
||||||
|
int ttr = iei.getTicksTillReturn();
|
||||||
|
m_confirmed_state[index]->setTicksTillReturn(ttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
world->setTicksForRewind(old_time); // Set time to rewind-to
|
||||||
|
|
||||||
if (m_confirmed_state[index]->isUsedUp())
|
if (m_confirmed_state[index]->isUsedUp())
|
||||||
{
|
{
|
||||||
delete m_confirmed_state[index];
|
delete m_confirmed_state[index];
|
||||||
@ -312,9 +338,9 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
}
|
}
|
||||||
else if(iei.isNewItem())
|
else if(iei.isNewItem())
|
||||||
{
|
{
|
||||||
AbstractKart *kart = World::getWorld()->getKart(iei.getKartId());
|
AbstractKart *kart = world->getKart(iei.getKartId());
|
||||||
ItemState *is = new ItemState(iei.getNewItemType(), iei.getIndex(),
|
ItemState *is = new ItemState(iei.getNewItemType(), kart,
|
||||||
kart);
|
iei.getIndex() );
|
||||||
is->initItem(iei.getNewItemType(), iei.getXYZ());
|
is->initItem(iei.getNewItemType(), iei.getXYZ());
|
||||||
if (m_confirmed_state.size() <= is->getItemId())
|
if (m_confirmed_state.size() <= is->getItemId())
|
||||||
{
|
{
|
||||||
@ -325,29 +351,34 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
if (m_confirmed_state[is->getItemId()] == NULL)
|
if (m_confirmed_state[is->getItemId()] == NULL)
|
||||||
m_confirmed_state[is->getItemId()] = is;
|
m_confirmed_state[is->getItemId()] = is;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
*m_confirmed_state[is->getItemId()] = *is;
|
*m_confirmed_state[is->getItemId()] = *is;
|
||||||
|
delete is;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current_time = iei.getTicks();
|
current_time = iei.getTicks();
|
||||||
} // while count >0
|
} // 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 (has_state)
|
||||||
{
|
{
|
||||||
if (auto gp = GameProtocol::lock())
|
if (auto gp = GameProtocol::lock())
|
||||||
gp->sendItemEventConfirmation(World::getWorld()->getTicksSinceStart());
|
gp->sendItemEventConfirmation(world->getTicksSinceStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward the confirmed item state to the world time:
|
// Forward the confirmed item state to the world time:
|
||||||
int dt = World::getWorld()->getTicksSinceStart() - current_time;
|
int dt = world->getTicksSinceStart() - current_time;
|
||||||
if(dt>0) forwardTime(dt);
|
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++)
|
for(unsigned int i=0; i<m_confirmed_state.size(); i++)
|
||||||
{
|
{
|
||||||
Item *item = m_all_items[i];
|
Item *item = i < m_all_items.size() ? m_all_items[i] : NULL;
|
||||||
const ItemState *is = m_confirmed_state[i];
|
const ItemState *is = m_confirmed_state[i];
|
||||||
if (is && item)
|
if (is && item)
|
||||||
*(ItemState*)item = *is;
|
*(ItemState*)item = *is;
|
||||||
@ -356,18 +387,33 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
Vec3 xyz = is->getXYZ();
|
Vec3 xyz = is->getXYZ();
|
||||||
Item *item_new = dropNewItem(is->getType(), is->getPreviousOwner(),
|
Item *item_new = dropNewItem(is->getType(), is->getPreviousOwner(),
|
||||||
&xyz);
|
&xyz);
|
||||||
item_new->setPredicted(false);
|
if (i != item_new->getItemId())
|
||||||
item_new->setItemId(i);
|
{
|
||||||
|
// The server has this item at a different index in the list
|
||||||
|
// of all items, which means the client has an incorrect
|
||||||
|
// item at the index given by the server - delete that item
|
||||||
|
Log::info("nim", "about to delete item with not matching index i %d item %d",
|
||||||
|
i, item_new->getItemId());
|
||||||
|
if(m_all_items[i])
|
||||||
|
deleteItem(m_all_items[i]);
|
||||||
|
m_all_items[item_new->getItemId()] = NULL;
|
||||||
m_all_items[i] = item_new;
|
m_all_items[i] = item_new;
|
||||||
|
item_new->setItemId(i);
|
||||||
|
}
|
||||||
|
item_new->setPredicted(false);
|
||||||
|
item_new->setDeactivatedTicks(is->getDeactivatedTicks());
|
||||||
*((ItemState*)m_all_items[i]) = *is;
|
*((ItemState*)m_all_items[i]) = *is;
|
||||||
}
|
}
|
||||||
else if (!is && item)
|
else if (!is && item)
|
||||||
{
|
{
|
||||||
|
Log::info("nim", "About to delete item index %d i %d",
|
||||||
|
item->getItemId(), i);
|
||||||
|
|
||||||
deleteItem(m_all_items[i]);
|
deleteItem(m_all_items[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we save the current local
|
// Now we save the current local
|
||||||
m_confirmed_state_time = World::getWorld()->getTicksSinceStart();
|
m_confirmed_state_time = world->getTicksSinceStart();
|
||||||
} // restoreState
|
} // restoreState
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ public:
|
|||||||
virtual void reset() OVERRIDE;
|
virtual void reset() OVERRIDE;
|
||||||
virtual void setItemConfirmationTime(std::weak_ptr<STKPeer> peer,
|
virtual void setItemConfirmationTime(std::weak_ptr<STKPeer> peer,
|
||||||
int ticks) OVERRIDE;
|
int ticks) OVERRIDE;
|
||||||
virtual void collectedItem(Item *item, AbstractKart *kart) OVERRIDE;
|
virtual void collectedItem(ItemState *item, AbstractKart *kart) OVERRIDE;
|
||||||
virtual Item* dropNewItem(ItemState::ItemType type, const AbstractKart *kart,
|
virtual Item* dropNewItem(ItemState::ItemType type, const AbstractKart *kart,
|
||||||
const Vec3 *xyz=NULL) OVERRIDE;
|
const Vec3 *xyz=NULL) OVERRIDE;
|
||||||
virtual BareNetworkString* saveState(std::vector<std::string>* ru)
|
virtual BareNetworkString* saveState(std::vector<std::string>* ru)
|
||||||
|
@ -561,11 +561,6 @@ void Powerup::hitBonusBox(const ItemState &item_state)
|
|||||||
|
|
||||||
new_powerup = powerup_manager->getRandomPowerup(position, &n,
|
new_powerup = powerup_manager->getRandomPowerup(position, &n,
|
||||||
random_number);
|
random_number);
|
||||||
// FIXME Disable switch and bubblegum for now in network
|
|
||||||
if (NetworkConfig::get()->isNetworking() &&
|
|
||||||
(new_powerup == PowerupManager::POWERUP_BUBBLEGUM ||
|
|
||||||
new_powerup == PowerupManager::POWERUP_SWITCH))
|
|
||||||
new_powerup = PowerupManager::POWERUP_BOWLING;
|
|
||||||
|
|
||||||
// Always add a new powerup in ITEM_MODE_NEW (or if the kart
|
// Always add a new powerup in ITEM_MODE_NEW (or if the kart
|
||||||
// doesn't have a powerup atm).
|
// doesn't have a powerup atm).
|
||||||
|
@ -1554,7 +1554,7 @@ void Kart::update(int ticks)
|
|||||||
"v(16-18) %f %f %f steerf(20) %f maxangle(22) %f speed(24) %f "
|
"v(16-18) %f %f %f steerf(20) %f maxangle(22) %f speed(24) %f "
|
||||||
"steering(26-27) %f %f clock(29) %lf skidstate(31) %d factor(33) %f "
|
"steering(26-27) %f %f clock(29) %lf skidstate(31) %d factor(33) %f "
|
||||||
"maxspeed(35) %f engf(37) %f braketick(39) %d brakes(41) %d heading(43) %f "
|
"maxspeed(35) %f engf(37) %f braketick(39) %d brakes(41) %d heading(43) %f "
|
||||||
"noderot(45) %f suslen %f",
|
"bubticks(45) %d bubtor(47) %f",
|
||||||
getIdent().c_str(),
|
getIdent().c_str(),
|
||||||
World::getWorld()->getTime(), World::getWorld()->getTicksSinceStart(),
|
World::getWorld()->getTime(), World::getWorld()->getTicksSinceStart(),
|
||||||
getXYZ().getX(), getXYZ().getY(), getXYZ().getZ(),
|
getXYZ().getX(), getXYZ().getY(), getXYZ().getZ(),
|
||||||
@ -1575,8 +1575,8 @@ void Kart::update(int ticks)
|
|||||||
m_brake_ticks, //39
|
m_brake_ticks, //39
|
||||||
m_controls.getButtonsCompressed(), //41
|
m_controls.getButtonsCompressed(), //41
|
||||||
getHeading(), //43
|
getHeading(), //43
|
||||||
m_node->getAbsoluteTransformation().getRotationDegrees().Y, //45
|
m_bubblegum_ticks, // 45
|
||||||
m_vehicle->getWheelInfo(0).m_raycastInfo.m_suspensionLength
|
m_bubblegum_torque // 47
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
// After the physics step was done, the position of the wheels (as stored
|
// After the physics step was done, the position of the wheels (as stored
|
||||||
|
@ -159,7 +159,8 @@ const std::string& EasterEggHunt::getIdent() const
|
|||||||
/** Called when a kart has collected an egg.
|
/** Called when a kart has collected an egg.
|
||||||
* \param kart The kart that collected an egg.
|
* \param kart The kart that collected an egg.
|
||||||
*/
|
*/
|
||||||
void EasterEggHunt::collectedItem(const AbstractKart *kart, const Item *item)
|
void EasterEggHunt::collectedItem(const AbstractKart *kart,
|
||||||
|
const ItemState *item )
|
||||||
{
|
{
|
||||||
if(item->getType() != ItemState::ITEM_EASTER_EGG) return;
|
if(item->getType() != ItemState::ITEM_EASTER_EGG) return;
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public:
|
|||||||
virtual void getKartsDisplayInfo(
|
virtual void getKartsDisplayInfo(
|
||||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
|
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
|
||||||
virtual void collectedItem(const AbstractKart *kart,
|
virtual void collectedItem(const AbstractKart *kart,
|
||||||
const Item *item ) OVERRIDE;
|
const ItemState *item ) OVERRIDE;
|
||||||
void collectedEasterEggGhost(int world_id);
|
void collectedEasterEggGhost(int world_id);
|
||||||
|
|
||||||
const int numberOfEggsFound() { return m_eggs_found; }
|
const int numberOfEggsFound() { return m_eggs_found; }
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
class AbstractKart;
|
class AbstractKart;
|
||||||
class btRigidBody;
|
class btRigidBody;
|
||||||
class Controller;
|
class Controller;
|
||||||
class Item;
|
class ItemState;
|
||||||
class PhysicalObject;
|
class PhysicalObject;
|
||||||
|
|
||||||
namespace Scripting
|
namespace Scripting
|
||||||
@ -263,7 +263,8 @@ public:
|
|||||||
int *amount );
|
int *amount );
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Receives notification if an item is collected. Used for easter eggs. */
|
/** Receives notification if an item is collected. Used for easter eggs. */
|
||||||
virtual void collectedItem(const AbstractKart *kart, const Item *item) {}
|
virtual void collectedItem(const AbstractKart *kart,
|
||||||
|
const ItemState *item ) {}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual void endRaceEarly() { return; }
|
virtual void endRaceEarly() { return; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -154,8 +154,27 @@ void RewindManager::saveState()
|
|||||||
|
|
||||||
m_overall_state_size = 0;
|
m_overall_state_size = 0;
|
||||||
std::vector<std::string> rewinder_using;
|
std::vector<std::string> rewinder_using;
|
||||||
|
|
||||||
|
// We must save the item state first (so that it is restored first),
|
||||||
|
// otherwise state updates for a kart could be overwritten by
|
||||||
|
// e.g. simulating the item collection later (which resets bubblegum
|
||||||
|
// counter).
|
||||||
|
BareNetworkString* buffer = NULL;
|
||||||
|
if(auto r = m_all_rewinder["N"].lock())
|
||||||
|
buffer = r->saveState(&rewinder_using);
|
||||||
|
if (buffer)
|
||||||
|
{
|
||||||
|
m_overall_state_size += buffer->size();
|
||||||
|
gp->addState(buffer);
|
||||||
|
}
|
||||||
|
delete buffer; // buffer can be freed
|
||||||
|
|
||||||
for (auto& p : m_all_rewinder)
|
for (auto& p : m_all_rewinder)
|
||||||
{
|
{
|
||||||
|
// The Network ItemManager was saved first before this loop,
|
||||||
|
// so skip it here.
|
||||||
|
if(p.first=="N") continue;
|
||||||
|
|
||||||
// TODO: check if it's worth passing in a sufficiently large buffer from
|
// TODO: check if it's worth passing in a sufficiently large buffer from
|
||||||
// GameProtocol - this would save the copy operation.
|
// GameProtocol - this would save the copy operation.
|
||||||
BareNetworkString* buffer = NULL;
|
BareNetworkString* buffer = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user