From 4b4bddf35e2cc2c7fb927986a7d984ea55988165 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Tue, 28 Sep 2010 23:29:21 +0000 Subject: [PATCH] Support for grouping check structures. E.g. it is now possible to have more than one lap line, which will always be in synch (i.e. if one is triggered, all will be set to inactive). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@6161 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/check_manager.cpp | 7 +- src/tracks/check_structure.cpp | 126 +++++++++++++++++++++------------ src/tracks/check_structure.hpp | 17 +++-- 3 files changed, 99 insertions(+), 51 deletions(-) diff --git a/src/tracks/check_manager.cpp b/src/tracks/check_manager.cpp index a76ca5009..6b8760e8a 100644 --- a/src/tracks/check_manager.cpp +++ b/src/tracks/check_manager.cpp @@ -29,6 +29,7 @@ CheckManager::CheckManager(const XMLNode &node, Track *track) { + bool lap_line_found = false; for(unsigned int i=0; igetType()==CheckStructure::CT_NEW_LAP) + // Only record the first lap line to be used to compute + // start coordinates with. The track exporter always exports + // the one based on the quads first. + if(cl->getType()==CheckStructure::CT_NEW_LAP && !lap_line_found) { track->setStartCoordinates(cl->getLine2D()); + lap_line_found = true; } } // checkline else if(type=="check-sphere") diff --git a/src/tracks/check_structure.cpp b/src/tracks/check_structure.cpp index 3a4b9e4aa..cdab31b86 100644 --- a/src/tracks/check_structure.cpp +++ b/src/tracks/check_structure.cpp @@ -42,13 +42,16 @@ CheckStructure::CheckStructure(CheckManager *check_manager, { printf("Unknown check structure '%s' - ignored.\n", kind.c_str()); } - m_activate_check_index = -1; - node.get("other-id", &m_activate_check_index); - if( (m_check_type==CT_TOGGLE || m_check_type==CT_ACTIVATE) && - m_activate_check_index==-1) - { - printf("Unknown other-id in checkline.\n"); - } + m_check_structures_to_change_state.clear(); + node.get("other-ids", &m_check_structures_to_change_state); + // Backwards compatibility to tracks exported with older versions of + // the track exporter + if(m_check_structures_to_change_state.size()==0) + node.get("other-id", &m_check_structures_to_change_state); + + m_same_group.clear(); + node.get("same-group", &m_same_group); + m_active_at_reset=true; node.get("active", &m_active_at_reset); } // CheckStructure @@ -103,45 +106,76 @@ void CheckStructure::trigger(unsigned int kart_index) { switch(m_check_type) { - 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); - } - break; - case CT_ACTIVATE: { - CheckStructure *cs= - m_check_manager->getCheckStructure(m_activate_check_index); - 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, m_activate_check_index); - } - break; - } - case CT_TOGGLE: { - CheckStructure *cs= - m_check_manager->getCheckStructure(m_activate_check_index); - 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, m_activate_check_index, - cs->m_is_active[kart_index]==true); - } - break; - } + 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; igetCheckStructure(m_same_group[i]); + cs->m_is_active[kart_index] = false; + printf("CHECK: also deactivating index %d\n", m_same_group[i]); + } + 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; } // switch m_check_type } // trigger diff --git a/src/tracks/check_structure.hpp b/src/tracks/check_structure.hpp index cb69d3d58..31bceea38 100644 --- a/src/tracks/check_structure.hpp +++ b/src/tracks/check_structure.hpp @@ -1,7 +1,7 @@ // $Id: check_structure.hpp 1681 2008-04-09 13:52:48Z hikerstk $ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2009 Joerg Henrichs +// Copyright (C) 2009-2010 Joerg Henrichs // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -53,7 +53,7 @@ public: /** Different types of check structures: * ACTIVATE: Activates another check structure (independent of * the state that check structure is in) - * TOGGLE: Switches (or inverts) the state of another check structure. + * TOGGLE: Switches (inverts) the state of another check structure. * NEW_LAP: On crossing a new lap is counted. * AMBIENT_SPHERE: Modifies the ambient color. * A combination of an activate and new_lap line are used to @@ -86,8 +86,17 @@ private: bool m_active_at_reset; /** If this is a CT_ACTIVATE or CT_SWITCH type, this will contain - * the index of the corresponding check structure that is triggered. */ - int m_activate_check_index; + * 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 + * lines is activated/switched. I.e. can be used if more than one lap + * counting line is used to make sure they are all in synch, otherwise + * players could cross first one then the other lap counting line + * as huge shortcuts. */ + std::vector m_same_group; + public: CheckStructure(CheckManager *check_manager, const XMLNode &node, unsigned int index);