- Fixed a bug where the AI would block its own attacking creatures (I reintroduced that bug recently when I removed a safeguard Zethfox had added a while ago)

- Added a way to specify "no interrupt" in modrules.xml (I need to write a doc about this file) for a given game. This does not mean the stack does not show up (the stack is interesting to see what the opponent does), but that it only offers to continue.
This commit is contained in:
wagic.the.homebrew
2011-05-07 11:58:37 +00:00
parent fe276ca330
commit ab33d29682
4 changed files with 95 additions and 40 deletions

View File

@@ -1,3 +1,16 @@
/*
* Wagic, The Homebrew ?! is licensed under the BSD license
* See LICENSE in the Folder's root
* http://wololo.net/wagic/
*/
/*
ModRules class describes global game rules used for a given Wagic Mod.
These rules describe some high level Game rules,
some graphical effects, what parts of the game are made accessible to the player, etc...
They are accessed through the global variable gModRules, and loaded from rules/modrules.xml
*/
#ifndef _MODRULES_H_
#define _MODRULES_H_
@@ -70,6 +83,16 @@ public:
~ModRulesMenu();
};
class ModRulesGame
{
public:
bool mCanInterrupt;
public:
bool canInterrupt() {return mCanInterrupt;};
ModRulesGame();
void parse(TiXmlElement* element);
};
class ModRulesGeneral
{
protected:
@@ -98,6 +121,7 @@ public:
ModRulesGeneral general;
ModRulesCards cards;
ModRulesMenu menu;
ModRulesGame game;
bool load(string filename);
static int getValueAsInt(TiXmlElement* element, string childName);

View File

@@ -882,8 +882,7 @@ int AIPlayer::interruptIfICan()
if (!clickstream.empty())
g->mLayers->stackLayer()->cancelInterruptOffer();
else
g->mLayers->stackLayer()->setIsInterrupting(this);
return 1;
return g->mLayers->stackLayer()->setIsInterrupting(this);
}
return 0;
}
@@ -1131,8 +1130,14 @@ int AIPlayer::canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy
int AIPlayer::chooseBlockers()
{
GameObserver * g = GameObserver::GetInstance();
//Should not block during my own turn...
if (g->currentPlayer == this)
return 0;
//Should not run this if I'm not the player with priority
if (g->currentActionPlayer != this)
return 0;
//I am interrupting, why would I be choosing blockers now?
if(g->isInterrupting == this)
return 0;
//ai should not be allowed to run this if it is not legally allowed to do so

View File

@@ -14,6 +14,7 @@ The Action Stack contains all information for Game Events that can be interrupte
#include "TargetChooser.h"
#include "Translate.h"
#include "WResourceManager.h"
#include "ModRules.h"
#include <typeinfo>
@@ -573,10 +574,17 @@ int ActionStack::AddNextCombatStep()
int ActionStack::setIsInterrupting(Player * player)
{
askIfWishesToInterrupt = NULL;
if (!gModRules.game.canInterrupt())
{
cancelInterruptOffer();
return 0;
}
int playerId = (player == game->players[1]) ? 1 : 0;
interruptDecision[playerId] = -1;
game->isInterrupting = player;
askIfWishesToInterrupt = NULL;
return 1;
}
@@ -634,12 +642,6 @@ ActionStack::ActionStack(GameObserver* game)
pspIcons[i] = WResourceManager::Instance()->RetrieveQuad("iconspsp.png", (float) i * 32, 0, 32, 32, stream.str(), RETRIEVE_MANAGE);
pspIcons[i]->SetHotSpot(16, 16);
}
// fix for translation.
kInterruptMessageString = _(kInterruptMessageString);
kInterruptString = _(kInterruptString);
kNoString = _(kNoString);
kNoToAllString = _(kNoToAllString);
}
int ActionStack::has(MTGAbility * ability)
@@ -961,7 +963,7 @@ bool ActionStack::CheckUserInput(JButton key)
{
if (askIfWishesToInterrupt)
{
if (JGE_BTN_SEC == key)
if (JGE_BTN_SEC == key && gModRules.game.canInterrupt())
{
setIsInterrupting(askIfWishesToInterrupt);
return true;
@@ -1100,12 +1102,8 @@ void ActionStack::Render()
mFont->SetColor(ARGB(255,255,255,255));
JRenderer * renderer = JRenderer::GetInstance();
//JQuad * back = WResourceManager::Instance()->GetQuad("interrupt");
//float xScale = width / back->mWidth;
//float yScale = height / back->mHeight;
renderer->FillRoundRect(x0 + 16, y0 + 16, width + 2, height + 2, 10, ARGB(128,0,0,0));
renderer->FillRoundRect(x0 - 5, y0, width + 2, height + 2, 10, ARGB(200,0,0,0));
//renderer->RenderQuad(back,x0,y0,0,xScale, yScale);
renderer->DrawRoundRect(x0 - 5, y0, width + 2, height + 2, 10, ARGB(255,255,255,255));
std::ostringstream stream;
@@ -1116,31 +1114,40 @@ void ActionStack::Render()
// Mootpoint 01/12/2011: draw the interrupt text first, at the top. Offset the rest of the
// unresolved stack effects down so that they don't collide with the interrupt text.
if (options[Options::INTERRUPT_SECONDS].number == 0)
stream << kInterruptMessageString;
stream << _(kInterruptMessageString);
else
stream << kInterruptMessageString << " " << static_cast<int>(timer);
stream << _(kInterruptMessageString) << " " << static_cast<int>(timer);
mFont->DrawString(stream.str(), x0 + 5, currenty);
static const float kIconVerticalOffset = 24;
if (mCount > 1)
static const float kIconHorizontalOffset = 9;
static const float kBeforeIconSpace = 10;
//Render "interrupt?" text + possible actions
{
renderer->RenderQuad(pspIcons[7].get(), x0 + 10, kIconVerticalOffset, 0, kGamepadIconSize, kGamepadIconSize);
mFont->DrawString(kInterruptString, x0 + 19, kIconVerticalOffset - 6);
float currentx = x0 + 10;
if (gModRules.game.canInterrupt())
{
renderer->RenderQuad(pspIcons[7].get(), currentx, kIconVerticalOffset, 0, kGamepadIconSize, kGamepadIconSize);
currentx+= kIconHorizontalOffset;
mFont->DrawString(_(kInterruptString), currentx, kIconVerticalOffset - 6);
currentx+= mFont->GetStringWidth(_(kInterruptString).c_str()) + kBeforeIconSpace;
}
renderer->RenderQuad(pspIcons[4].get(), x0 + 97, kIconVerticalOffset, 0, kGamepadIconSize, kGamepadIconSize);
mFont->DrawString(kNoString, x0 + 106, kIconVerticalOffset - 6);
renderer->RenderQuad(pspIcons[4].get(), currentx, kIconVerticalOffset, 0, kGamepadIconSize, kGamepadIconSize);
currentx+= kIconHorizontalOffset;
mFont->DrawString(_(kNoString), currentx, kIconVerticalOffset - 6);
currentx+= mFont->GetStringWidth(_(kNoString).c_str()) + kBeforeIconSpace;
renderer->RenderQuad(pspIcons[6].get(), x0 + 145, kIconVerticalOffset, 0, kGamepadIconSize, kGamepadIconSize);
mFont->DrawString(kNoToAllString, x0 + 154, kIconVerticalOffset - 6);
}
else
{
renderer->RenderQuad(pspIcons[7].get(), x0 + 40, kIconVerticalOffset, 0, kGamepadIconSize, kGamepadIconSize);
mFont->DrawString(kInterruptString, x0 + 49, kIconVerticalOffset - 6);
renderer->RenderQuad(pspIcons[4].get(), x0 + 140, kIconVerticalOffset - 6, 0, kGamepadIconSize, kGamepadIconSize);
mFont->DrawString(kNoString, x0 + 146, kIconVerticalOffset - 6);
if (mCount > 1)
{
renderer->RenderQuad(pspIcons[6].get(), currentx, kIconVerticalOffset, 0, kGamepadIconSize, kGamepadIconSize);
currentx+= kIconHorizontalOffset;
mFont->DrawString(_(kNoToAllString), currentx, kIconVerticalOffset - 6);
currentx+= mFont->GetStringWidth(_(kNoToAllString).c_str()) + kBeforeIconSpace;
}
}
currenty += kIconVerticalOffset + kSpacer;

View File

@@ -46,6 +46,10 @@ bool ModRules::load(string filename)
{
cards.parse(element);
}
else if (strcmp(element->Value(), "game") == 0)
{
game.parse(element);
}
}
}
return true;
@@ -174,21 +178,27 @@ ModRulesMenu::~ModRulesMenu()
other.clear();
}
//inGame rules
ModRulesGame::ModRulesGame()
{
mCanInterrupt = true;
}
void ModRulesGame::parse(TiXmlElement* element)
{
int value = ModRules::getValueAsInt(element, "canInterrupt");
if (value != -1)
mCanInterrupt = value;
}
//General Rules
ModRulesGeneral::ModRulesGeneral()
{
mHasDeckEditor = true;
mHasShop = true;
}
int ModRules::getValueAsInt(TiXmlElement* element, string childName){
TiXmlNode* node = element->FirstChild(childName.c_str());
if (node) {
const char* value = node->ToElement()->GetText();
return atoi(value);
}
return -1;
}
void ModRulesGeneral::parse(TiXmlElement* element)
{
int value = ModRules::getValueAsInt(element, "hasDeckEditor");
@@ -201,6 +211,15 @@ void ModRulesGeneral::parse(TiXmlElement* element)
}
int ModRules::getValueAsInt(TiXmlElement* element, string childName){
TiXmlNode* node = element->FirstChild(childName.c_str());
if (node) {
const char* value = node->ToElement()->GetText();
return atoi(value);
}
return -1;
}
ModRulesCards::ModRulesCards()
{
activateEffect = NEW SimpleCardEffectRotate(M_PI/2); //Default activation effect