⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 battle.cpp

📁 S.C.O.U.R.G.E.是一款类似Rogue的游戏
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************                          battle.cpp  -  description                             -------------------    begin                : Sat May 3 2003    copyright            : (C) 2003 by Gabor Torok    email                : cctorok@yahoo.com ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include "battle.h"//#define DEBUG_BATTLE#define GOD_MODE 0#define MONSTER_IMORTALITY 0enum {  NO_ACTION = 0,  LOITER,  ATTACK,  MOVE,  NO_TARGET,  WAIT,};char *actionName[] = { "NO ACTION", "LOITER", "ATTACK", "MOVE", "NO_TARGET", "WAIT"};Battle::Battle() {  this->creature = NULL;}Battle::Battle(Scourge *scourge, Creature *creature) {  this->scourge = scourge;  this->creature = creature;  this->item = NULL;  this->creatureInitiative = 0;  this->initiativeCheck = false;  this->speed = 0;  this->dist = creature->getDistanceToTarget();  this->spell = NULL;  this->empty = false;}Battle::~Battle() {}void Battle::setupBattles(Scourge *scourge, Battle *battle[], int count, vector<Battle *> *turns) {  if(count == 0) return;  bool battleStarted = false;  int battleCount = count;    int initiative = -10;//char message[200];  int turn = 0;#ifdef DEBUG_BATTLE  cerr << "==================================================" << endl;  cerr << "battleCount=" << battleCount << endl;  for(int i = 0; i < battleCount; i++) {    cerr << "\t(" << battle[i]->creature->getName() <<     "->" << (battle[i]->creature->getTargetCreature() ?              battle[i]->creature->getTargetCreature()->getName() :             "NULL") <<     ")" << endl;  }#endif// this is O(n^2) unfortunately... maybe we could use a linked list or something here  while(battleCount > 0) {    bool creatureFound = false;     for(int i = 0; i < battleCount; i++) {      int action = NO_ACTION;      battle[i]->empty = false;      battle[i]->projectileHit = false;      if(!battle[i]->creature->hasTarget()) {        // remove creatures with no target creature from this round        action = NO_TARGET;      } else if(!battle[i]->creature->isTargetValid()) {        // if someone already killed this target, skip it        battle[i]->creature->cancelTarget();        if(battle[i]->creature->isMonster()) {          //battle[i]->creature->setMotion(Constants::MOTION_LOITER);               action = LOITER;        } else {          // if party member re-join the battle          Creature *c = battle[i]->creature;          c->setTargetCreature(scourge->getClosestVisibleMonster(c->getX(),                                                                  c->getY(),                                                                  c->getShape()->getWidth(),                                                                 c->getShape()->getDepth(),                                                                 20));        }      } else {        GLint t = SDL_GetTicks();        // get the best weapon given the distance from the target        battle[i]->initTurn();        // check the creature's initiative        if(!battle[i]->initiativeCheck ||            battle[i]->creatureInitiative < initiative) {          // remember that it passed (creature can attack next time if timing (below) is good)          battle[i]->initiativeCheck = true;          creatureFound = true;          // this is to slow down battle, depending on your weapon          // getLastTurn is 0 when an action is decided to be executed          // this way it's two trips through this method forcing a spell (e.g.)          // to use the clock.          bool initialActionTurn = (battle[i]->creature->getLastTurn() == 0);#ifdef DEBUG_BATTLE                                                                             cerr << "speed=" << battle[i]->speed << " last=" << battle[i]->creature->getLastTurn() <<           " diff=" << (t - battle[i]->creature->getLastTurn()) << endl;#endif                                                                                                  if(initialActionTurn ||             battle[i]->speed < t - battle[i]->creature->getLastTurn()) {            // remember the last active turn			            battle[i]->creature->setLastTurn(t);            if(!battleStarted) {              scourge->getMap()->addDescription("A round of battle begins...", 1, 1, 1);              battleStarted = true;            }            if(initialActionTurn) {              // add a waiting term              battle[i]->empty = true;              action = WAIT;              turns->push_back(battle[i]);            } else {              // save this turn              turns->push_back(battle[i]);              action = ATTACK;            }          } else {            // add a waiting term            battle[i]->empty = true;            action = WAIT;            turns->push_back(battle[i]);          }        }      }      if(action != NO_ACTION) {#ifdef DEBUG_BATTLE                         cerr << "Turn: " << turn << " " << actionName[action] << ", " <<        battle[i]->creature->getName() << "(" << battle[i]->creatureInitiative << ")" <<        "->" << (battle[i]->creature->getTargetCreature() ?                  battle[i]->creature->getTargetCreature()->getName() :                  "<no target>") <<        endl;#endif                                                            // remove this battle from the turn        Battle *tmp = battle[i];        for(int t = i; t < battleCount - 1; t++) {          battle[t] = battle[t + 1];        }        // move current one to the end of the list so we don't loose it        battle[battleCount - 1] = tmp;        battleCount--;        i--;        turn++;      }    }    // if there are no creatures for this initiative slot, go to the next one    if(!creatureFound) initiative++;  }}                 void Battle::fightTurn() {  // waiting to cast a spell?  if(creature->getAction() == Constants::ACTION_CAST_SPELL) {    creature->startEffect(Constants::EFFECT_CAST_SPELL,                           Constants::DAMAGE_DURATION * 4);  }  // waiting to attack?  if(isEmpty()) return;  // target killed?  if(!creature->hasTarget()) return;  // if there was no 'item' selected it's because we're too far from the target  // (getBestWeapon returned NULL) and we're not casting a spell, follow the target  //  // If it's an empty-handed attack, follow the target  //  // If it's a ranged attack and we're not in range, follow the target (will move away from target)  //  // This sure is confusing code...  /*  cerr << "projectileHit=" << projectileHit <<        " dist=" << dist <<        " creature->isInRange()=" << creature->isInRange() <<        " item=" << item <<        " creature->getActionSpell()=" << creature->getActionSpell() <<        " spell=" << spell << endl;        */  if(!projectileHit &&     ((dist > Constants::MIN_DISTANCE && !item && !creature->getActionSpell() && !spell) ||        !creature->isInRange())) {     //cerr << "\tfollowing..." << endl;    creature->followTarget();    return;  }  //cerr << "\tcontinuing" << endl;  // handle action: eat/drink items  if(creature->getAction() == Constants::ACTION_EAT_DRINK) {    executeEatDrinkAction();    return;  }  // the attacked target may get upset  creature->decideMonsterAction();  // handle the action  if(!projectileHit && item && item->getRpgItem()->isRangedWeapon()) {    launchProjectile();  } else if(spell) {    // a spell projectile hit    SpellCaster *sc = new SpellCaster(this, spell, true);     sc->spellSucceeded();    delete sc;  } else if(creature->getActionSpell()) {    // casting a spell for the first time    castSpell();  } else {    hitWithItem();  }}void Battle::castSpell() {  // use up some MP (not when using a scroll)  if(!creature->getActionItem()) {    int n = creature->getMp() - creature->getActionSpell()->getMp();    if(n < 0) n = 0;    creature->setMp( n );  } else {    // try to destroy the scroll    int itemIndex = creature->findInInventory(creature->getActionItem());    if(itemIndex > -1) {      creature->removeInventory(itemIndex);      sprintf(message, "%s crumbles into dust.", creature->getActionItem()->getItemName());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -