Commit fdd391d2 authored by sm's avatar sm

New version 0.12

* Add event priority
* Improve xml parsing API
* Modify CumulCmpEvent output
* ShowTextEvent can be positioned
* VariableEvent supports reset increase decrease messages
* RandomEvent new message GENERATE_ADD
* Improve LogEvent
* Bug fixes
parent 8f3eeeaa
stmm-games (0.12) unstable; urgency=low
* Add event priority
* Improve xml parsing API
* Modify CumulCmpEvent output
* ShowTextEvent can be positioned
* VariableEvent supports reset increase decrease messages
* RandomEvent new message GENERATE_ADD
* Improve LogEvent
* Bug fixes
* Increase minor version
-- Stefano Marsili <efanomars@gmx.ch> Mon, 02 Sep 2019 19:29:39 +0100
stmm-games (0.11) unstable; urgency=low
* Fix parsing bugs
......
......@@ -20,12 +20,12 @@
# MINOR is REVISION (implementation of interface)
# AGE is always 0
set(STMM_GAMES_FAKE_MAJOR_VERSION 0)
set(STMM_GAMES_FAKE_MINOR_VERSION 11)
set(STMM_GAMES_FAKE_MINOR_VERSION 12)
set(STMM_GAMES_FAKE_VERSION "${STMM_GAMES_FAKE_MAJOR_VERSION}.${STMM_GAMES_FAKE_MINOR_VERSION}.0")
# required stmm-games version
set(STMM_GAMES_FAKE_REQ_STMM_GAMES_MAJOR_VERSION 0)
set(STMM_GAMES_FAKE_REQ_STMM_GAMES_MINOR_VERSION 11)
set(STMM_GAMES_FAKE_REQ_STMM_GAMES_MINOR_VERSION 12)
set(STMM_GAMES_FAKE_REQ_STMM_GAMES_VERSION "${STMM_GAMES_FAKE_REQ_STMM_GAMES_MAJOR_VERSION}.${STMM_GAMES_FAKE_REQ_STMM_GAMES_MINOR_VERSION}")
include("${PROJECT_SOURCE_DIR}/../libstmm-games/stmm-games-defs.cmake")
......
......@@ -352,8 +352,13 @@ void GameWindow::gameEnded() noexcept
activateResizeTimer();
changeScreen(STATUS_WAIT_1SEC, s_nScreenPlay);
int32_t nTotWaitMillisec = s_nGameEndedWaitMillisec;
if (m_refHighscoresDefinition) {
assert(m_refGame);
nTotWaitMillisec += m_refGame->getAdditionalHighscoresWait();
}
Glib::signal_timeout().connect_once(
sigc::mem_fun(*this, &GameWindow::gameEndedOut), s_nGameEndedWaitMillisec);
sigc::mem_fun(*this, &GameWindow::gameEndedOut), nTotWaitMillisec);
}
void GameWindow::gameEndedOut() noexcept
{
......@@ -361,7 +366,6 @@ void GameWindow::gameEndedOut() noexcept
if (m_refHighscoresDefinition) {
if (m_refHighscoresLoader) {
assert(m_refGame);
shared_ptr<Highscore> refHighscore = m_refHighscoresLoader->getHighscore(m_refGame->getName(), *m_refPrefs, m_refHighscoresDefinition);
if (refHighscore) {
//std::cout << "GameWindow::gameEnded() before refHighscore->getTotScores()=" << refHighscore->getTotScores() << '\n';
......@@ -504,7 +508,8 @@ bool GameWindow::startGame() noexcept
if (!refGame) {
std::string sErrorStr = oGameInfo.m_sGameErrorString;
if (sErrorStr.empty()) {
sErrorStr = "Game '" + sGameName + "' not compatible with current Preferences";
sErrorStr = "Game '" + sGameName + "' not compatible with current Preferences."
+ "\nSee Game Description tab in Games dialog.";
}
msgWarningBox("Could not load Game!\n" + sErrorStr);
return false; //--------------------------------------------------------
......
......@@ -20,11 +20,11 @@
# MINOR is REVISION (implementation of interface)
# AGE is always 0
set(STMM_GAMES_GTK_MAJOR_VERSION 0)
set(STMM_GAMES_GTK_MINOR_VERSION 11)
set(STMM_GAMES_GTK_MINOR_VERSION 12)
set(STMM_GAMES_GTK_VERSION "${STMM_GAMES_GTK_MAJOR_VERSION}.${STMM_GAMES_GTK_MINOR_VERSION}.0")
set(STMM_GAMES_GTK_REQ_STMM_GAMES_MAJOR_VERSION 0)
set(STMM_GAMES_GTK_REQ_STMM_GAMES_MINOR_VERSION 11)
set(STMM_GAMES_GTK_REQ_STMM_GAMES_MINOR_VERSION 12)
set(STMM_GAMES_GTK_REQ_STMM_GAMES_VERSION "${STMM_GAMES_GTK_REQ_STMM_GAMES_MAJOR_VERSION}.${STMM_GAMES_GTK_REQ_STMM_GAMES_MINOR_VERSION}")
set(STMM_GAMES_GTK_REQ_STMM_INPUT_GTK_MAJOR_VERSION 0)
......
......@@ -26,6 +26,7 @@
#include <string>
#include <map>
#include <algorithm>
#include <iostream>
namespace stmg
{
......
......@@ -96,6 +96,10 @@ public:
* @return The maximum or -1 if not defined.
*/
int32_t getMaxViewTicks() const { return m_nMaxViewTicks; }
/** Get additional time in milliseconds for highscores to appear when game ended.
* @return The additional time in milliseconds.
*/
int32_t getAdditionalHighscoresWait() const { return m_nAdditionalHighscoresWait; }
protected:
std::string err(const std::string& sErr) override
{
......@@ -116,6 +120,7 @@ private:
double m_fMinGameInterval;
double m_fInitialGameInterval;
int32_t m_nMaxViewTicks;
int32_t m_nAdditionalHighscoresWait;
static AssignableNamed s_oDummy;
private:
GameInfoCtx() = delete;
......
......@@ -25,6 +25,7 @@
#include "xmltraitsparser.h"
#include <stmm-games/block.h>
#include <stmm-games/event.h>
#include <libxml++/libxml++.h>
......@@ -53,7 +54,7 @@ public:
const std::string& getEventName() const;
/** Parse and create an event instance.
* The implementation must call parseBaseAndAddEvent() to add the
* The implementation must call integrateAndAdd() to add the
* newly created event to the level which will own it.
* @param oCtx The game context.
* @param p0Element The element. Cannot be null.
......@@ -118,15 +119,25 @@ protected:
*/
Event* parseChildEvent(GameCtx& oCtx, const xmlpp::Element* p0Element);
/** Parse the Event base class attributes and sub elements and add to level.
* Performs the Event base class specific initialization on the created instance
/** Parse event base.
* This function should be called rather than filling the attributes by hand
* in the subclass parser.
* @param oCtx The context.
* @param p0Element The event element. Cannot be null.
* @param oInit The even initialization data to fill.
*/
void parseEventBase(GameCtx& oCtx, const xmlpp::Element* p0Element, Event::Init& oInit);
/** Integrate the event add to level.
* Performs the xml specific integration that links the event to others and to widgets
* and adds the instance to the level, which will own it.
* @param oCtx The context.
* @param refEvent The event. Cannot be null.
* @param p0Element The event element. Cannot be null.
* @return The added event. Is always refEvent.get().
*/
Event* parseBaseAndAddEvent(GameCtx& oCtx, unique_ptr<Event> refEvent, const xmlpp::Element* p0Element);
Event* integrateAndAdd(GameCtx& oCtx, unique_ptr<Event> refEvent, const xmlpp::Element* p0Element);
/** Helper function for the 'repeat' attribute.
* Expects the value to be \> 0 or -1 (infinite). Default is -1.
* @param oCtx The context.
......
......@@ -37,29 +37,102 @@ namespace stmg
class XmlTraitsParser
{
public:
/** Constructor.
* @param oXmlConditionalParser The conditional parser to use.
*/
XmlTraitsParser(XmlConditionalParser& oXmlConditionalParser)
: m_oXmlConditionalParser(oXmlConditionalParser)
{
}
XmlConditionalParser& getXmlConditionalParser() { return m_oXmlConditionalParser; }
//
/** Parse all the traits of tile within the same element.
* If a trait is not defined its value in input/output parameter oTile is
* left unchanged, otherwise it is overwritten.
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @param oTile The possibly modified tile.
*/
void parseTile(ConditionalCtx& oCtx, const xmlpp::Element* p0Element, Tile& oTile);
/** Parse the tile color.
* If the trait is not defined the input/output value oTileColor is left unchanged.
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @param oTileColor The possibly modified tile color.
*/
void parseColor(ConditionalCtx& oCtx, const xmlpp::Element* p0Element, TileColor& oTileColor);
/** Parse the tile alpha.
* If the trait is not defined the input/output value oTileAlpha is left unchanged.
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @param oTileAlpha The possibly modified tile alpha.
*/
void parseAlpha(ConditionalCtx& oCtx, const xmlpp::Element* p0Element, TileAlpha& oTileAlpha);
/** Parse the tile char.
* If the trait is not defined the input/output value oTileChar is left unchanged.
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @param oTileChar The possibly modified tile char.
*/
void parseChar(ConditionalCtx& oCtx, const xmlpp::Element* p0Element, TileChar& oTileChar);
/** Parse the tile font.
* If the trait is not defined the input/output value oTileFont is left unchanged.
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @param oTileFont The possibly modified tile font.
*/
void parseFont(ConditionalCtx& oCtx, const xmlpp::Element* p0Element, TileFont& oTileFont);
/** Parse a char trait set.
* If the trait is defined the trait set is overwritten otherwise it is left unchanged.
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @param oTraitSet The char trait set.
*/
void parseChars(ConditionalCtx& oCtx, const xmlpp::Element* p0Element, CharTraitSet& oTraitSet);
/** Parse a color trait set.
* If the trait is defined the trait set is overwritten otherwise it is left unchanged.
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @param bAllowRgbFromTo Whether from to of rgb values is allowed.
* @param oTraitSet The color trait set.
*/
void parseColors(ConditionalCtx& oCtx, const xmlpp::Element* p0Element, bool bAllowRgbFromTo, ColorTraitSet& oTraitSet);
/** Parse a font trait set.
* If the trait is defined the trait set is overwritten otherwise it is left unchanged.
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @param oTraitSet The font trait set.
*/
void parseFonts(ConditionalCtx& oCtx, const xmlpp::Element* p0Element, FontTraitSet& oTraitSet);
/** Parse a alpha trait set.
* If the trait is defined the trait set is overwritten otherwise it is left unchanged.
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @param oTraitSet The alpha trait set.
*/
void parseAlphas(ConditionalCtx& oCtx, const xmlpp::Element* p0Element, AlphaTraitSet& oTraitSet);
/** Parse a player trait set.
* If the trait is defined the trait set is overwritten otherwise it is left unchanged.
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @param oIntSet The player trait set.
*/
void parsePlayers(ConditionalCtx& oCtx, const xmlpp::Element* p0Element, IntSet& oIntSet);
// Ties the p0Element children conditions with an "or" operator (default)
/** Parses a tile selector with children elements tied by an "or" condition.
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @return The tile selector. Is not null.
*/
std::unique_ptr<TileSelector> parseTileSelectorOr(ConditionalCtx& oCtx, const xmlpp::Element* p0Element);
// Ties the p0Element children conditions with an "and" operator
/** Parses a tile selector with children elements tied by an "and" condition.
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @return The tile selector. Is not null.
*/
std::unique_ptr<TileSelector> parseTileSelectorAnd(ConditionalCtx& oCtx, const xmlpp::Element* p0Element);
// Calls parseTileSelectorOr
/** Calls parseTileSelectorOr.
*/
inline std::unique_ptr<TileSelector> parseTileSelector(ConditionalCtx& oCtx, const xmlpp::Element* p0Element)
{
return parseTileSelectorOr(oCtx, p0Element);
......
......@@ -40,24 +40,37 @@ public:
XmlBasicParser(XmlConditionalParser& oXmlConditionalParser);
/** Parse integer rectangle.
* If any of the attributes is not defined it is inferred from the oInRect (provided it is not zero size)
* in that the resulting rectangle is extended as much as possible.
* If oInRect has non zero size and all the attributes are not defined and bMandatory is false
* a zero sized rectangle is returned.
* Otherwise, if oInRect has non zero size and any of the attributes is not defined it is inferred
* from the oInRect in that the resulting rectangle is extended as much as possible within it.
* If oInRect has zero size and bMandatory is true then all attributes must be defined.
* If oInRect has zero size and bMandatory is false then all attributes must be not defined.
*
* Ex. oInRect={0,0,5,4}, sAttrNameX value is 2. Result is {2,0,3,4}
*
* Ex. oInRect={10,20,5,4}, sAttrNameH value is 2. Result is {10,20,2,4}
*
* Ex. oInRect={10,20,5,4}, bMandatory is false, no attribute defined. Result is {?,?,0,0}
*
* Ex. oInRect={10,20,5,4}, bMandatory is true, no attribute defined. Result is {10,20,5,4}
*
* Ex. oInRect={?,?,0,0}, bMandatory is false, no attribute defined. Result is {?,?,0,0}
*
* Ex. oInRect={?,?,0,0}, bMandatory is true, sAttrNameH value is 2. throws an error
* @param oCtx The context.
* @param p0Element The element. Cannot be null.
* @param sAttrNameX The x attribute name.
* @param sAttrNameY The y attribute name.
* @param sAttrNameW The w attribute name.
* @param sAttrNameH The h attribute name.
* @param bMandatory WhetherIt must be defined
* @param oInRect The rectangle the parsed rectangle must fit in. If its size is 0 no limits.
* @param oMinSize The minimum size of the parsed rectangle or size 0 if returned rectangle can have size 0.
* @return The result rectangle. Can have size 0 if oMinSize allows it.
* @param oMinSize The minimum size of the parsed rectangle. Must be positive.
* @return The result rectangle. Has size 0 if not defined.
*/
NRect parseNRect(ConditionalCtx& oCtx, const xmlpp::Element* p0Element, const std::string& sAttrNameX, const std::string& sAttrNameY
, const std::string& sAttrNameW, const std::string& sAttrNameH, const NRect& oInRect, const NSize& oMinSize);
, const std::string& sAttrNameW, const std::string& sAttrNameH, bool bMandatory, const NRect& oInRect, const NSize& oMinSize);
protected:
XmlConditionalParser& m_oXmlConditionalParser;
......
......@@ -43,13 +43,14 @@ XmlAlarmsEventParser::XmlAlarmsEventParser()
}
Event* XmlAlarmsEventParser::parseEvent(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
return parseBaseAndAddEvent(oCtx, parseEventAlarms(oCtx, p0Element), p0Element);
return integrateAndAdd(oCtx, parseEventAlarms(oCtx, p0Element), p0Element);
}
unique_ptr<Event> XmlAlarmsEventParser::parseEventAlarms(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
//std::cout << "XmlAlarmsEventParser::parseEventAlarms" << '\n';
AlarmsEvent::Init oAInit;
oCtx.addChecker(p0Element);
parseEventBase(oCtx, p0Element, oAInit);
getXmlConditionalParser().visitElementChildren(oCtx, p0Element, [&](const xmlpp::Element* p0Changer)
{
......@@ -87,7 +88,6 @@ unique_ptr<Event> XmlAlarmsEventParser::parseEventAlarms(GameCtx& oCtx, const xm
}
});
oCtx.removeChecker(p0Element, false, true);
oAInit.m_p0Level = &oCtx.level();
auto refAlarmsEvent = std::make_unique<AlarmsEvent>(std::move(oAInit));
return refAlarmsEvent;
}
......
......@@ -58,7 +58,7 @@ XmlBackgroundEventParser::XmlBackgroundEventParser()
Event* XmlBackgroundEventParser::parseEvent(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
return parseBaseAndAddEvent(oCtx, parseEventBackground(oCtx, p0Element), p0Element);
return integrateAndAdd(oCtx, parseEventBackground(oCtx, p0Element), p0Element);
}
unique_ptr<Event> XmlBackgroundEventParser::parseEventBackground(GameCtx& oCtx, const xmlpp::Element* p0Element)
......@@ -66,6 +66,8 @@ unique_ptr<Event> XmlBackgroundEventParser::parseEventBackground(GameCtx& oCtx,
//std::cout << "XmlBackgroundEventParser::parseEventBackground" << '\n';
oCtx.addChecker(p0Element);
BackgroundEvent::Init oBEInit;
parseEventBase(oCtx, p0Element, oBEInit);
const auto oPairAniName = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventBackgroundAnimationNameAttr);
if (oPairAniName.first) {
const std::string& sName = oPairAniName.second;
......@@ -198,7 +200,6 @@ unique_ptr<Event> XmlBackgroundEventParser::parseEventBackground(GameCtx& oCtx,
throw XmlCommonErrors::errorElementExpected(oCtx, p0Element, s_sEventBackgroundImageNodeName);
}
oCtx.removeChecker(p0Element, true);
oBEInit.m_p0Level = &oCtx.level();
return std::make_unique<BackgroundEvent>(std::move(oBEInit));
}
void XmlBackgroundEventParser::parseEventBackgroundImage(GameCtx& oCtx, const xmlpp::Element* p0Element, BackgroundEvent::PatternImage& oPatternImage)
......
......@@ -52,14 +52,15 @@ XmlCumulCmpEventParser::XmlCumulCmpEventParser()
Event* XmlCumulCmpEventParser::parseEvent(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
return parseBaseAndAddEvent(oCtx, parseEventCumulCmp(oCtx, p0Element), p0Element);
return integrateAndAdd(oCtx, parseEventCumulCmp(oCtx, p0Element), p0Element);
}
unique_ptr<Event> XmlCumulCmpEventParser::parseEventCumulCmp(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
//std::cout << "XmlGameParser::parseEventCumulCmp" << '\n';
oCtx.addChecker(p0Element);
CumulCmpEvent::Init oCCInit;
parseEventBase(oCtx, p0Element, oCCInit);
const auto oPairInitialLeft = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventCumulCmpInitialLeftAttr);
if (oPairInitialLeft.first) {
const std::string& sInitialLeft = oPairInitialLeft.second;
......@@ -120,7 +121,6 @@ unique_ptr<Event> XmlCumulCmpEventParser::parseEventCumulCmp(GameCtx& oCtx, cons
}
oCtx.removeChecker(p0Element, true);
oCCInit.m_p0Level = &oCtx.level();
auto refCumulCmpEvent = std::make_unique<CumulCmpEvent>(std::move(oCCInit));
return refCumulCmpEvent;
}
......
......@@ -32,6 +32,7 @@ namespace stmg
static const std::string s_sEventLogNodeName = "LogEvent";
static const std::string s_sEventLogToStdOutAttr = "toStdOut";
static const std::string s_sEventLogElapsedMinuteFormatAttr = "elapsedMinuteFormat";
static const std::string s_sEventLogValueAsXYAttr = "valueAsXY";
static const std::string s_sEventLogTagAttr = "tag";
XmlLogEventParser::XmlLogEventParser()
......@@ -41,7 +42,7 @@ XmlLogEventParser::XmlLogEventParser()
Event* XmlLogEventParser::parseEvent(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
return parseBaseAndAddEvent(oCtx, parseEventLog(oCtx, p0Element), p0Element);
return integrateAndAdd(oCtx, parseEventLog(oCtx, p0Element), p0Element);
}
unique_ptr<Event> XmlLogEventParser::parseEventLog(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
......@@ -59,14 +60,19 @@ unique_ptr<Event> XmlLogEventParser::parseEventLog(GameCtx& oCtx, const xmlpp::E
oLInit.m_bElapsedMinuteFormat = XmlUtil::strToBool(oCtx, p0Element, s_sEventLogElapsedMinuteFormatAttr, oPairElapsedMinuteFormat.second);
}
const auto oPairValueAsXY = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventLogValueAsXYAttr);
if (oPairValueAsXY.first) {
oLInit.m_bValueAsXY = XmlUtil::strToBool(oCtx, p0Element, s_sEventLogValueAsXYAttr, oPairValueAsXY.second);
}
const auto oPairTag = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventLogTagAttr);
if (oPairTag.first) {
const std::string& sTag = oPairTag.second;
oLInit.m_nTag = XmlUtil::strToNumber<int32_t>(oCtx, p0Element, s_sEventLogTagAttr, sTag, false
, false, -1, false, -1);
}
parseEventBase(oCtx, p0Element, oLInit);
oCtx.removeChecker(p0Element, true);
oLInit.m_p0Level = &oCtx.level();
auto refLogEvent = std::make_unique<LogEvent>(std::move(oLInit));
return refLogEvent;
}
......
......@@ -37,15 +37,15 @@ XmlOthersSenderEventParser::XmlOthersSenderEventParser()
Event* XmlOthersSenderEventParser::parseEvent(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
return parseBaseAndAddEvent(oCtx, parseEventOthersSender(oCtx, p0Element), p0Element);
return integrateAndAdd(oCtx, parseEventOthersSender(oCtx, p0Element), p0Element);
}
unique_ptr<Event> XmlOthersSenderEventParser::parseEventOthersSender(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
//std::cout << "XmlOthersEventParser::parseEventOthersSender" << '\n';
oCtx.addChecker(p0Element);
oCtx.removeChecker(p0Element, true);
OthersSenderEvent::Init oOSInit;
oOSInit.m_p0Level = &oCtx.level();
parseEventBase(oCtx, p0Element, oOSInit);
oCtx.removeChecker(p0Element, true);
auto refOthersSenderEvent = std::make_unique<OthersSenderEvent>(std::move(oOSInit));
return refOthersSenderEvent;
}
......@@ -58,15 +58,15 @@ XmlOthersReceiverEventParser::XmlOthersReceiverEventParser()
Event* XmlOthersReceiverEventParser::parseEvent(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
return parseBaseAndAddEvent(oCtx, parseEventOthersReceiver(oCtx, p0Element), p0Element);
return integrateAndAdd(oCtx, parseEventOthersReceiver(oCtx, p0Element), p0Element);
}
unique_ptr<Event> XmlOthersReceiverEventParser::parseEventOthersReceiver(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
//std::cout << "XmlOthersEventParser::parseEventOthersReceiver" << '\n';
oCtx.addChecker(p0Element);
oCtx.removeChecker(p0Element, true);
OthersReceiverEvent::Init oORInit;
oORInit.m_p0Level = &oCtx.level();
parseEventBase(oCtx, p0Element, oORInit);
oCtx.removeChecker(p0Element, true);
auto refOthersReceiverEvent = std::make_unique<OthersReceiverEvent>(std::move(oORInit));
return refOthersReceiverEvent;
}
......
......@@ -45,15 +45,17 @@ XmlPositionerEventParser::XmlPositionerEventParser()
}
Event* XmlPositionerEventParser::parseEvent(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
return parseBaseAndAddEvent(oCtx, parseEventPositioner(oCtx, p0Element), p0Element);
return integrateAndAdd(oCtx, parseEventPositioner(oCtx, p0Element), p0Element);
}
unique_ptr<Event> XmlPositionerEventParser::parseEventPositioner(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
//std::cout << "XmlPositionerEventParser::parseEventPositioner" << '\n';
oCtx.addChecker(p0Element);
PositionerEvent::Init oInit;
parseEventBase(oCtx, p0Element, oInit);
Level& oLevel = oCtx.level();
oInit.m_p0Level = &oLevel;
//const bool bATIOL = oLevel.game().isAllTeamsInOneLevel();
const bool bSubshows = oLevel.subshowMode();
//std::cout << "XmlPositionerEventParser::parseEventPositioner: bSubshows = " << bSubshows << '\n';
......@@ -66,34 +68,13 @@ unique_ptr<Event> XmlPositionerEventParser::parseEventPositioner(GameCtx& oCtx,
oParentSize.m_nW = oLevel.showGet().getW();
oParentSize.m_nH = oLevel.showGet().getH();
}
oInit.m_oTrackingRect.m_nX = 0;
oInit.m_oTrackingRect.m_nY = 0;
oInit.m_oTrackingRect.m_nW = oParentSize.m_nW - oInit.m_oTrackingRect.m_nX;
oInit.m_oTrackingRect.m_nH = oParentSize.m_nH - oInit.m_oTrackingRect.m_nY;
const auto oPairRectX = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventPositionerTrackAreaXAttr);
if (oPairRectX.first) {
oInit.m_oTrackingRect.m_nX = XmlUtil::strToNumber<int32_t>(oCtx, p0Element, s_sEventPositionerTrackAreaXAttr, oPairRectX.second, false
, true, 0, true, oParentSize.m_nW - 1);
}
const auto oPairRectY = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventPositionerTrackAreaYAttr);
if (oPairRectY.first) {
oInit.m_oTrackingRect.m_nY = XmlUtil::strToNumber<int32_t>(oCtx, p0Element, s_sEventPositionerTrackAreaYAttr, oPairRectY.second, false
, true, 0, true, oParentSize.m_nH - 1);
}
oInit.m_oTrackingRect.m_nW = oParentSize.m_nW - oInit.m_oTrackingRect.m_nX;
const auto oPairRectW = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventPositionerTrackAreaWAttr);
if (oPairRectW.first) {
oInit.m_oTrackingRect.m_nW = XmlUtil::strToNumber<int32_t>(oCtx, p0Element, s_sEventPositionerTrackAreaWAttr, oPairRectW.second, false
, true, 1, true, oInit.m_oTrackingRect.m_nW);
}
oInit.m_oTrackingRect.m_nH = oParentSize.m_nH - oInit.m_oTrackingRect.m_nY;
const auto oPairRectH = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventPositionerTrackAreaHAttr);
if (oPairRectH.first) {
oInit.m_oTrackingRect.m_nH = XmlUtil::strToNumber<int32_t>(oCtx, p0Element, s_sEventPositionerTrackAreaHAttr, oPairRectH.second, false
, true, 1, true, oInit.m_oTrackingRect.m_nH);
}
XmlBasicParser oXmlBasicParser(getXmlConditionalParser());
oInit.m_oTrackingRect = oXmlBasicParser.parseNRect(oCtx, p0Element
, s_sEventPositionerTrackAreaXAttr, s_sEventPositionerTrackAreaYAttr, s_sEventPositionerTrackAreaWAttr, s_sEventPositionerTrackAreaHAttr
, true, NRect{0, 0, oParentSize.m_nW, oParentSize.m_nH}
, NSize{1, 1});
const auto oPairCheckEachTicks = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventPositionerCheckEachTicksAttr);
const auto oPairCheckEachTicks = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventPositionerCheckEachTicksAttr);
if (oPairCheckEachTicks.first) {
const std::string& sCheckEachTicks = oPairCheckEachTicks.second;
oInit.m_nCheckEachTicks = XmlUtil::strToNumber<int32_t>(oCtx, p0Element, s_sEventPositionerCheckEachTicksAttr, sCheckEachTicks, false
......@@ -105,6 +86,7 @@ unique_ptr<Event> XmlPositionerEventParser::parseEventPositioner(GameCtx& oCtx,
oInit.m_nTransitionTicks = XmlUtil::strToNumber<int32_t>(oCtx, p0Element, s_sEventPositionerTransitionTicksAttr, sTransitionTicks, false
, true, 1, false, -1);
}
oCtx.removeChecker(p0Element, true);
return std::make_unique<PositionerEvent>(std::move(oInit));
}
int32_t XmlPositionerEventParser::parseEventMsgName(ConditionalCtx& oCtx, const xmlpp::Element* p0Element, const std::string& sAttr
......
......@@ -44,15 +44,14 @@ XmlRandomEventParser::XmlRandomEventParser()
Event* XmlRandomEventParser::parseEvent(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
return parseBaseAndAddEvent(oCtx, parseEventRandom(oCtx, p0Element), p0Element);
return integrateAndAdd(oCtx, parseEventRandom(oCtx, p0Element), p0Element);
}
unique_ptr<Event> XmlRandomEventParser::parseEventRandom(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
//std::cout << "XmlRandomEventParser::parseEventRandom" << '\n';
oCtx.addChecker(p0Element);
RandomEvent::Init oRInit;
oRInit.m_p0Level = &oCtx.level();
parseEventBase(oCtx, p0Element, oRInit);
const auto oPairPermutations = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventRandomPermutationsAttr);
if (oPairPermutations.first) {
......@@ -95,6 +94,8 @@ int32_t XmlRandomEventParser::parseEventMsgName(ConditionalCtx& oCtx, const xmlp
int32_t nMsg;
if (sMsgName == "GENERATE") {
nMsg = RandomEvent::MESSAGE_GENERATE;
} else if (sMsgName == "GENERATE_ADD") {
nMsg = RandomEvent::MESSAGE_GENERATE_ADD;
} else {
return XmlEventParser::parseEventMsgName(oCtx, p0Element, sAttr, sMsgName);
}
......
......@@ -60,10 +60,10 @@ Event* XmlScrollerEventParser::parseEvent(GameCtx& oCtx, const xmlpp::Element* p
Event* XmlScrollerEventParser::parseEventScroller(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
//std::cout << "parseEventScroller" << '\n';
ScrollerEvent::Init oInit;
oCtx.addChecker(p0Element);
ScrollerEvent::Init oInit;
parseEventBase(oCtx, p0Element, oInit);
;
oInit.m_p0Level = &oCtx.level();
oInit.m_nRepeat = parseEventAttrRepeat(oCtx, p0Element);
oInit.m_nStep = parseEventAttrStep(oCtx, p0Element);
;
......@@ -104,7 +104,7 @@ Event* XmlScrollerEventParser::parseEventScroller(GameCtx& oCtx, const xmlpp::El
// TODO make sure random prob doesn't exceed some reasonable value (to stay within int32_t boundaries)
oCtx.removeChecker(p0Element, true);
auto refScrollerEvent = std::make_unique<ScrollerEvent>(std::move(oInit));
return parseBaseAndAddEvent(oCtx, std::move(refScrollerEvent), p0Element);
return integrateAndAdd(oCtx, std::move(refScrollerEvent), p0Element);
}
void XmlScrollerEventParser::parseNewRowChecker(GameCtx& oCtx, const xmlpp::Element* p0Element, ScrollerEvent::Init& oInit)
{
......
......@@ -28,6 +28,7 @@ namespace stmg
{
static const std::string s_sEventSelectNodeName = "SelectEvent";
static const std::string s_sEventSelectNameAttr = "varName";
XmlSelectEventParser::XmlSelectEventParser()
: XmlEventParser(s_sEventSelectNodeName)
......@@ -36,15 +37,49 @@ XmlSelectEventParser::XmlSelectEventParser()
Event* XmlSelectEventParser::parseEvent(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
return parseBaseAndAddEvent(oCtx, parseEventSelect(oCtx, p0Element), p0Element);
return integrateAndAdd(oCtx, parseEventSelect(oCtx, p0Element), p0Element);
}
unique_ptr<Event> XmlSelectEventParser::parseEventSelect(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
//std::cout << "XmlOthersEventParser::parseEventSelect" << '\n';
oCtx.addChecker(p0Element);
oCtx.removeChecker(p0Element, true);
SelectEvent::Init oOSInit;
oOSInit.m_p0Level = &oCtx.level();
parseEventBase(oCtx, p0Element, oOSInit);
const auto oPairName = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventSelectNameAttr);
if (oPairName.first) {
const std::string& sName = oPairName.second;
if (sName.empty()) {
throw XmlCommonErrors::errorAttrCannotBeEmpty(oCtx, p0Element, s_sEventSelectNameAttr);
}
//
const auto oPairOwner = getXmlConditionalParser().parseOwner(oCtx, p0Element);
oOSInit.m_nVarTeam = oPairOwner.first;
oOSInit.m_nVarMate = oPairOwner.second;
const auto oPair = oCtx.getVariableIdAndOwnerTypeFromContext(sName, oOSInit.m_nVarTeam, oOSInit.m_nVarMate);
oOSInit.m_nVarIndex = oPair.first;
if (oOSInit.m_nVarIndex < 0) {
throw XmlCommonErrors::errorAttrVariableNotDefined(oCtx, p0Element, s_sEventSelectNameAttr, sName);
}
const OwnerType eOwnerType = oPair.second;
if (eOwnerType == OwnerType::GAME) {
oOSInit.m_nVarTeam = -1;
oOSInit.m_nVarMate = -1;
} else if (eOwnerType == OwnerType::TEAM) {
assert(oOSInit.m_nVarTeam >= 0);
oOSInit.m_nVarMate = -1;
} else {
assert(oOSInit.m_nVarTeam >= 0);
assert(oOSInit.m_nVarMate >= 0);
}
} else {
oOSInit.m_nVarIndex = -1;
oOSInit.m_nVarTeam = -1;
oOSInit.m_nVarMate = -1;
}
//
oCtx.removeChecker(p0Element, true);
auto refSelectEvent = std::make_unique<SelectEvent>(std::move(oOSInit));
return refSelectEvent;
}
......
......@@ -53,7 +53,7 @@ XmlShowTextEventParser::XmlShowTextEventParser()
Event* XmlShowTextEventParser::parseEvent(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
return parseBaseAndAddEvent(oCtx, parseEventShowText(oCtx, p0Element), p0Element);
return integrateAndAdd(oCtx, parseEventShowText(oCtx, p0Element), p0Element);
}
unique_ptr<Event> XmlShowTextEventParser::parseEventShowText(GameCtx& oCtx, const xmlpp::Element* p0Element)
{
......@@ -61,6 +61,9 @@ unique_ptr<Event> XmlShowTextEventParser::parseEventShowText(GameCtx& oCtx, cons
Level& oLevel = oCtx.level();
oCtx.addChecker(p0Element);
ShowTextEvent::Init oSTInit;
parseEventBase(oCtx, p0Element, oSTInit);
std::string sToken;
const auto oPairToken = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventShowTextTokenAttr);
if (oPairToken.first) {
......@@ -70,8 +73,6 @@ unique_ptr<Event> XmlShowTextEventParser::parseEventShowText(GameCtx& oCtx, cons
sToken = s_sEventShowTextTokenAttrDefault;
}
ShowTextEvent::Init oSTInit;
const auto oPairAniName = getXmlConditionalParser().getAttributeValue(oCtx, p0Element, s_sEventShowTextTypeAttr);
if (oPairAniName.first) {
const std::string& sName = oPairAniName.second;
......@@ -102,7 +103,7 @@ unique_ptr<Event> XmlShowTextEventParser::parseEventShowText(GameCtx& oCtx, cons
}
if (oSTInit.m_eRefSys == LevelAnimation::REFSYS_SUBSHOW) {
if (!oLevel.subshowMode()) {
throw XmlCommonErrors::error(oCtx, p0Element, s_sEventShowTextRefSysAttr, "Subshow background needs Subshow mode.");