void CombatStart::apply(Dialog* dialog) { Combat* combat = CombatManager::getSingleton().startCombat(); std::vector<Creature*> allies = dialog->getPlayerCharacters(); for (std::vector<Creature*>::iterator it = allies.begin(); it != allies.end(); ++it) { combat->addAlly(*it); } std::vector<Creature*> enemies = dialog->getNonPlayerCharacters(); for (std::vector<Creature*>::iterator it = enemies.begin(); it != enemies.end(); ++it) { combat->addOpponent(*it); } combat->start(); }
void DuelEvent::happen() { CCScene* pScene = Combat::scene(); Combat* pLayer = (Combat*)pScene->getChildByTag(COMBATLAYER); //pass args(defined in CSV) here CCInteger* intg = (CCInteger*) this->args->lastObject(); if(intg!=NULL && pLayer!=NULL) pLayer->setMonsterType( intg->getValue() ); else if(intg==NULL && pLayer!=NULL) pLayer->setMonsterType( 1 ); else CCLog("Combat Layer get fail. "); CCTransitionFade *scenetrans = CCTransitionFade::create(0.7, pScene); CCDirector::sharedDirector()->pushScene(scenetrans); }
int main() { ////////// //Setup/// ////////// srand( (unsigned)time(0) ); Combat* pCombat = new Combat(); Report* pDamageReport = new Report( "damage_report.txt" ); pDamageReport->mFile.open( pDamageReport->getFilename(), ios::out | ios::app ); Report* pInitReport = new Report( "init_report.txt", false, 1 ); pDamageReport->addToReport( "Damage Report\n\n" ); pInitReport->addToReport( "Initialization Report\n\n" ); pDamageReport->mFile.close(); COORD newConsoleSize = {82,45}; //Resized the console so a more detailed output SMALL_RECT rDisplayArea = {0,0,0,0}; //of damage values, criticals, ability names, SetConsoleScreenBufferSize( pCombat->getHandle(), newConsoleSize ); //mana costs, and Damage Over Time ticks rDisplayArea.Right = newConsoleSize.X - 1; //could be seen on screen without scrolling SetConsoleWindowInfo( pCombat->getHandle(), true, &rDisplayArea ); Unit* pPlayer = pCombat->charInit(); Boss* pBoss = new Boss(); pCombat->units = pCombat->enemyInit( GameFunctions::getNumEnemies() ); pInitReport->initReport( pPlayer, pCombat->units ); //Output name, health, mana, armor, abilities and their names and values //for player and units vector of enemies pCombat->storyMsg( pPlayer->getPlayerName() ); stringstream initString; initString << "\nPrinting Story Message. Function call: storyMsg( pPlayer->getPlayerName() )" << "\nSetting up Game Loop variables..." << "\nDetermining Combat Order..." << "\nEntering Game Loop..."; pInitReport->addToReport( initString.str() ); pInitReport->addToReport( "\nStarting Combat..." ); //Final output, switching to Combat report: pDamageReport pCombat->startGameCombat( pPlayer, pBoss, pDamageReport, pCombat->units ); delete pPlayer; pPlayer= NULL; delete pBoss; pBoss = NULL; delete pCombat; pCombat = NULL; delete pDamageReport; pDamageReport = NULL; delete pInitReport; pInitReport = NULL; cin.ignore( 1000, '\n' ); cin.get(); return 0; }
bool Monsters::deserializeSpell(xmlNodePtr node, spellBlock_t& sb, const std::string& description) { sb.range = sb.minCombatValue = sb.maxCombatValue = 0; sb.combatSpell = sb.isMelee = false; sb.chance = 100; sb.speed = 2000; std::string name, scriptName; bool isScripted = false; if(readXMLString(node, "script", scriptName)) isScripted = true; else if(!readXMLString(node, "name", name)) return false; int32_t intValue; std::string strValue; if(readXMLInteger(node, "speed", intValue) || readXMLInteger(node, "interval", intValue)) sb.speed = std::max(1, intValue); if(readXMLInteger(node, "chance", intValue)) { if(intValue < 0 || intValue > 100) intValue = 100; sb.chance = intValue; } if(readXMLInteger(node, "range", intValue)) { if(intValue < 0) intValue = 0; if(intValue > Map::maxViewportX * 2) intValue = Map::maxViewportX * 2; sb.range = intValue; } if(readXMLInteger(node, "min", intValue)) sb.minCombatValue = intValue; if(readXMLInteger(node, "max", intValue)) sb.maxCombatValue = intValue; //normalize values if(std::abs(sb.minCombatValue) > std::abs(sb.maxCombatValue)) std::swap(sb.minCombatValue, sb.maxCombatValue); if((sb.spell = g_spells->getSpellByName(name))) return true; CombatSpell* combatSpell = NULL; bool needTarget = false, needDirection = false; if(isScripted) { if(readXMLString(node, "direction", strValue)) needDirection = booleanString(strValue); if(readXMLString(node, "target", strValue)) needTarget = booleanString(strValue); combatSpell = new CombatSpell(NULL, needTarget, needDirection); if(!combatSpell->loadScript(getFilePath(FILE_TYPE_OTHER, g_spells->getScriptBaseName() + "/scripts/" + scriptName), true)) { delete combatSpell; return false; } if(!combatSpell->loadScriptCombat()) { delete combatSpell; return false; } combatSpell->getCombat()->setPlayerCombatValues(FORMULA_VALUE, sb.minCombatValue, 0, sb.maxCombatValue, 0, 0, 0, 0, 0, 0, 0); } else { Combat* combat = new Combat; sb.combatSpell = true; if(readXMLInteger(node, "length", intValue)) { int32_t length = intValue; if(length > 0) { int32_t spread = 3; //need direction spell if(readXMLInteger(node, "spread", intValue)) spread = std::max(0, intValue); CombatArea* area = new CombatArea(); area->setupArea(length, spread); combat->setArea(area); needDirection = true; } } if(readXMLInteger(node, "radius", intValue)) { int32_t radius = intValue; //target spell if(readXMLInteger(node, "target", intValue)) needTarget = (intValue != 0); CombatArea* area = new CombatArea(); area->setupArea(radius); combat->setArea(area); } std::string tmpName = asLowerCaseString(name); if(tmpName == "melee" || tmpName == "distance") { int32_t attack = 0, skill = 0; if(readXMLInteger(node, "attack", attack) && readXMLInteger(node, "skill", skill)) { sb.minCombatValue = 0; sb.maxCombatValue = -Weapons::getMaxMeleeDamage(skill, attack); } uint32_t tickInterval = 2000; ConditionType_t conditionType = CONDITION_NONE; if(readXMLInteger(node, "physical", intValue)) conditionType = CONDITION_PHYSICAL; else if(readXMLInteger(node, "fire", intValue)) { conditionType = CONDITION_FIRE; tickInterval = 9000; } else if(readXMLInteger(node, "energy", intValue)) { conditionType = CONDITION_ENERGY; tickInterval = 10000; } else if(readXMLInteger(node, "earth", intValue)) { conditionType = CONDITION_POISON; tickInterval = 5000; } else if(readXMLInteger(node, "freeze", intValue)) { conditionType = CONDITION_FREEZING; tickInterval = 8000; } else if(readXMLInteger(node, "dazzle", intValue)) { conditionType = CONDITION_DAZZLED; tickInterval = 10000; } else if(readXMLInteger(node, "curse", intValue)) { conditionType = CONDITION_CURSED; tickInterval = 4000; } else if(readXMLInteger(node, "drown", intValue)) { conditionType = CONDITION_DROWN; tickInterval = 5000; } else if(readXMLInteger(node, "poison", intValue)) { conditionType = CONDITION_POISON; tickInterval = 5000; } uint32_t damage = std::abs(intValue); if(readXMLInteger(node, "tick", intValue) && intValue > 0) tickInterval = intValue; if(conditionType != CONDITION_NONE) { Condition* condition = getDamageCondition(conditionType, damage, damage, 0, tickInterval); if(condition) combat->setCondition(condition); } sb.isMelee = true; sb.range = 1; combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_PHYSICALDAMAGE); combat->setParam(COMBATPARAM_BLOCKEDBYSHIELD, 1); combat->setParam(COMBATPARAM_BLOCKEDBYARMOR, 1); } else if(tmpName == "physical") { combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_PHYSICALDAMAGE); combat->setParam(COMBATPARAM_BLOCKEDBYARMOR, 1); } else if(tmpName == "drown") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_DROWNDAMAGE); else if(tmpName == "fire") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_FIREDAMAGE); else if(tmpName == "energy") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_ENERGYDAMAGE); else if(tmpName == "poison" || tmpName == "earth") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_EARTHDAMAGE); else if(tmpName == "ice") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_ICEDAMAGE); else if(tmpName == "holy") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_HOLYDAMAGE); else if(tmpName == "death") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_DEATHDAMAGE); else if(tmpName == "lifedrain") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_LIFEDRAIN); else if(tmpName == "manadrain") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_MANADRAIN); else if(tmpName == "healing") { bool aggressive = false; if(readXMLInteger(node, "self", intValue)) aggressive = intValue; combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_HEALING); combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive); } else if(tmpName == "undefined") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_UNDEFINEDDAMAGE); else if(tmpName == "speed") { int32_t speedChange = 0, duration = 10000; if(readXMLInteger(node, "duration", intValue)) duration = intValue; enum Aggressive { NO, YES, AUTO } aggressive = AUTO; if(readXMLInteger(node, "self", intValue)) aggressive = (Aggressive)intValue; if(readXMLInteger(node, "speedchange", intValue)) speedChange = std::max(-1000, intValue); //cant be slower than 100% std::vector<Outfit_t> outfits; for(xmlNodePtr tmpNode = node->children; tmpNode; tmpNode = tmpNode->next) { if(xmlStrcmp(tmpNode->name,(const xmlChar*)"outfit")) continue; if(readXMLInteger(tmpNode, "type", intValue)) { Outfit_t outfit; outfit.lookType = intValue; if(readXMLInteger(tmpNode, "head", intValue)) outfit.lookHead = intValue; if(readXMLInteger(tmpNode, "body", intValue)) outfit.lookBody = intValue; if(readXMLInteger(tmpNode, "legs", intValue)) outfit.lookLegs = intValue; if(readXMLInteger(tmpNode, "feet", intValue)) outfit.lookFeet = intValue; if(readXMLInteger(tmpNode, "addons", intValue)) outfit.lookAddons = intValue; outfits.push_back(outfit); } if(readXMLInteger(tmpNode, "typeex", intValue) || readXMLInteger(tmpNode, "item", intValue)) { Outfit_t outfit; outfit.lookTypeEx = intValue; outfits.push_back(outfit); } if(readXMLString(tmpNode, "monster", strValue)) { if(MonsterType* mType = g_monsters.getMonsterType(strValue)) outfits.push_back(mType->outfit); } } ConditionType_t conditionType = CONDITION_PARALYZE; if(speedChange > 0) { conditionType = CONDITION_HASTE; if(aggressive == AUTO) aggressive = NO; } else if(aggressive == AUTO) aggressive = YES; if(ConditionSpeed* condition = dynamic_cast<ConditionSpeed*>(Condition::createCondition( CONDITIONID_COMBAT, conditionType, duration))) { condition->setFormulaVars((speedChange / 1000.), 0, (speedChange / 1000.), 0); if(!outfits.empty()) condition->setOutfits(outfits); combat->setCondition(condition); combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive); } } else if(tmpName == "outfit") { std::vector<Outfit_t> outfits; for(xmlNodePtr tmpNode = node->children; tmpNode; tmpNode = tmpNode->next) { if(xmlStrcmp(tmpNode->name,(const xmlChar*)"outfit")) continue; if(readXMLInteger(tmpNode, "type", intValue)) { Outfit_t outfit; outfit.lookType = intValue; if(readXMLInteger(tmpNode, "head", intValue)) outfit.lookHead = intValue; if(readXMLInteger(tmpNode, "body", intValue)) outfit.lookBody = intValue; if(readXMLInteger(tmpNode, "legs", intValue)) outfit.lookLegs = intValue; if(readXMLInteger(tmpNode, "feet", intValue)) outfit.lookFeet = intValue; if(readXMLInteger(tmpNode, "addons", intValue)) outfit.lookAddons = intValue; outfits.push_back(outfit); } if(readXMLInteger(tmpNode, "typeex", intValue) || readXMLInteger(tmpNode, "item", intValue)) { Outfit_t outfit; outfit.lookTypeEx = intValue; outfits.push_back(outfit); } if(readXMLString(tmpNode, "monster", strValue)) { if(MonsterType* mType = g_monsters.getMonsterType(strValue)) outfits.push_back(mType->outfit); } } if(outfits.empty()) { if(readXMLInteger(node, "type", intValue)) { Outfit_t outfit; outfit.lookType = intValue; if(readXMLInteger(node, "head", intValue)) outfit.lookHead = intValue; if(readXMLInteger(node, "body", intValue)) outfit.lookBody = intValue; if(readXMLInteger(node, "legs", intValue)) outfit.lookLegs = intValue; if(readXMLInteger(node, "feet", intValue)) outfit.lookFeet = intValue; if(readXMLInteger(node, "addons", intValue)) outfit.lookAddons = intValue; outfits.push_back(outfit); } if(readXMLInteger(node, "typeex", intValue) || readXMLInteger(node, "item", intValue)) { Outfit_t outfit; outfit.lookTypeEx = intValue; outfits.push_back(outfit); } if(readXMLString(node, "monster", strValue)) { if(MonsterType* mType = g_monsters.getMonsterType(strValue)) outfits.push_back(mType->outfit); } } if(!outfits.empty()) { int32_t duration = 10000; if(readXMLInteger(node, "duration", intValue)) duration = intValue; bool aggressive = false; if(readXMLInteger(node, "self", intValue)) aggressive = intValue; if(ConditionOutfit* condition = dynamic_cast<ConditionOutfit*>(Condition::createCondition( CONDITIONID_COMBAT, CONDITION_OUTFIT, duration))) { condition->setOutfits(outfits); combat->setCondition(condition); combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive); } } } else if(tmpName == "invisible") { int32_t duration = 10000; if(readXMLInteger(node, "duration", intValue)) duration = intValue; bool aggressive = false; if(readXMLInteger(node, "self", intValue)) aggressive = intValue; if(Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration)) { combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive); combat->setCondition(condition); } } else if(tmpName == "drunk") { int32_t duration = 10000; if(readXMLInteger(node, "duration", intValue)) duration = intValue; if(Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration)) combat->setCondition(condition); } else if(tmpName == "skills" || tmpName == "attributes") { uint32_t duration = 10000, subId = 0; if(readXMLInteger(node, "duration", intValue)) duration = intValue; if(readXMLInteger(node, "subid", intValue)) subId = intValue; intValue = 0; ConditionParam_t param = CONDITIONPARAM_BUFF; //to know was it loaded if(readXMLInteger(node, "melee", intValue)) param = CONDITIONPARAM_SKILL_MELEE; else if(readXMLInteger(node, "fist", intValue)) param = CONDITIONPARAM_SKILL_FIST; else if(readXMLInteger(node, "club", intValue)) param = CONDITIONPARAM_SKILL_CLUB; else if(readXMLInteger(node, "axe", intValue)) param = CONDITIONPARAM_SKILL_AXE; else if(readXMLInteger(node, "sword", intValue)) param = CONDITIONPARAM_SKILL_SWORD; else if(readXMLInteger(node, "distance", intValue) || readXMLInteger(node, "dist", intValue)) param = CONDITIONPARAM_SKILL_DISTANCE; else if(readXMLInteger(node, "shielding", intValue) || readXMLInteger(node, "shield", intValue)) param = CONDITIONPARAM_SKILL_SHIELD; else if(readXMLInteger(node, "fishing", intValue) || readXMLInteger(node, "fish", intValue)) param = CONDITIONPARAM_SKILL_FISHING; else if(readXMLInteger(node, "meleePercent", intValue)) param = CONDITIONPARAM_SKILL_MELEEPERCENT; else if(readXMLInteger(node, "fistPercent", intValue)) param = CONDITIONPARAM_SKILL_FISTPERCENT; else if(readXMLInteger(node, "clubPercent", intValue)) param = CONDITIONPARAM_SKILL_CLUBPERCENT; else if(readXMLInteger(node, "axePercent", intValue)) param = CONDITIONPARAM_SKILL_AXEPERCENT; else if(readXMLInteger(node, "swordPercent", intValue)) param = CONDITIONPARAM_SKILL_SWORDPERCENT; else if(readXMLInteger(node, "distancePercent", intValue) || readXMLInteger(node, "distPercent", intValue)) param = CONDITIONPARAM_SKILL_DISTANCEPERCENT; else if(readXMLInteger(node, "shieldingPercent", intValue) || readXMLInteger(node, "shieldPercent", intValue)) param = CONDITIONPARAM_SKILL_SHIELDPERCENT; else if(readXMLInteger(node, "fishingPercent", intValue) || readXMLInteger(node, "fishPercent", intValue)) param = CONDITIONPARAM_SKILL_FISHINGPERCENT; else if(readXMLInteger(node, "maxhealth", intValue)) param = CONDITIONPARAM_STAT_MAXHEALTHPERCENT; else if(readXMLInteger(node, "maxmana", intValue)) param = CONDITIONPARAM_STAT_MAXMANAPERCENT; else if(readXMLInteger(node, "soul", intValue)) param = CONDITIONPARAM_STAT_SOULPERCENT; else if(readXMLInteger(node, "magiclevel", intValue) || readXMLInteger(node, "maglevel", intValue)) param = CONDITIONPARAM_STAT_MAGICLEVELPERCENT; else if(readXMLInteger(node, "maxhealthPercent", intValue)) param = CONDITIONPARAM_STAT_MAXHEALTHPERCENT; else if(readXMLInteger(node, "maxmanaPercent", intValue)) param = CONDITIONPARAM_STAT_MAXMANAPERCENT; else if(readXMLInteger(node, "soulPercent", intValue)) param = CONDITIONPARAM_STAT_SOULPERCENT; else if(readXMLInteger(node, "magiclevelPercent", intValue) || readXMLInteger(node, "maglevelPercent", intValue)) param = CONDITIONPARAM_STAT_MAGICLEVELPERCENT; if(param != CONDITIONPARAM_BUFF) { if(ConditionAttributes* condition = dynamic_cast<ConditionAttributes*>(Condition::createCondition( CONDITIONID_COMBAT, CONDITION_ATTRIBUTES, duration, false, subId))) { condition->setParam(param, intValue); combat->setCondition(condition); } } } else if(tmpName == "firefield") combat->setParam(COMBATPARAM_CREATEITEM, 1492); else if(tmpName == "poisonfield") combat->setParam(COMBATPARAM_CREATEITEM, 1496); else if(tmpName == "energyfield") combat->setParam(COMBATPARAM_CREATEITEM, 1495); else if(tmpName == "firecondition" || tmpName == "energycondition" || tmpName == "drowncondition" || tmpName == "poisoncondition" || tmpName == "earthcondition" || tmpName == "freezecondition" || tmpName == "cursecondition" || tmpName == "dazzlecondition") { ConditionType_t conditionType = CONDITION_NONE; uint32_t tickInterval = 2000; if(tmpName == "physicalcondition") conditionType = CONDITION_PHYSICAL; else if(tmpName == "firecondition") { conditionType = CONDITION_FIRE; tickInterval = 9000; } else if(tmpName == "energycondition") { conditionType = CONDITION_ENERGY; tickInterval = 10000; } else if(tmpName == "earthcondition") { conditionType = CONDITION_POISON; tickInterval = 5000; } else if(tmpName == "freezecondition") { conditionType = CONDITION_FREEZING; tickInterval = 8000; } else if(tmpName == "cursecondition") { conditionType = CONDITION_CURSED; tickInterval = 4000; } else if(tmpName == "dazzlecondition") { conditionType = CONDITION_DAZZLED; tickInterval = 10000; } else if(tmpName == "drowncondition") { conditionType = CONDITION_DROWN; tickInterval = 5000; } else if(tmpName == "poisoncondition") { conditionType = CONDITION_POISON; tickInterval = 5000; } if(readXMLInteger(node, "tick", intValue) && intValue > 0) tickInterval = intValue; int32_t startDamage = 0, minDamage = std::abs(sb.minCombatValue), maxDamage = std::abs(sb.maxCombatValue); if(readXMLInteger(node, "start", intValue)) startDamage = std::max(std::abs(intValue), minDamage); if(Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, startDamage, tickInterval)) combat->setCondition(condition); } else if(tmpName == "strength") { //TODO: monster extra strength } else if(tmpName == "effect") {/*show some effect and bye bye!*/} else { delete combat; std::clog << "[Error - Monsters::deserializeSpell] " << description << " - Unknown spell name: " << name << std::endl; return false; } combat->setPlayerCombatValues(FORMULA_VALUE, sb.minCombatValue, 0, sb.maxCombatValue, 0, 0, 0, 0, 0, 0, 0); combatSpell = new CombatSpell(combat, needTarget, needDirection); for(xmlNodePtr attributeNode = node->children; attributeNode; attributeNode = attributeNode->next) { if(!xmlStrcmp(attributeNode->name, (const xmlChar*)"attribute")) { if(readXMLString(attributeNode, "key", strValue)) { std::string tmpStrValue = asLowerCaseString(strValue); if(tmpStrValue == "shooteffect") { if(readXMLString(attributeNode, "value", strValue)) { ShootEffect_t shoot = getShootType(strValue); if(shoot != SHOOT_EFFECT_UNKNOWN) combat->setParam(COMBATPARAM_DISTANCEEFFECT, shoot); else std::clog << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown shootEffect: " << strValue << std::endl; } } else if(tmpStrValue == "areaeffect") { if(readXMLString(attributeNode, "value", strValue)) { MagicEffect_t effect = getMagicEffect(strValue); if(effect != MAGIC_EFFECT_UNKNOWN) combat->setParam(COMBATPARAM_EFFECT, effect); else std::clog << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown areaEffect: " << strValue << std::endl; } } else std::clog << "[Warning - Monsters::deserializeSpells] Effect type \"" << strValue << "\" does not exist." << std::endl; } } } } sb.spell = combatSpell; return true; }
bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, const std::string& description) { std::string name; std::string scriptName; bool isScripted; pugi::xml_attribute attr; if ((attr = node.attribute("script"))) { scriptName = attr.as_string(); isScripted = true; } else if ((attr = node.attribute("name"))) { name = attr.as_string(); isScripted = false; } else { return false; } if ((attr = node.attribute("speed")) || (attr = node.attribute("interval"))) { sb.speed = std::max<int32_t>(1, pugi::cast<int32_t>(attr.value())); } if ((attr = node.attribute("chance"))) { uint32_t chance = pugi::cast<uint32_t>(attr.value()); if (chance > 100) { chance = 100; } sb.chance = chance; } if ((attr = node.attribute("range"))) { uint32_t range = pugi::cast<uint32_t>(attr.value()); if (range > (Map::maxViewportX * 2)) { range = Map::maxViewportX * 2; } sb.range = range; } if ((attr = node.attribute("min"))) { sb.minCombatValue = pugi::cast<int32_t>(attr.value()); } if ((attr = node.attribute("max"))) { sb.maxCombatValue = pugi::cast<int32_t>(attr.value()); //normalize values if (std::abs(sb.minCombatValue) > std::abs(sb.maxCombatValue)) { int32_t value = sb.maxCombatValue; sb.maxCombatValue = sb.minCombatValue; sb.minCombatValue = value; } } if (auto spell = g_spells->getSpellByName(name)) { sb.spell = spell; return true; } CombatSpell* combatSpell = nullptr; bool needTarget = false; bool needDirection = false; if (isScripted) { if ((attr = node.attribute("direction"))) { needDirection = attr.as_bool(); } if ((attr = node.attribute("target"))) { needTarget = attr.as_bool(); } std::unique_ptr<CombatSpell> combatSpellPtr(new CombatSpell(nullptr, needTarget, needDirection)); if (!combatSpellPtr->loadScript("data/" + g_spells->getScriptBaseName() + "/scripts/" + scriptName)) { return false; } if (!combatSpellPtr->loadScriptCombat()) { return false; } combatSpell = combatSpellPtr.release(); combatSpell->getCombat()->setPlayerCombatValues(COMBAT_FORMULA_DAMAGE, sb.minCombatValue, 0, sb.maxCombatValue, 0); } else { Combat* combat = new Combat; if ((attr = node.attribute("length"))) { int32_t length = pugi::cast<int32_t>(attr.value()); if (length > 0) { int32_t spread = 3; //need direction spell if ((attr = node.attribute("spread"))) { spread = std::max<int32_t>(0, pugi::cast<int32_t>(attr.value())); } AreaCombat* area = new AreaCombat(); area->setupArea(length, spread); combat->setArea(area); needDirection = true; } } if ((attr = node.attribute("radius"))) { int32_t radius = pugi::cast<int32_t>(attr.value()); //target spell if ((attr = node.attribute("target"))) { needTarget = attr.as_bool(); } AreaCombat* area = new AreaCombat(); area->setupArea(radius); combat->setArea(area); } std::string tmpName = asLowerCaseString(name); if (tmpName == "melee") { sb.isMelee = true; pugi::xml_attribute attackAttribute, skillAttribute; if ((attackAttribute = node.attribute("attack")) && (skillAttribute = node.attribute("skill"))) { sb.minCombatValue = 0; sb.maxCombatValue = -Weapons::getMaxMeleeDamage(pugi::cast<int32_t>(skillAttribute.value()), pugi::cast<int32_t>(attackAttribute.value())); } ConditionType_t conditionType = CONDITION_NONE; int32_t minDamage = 0; int32_t maxDamage = 0; uint32_t tickInterval = 2000; if ((attr = node.attribute("fire"))) { conditionType = CONDITION_FIRE; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 9000; } else if ((attr = node.attribute("poison"))) { conditionType = CONDITION_POISON; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 5000; } else if ((attr = node.attribute("energy"))) { conditionType = CONDITION_ENERGY; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 10000; } else if ((attr = node.attribute("drown"))) { conditionType = CONDITION_DROWN; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 5000; } else if ((attr = node.attribute("freeze"))) { conditionType = CONDITION_FREEZING; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 8000; } else if ((attr = node.attribute("dazzle"))) { conditionType = CONDITION_DAZZLED; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 10000; } else if ((attr = node.attribute("curse"))) { conditionType = CONDITION_CURSED; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 4000; } else if ((attr = node.attribute("bleed")) || (attr = node.attribute("physical"))) { conditionType = CONDITION_BLEEDING; tickInterval = 5000; } if ((attr = node.attribute("tick"))) { int32_t value = pugi::cast<int32_t>(attr.value()); if (value > 0) { tickInterval = value; } } if (conditionType != CONDITION_NONE) { Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, 0, tickInterval); combat->setCondition(condition); } sb.range = 1; combat->setParam(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE); combat->setParam(COMBAT_PARAM_BLOCKARMOR, 1); combat->setParam(COMBAT_PARAM_BLOCKSHIELD, 1); combat->setOrigin(ORIGIN_MELEE); } else if (tmpName == "physical") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE); combat->setParam(COMBAT_PARAM_BLOCKARMOR, 1); combat->setOrigin(ORIGIN_RANGED); } else if (tmpName == "bleed") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE); } else if (tmpName == "poison" || tmpName == "earth") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE); } else if (tmpName == "fire") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE); } else if (tmpName == "energy") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE); } else if (tmpName == "drown") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE); } else if (tmpName == "ice") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE); } else if (tmpName == "holy") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE); } else if (tmpName == "death") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE); } else if (tmpName == "lifedrain") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN); } else if (tmpName == "manadrain") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_MANADRAIN); } else if (tmpName == "healing") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_HEALING); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); } else if (tmpName == "speed") { int32_t speedChange = 0; int32_t duration = 10000; if ((attr = node.attribute("duration"))) { duration = pugi::cast<int32_t>(attr.value()); } if ((attr = node.attribute("speedchange"))) { speedChange = pugi::cast<int32_t>(attr.value()); if (speedChange < -1000) { //cant be slower than 100% speedChange = -1000; } } ConditionType_t conditionType; if (speedChange > 0) { conditionType = CONDITION_HASTE; combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); } else { conditionType = CONDITION_PARALYZE; } ConditionSpeed* condition = static_cast<ConditionSpeed*>(Condition::createCondition(CONDITIONID_COMBAT, conditionType, duration, 0)); condition->setFormulaVars(speedChange / 1000.0, 0, speedChange / 1000.0, 0); combat->setCondition(condition); } else if (tmpName == "outfit") { int32_t duration = 10000; if ((attr = node.attribute("duration"))) { duration = pugi::cast<int32_t>(attr.value()); } if ((attr = node.attribute("monster"))) { MonsterType* mType = g_monsters.getMonsterType(attr.as_string()); if (mType) { ConditionOutfit* condition = static_cast<ConditionOutfit*>(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0)); condition->setOutfit(mType->outfit); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); combat->setCondition(condition); } } else if ((attr = node.attribute("item"))) { Outfit_t outfit; outfit.lookTypeEx = pugi::cast<uint16_t>(attr.value()); ConditionOutfit* condition = static_cast<ConditionOutfit*>(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0)); condition->setOutfit(outfit); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); combat->setCondition(condition); } } else if (tmpName == "invisible") { int32_t duration = 10000; if ((attr = node.attribute("duration"))) { duration = pugi::cast<int32_t>(attr.value()); } Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration, 0); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); combat->setCondition(condition); } else if (tmpName == "drunk") { int32_t duration = 10000; if ((attr = node.attribute("duration"))) { duration = pugi::cast<int32_t>(attr.value()); } Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration, 0); combat->setCondition(condition); } else if (tmpName == "firefield") { combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_FIREFIELD_PVP_FULL); } else if (tmpName == "poisonfield") { combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_POISONFIELD_PVP); } else if (tmpName == "energyfield") { combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_ENERGYFIELD_PVP); } else if (tmpName == "firecondition" || tmpName == "energycondition" || tmpName == "earthcondition" || tmpName == "poisoncondition" || tmpName == "icecondition" || tmpName == "freezecondition" || tmpName == "deathcondition" || tmpName == "cursecondition" || tmpName == "holycondition" || tmpName == "dazzlecondition" || tmpName == "drowncondition" || tmpName == "bleedcondition" || tmpName == "physicalcondition") { ConditionType_t conditionType = CONDITION_NONE; uint32_t tickInterval = 2000; if (tmpName == "firecondition") { conditionType = CONDITION_FIRE; tickInterval = 10000; } else if (tmpName == "poisoncondition" || tmpName == "earthcondition") { conditionType = CONDITION_POISON; tickInterval = 5000; } else if (tmpName == "energycondition") { conditionType = CONDITION_ENERGY; tickInterval = 10000; } else if (tmpName == "drowncondition") { conditionType = CONDITION_DROWN; tickInterval = 5000; } else if (tmpName == "freezecondition" || tmpName == "icecondition") { conditionType = CONDITION_FREEZING; tickInterval = 10000; } else if (tmpName == "cursecondition" || tmpName == "deathcondition") { conditionType = CONDITION_CURSED; tickInterval = 4000; } else if (tmpName == "dazzlecondition" || tmpName == "holycondition") { conditionType = CONDITION_DAZZLED; tickInterval = 10000; } else if (tmpName == "physicalcondition" || tmpName == "bleedcondition") { conditionType = CONDITION_BLEEDING; tickInterval = 5000; } if ((attr = node.attribute("tick"))) { int32_t value = pugi::cast<int32_t>(attr.value()); if (value > 0) { tickInterval = value; } } int32_t minDamage = std::abs(sb.minCombatValue); int32_t maxDamage = std::abs(sb.maxCombatValue); int32_t startDamage = 0; if ((attr = node.attribute("start"))) { int32_t value = std::abs(pugi::cast<int32_t>(attr.value())); if (value <= minDamage) { startDamage = value; } } Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, startDamage, tickInterval); combat->setCondition(condition); } else if (tmpName == "strength") { // } else if (tmpName == "effect") { // } else { std::cout << "[Error - Monsters::deserializeSpell] - " << description << " - Unknown spell name: " << name << std::endl; delete combat; return false; } combat->setPlayerCombatValues(COMBAT_FORMULA_DAMAGE, sb.minCombatValue, 0, sb.maxCombatValue, 0); combatSpell = new CombatSpell(combat, needTarget, needDirection); for (auto attributeNode : node.children()) { if ((attr = attributeNode.attribute("key"))) { const char* value = attr.value(); if (strcasecmp(value, "shooteffect") == 0) { if ((attr = attributeNode.attribute("value"))) { ShootType_t shoot = getShootType(attr.as_string()); if (shoot != CONST_ANI_NONE) { combat->setParam(COMBAT_PARAM_DISTANCEEFFECT, shoot); } else { std::cout << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown shootEffect: " << attr.as_string() << std::endl; } } } else if (strcasecmp(value, "areaeffect") == 0) { if ((attr = attributeNode.attribute("value"))) { MagicEffectClasses effect = getMagicEffect(attr.as_string()); if (effect != CONST_ME_NONE) { combat->setParam(COMBAT_PARAM_EFFECT, effect); } else { std::cout << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown areaEffect: " << attr.as_string() << std::endl; } } } else { std::cout << "[Warning - Monsters::deserializeSpells] Effect type \"" << attr.as_string() << "\" does not exist." << std::endl; } } } } sb.spell = combatSpell; if (combatSpell) { sb.combatSpell = true; } return true; }
/****************************************************************** **Function: choice **Description:Creates the appropriate monsters based on user choice and passes to game. **Parameters:&option, &option2, &game **Pre-Conditions: Game must be created **Post-Conditions: Monsters will be put into attack function from Combat class ********************************************************************/ void choice(int &option1, int &option2, Combat &game) { Barbarian *barb = new Barbarian; Barbarian *barb2 = new Barbarian; Blue *blue = new Blue; Blue *blue2 = new Blue; Goblin *goblin = new Goblin; Goblin *goblin2 = new Goblin; Reptile *reptile = new Reptile; Reptile *reptile2 = new Reptile; Shadow *shadow = new Shadow; Shadow *shadow2 = new Shadow; if (option1 == 1 && option2 == 1) game.attack1(barb, barb2); else if (option1 == 1 && option2 == 2) game.attack1(barb, blue); else if (option1 == 1 && option2 == 3) game.attack1(barb, reptile); else if (option1 == 1 && option2 == 4) game.attack1(barb, goblin); else if (option1 == 1 && option2 == 5) game.attack1(barb, shadow); else if (option1 == 2 && option2 == 1) game.attack1(blue, barb); else if (option1 == 2 && option2 == 2) game.attack1(blue, blue2); else if (option1 == 2 && option2 == 3) game.attack1(blue, reptile); else if (option1 == 2 && option2 == 4) game.attack1(blue, goblin); else if (option1 == 2 && option2 == 5) game.attack1(blue, shadow); else if (option1 == 3 && option2 == 1) game.attack1(reptile, barb); else if (option1 == 3 && option2 == 2) game.attack1(reptile, blue); else if (option1 == 3 && option2 == 3) game.attack1(reptile, reptile2); else if (option1 == 3 && option2 == 4) game.attack1(reptile, goblin); else if (option1 == 3 && option2 == 5) game.attack1(reptile, shadow); else if (option1 == 4 && option2 == 1) game.attack1(goblin, barb); else if (option1 == 4 && option2 == 2) game.attack1(goblin, blue); else if (option1 == 4 && option2 == 3) game.attack1(goblin, reptile); else if (option1 == 4 && option2 == 4) game.attack1(goblin, goblin2); else if (option1 == 4 && option2 == 5) game.attack1(goblin, shadow); else if (option1 == 5 && option2 == 1) game.attack1(shadow, barb); else if (option1 == 5 && option2 == 2) game.attack1(shadow, blue); else if (option1 == 5 && option2 == 3) game.attack1(shadow, reptile); else if (option1 == 5 && option2 == 4) game.attack1(shadow, goblin); else if (option1 == 5 && option2 == 5) game.attack1(shadow, shadow2); }