Split Item into two classes: ItemState which contains the non-graphical

and changing properties (e.g. collected,item type etc), and Item (using
ItemState as base class) which contains graphical and constant values.
This commit is contained in:
hiker 2018-05-04 01:01:15 +10:00
parent 0d1e799b4b
commit 9392354663
8 changed files with 330 additions and 246 deletions

View File

@ -361,9 +361,9 @@ void Attachment::hitBanana(Item *item, int new_attachment)
// default time. This is necessary to avoid that a kart lands on the
// same banana again once the explosion animation is finished, giving
// the kart the same penalty twice.
int ticks = std::max(item->getDisableTicks(),
int ticks = std::max(item->getTicksTillReturn(),
stk_config->time2Ticks(kp->getExplosionDuration() + 2.0f));
item->setDisableTicks(ticks);
item->setTicksTillReturn(ticks);
break;
}
case ATTACH_ANVIL:

View File

@ -39,8 +39,77 @@
#include <IMeshSceneNode.h>
#include <ISceneManager.h>
// ------------------------------------------------------------------------
/** Sets the disappear counter depending on type. */
void ItemState::setDisappearCounter()
{
switch (m_type)
{
case ITEM_BUBBLEGUM:
m_disappear_counter = stk_config->m_bubblegum_counter; break;
case ITEM_EASTER_EGG:
m_disappear_counter = -1; break;
default:
m_disappear_counter = -1;
} // switch
} // setDisappearCounter
// ----------------------------------------------------------------------------
/** Update the state of the item, called once per physics frame.
* \param ticks Number of ticks to simulate (typically 1).
*/
void ItemState::update(int ticks)
{
if (m_deactive_ticks > 0) m_deactive_ticks -= ticks;
if (m_collected)
{
m_ticks_till_return -= ticks;
if (m_ticks_till_return<=0) m_collected = false;
} // if collected
} // update
// ----------------------------------------------------------------------------
void ItemState::collected(float t, const AbstractKart *kart)
{
m_collected = true;
if (m_type == ITEM_EASTER_EGG)
{
m_ticks_till_return = stk_config->time2Ticks(99999);
EasterEggHunt *world = dynamic_cast<EasterEggHunt*>(World::getWorld());
assert(world);
world->collectedEasterEgg(kart);
}
else if (m_type == ITEM_BUBBLEGUM && m_disappear_counter > 0)
{
m_disappear_counter--;
// Deactivates the item for a certain amount of time. It is used to
// prevent bubble gum from hitting a kart over and over again (in each
// frame) by giving it time to drive away.
m_deactive_ticks = stk_config->time2Ticks(0.5f);
// Set the time till reappear to -1 seconds --> the item will
// reappear immediately.
m_ticks_till_return = -1;
}
else
{
// Note if the time is negative, in update the m_collected flag will
// be automatically set to false again.
m_ticks_till_return = stk_config->time2Ticks(t);
}
if (dynamic_cast<ThreeStrikesBattle*>(World::getWorld()) != NULL)
{
m_ticks_till_return *= 3;
}
} // collected
// ============================================================================
Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
scene::IMesh* mesh, scene::IMesh* lowres_mesh)
: ItemState(type)
{
assert(type != ITEM_TRIGGER); // use other constructor for that
@ -76,7 +145,7 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
#ifdef DEBUG
std::string debug_name("item: ");
debug_name += m_type;
debug_name += getType();
m_node->setName(debug_name.c_str());
#endif
m_node->setAutomaticCulling(scene::EAC_FRUSTUM_BOX);
@ -94,6 +163,7 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
* approaching a point.
*/
Item::Item(const Vec3& xyz, float distance, TriggerItemListener* trigger)
: ItemState(ITEM_TRIGGER)
{
m_distance_2 = distance*distance;
initItem(ITEM_TRIGGER, xyz);
@ -112,25 +182,12 @@ Item::Item(const Vec3& xyz, float distance, TriggerItemListener* trigger)
*/
void Item::initItem(ItemType type, const Vec3 &xyz)
{
m_type = type;
ItemState::initItem(type);
m_xyz = xyz;
m_event_handler = NULL;
m_item_id = -1;
m_collected = false;
m_original_type = ITEM_NONE;
m_deactive_ticks = 0;
m_ticks_till_return = 0; // not strictly necessary, see isCollected()
m_emitter = NULL;
m_rotate = (type!=ITEM_BUBBLEGUM) && (type!=ITEM_TRIGGER);
switch(m_type)
{
case ITEM_BUBBLEGUM:
m_disappear_counter = stk_config->m_bubblegum_counter; break;
case ITEM_EASTER_EGG:
m_disappear_counter = -1; break;
default:
m_disappear_counter = -1;
}
m_rotate = (getType()!=ITEM_BUBBLEGUM) &&
(getType()!=ITEM_TRIGGER );
// Now determine in which quad this item is, and its distance
// from the center within this quad.
m_graph_node = Graph::UNKNOWN_SECTOR;
@ -167,7 +224,7 @@ void Item::initItem(ItemType type, const Vec3 &xyz)
*/
void Item::setType(ItemType type)
{
m_type = type;
ItemState::setType(type);
m_rotate = (type!=ITEM_BUBBLEGUM) && (type!=ITEM_TRIGGER);
for (auto* node : m_node->getAllNodes())
{
@ -186,12 +243,8 @@ void Item::setType(ItemType type)
*/
void Item::switchTo(ItemType type, scene::IMesh *mesh, scene::IMesh *lowmesh)
{
// triggers and easter eggs should not be switched
if (m_type == ITEM_TRIGGER || m_type == ITEM_EASTER_EGG) return;
m_original_type = m_type;
setMesh(mesh, lowmesh);
setType(type);
ItemState::switchTo(type);
} // switchTo
//-----------------------------------------------------------------------------
@ -199,18 +252,9 @@ void Item::switchTo(ItemType type, scene::IMesh *mesh, scene::IMesh *lowmesh)
*/
void Item::switchBack()
{
// triggers should not be switched
if (m_type == ITEM_TRIGGER) return;
// If the item is not switched, do nothing. This can happen if a bubble
// gum is dropped while items are switched - when switching back, this
// bubble gum has no original type.
if(m_original_type==ITEM_NONE)
return;
if (ItemState::switchBack()) return;
setMesh(m_original_mesh, m_original_lowmesh);
setType(m_original_type);
m_original_type = ITEM_NONE;
Vec3 hpr;
hpr.setHPR(m_original_rotation);
@ -264,24 +308,7 @@ Item::~Item()
*/
void Item::reset()
{
m_collected = false;
m_ticks_till_return = 0;
m_deactive_ticks = 0;
switch(m_type)
{
case ITEM_BUBBLEGUM:
m_disappear_counter = stk_config->m_bubblegum_counter; break;
case ITEM_EASTER_EGG:
m_disappear_counter = -1; break;
default:
m_disappear_counter = -1;
}
if(m_original_type!=ITEM_NONE)
{
setType(m_original_type);
m_original_type = ITEM_NONE;
}
ItemState::reset();
if (m_node != NULL)
{
m_node->setScale(core::vector3df(1,1,1));
@ -298,7 +325,7 @@ void Item::setParent(AbstractKart* parent)
{
m_event_handler = parent;
m_emitter = parent;
m_deactive_ticks = stk_config->time2Ticks(1.5f);
ItemState::setDeactivatedTicks(stk_config->time2Ticks(1.5f));
} // setParent
//-----------------------------------------------------------------------------
@ -308,32 +335,24 @@ void Item::setParent(AbstractKart* parent)
*/
void Item::update(int ticks)
{
if(m_deactive_ticks > 0) m_deactive_ticks -= ticks;
bool was_collected = !isAvailable();
ItemState::update(ticks);
if(m_collected)
if (was_collected && isAvailable() && m_node)
{
m_ticks_till_return -= ticks;
if(m_ticks_till_return<0)
{
m_collected=false;
if (m_node != NULL)
{
m_node->setScale(core::vector3df(1,1,1));
}
} // time till return <0 --> is fully visible again
else if ( m_ticks_till_return <= stk_config->time2Ticks(1.0f) )
{
if (m_node != NULL)
{
// Make it visible by scaling it from 0 to 1:
m_node->setVisible(true);
float t = stk_config->ticks2Time(m_ticks_till_return);
m_node->setScale(core::vector3df(1,1,1)*(1-t));
}
} // time till return < 1
} // if collected
else
// This item is now available again - make sure it is not
// scaled anymore.
m_node->setScale(core::vector3df(1, 1, 1));
}
if (!isAvailable() && m_node &&
getTicksTillReturn() <= stk_config->time2Ticks(1.0f) )
{
// Make it visible by scaling it from 0 to 1:
m_node->setVisible(true);
float t = stk_config->ticks2Time(getTicksTillReturn());
m_node->setScale(core::vector3df(1, 1, 1)*(1 - t));
}
if(isAvailable())
{ // not m_collected
if(!m_rotate || m_node == NULL) return;
@ -364,49 +383,17 @@ void Item::update(int ticks)
*/
void Item::collected(const AbstractKart *kart, float t)
{
m_collected = true;
ItemState::collected(t, kart);
m_event_handler = kart;
if(m_type==ITEM_EASTER_EGG)
if (m_node && (getType() != ITEM_BUBBLEGUM || isUsedUp() ) )
{
m_ticks_till_return=stk_config->time2Ticks(99999);
EasterEggHunt *world = dynamic_cast<EasterEggHunt*>(World::getWorld());
assert(world);
world->collectedEasterEgg(kart);
if (m_node != NULL)
{
m_node->setVisible(false);
}
m_node->setVisible(false);
}
else if(m_type==ITEM_BUBBLEGUM && m_disappear_counter>0)
{
m_disappear_counter --;
// Deactivates the item for a certain amount of time. It is used to
// prevent bubble gum from hitting a kart over and over again (in each
// frame) by giving it time to drive away.
m_deactive_ticks = stk_config->time2Ticks(0.5f);
// Set the time till reappear to -1 seconds --> the item will
// reappear immediately.
m_ticks_till_return = -1;
}
else
{
// Note if the time is negative, in update the m_collected flag will
// be automatically set to false again.
m_ticks_till_return = stk_config->time2Ticks(t);
if (m_node != NULL)
{
m_node->setVisible(false);
}
}
if (m_listener != NULL)
{
m_listener->onTriggerItemApproached();
}
if (dynamic_cast<ThreeStrikesBattle*>(World::getWorld()) != NULL)
{
m_ticks_till_return *= 3;
}
} // isCollected

View File

@ -42,7 +42,7 @@ namespace irr
}
using namespace irr;
// -----------------------------------------------------------------------------
// ============================================================================
/**
* \ingroup items
@ -55,17 +55,21 @@ public:
virtual void onTriggerItemApproached() = 0;
};
/**
* \ingroup items
*/
class Item : public NoCopy
// ============================================================================
/** \ingroup items
* Contains the state information of an item, i.e. all non-visual information
* only, which also can change (e.g. position and AI information is constant
* and therefore not stored here). This class is used as a base class for
* item and for networking to save item states.
*/
class ItemState : public NoCopy
{
public:
/**
* The list of all items. Important for the switch item function:
* bubblegum must be the last item (since bubble gum can't be
* switched with any other item, since it's a different objecct).
*/
* The list of all items. Important for the switch item function:
* bubblegum must be the last item (since bubble gum can't be
* switched with any other item, since it's a different objecct).
*/
enum ItemType
{
ITEM_FIRST,
@ -79,8 +83,8 @@ public:
/** For easter egg mode only. */
ITEM_EASTER_EGG,
/** An invisible item that can be used to trigger some behavior when
* approaching a point
*/
* approaching a point
*/
ITEM_TRIGGER,
ITEM_LAST = ITEM_TRIGGER,
ITEM_COUNT,
@ -88,14 +92,165 @@ public:
};
private:
LEAK_CHECK();
/** Item type. */
ItemType m_type;
ItemType m_type;
/** If the item is switched, this contains the original type.
* It is ITEM_NONE if the item is not switched. */
ItemType m_original_type;
* It is ITEM_NONE if the item is not switched. */
ItemType m_original_type;
/** True if item was collected & is not displayed. */
bool m_collected;
/** Time till a collected item reappears. */
int m_ticks_till_return;
/** Index in item_manager field. */
unsigned int m_item_id;
/** Optionally if item was placed by a kart, a timer can be used to
* temporarly deactivate collision so a kart is not hit by its own item */
int m_deactive_ticks;
/** Counts how often an item is used before it disappears. Used for
* bubble gum to make them disappear after a while. A value >0
* indicates that the item still exists, =0 that the item can be
* deleted, and <0 that the item will never be deleted. */
int m_disappear_counter;
public:
/** Constructor. */
ItemState(ItemType type)
{
m_item_id = -1;
setType(type);
}
void setDisappearCounter();
void update(int ticks);
void collected(float t, const AbstractKart *kart);
// -----------------------------------------------------------------------
void reset()
{
m_deactive_ticks = 0;
m_ticks_till_return = 0;
m_collected = false;
setDisappearCounter();
// If the item was switched:
if (m_original_type != ITEM_NONE)
{
setType(m_original_type);
m_original_type = ITEM_NONE;
}
} // reset
// -----------------------------------------------------------------------
/** Initialises an item.
/* \param type Type for this item.
*/
void initItem(ItemType type)
{
setType(type);
m_original_type = ITEM_NONE;
m_deactive_ticks = 0;
m_ticks_till_return = 0;
m_item_id = -1;
m_collected = false;
setDisappearCounter();
} // initItem
// ------------------------------------------------------------------------
/** Switches an item to be of a different type. Used for the switch
* powerup.
* \param type New type for this item.
*/
void switchTo(ItemType type)
{
// triggers and easter eggs should not be switched
if (m_type == ITEM_TRIGGER || m_type == ITEM_EASTER_EGG) return;
m_original_type = m_type;
setType(type);
} // switchTo
// ------------------------------------------------------------------------
/** Returns true if this item was not actually switched (e.g. trigger etc)
*/
bool switchBack()
{
// triggers should not be switched
if (m_type == ITEM_TRIGGER) return true;
// If the item is not switched, do nothing. This can happen if a bubble
// gum is dropped while items are switched - when switching back, this
// bubble gum has no original type.
if (m_original_type == ITEM_NONE)
return true;
setType(m_original_type);
m_original_type = ITEM_NONE;
return false;
} // switchBack
// ------------------------------------------------------------------------
/** Returns if this item is negative, i.e. a banana or bubblegum. */
bool isNegativeItem() const
{
return m_type == ITEM_BANANA || m_type == ITEM_BUBBLEGUM ||
m_type == ITEM_BUBBLEGUM_NOLOK;
}
// ------------------------------------------------------------------------
/** Sets how long an item should be disabled. While item itself sets
* a default, this time is too short in case that a kart that has a bomb
* hits a banana: by the time the explosion animation is ended and the
* kart is back at its original position, the banana would be back again
* and therefore hit the kart again. See Attachment::hitBanana for more
* details.
* \param f Time till the item can be used again.
*/
void setTicksTillReturn(int t) { m_ticks_till_return = t; }
// ------------------------------------------------------------------------
/** Returns the time the item is disabled for. */
int getTicksTillReturn() const { return m_ticks_till_return; }
// ------------------------------------------------------------------------
/** Returns true if this item is currently collected. */
bool isAvailable() const { return m_ticks_till_return <= 0; }
// ------------------------------------------------------------------------
/** Useless function ;) But it makes some conditionals easier to read. */
bool isUnavailable() const { return m_collected; }
// ------------------------------------------------------------------------
/** Returns the type of this item. */
ItemType getType() const { return m_type; }
// ------------------------------------------------------------------------
void setType(ItemType type) { m_type = type; }
// ------------------------------------------------------------------------
/** Sets the index of this item in the item manager list. */
void setItemId(unsigned int n) { m_item_id = n; }
// ------------------------------------------------------------------------
/** Returns the index of this item in the item manager list. */
unsigned int getItemId() const { return m_item_id; }
// ------------------------------------------------------------------------
/** Returns true if this item is used up and can be removed. */
bool isUsedUp() const { return m_disappear_counter == 0; }
// ------------------------------------------------------------------------
/** Returns true if this item can be used up, and therefore needs to
* be removed when the game is reset. */
bool canBeUsedUp() const { return m_disappear_counter>-1; }
// ------------------------------------------------------------------------
/** Returns the number of ticks during which the item is deactivated (i.e.
* it was collected). */
int getDeactivatedTicks() const { return m_deactive_ticks; }
// ------------------------------------------------------------------------
/** Sets the number of ticks during which the item is deactivated (i.e.
* it was collected). */
void setDeactivatedTicks(int ticks) { m_deactive_ticks = ticks; }
}; // class ItemState
// ============================================================================
/**
* \ingroup items
*/
class Item : public ItemState
{
private:
LEAK_CHECK();
/** Stores the original rotation of an item. This is used in
* case of a switch to restore the rotation of a bubble gum
@ -107,12 +262,6 @@ private:
/** Used when rotating the item */
float m_rotation_angle;
/** True if item was collected & is not displayed. */
bool m_collected;
/** Time till a collected item reappears. */
int m_ticks_till_return;
/** Scene node of this item. */
LODNode *m_node;
@ -124,9 +273,6 @@ private:
* and then converting this value to a Vec3. */
Vec3 m_xyz;
/** Index in item_manager field. */
unsigned int m_item_id;
/** Set to false if item should not rotate. */
bool m_rotate;
@ -137,16 +283,6 @@ private:
/** Kart that emitted this item if any */
const AbstractKart *m_emitter;
/** Optionally if item was placed by a kart, a timer can be used to
* temporarly deactivate collision so a kart is not hit by its own item */
int m_deactive_ticks;
/** Counts how often an item is used before it disappears. Used for
* bubble gum to make them disappear after a while. A value >0
* indicates that the item still exists, =0 that the item can be
* deleted, and <0 that the item will never be deleted. */
int m_disappear_counter;
/** callback used if type == ITEM_TRIGGER */
TriggerItemListener* m_listener;
@ -163,11 +299,10 @@ private:
/** The closest point to the left and right of this item at which it
* would not be collected. Used by the AI to avoid items. */
Vec3 *m_avoidance_points[2];
Vec3 *m_avoidance_points[2];
void initItem(ItemType type, const Vec3 &xyz);
void setType(ItemType type);
void initItem(ItemType type, const Vec3 &xyz);
void setMesh(scene::IMesh* mesh, scene::IMesh* lowres_mesh);
public:
@ -195,7 +330,7 @@ public:
*/
bool hitKart(const Vec3 &xyz, const AbstractKart *kart=NULL) const
{
if (m_event_handler == kart && m_deactive_ticks > 0)
if (m_event_handler == kart && getDeactivatedTicks() > 0)
return false;
Vec3 lc = quatRotate(m_original_rotation, xyz - m_xyz);
// Don't be too strict if the kart is a bit above the item
@ -216,51 +351,19 @@ protected:
bool hitLine(const core::line3df &line,
const AbstractKart *kart=NULL) const
{
if(m_event_handler==kart && m_deactive_ticks >0) return false;
if(m_event_handler==kart && getDeactivatedTicks() >0) return false;
Vec3 closest = line.getClosestPoint(m_xyz.toIrrVector());
return hitKart(closest, kart);
} // hitLine
public:
// ------------------------------------------------------------------------
/** Sets the index of this item in the item manager list. */
void setItemId(unsigned int n) { m_item_id = n; }
// ------------------------------------------------------------------------
/** Returns the index of this item in the item manager list. */
unsigned int getItemId() const { return m_item_id; }
// ------------------------------------------------------------------------
/** Returns the type of this item. */
ItemType getType() const { return m_type; }
// ------------------------------------------------------------------------
/** Returns true if this item is currently collected. */
bool wasCollected() const { return m_collected;}
// ------------------------------------------------------------------------
/** Returns true if this item is used up and can be removed. */
bool isUsedUp() const {return m_disappear_counter==0; }
// ------------------------------------------------------------------------
/** Returns true if this item can be used up, and therefore needs to
* be removed when the game is reset. */
bool canBeUsedUp() const {return m_disappear_counter>-1; }
// ------------------------------------------------------------------------
/** Sets how long an item should be disabled. While item itself sets
* a default, this time is too short in case that a kart that has a bomb
* hits a banana: by the time the explosion animation is ended and the
* kart is back at its original position, the banana would be back again
* and therefore hit the kart again. See Attachment::hitBanana for more
* details.
* \param f Time till the item can be used again.
*/
void setDisableTicks(int t) { m_ticks_till_return = t; }
// ------------------------------------------------------------------------
/** Returns the time the item is disabled for. */
int getDisableTicks() const { return m_ticks_till_return; }
// ------------------------------------------------------------------------
/** Returns the XYZ position of the item. */
const Vec3& getXYZ() const { return m_xyz; }
const Vec3& getXYZ() const { return m_xyz; }
// ------------------------------------------------------------------------
/** Returns the index of the graph node this item is on. */
int getGraphNode() const { return m_graph_node; }
int getGraphNode() const { return m_graph_node; }
// ------------------------------------------------------------------------
/** Returns the distance from center: negative means left of center,
* positive means right of center. */

View File

@ -18,10 +18,6 @@
#include "items/item_manager.hpp"
#include <stdexcept>
#include <string>
#include <sstream>
#include "config/stk_config.hpp"
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
@ -41,6 +37,12 @@
#include <IMesh.h>
#include <IAnimatedMesh.h>
#include <assert.h>
#include <stdexcept>
#include <sstream>
#include <string>
std::vector<scene::IMesh *> ItemManager::m_item_mesh;
std::vector<scene::IMesh *> ItemManager::m_item_lowres_mesh;
std::vector<video::SColorf> ItemManager::m_glow_color;
@ -69,28 +71,28 @@ void ItemManager::destroy()
*/
void ItemManager::loadDefaultItemMeshes()
{
m_item_mesh.resize(Item::ITEM_LAST-Item::ITEM_FIRST+1, NULL);
m_glow_color.resize(Item::ITEM_LAST-Item::ITEM_FIRST+1,
m_item_mesh.resize(ItemState::ITEM_LAST-ItemState::ITEM_FIRST+1, NULL);
m_glow_color.resize(ItemState::ITEM_LAST-ItemState::ITEM_FIRST+1,
video::SColorf(255.0f, 255.0f, 255.0f) );
m_item_lowres_mesh.resize(Item::ITEM_LAST-Item::ITEM_FIRST+1, NULL);
m_item_lowres_mesh.resize(ItemState::ITEM_LAST-ItemState::ITEM_FIRST+1, NULL);
// A temporary mapping of items to names used in the XML file:
std::map<Item::ItemType, std::string> item_names;
item_names[Item::ITEM_BANANA ] = "banana";
item_names[Item::ITEM_BONUS_BOX ] = "bonus-box";
item_names[Item::ITEM_BUBBLEGUM ] = "bubblegum";
item_names[Item::ITEM_NITRO_BIG ] = "nitro-big";
item_names[Item::ITEM_NITRO_SMALL] = "nitro-small";
item_names[Item::ITEM_TRIGGER ] = "trigger";
item_names[Item::ITEM_BUBBLEGUM_NOLOK] = "bubblegum-nolok";
item_names[Item::ITEM_EASTER_EGG ] = "easter-egg";
std::map<ItemState::ItemType, std::string> item_names;
item_names[ItemState::ITEM_BANANA ] = "banana";
item_names[ItemState::ITEM_BONUS_BOX ] = "bonus-box";
item_names[ItemState::ITEM_BUBBLEGUM ] = "bubblegum";
item_names[ItemState::ITEM_NITRO_BIG ] = "nitro-big";
item_names[ItemState::ITEM_NITRO_SMALL] = "nitro-small";
item_names[ItemState::ITEM_TRIGGER ] = "trigger";
item_names[ItemState::ITEM_BUBBLEGUM_NOLOK] = "bubblegum-nolok";
item_names[ItemState::ITEM_EASTER_EGG ] = "easter-egg";
const std::string file_name = file_manager->getAsset("items.xml");
const XMLNode *root = file_manager->createXMLTree(file_name);
for(unsigned int i=Item::ITEM_FIRST; i<=Item::ITEM_LAST; i++)
for(unsigned int i=ItemState::ITEM_FIRST; i<=ItemState::ITEM_LAST; i++)
{
const std::string &name = item_names[(Item::ItemType)i];
const std::string &name = item_names[(ItemState::ItemType)i];
const XMLNode *node = root->getNode(name);
if (!node) continue;
@ -133,7 +135,7 @@ void ItemManager::loadDefaultItemMeshes()
*/
void ItemManager::removeTextures()
{
for(unsigned int i=0; i<Item::ITEM_LAST-Item::ITEM_FIRST+1; i++)
for(unsigned int i=0; i<ItemState::ITEM_LAST-ItemState::ITEM_FIRST+1; i++)
{
if(m_item_mesh[i])
{
@ -162,9 +164,9 @@ ItemManager::ItemManager()
// Prepare the switch to array, which stores which item should be
// switched to what other item. Initialise it with a mapping that
// each item is switched to itself, so basically a no-op.
m_switch_to.reserve(Item::ITEM_COUNT);
for(unsigned int i=Item::ITEM_FIRST; i<Item::ITEM_COUNT; i++)
m_switch_to.push_back((Item::ItemType)i);
m_switch_to.reserve(ItemState::ITEM_COUNT);
for(unsigned int i=ItemState::ITEM_FIRST; i<ItemState::ITEM_COUNT; i++)
m_switch_to.push_back((ItemState::ItemType)i);
setSwitchItems(stk_config->m_switch_items);
if(Graph::get())
@ -187,8 +189,8 @@ ItemManager::ItemManager()
*/
void ItemManager::setSwitchItems(const std::vector<int> &switch_items)
{
for(unsigned int i=Item::ITEM_FIRST; i<Item::ITEM_COUNT; i++)
m_switch_to[i]=(Item::ItemType)stk_config->m_switch_items[i];
for(unsigned int i=ItemState::ITEM_FIRST; i<ItemState::ITEM_COUNT; i++)
m_switch_to[i]=(ItemState::ItemType)stk_config->m_switch_items[i];
} // setSwitchItems
@ -252,13 +254,13 @@ void ItemManager::insertItem(Item *item)
* \param parent In case of a dropped item used to avoid that a kart
* is affected by its own items.
*/
Item* ItemManager::newItem(Item::ItemType type, const Vec3& xyz,
Item* ItemManager::newItem(ItemState::ItemType type, const Vec3& xyz,
const Vec3 &normal, AbstractKart *parent)
{
Item::ItemType mesh_type = type;
if (type == Item::ITEM_BUBBLEGUM && parent->getIdent() == "nolok")
ItemState::ItemType mesh_type = type;
if (type == ItemState::ITEM_BUBBLEGUM && parent->getIdent() == "nolok")
{
mesh_type = Item::ITEM_BUBBLEGUM_NOLOK;
mesh_type = ItemState::ITEM_BUBBLEGUM_NOLOK;
}
Item* item = new Item(type, xyz, normal, m_item_mesh[mesh_type],
@ -268,7 +270,7 @@ Item* ItemManager::newItem(Item::ItemType type, const Vec3& xyz,
if(parent != NULL) item->setParent(parent);
if(m_switch_ticks>=0)
{
Item::ItemType new_type = m_switch_to[item->getType()];
ItemState::ItemType new_type = m_switch_to[item->getType()];
item->switchTo(new_type, m_item_mesh[(int)new_type],
m_item_lowres_mesh[(int)new_type]);
}
@ -298,8 +300,8 @@ void ItemManager::collectedItem(Item *item, AbstractKart *kart, int add_info)
assert(item);
// Spare tire karts don't collect items
if (dynamic_cast<SpareTireAI*>(kart->getController()) != NULL) return;
if( (item->getType() == Item::ITEM_BUBBLEGUM ||
item->getType() == Item::ITEM_BUBBLEGUM_NOLOK) && kart->isShielded())
if( (item->getType() == ItemState::ITEM_BUBBLEGUM ||
item->getType() == ItemState::ITEM_BUBBLEGUM_NOLOK) && kart->isShielded())
{
// shielded karts can simply drive over bubble gums without any effect.
return;
@ -327,7 +329,7 @@ void ItemManager::checkItemHit(AbstractKart* kart)
for(AllItemTypes::iterator i =m_all_items.begin();
i!=m_all_items.end(); i++)
{
if((!*i) || (*i)->wasCollected()) continue;
if((!*i) || !(*i)->isAvailable()) continue;
// To allow inlining and avoid including kart.hpp in item.hpp,
// we pass the kart and the position separately.
if((*i)->hitKart(kart->getXYZ(), kart))
@ -376,7 +378,7 @@ void ItemManager::reset()
i++;
continue;
}
if((*i)->canBeUsedUp() || (*i)->getType()==Item::ITEM_BUBBLEGUM)
if((*i)->canBeUsedUp() || (*i)->getType()==ItemState::ITEM_BUBBLEGUM)
{
deleteItem( *i );
i++;
@ -462,7 +464,8 @@ void ItemManager::switchItems()
{
if(!*i) continue;
if ((*i)->getType() == Item::ITEM_BUBBLEGUM || (*i)->getType() == Item::ITEM_BUBBLEGUM_NOLOK)
if ( (*i)->getType() == ItemState::ITEM_BUBBLEGUM ||
(*i)->getType() == ItemState::ITEM_BUBBLEGUM_NOLOK)
{
if (race_manager->getAISuperPower() == RaceManager::SUPERPOWER_NOLOK_BOSS)
{
@ -470,7 +473,7 @@ void ItemManager::switchItems()
}
}
Item::ItemType new_type = m_switch_to[(*i)->getType()];
ItemState::ItemType new_type = m_switch_to[(*i)->getType()];
if(m_switch_ticks<0)
(*i)->switchTo(new_type, m_item_mesh[(int)new_type], m_item_lowres_mesh[(int)new_type]);
@ -572,9 +575,9 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
for (unsigned int i = 0; i < TOTAL_ITEM; i++)
{
const int j = random.get(10);
Item::ItemType type = (j > BONUS_BOX ? Item::ITEM_BONUS_BOX :
j > NITRO_BIG ? Item::ITEM_NITRO_BIG :
j > NITRO_SMALL ? Item::ITEM_NITRO_SMALL : Item::ITEM_BANANA);
ItemState::ItemType type = (j > BONUS_BOX ? ItemState::ITEM_BONUS_BOX :
j > NITRO_BIG ? ItemState::ITEM_NITRO_BIG :
j > NITRO_SMALL ? ItemState::ITEM_NITRO_SMALL : ItemState::ITEM_BANANA);
ArenaNode* an = ag->getNode(used_location[i]);
Vec3 loc = an->getCenter();

View File

@ -60,11 +60,11 @@ public:
// ------------------------------------------------------------------------
/** Returns the mesh for a certain item. */
static scene::IMesh* getItemModel(Item::ItemType type)
static scene::IMesh* getItemModel(ItemState::ItemType type)
{ return m_item_mesh[type]; }
// ------------------------------------------------------------------------
/** Returns the glow color for an item. */
static video::SColorf& getGlowColor(Item::ItemType type)
static video::SColorf& getGlowColor(ItemState::ItemType type)
{ return m_glow_color[type]; }
// ------------------------------------------------------------------------
/** Return an instance of the item manager (it does not automatically
@ -86,7 +86,7 @@ private:
std::vector< AllItemTypes > *m_items_in_quads;
/** What item this item is switched to. */
std::vector<Item::ItemType> m_switch_to;
std::vector<ItemState::ItemType> m_switch_to;
/** Remaining time that items should remain switched. If the
* value is <0, it indicates that the items are not switched atm. */
@ -101,7 +101,7 @@ private:
void setSwitchItems(const std::vector<int> &switch_items);
public:
Item* newItem (Item::ItemType type, const Vec3& xyz,
Item* newItem (ItemState::ItemType type, const Vec3& xyz,
const Vec3 &normal,
AbstractKart* parent=NULL);
Item* newItem (const Vec3& xyz, float distance,

View File

@ -581,10 +581,7 @@ void ArenaAI::tryCollectItem(Vec3* aim_point, int* target_node) const
ItemManager::get()->getFirstItemInQuad(*target_node));
// Don't look for a new item unless it's collected or swapped
if (selected && !(selected->wasCollected() ||
selected->getType() == Item::ITEM_BANANA ||
selected->getType() == Item::ITEM_BUBBLEGUM ||
selected->getType() == Item::ITEM_BUBBLEGUM_NOLOK))
if (selected && selected->isAvailable() && !selected->isNegativeItem())
{
*aim_point = selected->getXYZ();
return;
@ -594,10 +591,7 @@ void ArenaAI::tryCollectItem(Vec3* aim_point, int* target_node) const
{
Item* cur_item = ItemManager::get()->getFirstItemInQuad(i);
if (cur_item == NULL) continue;
if (cur_item->wasCollected() ||
cur_item->getType() == Item::ITEM_BANANA ||
cur_item->getType() == Item::ITEM_BUBBLEGUM ||
cur_item->getType() == Item::ITEM_BUBBLEGUM_NOLOK)
if (!cur_item->isAvailable() || cur_item->isNegativeItem())
continue;
if ((cur_item->getType() == Item::ITEM_NITRO_BIG ||
@ -667,10 +661,7 @@ void ArenaAI::determinePath(int forward, std::vector<int>* path)
const int node = (*path)[i];
Item* selected = ItemManager::get()->getFirstItemInQuad(node);
if (selected && !selected->wasCollected() &&
(selected->getType() == Item::ITEM_BANANA ||
selected->getType() == Item::ITEM_BUBBLEGUM ||
selected->getType() == Item::ITEM_BUBBLEGUM_NOLOK))
if (selected && selected->isAvailable() && selected->isNegativeItem())
{
bad_item_nodes.push_back(node);
}

View File

@ -852,7 +852,7 @@ bool SkiddingAI::handleSelectedItem(Vec3 kart_aim_direction, Vec3 *aim_point)
// If the item is unavailable keep on testing. It is not necessary
// to test if an item has turned bad, this was tested before this
// function is called.
if(m_item_to_collect->getDisableTicks()>0)
if(!m_item_to_collect->isAvailable())
return false;
const Vec3 &xyz = m_item_to_collect->getXYZ();
@ -1042,7 +1042,7 @@ void SkiddingAI::evaluateItems(const Item *item, Vec3 kart_aim_direction,
const KartProperties *kp = m_kart->getKartProperties();
// Ignore items that are currently disabled
if(item->getDisableTicks()>0) return;
if(!item->isAvailable()) return;
// If the item type is not handled here, ignore it
Item::ItemType type = item->getType();

View File

@ -856,7 +856,7 @@ bool SkiddingAI::handleSelectedItem(Vec3 kart_aim_direction, Vec3 *aim_point)
// If the item is unavailable keep on testing. It is not necessary
// to test if an item has turned bad, this was tested before this
// function is called.
if(m_item_to_collect->getDisableTicks()>0)
if(!m_item_to_collect->isAvailable())
return false;
const Vec3 &xyz = m_item_to_collect->getXYZ();
@ -1046,7 +1046,7 @@ void SkiddingAI::evaluateItems(const Item *item, Vec3 kart_aim_direction,
const KartProperties *kp = m_kart->getKartProperties();
// Ignore items that are currently disabled
if(item->getDisableTicks()>0) return;
if(!item->isAvailable()) return;
// If the item type is not handled here, ignore it
Item::ItemType type = item->getType();