From 3812d6b08405876d45540d8bca1854ffb67adc93 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Sun, 14 Nov 2010 21:47:29 +0000 Subject: [PATCH] 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 --- src/tracks/check_structure.cpp | 148 ++++++++++++++++++--------------- src/tracks/check_structure.hpp | 27 +++--- 2 files changed, 96 insertions(+), 79 deletions(-) diff --git a/src/tracks/check_structure.cpp b/src/tracks/check_structure.cpp index fc62899fd..925a72cba 100644 --- a/src/tracks/check_structure.cpp +++ b/src/tracks/check_structure.cpp @@ -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 + #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 indices, + int kart_index, + ChangeState change_state) +{ + for(unsigned int i=0; igetCheckStructure(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 inewLap(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; igetCheckStructure(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; igetCheckStructure(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 igetCheckStructure(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 diff --git a/src/tracks/check_structure.hpp b/src/tracks/check_structure.hpp index 11535f3c1..5d1e1ad7e 100644 --- a/src/tracks/check_structure.hpp +++ b/src/tracks/check_structure.hpp @@ -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 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 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 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 m_same_group; + enum ChangeState {CS_DEACTIVATE, CS_ACTIVATE, CS_TOGGLE}; + + void changeStatus(const std::vector indices, int kart_index, + ChangeState change_state); + public: CheckStructure(CheckManager *check_manager, const XMLNode &node, unsigned int index);