Fixed bug in checck structures (activation lines were set to active as default,
which means that if there is more than one activation line, you only needed to cross the last one). This will break proper lap counting in all tracks! git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@6530 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
940fb65e8a
commit
3812d6b084
@ -17,10 +17,13 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "tracks/check_structure.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "modes/world.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "tracks/check_manager.hpp"
|
||||
#include "tracks/check_structure.hpp"
|
||||
|
||||
|
||||
CheckStructure::CheckStructure(CheckManager *check_manager,
|
||||
@ -51,8 +54,16 @@ CheckStructure::CheckStructure(CheckManager *check_manager,
|
||||
|
||||
m_same_group.clear();
|
||||
node.get("same-group", &m_same_group);
|
||||
// Make sure that the index of this check structure is included in
|
||||
// the same_group list. While this should be guaranteed by the
|
||||
// current track exporter, tracks exported with the old track
|
||||
// exporter will not have this.
|
||||
if(std::find(m_same_group.begin(), m_same_group.end(), m_index)
|
||||
== m_same_group.end())
|
||||
m_same_group.push_back(m_index);
|
||||
|
||||
m_active_at_reset=true;
|
||||
// As a default, only lap lines are activated
|
||||
m_active_at_reset= m_check_type==CT_NEW_LAP;
|
||||
node.get("active", &m_active_at_reset);
|
||||
} // CheckStructure
|
||||
|
||||
@ -98,6 +109,61 @@ void CheckStructure::update(float dt)
|
||||
} // for i<getNumKarts
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Changes the status (active/inactive) of all check structures contained
|
||||
* in the index list indices.
|
||||
* \param indices List of index of check structures in check_manager that
|
||||
* are to be changed.
|
||||
* \param int kart_index For which the status should be changed.
|
||||
* \param change_state How to change the state (active, deactivate, toggle).
|
||||
*/
|
||||
void CheckStructure::changeStatus(const std::vector<int> indices,
|
||||
int kart_index,
|
||||
ChangeState change_state)
|
||||
{
|
||||
for(unsigned int i=0; i<indices.size(); i++)
|
||||
{
|
||||
CheckStructure *cs =
|
||||
m_check_manager->getCheckStructure(indices[i]);
|
||||
switch(change_state)
|
||||
{
|
||||
case CS_DEACTIVATE:
|
||||
cs->m_is_active[kart_index] = false;
|
||||
if(UserConfigParams::m_check_debug)
|
||||
{
|
||||
printf("CHECK: Deactivating %d for %s.\n",
|
||||
indices[i],
|
||||
World::getWorld()->getKart(kart_index)->getIdent().c_str());
|
||||
}
|
||||
break;
|
||||
case CS_ACTIVATE:
|
||||
cs->m_is_active[kart_index] = true;
|
||||
if(UserConfigParams::m_check_debug)
|
||||
{
|
||||
printf("CHECK: Activating %d for %s.\n",
|
||||
indices[i],
|
||||
World::getWorld()->getKart(kart_index)->getIdent().c_str());
|
||||
}
|
||||
break;
|
||||
case CS_TOGGLE:
|
||||
if(UserConfigParams::m_check_debug)
|
||||
{
|
||||
// At least on gcc 4.3.2 we can't simply print
|
||||
// cs->m_is_active[kart_index] ("cannot pass objects of
|
||||
// non-POD type ‘struct std::_Bit_reference’ through ‘...’;
|
||||
// call will abort at runtime"). So we use this somewhat
|
||||
// unusual but portable construct.
|
||||
printf("CHECK: Toggling %d for %s from %d.\n",
|
||||
indices[i],
|
||||
World::getWorld()->getKart(kart_index)->getIdent().c_str(),
|
||||
cs->m_is_active[kart_index]==true);
|
||||
}
|
||||
cs->m_is_active[kart_index] = !cs->m_is_active[kart_index];
|
||||
} // switch
|
||||
|
||||
} // for i<indices.size()
|
||||
} //changeStatus
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Is called when this check structure is triggered. This then can cause
|
||||
* a lap to be counted, animation to be started etc.
|
||||
@ -108,75 +174,25 @@ void CheckStructure::trigger(unsigned int kart_index)
|
||||
{
|
||||
case CT_NEW_LAP :
|
||||
World::getWorld()->newLap(kart_index);
|
||||
m_is_active[kart_index] = false;
|
||||
if(UserConfigParams::m_check_debug)
|
||||
{
|
||||
printf("CHECK: %s new lap %d triggered, now deactivated.\n",
|
||||
World::getWorld()->getKart(kart_index)->getIdent().c_str(),
|
||||
m_index);
|
||||
}
|
||||
// Set all checkstructures of the same group to the same state.
|
||||
// This is to avoid e.g. only deactivating one of many new lap
|
||||
// counters, which could enable the user to cheat by crossing
|
||||
// all different lap counting lines.
|
||||
for(unsigned int i=0; i<m_same_group.size(); i++)
|
||||
{
|
||||
CheckStructure *cs =
|
||||
m_check_manager->getCheckStructure(m_same_group[i]);
|
||||
cs->m_is_active[kart_index] = false;
|
||||
if(UserConfigParams::m_check_debug)
|
||||
printf("CHECK: also deactivating index %d\n", m_same_group[i]);
|
||||
printf("CHECK: %s new lap %d triggered\n",
|
||||
World::getWorld()->getKart(kart_index)->getIdent().c_str(),
|
||||
m_index);
|
||||
}
|
||||
changeStatus(m_check_structures_to_change_state,
|
||||
kart_index, CS_ACTIVATE);
|
||||
break;
|
||||
case CT_ACTIVATE:
|
||||
{
|
||||
for(unsigned int i=0; i<m_check_structures_to_change_state.size();
|
||||
i++)
|
||||
{
|
||||
int check_index = m_check_structures_to_change_state[i];
|
||||
CheckStructure *cs=
|
||||
m_check_manager->getCheckStructure(check_index);
|
||||
// We don't have to activate all members of the group of
|
||||
// cs, since this check line's m_check_structure_to_change
|
||||
// will include the full groups.
|
||||
cs->m_is_active[kart_index] = true;
|
||||
if(UserConfigParams::m_check_debug)
|
||||
{
|
||||
printf("CHECK: %s %d triggered, activating %d.\n",
|
||||
World::getWorld()->getKart(kart_index)->getIdent().c_str(),
|
||||
m_index, check_index);
|
||||
}
|
||||
} // for i<m_check_structures_to_change_state.size()
|
||||
break;
|
||||
}
|
||||
changeStatus(m_check_structures_to_change_state,
|
||||
kart_index, CS_ACTIVATE);
|
||||
break;
|
||||
case CT_TOGGLE:
|
||||
{
|
||||
for(unsigned int i=0; i<m_check_structures_to_change_state.size();
|
||||
i++)
|
||||
{
|
||||
int check_index = m_check_structures_to_change_state[i];
|
||||
CheckStructure *cs=
|
||||
m_check_manager->getCheckStructure(check_index);
|
||||
// We don't have to toggle all members of the group of
|
||||
// cs, since this check line's m_check_structure_to_change
|
||||
// will include the full groups. This esp. avoids toggling
|
||||
// cs more than once!
|
||||
cs->m_is_active[kart_index] = !cs->m_is_active[kart_index];
|
||||
if(UserConfigParams::m_check_debug)
|
||||
{
|
||||
// At least on gcc 4.3.2 we can't simply print
|
||||
// cs->m_is_active[kart_index] ("cannot pass objects of
|
||||
// non-POD type ‘struct std::_Bit_reference’ through ‘...’;
|
||||
// call will abort at runtime"). So we use this somewhat
|
||||
// unusual but portable construct.
|
||||
printf("CHECK: %s %d triggered, setting %d to %d.\n",
|
||||
World::getWorld()->getKart(kart_index)->getIdent().c_str(),
|
||||
m_index, check_index,
|
||||
cs->m_is_active[kart_index]==true);
|
||||
}
|
||||
} // for i < m_check_structures_to_change_state
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
changeStatus(m_check_structures_to_change_state,
|
||||
kart_index, CS_TOGGLE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} // switch m_check_type
|
||||
changeStatus(m_same_group, kart_index, CS_DEACTIVATE);
|
||||
} // trigger
|
||||
|
@ -31,19 +31,17 @@ class CheckManager;
|
||||
/**
|
||||
* \brief Virtual base class for a check structure.
|
||||
*
|
||||
* A check structure has a certain ype:
|
||||
* A check structure has a certain ype:
|
||||
* CT_NEW_LAP : triggering this check structure will cause a new lap to be
|
||||
* counted. If this type is triggered, it will set itselt to
|
||||
* inactive (which means it is not possible to count several
|
||||
* laps by driving over the starting line forwardws and
|
||||
* backwards)
|
||||
* CT_RESET_NEW_LAP: Activates all lap checks. Each track must have at least
|
||||
* one reset checks somewhere on the track. This is used to
|
||||
* avoid shortcuts, since karts are forced to cross this reset
|
||||
* check first before a new lap can be counted.
|
||||
* Each check structure can be active or inactive. A new_la counter is
|
||||
* initialised as non-active, so that karts have to trigger a reset check
|
||||
* before a lap can be counted.
|
||||
* CT_ACTIVATE: Activates the specified other check structures.
|
||||
* CT_TOGGLE: Toggles the specified other check structures (active to
|
||||
* inactive and vice versa.
|
||||
* Each check structure can be active or inactive. Only lap counters are
|
||||
* initialised to be active, all other check structures are inactive.
|
||||
*
|
||||
* \ingroup tracks
|
||||
*/
|
||||
@ -68,8 +66,7 @@ protected:
|
||||
* when e.g. a check point is reached the first time, or a checkline is
|
||||
* crossed. */
|
||||
std::vector<Vec3> m_previous_position;
|
||||
/** Stores if this check structure is active (for a given kart). Used e.g.
|
||||
* in lap counting. */
|
||||
/** Stores if this check structure is active (for a given kart). */
|
||||
std::vector<bool> m_is_active;
|
||||
private:
|
||||
/** Stores a pointer to the check manager. */
|
||||
@ -85,9 +82,8 @@ private:
|
||||
/** True if this check structure should be activated at a reset. */
|
||||
bool m_active_at_reset;
|
||||
|
||||
/** If this is a CT_ACTIVATE or CT_SWITCH type, this will contain
|
||||
* the indices of the corresponding check structures that get their
|
||||
* state changed (activated or switched). */
|
||||
/** Contains the indices of the corresponding check structures that
|
||||
* get their state changed (activated or switched). */
|
||||
std::vector<int> m_check_structures_to_change_state;
|
||||
|
||||
/** A list of check lines that should be activated/switched when this
|
||||
@ -97,6 +93,11 @@ private:
|
||||
* as huge shortcuts. */
|
||||
std::vector<int> m_same_group;
|
||||
|
||||
enum ChangeState {CS_DEACTIVATE, CS_ACTIVATE, CS_TOGGLE};
|
||||
|
||||
void changeStatus(const std::vector<int> indices, int kart_index,
|
||||
ChangeState change_state);
|
||||
|
||||
public:
|
||||
CheckStructure(CheckManager *check_manager, const XMLNode &node,
|
||||
unsigned int index);
|
||||
|
Loading…
Reference in New Issue
Block a user