Handle copying ItemState to Item properly (esp in live join)
This commit is contained in:
parent
6ecd606e3f
commit
664129e448
@ -235,9 +235,18 @@ unsigned int ItemManager::insertItem(Item *item)
|
||||
m_all_items[index] = item;
|
||||
}
|
||||
item->setItemId(index);
|
||||
|
||||
insertItemInQuad(item);
|
||||
// Now insert into the appropriate quad list, if there is a quad list
|
||||
// (i.e. race mode has a quad graph).
|
||||
return index;
|
||||
} // insertItem
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Insert into the appropriate quad list, if there is a quad list
|
||||
* (i.e. race mode has a quad graph).
|
||||
*/
|
||||
void ItemManager::insertItemInQuad(Item *item)
|
||||
{
|
||||
if(m_items_in_quads)
|
||||
{
|
||||
int graph_node = item->getGraphNode();
|
||||
@ -249,8 +258,7 @@ unsigned int ItemManager::insertItem(Item *item)
|
||||
else // otherwise store it in the 'outside' index
|
||||
(*m_items_in_quads)[m_items_in_quads->size()-1].push_back(item);
|
||||
} // if m_items_in_quads
|
||||
return index;
|
||||
} // insertItem
|
||||
} // insertItemInQuad
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Creates a new item at the location of the kart (e.g. kart drops a
|
||||
@ -303,7 +311,10 @@ Item* ItemManager::dropNewItem(ItemState::ItemType type,
|
||||
|
||||
Item* item = new Item(type, pos, normal, m_item_mesh[mesh_type],
|
||||
m_item_lowres_mesh[mesh_type], /*prev_owner*/kart);
|
||||
insertItem(item);
|
||||
|
||||
// restoreState in NetworkItemManager will handle the insert item
|
||||
if (!server_xyz)
|
||||
insertItem(item);
|
||||
if(m_switch_ticks>=0)
|
||||
{
|
||||
ItemState::ItemType new_type = m_switch_to[item->getType()];
|
||||
@ -522,6 +533,18 @@ void ItemManager::updateGraphics(float dt)
|
||||
void ItemManager::deleteItem(ItemState *item)
|
||||
{
|
||||
// First check if the item needs to be removed from the items-in-quad list
|
||||
deleteItemInQuad(item);
|
||||
int index = item->getItemId();
|
||||
m_all_items[index] = NULL;
|
||||
delete item;
|
||||
} // delete item
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Removes an items from the items-in-quad list only
|
||||
* \param The item to delete.
|
||||
*/
|
||||
void ItemManager::deleteItemInQuad(ItemState* item)
|
||||
{
|
||||
if(m_items_in_quads)
|
||||
{
|
||||
int sector = item->getGraphNode();
|
||||
@ -533,11 +556,7 @@ void ItemManager::deleteItem(ItemState *item)
|
||||
assert(it!=items.end());
|
||||
items.erase(it);
|
||||
} // if m_items_in_quads
|
||||
|
||||
int index = item->getItemId();
|
||||
m_all_items[index] = NULL;
|
||||
delete item;
|
||||
} // delete item
|
||||
} // deleteItemInQuad
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Switches all items: boxes become bananas and vice versa for a certain
|
||||
|
@ -125,7 +125,8 @@ protected:
|
||||
virtual unsigned int insertItem(Item *item);
|
||||
void switchItemsInternal(std::vector < ItemState*> &all_items);
|
||||
void setSwitchItems(const std::vector<int> &switch_items);
|
||||
|
||||
void insertItemInQuad(Item *item);
|
||||
void deleteItemInQuad(ItemState *item);
|
||||
ItemManager();
|
||||
public:
|
||||
virtual ~ItemManager();
|
||||
|
@ -492,12 +492,15 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
||||
// the client, but not yet confirmed). So
|
||||
unsigned int max_index = std::max(m_confirmed_state.size(),
|
||||
m_all_items.size() );
|
||||
m_all_items.resize(max_index, NULL);
|
||||
|
||||
for(unsigned int i=0; i<max_index; i++)
|
||||
{
|
||||
ItemState *item = i < m_all_items.size() ? m_all_items[i] : NULL;
|
||||
ItemState *item = m_all_items[i];
|
||||
const ItemState *is = i < m_confirmed_state.size()
|
||||
? m_confirmed_state[i] : NULL;
|
||||
// For every *(ItemState*)item = *is, all deactivated ticks, item id
|
||||
// ... will be copied from item state to item
|
||||
if (is && item)
|
||||
{
|
||||
*(ItemState*)item = *is;
|
||||
@ -510,31 +513,19 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
||||
Vec3 normal = is->getNormal();
|
||||
Item *item_new = dropNewItem(is->getType(), is->getPreviousOwner(),
|
||||
&xyz, &normal );
|
||||
if (i != item_new->getItemId())
|
||||
{
|
||||
// The newly created item on the client has been given a
|
||||
// different index than the one given by the server. This
|
||||
// indicates that this client has either a different item
|
||||
// at the index that the server sent (i.e. client predicted
|
||||
// an item, which the server has not confirmed), or the
|
||||
// client found an empty slot that the server did not have
|
||||
// (so an earlier index was found).
|
||||
if(i < m_all_items.size() && m_all_items[i])
|
||||
deleteItem(m_all_items[i]);
|
||||
// Move item_new from its position to the index given
|
||||
// by the server
|
||||
m_all_items[item_new->getItemId()] = NULL;
|
||||
m_all_items[i] = item_new;
|
||||
item_new->setItemId(i);
|
||||
}
|
||||
item_new->setDeactivatedTicks(is->getDeactivatedTicks());
|
||||
*((ItemState*)m_all_items[i]) = *is;
|
||||
*((ItemState*)item_new) = *is;
|
||||
m_all_items[i] = item_new;
|
||||
insertItemInQuad(item_new);
|
||||
}
|
||||
else if (!is && item)
|
||||
{
|
||||
deleteItem(m_all_items[i]);
|
||||
deleteItemInQuad(item);
|
||||
delete item;
|
||||
m_all_items[i] = NULL;
|
||||
}
|
||||
} // for i < max_index
|
||||
// Clean up the rest
|
||||
m_all_items.resize(m_confirmed_state.size());
|
||||
|
||||
// Now set the clock back to the 'rewindto' time:
|
||||
world->setTicksForRewind(rewind_to_time);
|
||||
|
Loading…
x
Reference in New Issue
Block a user