Files
wagic/projects/mtg/src/PhaseRing.cpp
T
wagic.the.homebrew@gmail.com b1079942af Erwan
- Reward system in Story mode (currently, either credits or random set)
- Rules now accept for player 2 to start (see story mode "block" stage)
- Story mode now has an autosave/autoload mechanism. This is for convenience but also to prevent people from abusing the reward mechanism too easily.
- possibility to choose an avatar for both players through the rules (see example in story mode)
2010-05-09 08:14:01 +00:00

137 lines
4.3 KiB
C++

#include "../include/PhaseRing.h"
#include "../include/MTGDefinitions.h"
#include "../include/Player.h"
#include "../include/config.h"
#include "../include/WEvent.h"
//Parses a string and gives phase numer
int PhaseRing::phaseStrToInt(string s){
if (s.compare("untap") == 0) return Constants::MTG_PHASE_UNTAP;
if (s.compare("upkeep") == 0)return Constants::MTG_PHASE_UPKEEP;
if (s.compare("draw") == 0)return Constants::MTG_PHASE_DRAW;
if (s.compare("firstmain") == 0)return Constants::MTG_PHASE_FIRSTMAIN;
if (s.compare("combatbegin") == 0)return Constants::MTG_PHASE_COMBATBEGIN;
if (s.compare("combatattackers") == 0)return Constants::MTG_PHASE_COMBATATTACKERS;
if (s.compare("combatblockers") == 0)return Constants::MTG_PHASE_COMBATBLOCKERS;
if (s.compare("combatdamage") == 0)return Constants::MTG_PHASE_COMBATDAMAGE;
if (s.compare("combatend") == 0)return Constants::MTG_PHASE_COMBATEND;
if (s.compare("secondmain") == 0)return Constants::MTG_PHASE_SECONDMAIN;
if (s.compare("endofturn") == 0)return Constants::MTG_PHASE_ENDOFTURN;
if (s.compare("cleanup") == 0)return Constants::MTG_PHASE_CLEANUP;
OutputDebugString("PHASERING: Unknown Phase name:");
OutputDebugString(s.c_str());
OutputDebugString("\n");
return Constants::MTG_PHASE_FIRSTMAIN;
}
/* Creates a New phase ring with the default rules */
PhaseRing::PhaseRing(Player* players[], int nbPlayers){
for (int i = 0; i < nbPlayers; i++){
for (int j = 0; j < Constants::NB_MTG_PHASES; j++){
Phase * phase = NEW Phase(j,players[i]);
addPhase(phase);
}
}
current = ring.begin();
}
PhaseRing::~PhaseRing(){
list<Phase *>::iterator it;
for (it = ring.begin(); it != ring.end(); it++){
Phase * currentPhase = *it;
delete(currentPhase);
}
}
//Tells if next phase will be another Damage phase rather than combat ends
bool PhaseRing::extraDamagePhase(int id){
GameObserver * g = GameObserver::GetInstance();
if (id != Constants::MTG_PHASE_COMBATEND) return false;
if (g->combatStep != END_FIRST_STRIKE) return false;
for (int j = 0; j < 2; ++j){
MTGGameZone * z = g->players[j]->game->inPlay;
for (int i= 0; i < z->nb_cards; ++i){
MTGCardInstance * card = z->cards[i];
if ((card->isAttacker() || card->isDefenser()) && !(card->has(Constants::FIRSTSTRIKE) || card->has(Constants::DOUBLESTRIKE))) return true;
}
}
return false;
}
const char * PhaseRing::phaseName(int id){
if (extraDamagePhase(id)) return "Combat Damage (2)";
return Constants::MTGPhaseNames[id];
}
Phase * PhaseRing::getCurrentPhase(){
if (current == ring.end()){
current = ring.begin();
}
return *current;
}
Phase * PhaseRing::forward(bool sendEvents){
Phase * cPhaseOld = *current;
if (current != ring.end()) current++;
if (current == ring.end()) current = ring.begin();
if (sendEvents) {
//Warn the layers about the phase Change
WEvent * e = NEW WEventPhaseChange(cPhaseOld, *current);
GameObserver::GetInstance()->receiveEvent(e);
}
return *current;
}
Phase * PhaseRing::goToPhase(int id, Player * player, bool sendEvents){
Phase * currentPhase = *current;
while(currentPhase->id !=id || currentPhase->player != player){ //Dangerous, risk for inifinte loop !
#ifdef WIN32
OutputDebugString("goto");
#endif
currentPhase = forward(sendEvents);
}
return currentPhase;
}
int PhaseRing::addPhase(Phase * phase){
ring.push_back(phase);
return 1;
}
int PhaseRing::addPhaseBefore(int id, Player* player,int after_id, Player * after_player, int allOccurences){
int result = 0;
list<Phase *>::iterator it;
for (it = ring.begin(); it != ring.end(); it++){
Phase * currentPhase = *it;
if (currentPhase->id == after_id && currentPhase->player == after_player){
result++;
ring.insert(it,NEW Phase(id,player));
if (!allOccurences) return 1;
}
}
return result;
}
int PhaseRing::removePhase (int id, Player * player, int allOccurences){
int result = 0;
list<Phase *>::iterator it = ring.begin();
while (it != ring.end()){
Phase * currentPhase = *it;
if (currentPhase->id == id && currentPhase->player == player){
if (current == it) current++; //Avoid our cursor to get invalidated
it = ring.erase(it);
delete(currentPhase);
result++;
if (!allOccurences) return 1;
}else{
it++;
}
}
return result;
}