Esempio n. 1
0
bool Player::meleeAttack(sf::Vector2i position) {
	for (int a = 0; a < (*npcs).size(); a++) {
		if ((*npcs)[a].getPosition() == position) {
			(*npcs)[a].takeDamage(calculateDamage(stats, (*npcs)[a].getStats()));
			return true;
		}
	}
	return false;
}
//一列に並んだボールがあるかチェックする
void GameLayer::checksLinedBalls()
{
    //画面をタップ不可とする
    _touchable = false;
    
    if (existsLinedBalls())
    {
        //3個以上並んだボールの存在する場合
        
        //連鎖カウントアップ
        _chainNumber++;
        
        //ボールの削除と生成
        removeAndGenerateBalls();
        
        //アニメーション後に再チェック
        auto delay = DelayTime::create(ONE_ACTION_TIME * (_maxRemovedNo + 1));
        auto func = CallFunc::create(CC_CALLBACK_0(GameLayer::checksLinedBalls, this));
        auto seq = Sequence::create(delay, func, nullptr);
        runAction(seq);
    }
    else
    {
        int chainNum = 0;
        int damage = 0;
        int healing = 0;
        std::set<int> attackers;
        
        //ダメージ・回復量の計算
        calculateDamage(chainNum, healing, damage, attackers);
        
        //敵にダメージを与える
        int afterHp = _enemyData->getHp() - damage;
        
        if (damage > 0)
            //アタック処理
            attackToEnemy(damage, attackers);
        
        if (healing > 0)
            //回復処理
            healMember(healing);
        
        //敵にダメージを与えた後の処理を設定
        CallFunc* func;
        if (afterHp <= 0)
            func = CallFunc::create(CC_CALLBACK_0(GameLayer::winAnimation, this));
        else
            func = CallFunc::create(CC_CALLBACK_0(GameLayer::attackFromEnemy, this));
        
        runAction(Sequence::create(DelayTime::create(0.5), func, nullptr));
    }
}
Esempio n. 3
0
//Initiates the attack action between the two Characters.
//Pre:  Both characters have been loaded.
//Post: The initiator's attack is checked against the
//      receiver's defense. The attack that is leftover
//      after the defense is subtracted is then reduced
//      from the receiver's hitpoints. If the HP are reduced
//      to 0 or below, the Character will be dead.
void ShieldBash::execute(){

    if(initiator == NULL || receiver == NULL)
        return;

    //Determines the damage to the receiver.
    calculateDamage();

    //Remove receiver's hitpoints.
    receiver->addToRemainingHP(-damageToReceiver);

    loadAnimations();
}
void BattleManager::applyDamage(Actor* caster, DamageAbility* damageAbility, Actor* target)
{
	if (caster->getAbility(damageAbility->getName())->getCost() <= caster->getResource())
	{
		int targetArmor;
		if (target->getAttribute(BONUS_ARMOR) == nullptr && target->getAttribute(BONUS_ARMOR) == nullptr)
			targetArmor = target->getAttribute(ARMOR)->getValue();
		else{
			targetArmor = target->getAttribute(ARMOR)->getValue();
		}

		//full damage da ability tendo em conta as stats do player
		int abilityDamage = damageAbility->getFullDamage(caster);
		caster->changeResource(-(damageAbility->getCost()));

		target->takeDamage(calculateDamage(targetArmor, abilityDamage));
		caster->update();
	}
}
Esempio n. 5
0
void pkCU::evaluateMove_damage()
{
	assert(getStackStage() == STAGE_MOVEBASE);
	assert(getTPKV().isAlive() && getPKV().isAlive());

	// the floor of the stack: everything below this stack value has been evaluated
	size_t baseFloor = iBase, baseCeil = getStack().size();

	const pokemon_nonvolatile& cPKNV = getPKNV();
	const pokemon_nonvolatile& tPKNV = getTPKNV();
	const move_nonvolatile& cMNV = cPKNV.getMove(getICAction());
	const pokemon_base& cPKB = cPKNV.getBase();
	const pokemon_base& tPKB = tPKNV.getBase();
	const move& cMove = cMNV.getBase();
	
	//Source: http://www.smogon.com/dp/articles/damage_formula

	/*BasePower = HH × BP × IT × CHG × (MS × WS) × UA × FA*/
	// set basePower:
	//for (/*iBase = baseFloor, baseCeil = getStack().size()*/; iBase != baseCeil; ++iBase)
	{
		//if (getStackStage() != STAGE_MOVEBASE) { continue; }
		advanceStackStage();

		uint32_t& basePower = getDamageComponent().damage;
		basePower = cMove.getPower();

		int result = (basePower != UINT8_MAX)?1:0;
		CALLPLUGIN(result, PLUGIN_ON_SETBASEPOWER, onSetPower_rawType, 
			*this, cMNV, cPKNV, tPKNV, getTMV(), getTTMV(), getPKV(), getTPKV(), basePower);

		assert(result > 0 && basePower > 0);
	}

	// calculate this move's type:
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_SETBASEPOWER) { continue; }
		advanceStackStage();

		const type*& cType = getDamageComponent().mType;
		cType = &cMove.getType();

		int result = 0;
		CALLPLUGIN(result, PLUGIN_ON_SETMOVETYPE, onModifyMoveType_rawType, 
			*this, cMNV, cPKNV, tPKNV, getTMV(), getTTMV(), getPKV(), getTPKV(), cType);
	}

	// modify basePower:
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_SETMOVETYPE) { continue; }
		advanceStackStage();

		uint32_t& basePower = getDamageComponent().damage;
		fpType baseModifier = 1.0;

		int result = 0;
		CALLPLUGIN(result, PLUGIN_ON_MODIFYBASEPOWER, onModifyPower_rawType, 
			*this, cMNV, cPKNV, tPKNV, getTMV(), getTTMV(), getPKV(), getTPKV(), baseModifier);

		basePower = (uint32_t)(basePower * baseModifier);
	}

	// calculate attack and damage modifiers:
	uint32_t levelModifier = ((cPKNV.getLevel() * 2) / 5) + 2;
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_MODIFYBASEPOWER) { continue; }
		advanceStackStage();

		damageComponents_t& cDamage = getDamageComponent();

		size_t attackType;
		size_t defenseType;
		if (cMove.getDamageType() == ATK_PHYSICAL)
		{ attackType = FV_ATTACK; defenseType = FV_DEFENSE; }
		else
		{ attackType = FV_SPATTACK; defenseType = FV_SPDEFENSE; }

		uint32_t attackPower = getTMV().cGetFV_boosted(cPKNV, attackType);
		uint32_t attackPowerCrit = std::max(cPKNV.getFV_base(attackType), attackPower);

		uint32_t defensePower = getTTMV().cGetFV_boosted(tPKNV, defenseType);
		uint32_t defensePowerCrit = std::min(tPKNV.getFV_base(defenseType), defensePower);

		// calculate crit first:
		cDamage.damageCrit = ((levelModifier * cDamage.damage * attackPowerCrit) / 50) / defensePowerCrit;
		// and regular damage:
		cDamage.damage = ((levelModifier * cDamage.damage * attackPower) / 50) / defensePower;


		/* Mod1 = BRN × RL × TVT × SR × FF */
		// modifier1:
		fpType attackPowerModifier = 1.0;

		int result = 0;
		CALLPLUGIN(result, PLUGIN_ON_MODIFYATTACKPOWER, onModifyPower_rawType, 
			*this, cMNV, cPKNV, tPKNV, getTMV(), getTTMV(), getPKV(), getTPKV(), attackPowerModifier);

		// incorporate attack power modifier:
		cDamage.damage = (uint32_t)(cDamage.damage * attackPowerModifier) + 2;
		cDamage.damageCrit = (uint32_t)(cDamage.damageCrit * attackPowerModifier) + 2;
	}

	// calculate critical hit modifiers:
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_MODIFYATTACKPOWER) { continue; }
		advanceStackStage();

		damageComponents_t& cDamage = getDamageComponent();

		/* CH - Critical Hit modifier
			3 if has sniper ability AND critical hit (mult 1.5)
			2 if critical hit (mult 1.0)
			1 else
		 */
		fpType criticalHitModifier = 2.0;
		int result = 0;
		CALLPLUGIN(result, PLUGIN_ON_MODIFYCRITICALPOWER, onModifyPower_rawType, 
			*this, cMNV, cPKNV, tPKNV, getTMV(), getTTMV(), getPKV(), getTPKV(), criticalHitModifier);

		// incorporate critical power modifier:
		cDamage.damageCrit = (uint32_t)(cDamage.damageCrit * criticalHitModifier);
	}

	// calculate raw damage modifiers:
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_MODIFYCRITICALPOWER) { continue; }
		advanceStackStage();

		damageComponents_t& cDamage = getDamageComponent();

		/* Mod2 = Other modifier
			1.3 if item = life orb
			1+.1*n if item = metronome and used the same move n previous times, to a max of n=10
			1.5 if attacking with Me First and attacks first (NOTE: SPECIAL BEHAVIOR with life orb / metronome!)
			1 else
		 */
		fpType rawDamageMultiplier = 1.0;
		int result = 0;
		CALLPLUGIN(result, PLUGIN_ON_MODIFYRAWDAMAGE, onModifyPower_rawType, 
			*this, cMNV, cPKNV, tPKNV, getTMV(), getTTMV(), getPKV(), getTPKV(), rawDamageMultiplier);

		// incorporate critical power modifier:
		cDamage.damage = (uint32_t)(cDamage.damage * rawDamageMultiplier);
		cDamage.damageCrit = (uint32_t)(cDamage.damageCrit * rawDamageMultiplier);
	}

	// calculate this move's STAB:
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_MODIFYRAWDAMAGE) { continue; }
		advanceStackStage();

		damageComponents_t& cDamage = getDamageComponent();

		bool hasStab = ((&cPKB.getType(0) == cDamage.mType) || (&cPKB.getType(1) == cDamage.mType));
		fpType STABMultiplier = hasStab?1.5:1.0;
		int result = 0;
		CALLPLUGIN(result, PLUGIN_ON_MODIFYSTAB, onModifyPower_rawType, 
			*this, cMNV, cPKNV, tPKNV, getTMV(), getTTMV(), getPKV(), getTPKV(), STABMultiplier);

		// incorporate STAB modifier:
		cDamage.damage = (uint32_t)(cDamage.damage * STABMultiplier);
		cDamage.damageCrit = (uint32_t)(cDamage.damageCrit * STABMultiplier);
	}

	// calculate the enemy pokemon's type resistance:
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_MODIFYSTAB) { continue; }
		advanceStackStage();

		damageComponents_t& cDamage = getDamageComponent();

		fpType typeModifier = 1.0;
		{
			// type1:
			typeModifier *= cDamage.mType->getModifier(tPKB.getType(0));
			// type 2:
			typeModifier *= cDamage.mType->getModifier(tPKB.getType(1));
		}
		int result = 0;
		CALLPLUGIN(result, PLUGIN_ON_SETDEFENSETYPE, onModifyTypePower_rawType, 
			*this, cMNV, cPKNV, tPKNV, *cDamage.mType, getTMV(), getTTMV(), getPKV(), getTPKV(), typeModifier);

		// incorporate type modifier:
		cDamage.damage = (uint32_t)(cDamage.damage * typeModifier);
		cDamage.damageCrit = (uint32_t)(cDamage.damageCrit * typeModifier);
	}

	// calculate item resistance modifiers:
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_MODIFYTYPERESISTANCE) { continue; }
		advanceStackStage();

		damageComponents_t& cDamage = getDamageComponent();

		/* Mod3 = SRF × EB × TL × TRB */
		fpType itemModifier = 1.0;
		int result = 0;
		CALLPLUGIN(result, PLUGIN_ON_MODIFYITEMPOWER, onModifyPower_rawType, 
			*this, cMNV, cPKNV, tPKNV, getTMV(), getTTMV(), getPKV(), getTPKV(), itemModifier);

		// incorporate type modifier:
		cDamage.damage = (uint32_t)(cDamage.damage * itemModifier);
		cDamage.damageCrit = (uint32_t)(cDamage.damageCrit * itemModifier);
	}

	/* Damage Formula = (((((((Level × 2 ÷ 5) + 2) × BasePower × [Sp]Atk ÷ 50) ÷ [Sp]Def) × Mod1) + 2) × CH × Mod2 × R ÷ 100) × STAB × Type1 × Type2 × Mod3 */

	// calculate probability to hit, miss:
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_MODIFYITEMPOWER) { continue; }
		advanceStackStage();

		fpType& probabilityToHit = getDamageComponent().tProbability;

		/* probability to hit enemy pokemon */
		probabilityToHit = 
				getTMV().cGetAccuracy_boosted(FV_ACCURACY) // lowest is 33% or 1/3
				* getTTMV().cGetAccuracy_boosted(FV_EVASION) // highest is 300% or 3
				* cMove.getPrimaryAccuracy(); // lowest is 30%

		// to-hit modifying values:
		int result = 0;
		CALLPLUGIN(result, PLUGIN_ON_MODIFYHITPROBABILITY, onModifyPower_rawType, 
			*this, cMNV, cPKNV, tPKNV, getTMV(), getTTMV(), getPKV(), getTPKV(), probabilityToHit);

	}

	// evaluate miss(1), hit(0):
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_MODIFYHITCHANCE) { continue; }
		advanceStackStage();

		fpType& probabilityToHit = getDamageComponent().tProbability;

		// bound at MIN 0.033~ ... MAX 1.0
		probabilityToHit = std::max(std::min(probabilityToHit, (fpType)1.0), (fpType)0.0);

		boost::array<size_t, 2> iHEnv = {{ getIBase(), SIZE_MAX }};
		// did the move hit its target? Is it possible for the move to miss?
		if (mostlyGT(probabilityToHit, 0.0))
		{
			// if there's a chance the primary effect will not occur:
			if (mostlyLT(probabilityToHit, 1.0))
			{
				// duplicate the environment (duplicated environment is the miss environment):
				duplicateState(iHEnv, (1.0 - probabilityToHit));
			}

			// modify bitmask as the hit effect occuring:
			getStack()[iHEnv[0]].setHit(getICTeam());

		} // end of primary attack hits, and secondary attack is not assured
		else
		{
			// pass-through: no chance to hit or crit
			stackStage[iBase] = STAGE_POSTDAMAGE;
		}
	}

	// calculate probability to crit:
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_EVALUATEHITCHANCE) { continue; }
		advanceStackStage();

		// don't continue to evaluate a stage that has not hit the enemy team:
		if (!getBase().hasHit(getICTeam())) { stackStage[iBase] = STAGE_POSTDAMAGE; continue; }

		fpType& probabilityToCrit = getDamageComponent().tProbability;

		/* Probability to critical hit, if the move has already hit */
		probabilityToCrit = 
			getTMV().cGetAccuracy_boosted(FV_CRITICALHIT);

		// to-crit modifying values:
		int result = 0;
		CALLPLUGIN(result, PLUGIN_ON_MODIFYCRITPROBABILITY, onModifyPower_rawType, 
			*this, cMNV, cPKNV, tPKNV, getTMV(), getTTMV(), getPKV(), getTPKV(), probabilityToCrit);
	}

	// evaluate crit(2):
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_MODIFYCRITCHANCE) { continue; }
		advanceStackStage();

		fpType& probabilityToCrit = getDamageComponent().tProbability;

		// determine the possibility that the move crit:
		boost::array<size_t, 2> iCEnv = {{ SIZE_MAX, getIBase() }};
		
		if (mostlyGT(probabilityToCrit, 0.0) )
		{
			if (mostlyLT(probabilityToCrit, 1.0))
			{
				// duplicate the environment (duplicated environment is the crit environment):
				duplicateState(iCEnv, probabilityToCrit);
			}

			// modify bitmask as the crit effect occuring:
			getStack()[iCEnv[1]].setCrit(getICTeam());
		}
		// even with no chance to crit there's still the possibility of damage
	}

	// perform actual damage calculation
	for (iBase = baseFloor, baseCeil = getStack().size(); iBase != baseCeil; ++iBase)
	{
		if (getStackStage() != STAGE_PREDAMAGE) { continue; }
		advanceStackStage();

		if (!getBase().hasHit(getICTeam())) { continue; }

		calculateDamage(getBase().hasCrit(getICTeam()));
	}
} // end of evaluateMove_damage