예제 #1
0
	void PlayerShip::hit(DamagePackage& pack, GameObject* hitter, GameObject* child, float distance, double time){
		//DamagePackage& pack = hitter->getDamagePackage();
		if (pack.getDamageCycle() == DAM_CYCLE_INSTANT){
			if (mInvulnerabilityTimer == 0){
				takeDamage(pack, time);
				mLevelSegment->getActiveCamera()->shake();
				mInvulnerabilityTimer = .5;
			}
		}else if (pack.getDamageCycle() == DAM_CYCLE_CONTINUOUS){
				takeDamage(pack, time);
				mLevelSegment->getActiveCamera()->shake(2);
		}else{
			throw("Damage Cycle Unknown "+hitter->getId());
		}
	}
예제 #2
0
bool BarrierTile::strikeWith(Bullet &bullet){
    if (health && bullet.isAlive() && sprite.getGlobalBounds().intersects(bullet.getSprite().getGlobalBounds())) {
        takeDamage();
        bullet.kill();
        return true;
    }
    return false;
}
void ArmyAntQueen::defend(Animal* opponent, int damage) {
  takeDamage(damage);
  // Implement revenge function, all other Ants deal 2 unblockable damage.
  for (int i = 0; i < 5; ++i) {
    if (allies[i]->getName() == "Army Ant" && !(allies[i]->isDead()))
      opponent->takeDamage(2);
  }
}
예제 #4
0
static void touch(Entity *other)
{
	if (other->flags & ATTACKING)
	{
		takeDamage(other, other->damage);
	}

	if (self->inUse == TRUE && self->touch != NULL)
	{
		pushEntity(other);
	}
}
예제 #5
0
파일: Mob.cpp 프로젝트: ADFLin/QuadAssault
void Mob::onBodyCollision( ColBody& self , ColBody& other )
{
	LevelObject* obj = other.getClient();
	switch( obj->getType() )
	{
	case OT_BULLET:
		{
			Bullet* bullet = obj->cast< Bullet >();
			if ( bullet->team == TEAM_PLAYER )
			{
				takeDamage( bullet );
			}
		}
		break;
	}	
}
예제 #6
0
//------------------------------------------------------------------------------
void
Cloud::collide( Entity * entity, b2ContactPoint * point )
{
    if ( getFriend() || entity->getType() != Bullet::TYPE )
    {
        return;
    }
    if ( entity->getBlack() != getBlack() || m_size == 0 )
    {
        takeDamage( DAMAGE[ m_size ] );
    }
    else if ( m_size > 0 && m_size < 4 )
    {
        addStrength( DAMAGE[ m_size + 1 ] );
    }
    entity->destroy();
}
예제 #7
0
파일: vines.c 프로젝트: LibreGames/edgar
static void touch(Entity *other)
{
	if (strcmpignorecase(other->name, "weapon/flaming_arrow") == 0)
	{
		self->active = TRUE;

		other->inUse = FALSE;
	}

	else if ((other->flags & ATTACKING) && !(self->flags & INVULNERABLE))
	{
		takeDamage(other, other->damage);
	}

	else
	{
		pushEntity(other);
	}
}
예제 #8
0
void			Player::Update()
{
  _deltaTime = indie::GameManager::getDeltaTime();
  _movement = false;
  _attack = false;

  if (_dead)
    {
      death();
      return;
    }

  // For debug purpose
  if (_im->getKeyDown(OIS::KC_P))
    takeDamage(10);

  _handleController();
  _handleCamera();
  _handleOrientation();
  _handleAnimations();
}
예제 #9
0
void CPlayer::move()
{
	//x pos
	if (!playerLocked)
	{
		if (!shooting && !(breaking && landed))
		{
			if (getPressed(input, 0) && velocityX >= -5)
			{
				velocityX -= 0.3;
			}
			else if (getPressed(input, 1) && velocityX <= 5)
			{
				velocityX += 0.3;
			}
		}

		//y pos
		if (getPressed(input, 2) && jumpDurration < jumpMaxDurration)
		{
			if (landed && image->getX() / 40 >= 0 && image->getX() / 40 < world->getWidth() && image->getY() / 40 - 1 >= 0 && image->getY() / 40 - 1 < world->getHeight())
			{
				if (world->getBlock(image->getX() / 40, image->getY() / 40 - 1)->getPassable())
				{
					velocityY = -5;
					jumpDurration++;
					if (landed)
						jumpedLast = SDL_GetTicks();
				}
			}
			else if (landed && image->getX() / 40 + 1 >= 0 && image->getX() / 40 + 1 < world->getWidth() && image->getY() / 40 - 1 >= 0 && image->getY() / 40 - 1 < world->getHeight())
			{
				if (world->getBlock(image->getX() / 40 + 1, image->getY() / 40 - 1)->getPassable())
				{
					velocityY = -5;
					jumpDurration++;
					if (landed)
						jumpedLast = SDL_GetTicks();
				}
			}
			else
			{
				velocityY = -5;
				jumpDurration++;
				if (landed)
					jumpedLast = SDL_GetTicks();
			}
		}
		if (!getPressed(input, 2) && !landed)
		{
			jumpDurration = jumpMaxDurration + 1;
		}
		if (landed)
			jumpDurration = 0;

		if (!landed && getPressed(input, 2) && touchingRight && jumpDurration > jumpMaxDurration && jumpedLast + 200 < SDL_GetTicks())
		{
			velocityY = -5;
			velocityX = -6;
			jumpDurration = 0;
			jumpedLast = SDL_GetTicks();
		}
		else if (!landed && getPressed(input, 2) && touchingLeft && jumpDurration > jumpMaxDurration && jumpedLast + 200 < SDL_GetTicks())
		{
			velocityY = -5;
			velocityX = 6;
			jumpDurration = 0;
			jumpedLast = SDL_GetTicks();
		}
	}
	//gravity and friction
	if (((!getPressed(input, 0) && !getPressed(input, 1)) | shooting | breaking | playerLocked) && landed)
	{
		if (velocityX > 0)
			velocityX -= 0.3;
		else if (velocityX < 0)
			velocityX += 0.3;
		if (abs(velocityX) < 0.3)
			velocityX = 0;
	}
	velocityY += gravity;
	if (velocityY > 40)
		velocityY = 40;

	//x pos wall collisions
	image->setX(image->getX() + velocityX);
	
	for (int y = image->getY() / 40; y < (image->getY() / 40) + 2; y++)
	{
		for (int x = image->getX() / 40; x < (image->getX() / 40) + 2; x++)
		{
			if (x >= 0 && x < world->getWidth() && y >= 0 && y < world->getHeight())
			{
				if (!(image->getX() + image->getW() <= world->getBlock(x, y)->getRect().x || world->getBlock(x, y)->getRect().x + world->getBlock(x, y)->getRect().w <= image->getX() || image->getY() + image->getH() <= world->getBlock(x, y)->getRect().y || world->getBlock(x, y)->getRect().y + world->getBlock(x, y)->getRect().h <= image->getY()))
				{
					//solid block mechanics
					if (!world->getBlock(x, y)->getPassable())
					{
						if (velocityX > 0) { image->setX(world->getBlock(x, y)->getRect().x - image->getW()); }
						if (velocityX < 0) { image->setX(world->getBlock(x, y)->getRect().x + world->getBlock(x, y)->getRect().w); }
						velocityX = 0;
					}
					// waterfall mechanics
					if (world->getBlock(x, y)->getType() == 7)
					{
						if (velocityX > 3 && !landed)
							velocityX--;
						else if (velocityX < -3 && !landed)
							velocityX++;
						if (velocityY > 3)
							velocityY--;
						else if (velocityY < -3)
							velocityY++;
					}
				}
			}
		}
	}

	touchingLeft = false;
	touchingRight = false;
	if (image->getX() / 40 - 1 >= 0 && image->getX() / 40 - 1 < world->getWidth() && image->getY() / 40 >= 0 && image->getY() / 40 < world->getHeight())
	{
		if (image->getX() == world->getBlock(image->getX() / 40 - 1, image->getY() / 40)->getRect().x + world->getBlock(image->getX() / 40 - 1, image->getY() / 40)->getRect().w && !world->getBlock(image->getX() / 40 - 1, image->getY() / 40)->getPassable())
			touchingLeft = true;
	}
	if (image->getX() / 40 + 1 >= 0 && image->getX() / 40 + 1 < world->getWidth() && image->getY() / 40 >= 0 && image->getY() / 40 < world->getHeight())
	{
		if (image->getX() + image->getW() == world->getBlock(image->getX() / 40 + 1, image->getY() / 40)->getRect().x && !world->getBlock(image->getX() / 40 + 1, image->getY() / 40)->getPassable())
			touchingRight = true;
	}

	//y pos ground and celling collisions
	image->setY(image->getY() + velocityY);

	for (int y = image->getY() / 40; y < (image->getY() / 40) + 2; y++)
	{
		for (int x = image->getX() / 40; x < (image->getX() / 40) + 2; x++)
		{
			if (x >= 0 && x < world->getWidth() && y >=0 && y < world->getHeight())
			{
				if (!world->getBlock(x, y)->getPassable() && !(image->getX() + image->getW() <= world->getBlock(x, y)->getRect().x || world->getBlock(x, y)->getRect().x + world->getBlock(x, y)->getRect().w <= image->getX() || image->getY() + image->getH() <= world->getBlock(x, y)->getRect().y || world->getBlock(x, y)->getRect().y + world->getBlock(x, y)->getRect().h <= image->getY()))
				{
					if (velocityY > 0)
					{
						image->setY(world->getBlock(x, y)->getRect().y - image->getH());
						if (velocityY > 10)
							takeDamage(velocityY - 10);
						velocityY = 0;
					}
					if (velocityY < 0)
					{
						image->setY(world->getBlock(x, y)->getRect().y + world->getBlock(x, y)->getRect().h);
						velocityY = 0;
						jumpDurration = jumpMaxDurration;
					}
				}
			}
		}
	}
	
	bool wasLanded = landed;
	landed = false; //makes sure to check everytime
	if ((image->getY() / 40) + 1 < world->getHeight() && (image->getY() / 40) + 1 >= 0 && image->getX() / 40 < world->getWidth() && image->getX() / 40 >= 0)
	{
		if (image->getY() + image->getH() == world->getBlock(image->getX() / 40, (image->getY() / 40) + 1)->getRect().y && !world->getBlock(image->getX() / 40, (image->getY() / 40) + 1)->getPassable())
			landed = true;
	}
	if ((image->getY() / 40) + 1 < world->getHeight() && (image->getY() / 40) + 1 >= 0 && image->getX() / 40 + 1 < world->getWidth() && image->getX() / 40 + 1 >= 0 && wasLanded)
	{
		if (image->getY() + image->getH() == world->getBlock(image->getX() / 40 + 1, (image->getY() / 40) + 1)->getRect().y && !world->getBlock(image->getX() / 40 + 1, (image->getY() / 40) + 1)->getPassable())
			landed = true;
	}

	//update players position in world
	world->setPlayerPosition(image->getX(), image->getY());
}
예제 #10
0
/**
 * Process per-frame actions
 */
void StatBlock::logic() {
	alive = !(hp <= 0 && !effects.triggered_death && !effects.revive);

	// handle party buffs
	if (enemym && powers) {
		while (!party_buffs.empty()) {
			int power_index = party_buffs.front();
			party_buffs.pop();
			Power *buff_power = &powers->powers[power_index];

			for (size_t i=0; i < enemym->enemies.size(); ++i) {
				if(enemym->enemies[i]->stats.hp > 0 &&
				   ((enemym->enemies[i]->stats.hero_ally && hero) || (enemym->enemies[i]->stats.enemy_ally && enemym->enemies[i]->stats.summoner == this)) &&
				   (buff_power->buff_party_power_id == 0 || buff_power->buff_party_power_id == enemym->enemies[i]->stats.summoned_power_index)
				) {
					powers->effect(&enemym->enemies[i]->stats, this, power_index, (hero ? Power::SOURCE_TYPE_HERO : Power::SOURCE_TYPE_ENEMY));
				}
			}
		}
	}

	// handle effect timers
	effects.logic();

	// apply bonuses from items/effects to base stats
	applyEffects();

	if (hero && effects.refresh_stats) {
		refresh_stats = true;
		effects.refresh_stats = false;
	}

	// preserve ratio on maxmp and maxhp changes
	float ratio;
	if (prev_maxhp != get(Stats::HP_MAX)) {
		ratio = static_cast<float>(prev_hp) / static_cast<float>(prev_maxhp);
		hp = static_cast<int>(ratio * static_cast<float>(get(Stats::HP_MAX)));
	}
	if (prev_maxmp != get(Stats::MP_MAX)) {
		ratio = static_cast<float>(prev_mp) / static_cast<float>(prev_maxmp);
		mp = static_cast<int>(ratio * static_cast<float>(get(Stats::MP_MAX)));
	}

	// handle cooldowns
	if (cooldown_ticks > 0) cooldown_ticks--; // global cooldown

	for (size_t i=0; i<powers_ai.size(); ++i) { // NPC/enemy powerslot cooldown
		if (powers_ai[i].ticks > 0) powers_ai[i].ticks--;
	}

	// HP regen
	if (get(Stats::HP_REGEN) > 0 && hp < get(Stats::HP_MAX) && hp > 0) {
		hp_ticker++;
		if (hp_ticker >= (60 * settings->max_frames_per_sec) / get(Stats::HP_REGEN)) {
			hp++;
			hp_ticker = 0;
		}
	}

	// MP regen
	if (get(Stats::MP_REGEN) > 0 && mp < get(Stats::MP_MAX) && hp > 0) {
		mp_ticker++;
		if (mp_ticker >= (60 * settings->max_frames_per_sec) / get(Stats::MP_REGEN)) {
			mp++;
			mp_ticker = 0;
		}
	}

	// handle buff/debuff durations
	if (transform_duration > 0)
		transform_duration--;

	// apply bleed
	if (effects.damage > 0 && hp > 0) {
		takeDamage(effects.damage);
		comb->addInt(effects.damage, pos, CombatText::MSG_TAKEDMG);
	}
	if (effects.damage_percent > 0 && hp > 0) {
		int damage = (get(Stats::HP_MAX)*effects.damage_percent)/100;
		takeDamage(damage);
		comb->addInt(damage, pos, CombatText::MSG_TAKEDMG);
	}

	if(effects.death_sentence)
		hp = 0;

	if(cooldown_hit_ticks > 0)
		cooldown_hit_ticks--;

	if (effects.stun) {
		// stun stops charge attacks
		state_ticks = 0;
		charge_speed = 0;
	}
	else if (state_ticks > 0) {
		state_ticks--;
	}

	// apply healing over time
	if (effects.hpot > 0) {
		comb->addString(msg->get("+%d HP",effects.hpot), pos, CombatText::MSG_BUFF);
		hp += effects.hpot;
		if (hp > get(Stats::HP_MAX)) hp = get(Stats::HP_MAX);
	}
	if (effects.hpot_percent > 0) {
		int hpot = (get(Stats::HP_MAX)*effects.hpot_percent)/100;
		comb->addString(msg->get("+%d HP",hpot), pos, CombatText::MSG_BUFF);
		hp += hpot;
		if (hp > get(Stats::HP_MAX)) hp = get(Stats::HP_MAX);
	}
	if (effects.mpot > 0) {
		comb->addString(msg->get("+%d MP",effects.mpot), pos, CombatText::MSG_BUFF);
		mp += effects.mpot;
		if (mp > get(Stats::MP_MAX)) mp = get(Stats::MP_MAX);
	}
	if (effects.mpot_percent > 0) {
		int mpot = (get(Stats::MP_MAX)*effects.mpot_percent)/100;
		comb->addString(msg->get("+%d MP",mpot), pos, CombatText::MSG_BUFF);
		mp += mpot;
		if (mp > get(Stats::MP_MAX)) mp = get(Stats::MP_MAX);
	}

	// set movement type
	// some creatures may shift between movement types
	if (intangible) movement_type = MapCollision::MOVE_INTANGIBLE;
	else if (flying) movement_type = MapCollision::MOVE_FLYING;
	else movement_type = MapCollision::MOVE_NORMAL;

	if (hp == 0)
		removeSummons();

	if (effects.knockback_speed != 0) {
		float theta = Utils::calcTheta(knockback_srcpos.x, knockback_srcpos.y, knockback_destpos.x, knockback_destpos.y);
		knockback_speed.x = effects.knockback_speed * cosf(theta);
		knockback_speed.y = effects.knockback_speed * sinf(theta);

		mapr->collider.unblock(pos.x, pos.y);
		mapr->collider.move(pos.x, pos.y, knockback_speed.x, knockback_speed.y, movement_type, mapr->collider.getCollideType(hero));
		mapr->collider.block(pos.x, pos.y, hero_ally);
	}
	else if (charge_speed != 0.0f) {
		float tmp_speed = charge_speed * speedMultiplyer[direction];
		float dx = tmp_speed * static_cast<float>(directionDeltaX[direction]);
		float dy = tmp_speed * static_cast<float>(directionDeltaY[direction]);

		mapr->collider.unblock(pos.x, pos.y);
		mapr->collider.move(pos.x, pos.y, dx, dy, movement_type, mapr->collider.getCollideType(hero));
		mapr->collider.block(pos.x, pos.y, hero_ally);
	}


	// enemies heal rapidly while not in combat
	if (!in_combat && !hero_ally && !hero) {
		if (alive && pc->stats.alive) {
			hp++;
			if (hp > get(Stats::HP_MAX))
				hp = get(Stats::HP_MAX);
		}
	}

	if (waypoint_pause_ticks > 0)
		waypoint_pause_ticks--;

	// check for revive
	if (hp <= 0 && effects.revive) {
		hp = get(Stats::HP_MAX);
		alive = true;
		corpse = false;
		if (hero)
			cur_state = AVATAR_STANCE;
		else
			cur_state = ENEMY_STANCE;
	}

	// check for bleeding to death
	if (hp <= 0 && !hero && cur_state != ENEMY_DEAD && cur_state != ENEMY_CRITDEAD) {
		for (size_t i = 0; i < effects.effect_list.size(); ++i) {
			if (effects.effect_list[i].type == Effect::DAMAGE || effects.effect_list[i].type == Effect::DAMAGE_PERCENT) {
				bleed_source_type = effects.effect_list[i].source_type;
				break;
			}
		}
		effects.triggered_death = true;
		cur_state = ENEMY_DEAD;
	}
	else if (hp <= 0 && hero && cur_state != AVATAR_DEAD) {
		effects.triggered_death = true;
		cur_state = AVATAR_DEAD;
	}
}
예제 #11
0
void Creep::takeZapDamage(int damage)
{
    m_stickyCount--;
    
    takeDamage(damage, ELECTRIC);
}
예제 #12
0
/**
 * Process per-frame actions
 */
void StatBlock::logic() {
	if (hp <= 0 && !effects.triggered_death && !effects.revive) alive = false;
	else alive = true;

	// handle party buffs
	if (enemym && powers) {
		while (!party_buffs.empty()) {
			int power_index = party_buffs.front();
			party_buffs.pop();
			Power *buff_power = &powers->powers[power_index];

			for (size_t i=0; i < enemym->enemies.size(); ++i) {
				if(enemym->enemies[i]->stats.hp > 0 &&
				   ((enemym->enemies[i]->stats.hero_ally && hero) || (enemym->enemies[i]->stats.enemy_ally && enemym->enemies[i]->stats.summoner == this)) &&
				   (buff_power->buff_party_power_id == 0 || buff_power->buff_party_power_id == enemym->enemies[i]->stats.summoned_power_index)
				) {
					powers->effect(&enemym->enemies[i]->stats, this, power_index, (hero ? SOURCE_TYPE_HERO : SOURCE_TYPE_ENEMY));
				}
			}
		}
	}

	// handle effect timers
	effects.logic();

	// apply bonuses from items/effects to base stats
	applyEffects();

	if (hero && effects.refresh_stats) {
		refresh_stats = true;
		effects.refresh_stats = false;
	}

	// preserve ratio on maxmp and maxhp changes
	float ratio;
	if (prev_maxhp != get(STAT_HP_MAX)) {
		ratio = static_cast<float>(pres_hp) / static_cast<float>(prev_maxhp);
		hp = static_cast<int>(ratio * static_cast<float>(get(STAT_HP_MAX)));
	}
	if (prev_maxmp != get(STAT_MP_MAX)) {
		ratio = static_cast<float>(pres_mp) / static_cast<float>(prev_maxmp);
		mp = static_cast<int>(ratio * static_cast<float>(get(STAT_MP_MAX)));
	}

	// handle cooldowns
	if (cooldown_ticks > 0) cooldown_ticks--; // global cooldown

	for (size_t i=0; i<powers_ai.size(); ++i) { // NPC/enemy powerslot cooldown
		if (powers_ai[i].ticks > 0) powers_ai[i].ticks--;
	}

	// HP regen
	if (get(STAT_HP_REGEN) > 0 && hp < get(STAT_HP_MAX) && hp > 0) {
		hp_ticker++;
		if (hp_ticker >= (60 * MAX_FRAMES_PER_SEC)/get(STAT_HP_REGEN)) {
			hp++;
			hp_ticker = 0;
		}
	}

	// MP regen
	if (get(STAT_MP_REGEN) > 0 && mp < get(STAT_MP_MAX) && hp > 0) {
		mp_ticker++;
		if (mp_ticker >= (60 * MAX_FRAMES_PER_SEC)/get(STAT_MP_REGEN)) {
			mp++;
			mp_ticker = 0;
		}
	}

	// handle buff/debuff durations
	if (transform_duration > 0)
		transform_duration--;

	// apply bleed
	if (effects.damage > 0 && hp > 0) {
		takeDamage(effects.damage);
		comb->addInt(effects.damage, pos, COMBAT_MESSAGE_TAKEDMG);
	}
	if (effects.damage_percent > 0 && hp > 0) {
		int damage = (get(STAT_HP_MAX)*effects.damage_percent)/100;
		takeDamage(damage);
		comb->addInt(damage, pos, COMBAT_MESSAGE_TAKEDMG);
	}

	if(effects.death_sentence)
		hp = 0;

	if(cooldown_hit_ticks > 0)
		cooldown_hit_ticks--;

	if (effects.stun) {
		// stun stops charge attacks
		state_ticks = 0;
		charge_speed = 0;
	}
	else if (state_ticks > 0) {
		state_ticks--;
	}

	// apply healing over time
	if (effects.hpot > 0) {
		comb->addString(msg->get("+%d HP",effects.hpot), pos, COMBAT_MESSAGE_BUFF);
		hp += effects.hpot;
		if (hp > get(STAT_HP_MAX)) hp = get(STAT_HP_MAX);
	}
	if (effects.hpot_percent > 0) {
		int hpot = (get(STAT_HP_MAX)*effects.hpot_percent)/100;
		comb->addString(msg->get("+%d HP",hpot), pos, COMBAT_MESSAGE_BUFF);
		hp += hpot;
		if (hp > get(STAT_HP_MAX)) hp = get(STAT_HP_MAX);
	}
	if (effects.mpot > 0) {
		comb->addString(msg->get("+%d MP",effects.mpot), pos, COMBAT_MESSAGE_BUFF);
		mp += effects.mpot;
		if (mp > get(STAT_MP_MAX)) mp = get(STAT_MP_MAX);
	}
	if (effects.mpot_percent > 0) {
		int mpot = (get(STAT_MP_MAX)*effects.mpot_percent)/100;
		comb->addString(msg->get("+%d MP",mpot), pos, COMBAT_MESSAGE_BUFF);
		mp += mpot;
		if (mp > get(STAT_MP_MAX)) mp = get(STAT_MP_MAX);
	}

	// set movement type
	// some creatures may shift between movement types
	if (intangible) movement_type = MOVEMENT_INTANGIBLE;
	else if (flying) movement_type = MOVEMENT_FLYING;
	else movement_type = MOVEMENT_NORMAL;

	if (hp == 0)
		removeSummons();

	if (effects.knockback_speed != 0) {
		float theta = calcTheta(knockback_srcpos.x, knockback_srcpos.y, knockback_destpos.x, knockback_destpos.y);
		knockback_speed.x = effects.knockback_speed * cosf(theta);
		knockback_speed.y = effects.knockback_speed * sinf(theta);

		mapr->collider.unblock(pos.x, pos.y);
		mapr->collider.move(pos.x, pos.y, knockback_speed.x, knockback_speed.y, movement_type, hero);
		mapr->collider.block(pos.x, pos.y, hero_ally);
	}
	else if (charge_speed != 0.0f) {
		float tmp_speed = charge_speed * speedMultiplyer[direction];
		float dx = tmp_speed * static_cast<float>(directionDeltaX[direction]);
		float dy = tmp_speed * static_cast<float>(directionDeltaY[direction]);

		mapr->collider.unblock(pos.x, pos.y);
		mapr->collider.move(pos.x, pos.y, dx, dy, movement_type, hero);
		mapr->collider.block(pos.x, pos.y, hero_ally);
	}
}
예제 #13
0
bool Projectile::collide(Entity * other, b2Contact& contact, std::string tag)
{
	bool handled = false;
	
	//Get fixture string
	std::string tig = std::string(static_cast<char*>(contact.GetFixtureA()->GetUserData()));

	//If it's the other, get what we are in contact
	if (tig == tag)
		tig = std::string(static_cast<char*>(contact.GetFixtureB()->GetUserData()));

	//If it's our tracking, don't bother
	if (tig == "projtracking")
	{
		handled = true;
	}

	else if (tag == "player" || tag == "enemy" || tag == "shape")////
	{
		Shape* shape = static_cast<Shape*>(other);
		//Projectiles do get hurt by their friends
		if (faction_ != shape->getFaction() && shape->getFaction() != GOD)
		{
			//Onehit projectiles die on hit, precedence over all
			if (oneHit_)
			{
				alive_ = false;
			}

			//If we can't penetrate
			if (penetration_-- <= 0)
			{
				takeDamage(1);
				if (size_.y > 0)
				{
					//b2Vec2 vel = body_->GetLinearVelocity();
					//vel *= (0.1* size_.x * size_.y);
					//
					//body_->SetLinearVelocity(vel);
				}
			}

			//Do our force on penetration
			else
			{
				lastPen_ = b2Vec3(body_->GetPosition().x, body_->GetPosition().y, 1);
			}

			if (alive_ == false)
				contact.SetEnabled(false);
		}

		else contact.SetEnabled(false);

		handled = true;
	}

	else if (tag == "projectile")
	{
		Projectile* proj = static_cast<Projectile*>(other);
		//If we're not friends
		if (faction_ != proj->getFaction())
		{
			//If we can't penetrate
			if (--penetration_ < 0)
			{
				takeDamage(proj->getDamage());

				if (alive_ == false)
					contact.SetEnabled(false);
			}

			//Do our force on penetration
			else
			{
				lastPen_ = b2Vec3(body_->GetPosition().x, body_->GetPosition().y, 1);
			}
			//Maybe set contact to false so stronger proj continues?
		}

		//Else we must have same owner, do not interact
		else contact.SetEnabled(false);

		handled = true;
	}

	else if (tag == "pickup")
	{
		contact.SetEnabled(false);
		handled = true;
	}

	else if (tag == "shield")
	{
		Pickup::Shield* shield = static_cast<Pickup::Shield*>(other);

		//If we don't own the shield
		if (shield->getOwner() != owner_)
		{
			//Penetrate if we can
			if (penetration_ > 0)
			{
				//Shields block more pen
				penetration_ -= shield->getStrength();
			}
		
			//if (contact.IsEnabled())
			//{
			//	b2Vec2 back = body_->GetLinearVelocity();
			//	back *= -0.5;
			//	body_->SetLinearVelocity(back);
			//}
		}
		
		handled = true;
	}

	else if (tag == "bounds")
	{
		takeDamage(1);
		handled = true;
	}

	return handled;
}
예제 #14
0
bool player::combat()
{
    if (currentRoom->hasMonster())
    {
        //FIGHT!
        functions::clearScreen();

        //Copy monster by reference
        monster mon(currentRoom->getMonster());

        while ( true )      //Breaks by returning a bool when either monster or player dies
        {
            int dmg(0);

            //Player hits Monster
            dmg = strike();
            mon.takeDamage( dmg );

            //Combat Header
            player::printCombatHeader<int, std::string>(getHealth(), mon.getHealth(), mon.getName());

            //Displays damage done on either side
            if( dmg > 0)
                std::cerr << std::right << std::setw(44) << "Hit!    -" << dmg;
            else
                std::cerr << std::right << std::setw(44) << "Miss!";

            std::cout << "\n\n\n\n";
            currentRoom->displayDoors();

            //Wait
            //sleepFunc(1200);  //Didn't work on Linux, so Busy-Wait...
            for(int i(0); i < 220000000; i++)
            { }

            if (mon.getHealth() < 1)    //Monster Death Check
            {
                //VICTORY
                monstersKilled++;
                currentRoom->killMonster();
                addTreasure(currentRoom->getTreasure());

                functions::clearScreen();
                std::cout << "Victory!\n\n";
                print_Score_Screen();
                std::cout << "\n";
                return true;
            }

            //Monster hits Player
            dmg = mon.strike();
            takeDamage( dmg );

            //Combat Header
            player::printCombatHeader<int, std::string>(getHealth(), mon.getHealth(), mon.getName());

            //Displays damage done on either side
            if( dmg > 0)
                std::cerr << "Hit!    -" << dmg;
            else
                std::cerr << "Miss!";

            std::cout << "\n\n\n\n";
            currentRoom->displayDoors();

            //Wait
            //sleepFunc(1200);  //Didn't work on Linux, so Busy-Wait...
            for(int i(0); i < 220000000; i++)
            { }

            if (getHealth() < 1)    //Player Death Check
            {
                return false;       //DEAD!
            }

        }
    }
    else
    {
        //No Monster
        functions::clearScreen();
        std::cerr << "\nRoom Clear:  No Monster\n\n\n\n\n";
    }
}
예제 #15
0
void Player::collidedWith(GameObject* Other)
{
	Obstacle* Ob = dynamic_cast<Obstacle*>(Other);
	if(Ob != NULL)
	{

		if(alive == true){
			sf::Vector2i vecInt;
			vecInt.x = (int)m_Sprite.getPosition().x + collidePoint.x;
			vecInt.y = (int)m_Sprite.getPosition().y + collidePoint.y;

		
			sf::Vector2f vecFloat;
			vecFloat.x = m_Sprite.getPosition().x + collidePoint.x;
			vecFloat.y = m_Sprite.getPosition().y + collidePoint.y;
			
			float lenght = sqrt((m_Velocity.x*m_Velocity.x) + (m_Velocity.y*m_Velocity.y));
			sf::Vector2f normVelocity;
			if(lenght == 0){
				lenght = 1;
			}

			normVelocity.x = m_Velocity.x / lenght;
			normVelocity.y = m_Velocity.y / lenght;

			for(int i = 0; i <40; i++)
			{
				vecFloat.x -= normVelocity.x;
				vecFloat.y -= normVelocity.y;
				vecInt.x = (int) floorf(vecFloat.x);
				vecInt.y = (int) floorf(vecFloat.y);

				if(!Other->checkCollisionPoint(vecInt)){
					break;
				}
			}

			m_Sprite.setPosition((float)vecInt.x - collidePoint.x, (float)vecInt.y - collidePoint.y);
			m_Sprite.move((float)-normVelocity.x*10, (float)-normVelocity.y*10);

			sf::Sound* tempS = AudioManager::playSound("Assets/Audio/Sfx/groundHit.wav", 0.9f, 1.1f);
			float MasterVol = (float)(PhoenixEngine::GlobalConfig->GetInt("Audio", "VolumeMaster"))/100.0f;
			float SfxVol = (float)(PhoenixEngine::GlobalConfig->GetInt("Audio", "VolumeSfx"))/100.0f;
			float vol = lenght/6 -20;
			if(vol < 0){
				vol = 0;
			}
			tempS->setVolume(vol*MasterVol*SfxVol);
			
			checkSlope = true;
			

		}else{
			
			if(m_Velocity.y > 150){

				AudioManager::playSound("Assets/Audio/Sfx/groundHit.wav", 0.9f, 1.1f);

				sf::Vector2i vecInt;
				vecInt.x = (int)m_Sprite.getPosition().x + collidePoint.x;
				vecInt.y = (int)m_Sprite.getPosition().y + collidePoint.y;

				sf::Vector2f vecFloat;
				vecFloat.x = m_Sprite.getPosition().x + collidePoint.x;
				vecFloat.y = m_Sprite.getPosition().y + collidePoint.y;

				float lenght = sqrt((m_Velocity.x*m_Velocity.x) + (m_Velocity.y*m_Velocity.y));
				sf::Vector2f normVelocity;
				normVelocity.x = m_Velocity.x / lenght;
				normVelocity.y = m_Velocity.y / lenght;

				while(Other->checkCollisionPoint(vecInt)){
					vecFloat.x -= normVelocity.x;
					vecFloat.y -= normVelocity.y;
					vecInt.x = (int) floorf(vecFloat.x);
					vecInt.y = (int) floorf(vecFloat.y);
				}

				m_Sprite.setPosition((float)vecInt.x - collidePoint.x, (float)vecInt.y - collidePoint.y);
				this->getSlope(Other);		

				m_Velocity.x /=2;
				m_Velocity.y /=2;

				m_Sprite.move((float)-normVelocity.x*2, (float)-normVelocity.y*2);
			}else{

				m_Velocity.y = 0;
				m_Velocity.x = 0;
				superDead = true;
			}

		}

	}

	Enemy* En = dynamic_cast<Enemy*>(Other);
	if(En != NULL)
	{
		if(En->isAlive==true){

			KnockBack(En->m_Sprite.getPosition().x, En->m_Sprite.getPosition().y, 400);
			takeDamage();

			AudioManager::playSound("Assets/Audio/Sfx/collideHit.wav", 0.9f, 1.1f);
			

			//std::cout << "heeheheheheheh " << rand() << std::endl;
		}
	}
}
예제 #16
0
/**
 * Process per-frame actions
 */
void StatBlock::logic() {
	if (hp <= 0 && !effects.triggered_death && !effects.revive) alive = false;
	else alive = true;

	// handle effect timers
	effects.logic();

	// apply bonuses from items/effects to base stats
	applyEffects();

	// preserve ratio on maxmp and maxhp changes
	float ratio;
	if (prev_maxhp != get(STAT_HP_MAX)) {
		ratio = static_cast<float>(pres_hp) / static_cast<float>(prev_maxhp);
		hp = static_cast<int>(ratio * static_cast<float>(get(STAT_HP_MAX)));
	}
	if (prev_maxmp != get(STAT_MP_MAX)) {
		ratio = static_cast<float>(pres_mp) / static_cast<float>(prev_maxmp);
		mp = static_cast<int>(ratio * static_cast<float>(get(STAT_MP_MAX)));
	}

	// handle cooldowns
	if (cooldown_ticks > 0) cooldown_ticks--; // global cooldown

	for (size_t i=0; i<powers_ai.size(); ++i) { // NPC/enemy powerslot cooldown
		if (powers_ai[i].ticks > 0) powers_ai[i].ticks--;
	}

	// HP regen
	if (get(STAT_HP_REGEN) > 0 && hp < get(STAT_HP_MAX) && hp > 0) {
		hp_ticker++;
		if (hp_ticker >= (60 * MAX_FRAMES_PER_SEC)/get(STAT_HP_REGEN)) {
			hp++;
			hp_ticker = 0;
		}
	}

	// MP regen
	if (get(STAT_MP_REGEN) > 0 && mp < get(STAT_MP_MAX) && hp > 0) {
		mp_ticker++;
		if (mp_ticker >= (60 * MAX_FRAMES_PER_SEC)/get(STAT_MP_REGEN)) {
			mp++;
			mp_ticker = 0;
		}
	}

	// handle buff/debuff durations
	if (transform_duration > 0)
		transform_duration--;

	// apply bleed
	if (effects.damage > 0 && hp > 0) {
		takeDamage(effects.damage);
		comb->addMessage(effects.damage, pos, COMBAT_MESSAGE_TAKEDMG);
	}
	if (effects.damage_percent > 0 && hp > 0) {
		int damage = (get(STAT_HP_MAX)*effects.damage_percent)/100;
		takeDamage(damage);
		comb->addMessage(damage, pos, COMBAT_MESSAGE_TAKEDMG);
	}

	if(effects.death_sentence)
		hp = 0;

	if(cooldown_hit_ticks > 0)
		cooldown_hit_ticks--;

	// apply healing over time
	if (effects.hpot > 0) {
		comb->addMessage(msg->get("+%d HP",effects.hpot), pos, COMBAT_MESSAGE_BUFF);
		hp += effects.hpot;
		if (hp > get(STAT_HP_MAX)) hp = get(STAT_HP_MAX);
	}
	if (effects.hpot_percent > 0) {
		int hpot = (get(STAT_HP_MAX)*effects.hpot_percent)/100;
		comb->addMessage(msg->get("+%d HP",hpot), pos, COMBAT_MESSAGE_BUFF);
		hp += hpot;
		if (hp > get(STAT_HP_MAX)) hp = get(STAT_HP_MAX);
	}
	if (effects.mpot > 0) {
		comb->addMessage(msg->get("+%d MP",effects.mpot), pos, COMBAT_MESSAGE_BUFF);
		mp += effects.mpot;
		if (mp > get(STAT_MP_MAX)) mp = get(STAT_MP_MAX);
	}
	if (effects.mpot_percent > 0) {
		int mpot = (get(STAT_MP_MAX)*effects.mpot_percent)/100;
		comb->addMessage(msg->get("+%d MP",mpot), pos, COMBAT_MESSAGE_BUFF);
		mp += mpot;
		if (mp > get(STAT_MP_MAX)) mp = get(STAT_MP_MAX);
	}

	// set movement type
	// some creatures may shift between movement types
	if (intangible) movement_type = MOVEMENT_INTANGIBLE;
	else if (flying) movement_type = MOVEMENT_FLYING;
	else movement_type = MOVEMENT_NORMAL;

	if (hp == 0)
		removeSummons();

	if (effects.knockback_speed != 0) {
		float theta = calcTheta(knockback_srcpos.x, knockback_srcpos.y, knockback_destpos.x, knockback_destpos.y);
		knockback_speed.x = effects.knockback_speed * static_cast<float>(cos(theta));
		knockback_speed.y = effects.knockback_speed * static_cast<float>(sin(theta));
	}

	if (effects.knockback_speed != 0) {
		mapr->collider.unblock(pos.x, pos.y);
		mapr->collider.move(pos.x, pos.y, knockback_speed.x, knockback_speed.y, movement_type, hero);
		mapr->collider.block(pos.x, pos.y, hero_ally);
	}
}
예제 #17
0
파일: StatBlock.cpp 프로젝트: iooioio/flare
/**
 * Process per-frame actions
 */
void StatBlock::logic() {

	// handle cooldowns
	if (cooldown_ticks > 0) cooldown_ticks--; // global cooldown

	for (int i=0; i<POWERSLOT_COUNT; i++) { // NPC/enemy powerslot cooldown
		if (power_ticks[i] > 0) power_ticks[i]--;
	}

	// HP regen
	if (hp_per_minute > 0 && hp < maxhp && hp > 0) {
		hp_ticker++;
		if (hp_ticker >= (60 * FRAMES_PER_SEC)/hp_per_minute) {
			hp++;
			hp_ticker = 0;
		}
	}

	// MP regen
	if (mp_per_minute > 0 && mp < maxmp && hp > 0) {
		mp_ticker++;
		if (mp_ticker >= (60 * FRAMES_PER_SEC)/mp_per_minute) {
			mp++;
			mp_ticker = 0;
		}
	}
	
	// handle buff/debuff durations
	if (slow_duration > 0)
		slow_duration--;
	if (bleed_duration > 0)
		bleed_duration--;
	if (stun_duration > 0)
		stun_duration--;
	if (immobilize_duration > 0)
		immobilize_duration--;
	if (immunity_duration > 0)
		immunity_duration--;
	if (haste_duration > 0)
		haste_duration--;
	if (hot_duration > 0)
		hot_duration--;
	
	// apply bleed
	if (bleed_duration % FRAMES_PER_SEC == 1) {
		takeDamage(1);
	}
	
	// apply healing over time
	if (hot_duration % FRAMES_PER_SEC == 1) {
		hp += hot_value;
		if (hp > maxhp) hp = maxhp;
	}
	
	// handle targeted
	if (targeted > 0)
		targeted--;
		
	// handle buff/debuff animations
	shield_frame++;
	if (shield_frame == 12) shield_frame = 0;
	
	vengeance_frame+= vengeance_stacks;
	if (vengeance_frame >= 24) vengeance_frame -= 24;
	

}
예제 #18
0
void Hero::update(float frameDelta) {
	if(!dying) {
		char* scoretext = new char[64];
		sprintf(scoretext, "Score: %0.f", score);
		game->getFont()->printText(scoretext, vec2(50.f, 50.f), 18);
		delete [] scoretext;
		score += 0.1f*frameDelta;

	}
	
	shield->setPosition(pos-vec2(15.f, 10.f));


	if(shieldShowTimer > 0.f) {
		shieldShowTimer -= frameDelta;
		if(shieldShowTimer < 0.f) {
			shieldShowTimer = 0.f;
			shield->flags ^= ACTIVE;
		}
	}


	GameNode::update(frameDelta);
	Sprite::update(frameDelta);
	Collidable::update(frameDelta);

	if(dying) return;

	if(shieldPower < 0.f) {
		if(!dying) {
			game->setState(STATE_GAME_OVER);
			dying = true;
			shield->flags ^= ACTIVE;
			flags ^= ACTIVE;
			game->getEffectMgr()->spawnEffect(EFFECT_TYPE_EXPLOSION, pos);
		}
	}
	

	if(colevent.hasCollided) {
		takeDamage(1.f);
		colevent.hasCollided = false;
	}

	CollisionEvent col_event = game->getCollisionMgr()->collideObject(this, this, C_LEVEL);
	if(col_event.hasCollided) {
			takeDamage(100.f);
	}
	
	col_event = game->getCollisionMgr()->collideObject(this, this, C_POWERUPS);
	if(col_event.hasCollided) {
		weapon->randomizeAttributes();
	}

	col_event = game->getCollisionMgr()->collideObject(this, this, C_ENEMIES);
	if(col_event.hasCollided) {
		takeDamage(7.5f);
	}
	//bc.pos = pos + vec2(frame_size_x, frame_size_y) * 0.5f;
	vec2 cameraPos = game->getCameraPos();
	//game->drawCircle(bc.pos - cameraPos, bc.radius, 0xfffff

	if(shootDelay > 0.f) {
		shootDelay -= frameDelta;
		if(shootDelay < 0.f) {
			shootDelay = 0.f;
		}
	}

	int keymask = game->getKeymask();
	int mousemask = game->getMousemask();
	vec2 mousePos = game->getMousePos();


	if(keymask&KEY_Z) {
		weapon->fire();
	}

	if(keymask&KEY_X) {
		
	}
	
	if(keymask&UP) {
		pos[1] -= 0.2f*frameDelta;
		//setAnimation(ONCE, 1, 1, 12.f);
	} else {
		//setAnimation(LOOP, 0, 0, 12.f);
	}

	if(keymask&DOWN) {
		pos[1] += 0.2f*frameDelta;
		//setAnimation(ONCE, 2, 2, 12.f);
	} else if(!(keymask&UP)) {
		//setAnimation(LOOP, 0, 0, 12.f);
	}

	if(keymask&RIGHT) {
		pos[0] += 0.4f*frameDelta;
	} else {
		pos[0] += 0.3f*frameDelta;
	}

	if(keymask&LEFT) {
		pos[0] -= 0.2f*frameDelta;
		//if(keymask&DOWN)
			//setAnimation(ONCE, 4, 4, 12.f);
		//else if(keymask&UP)
			//setAnimation(ONCE, 5, 5, 12.f);
		//else
			//setAnimation(ONCE, 3, 3, 12.f);
	}

	keymask = 0;
	mousemask = 0;

	// check if within screen
	if(pos[0] < cameraPos[0]) pos[0] = cameraPos[0];
	if(pos[1] < 0.f) pos[1] = 0.f;
	if(pos[0]+frame_size_x > cameraPos[0]+SCRWIDTH) pos[0] = cameraPos[0]+SCRWIDTH-frame_size_x;
	if(pos[1]+frame_size_y > SCRHEIGHT) pos[1] = SCRHEIGHT-frame_size_y;
}
예제 #19
0
void Animal::defend(Animal* opponent, int damage) {
  takeDamage(damage);
}
예제 #20
0
파일: Bullet.cpp 프로젝트: zheck/rtype
void Bullet::attack(Entity *e, int gameTime)
{
    takeDamage(gameTime);
    e->takeDamage(gameTime);
}
	//What happens when someone bumps into me
	bool collide(Entity* unit){ takeDamage(unit); return true;}
예제 #22
0
void Creep::update(float deltaTime)
{
    m_fStateTime += deltaTime;
    
    m_healthBarFrame = m_health * 16 / m_maxHealth - 1;
    m_healthBarFrame = m_healthBarFrame < 0 ? 0 : m_healthBarFrame;
    
    m_timeToShowHealthBar -= deltaTime;
    
    if (FlagUtil::isFlagSet(m_creepCondition, ELECTRIFIED))
    {
        if (m_electrifiedTime > 0)
        {
            m_electrifiedTime -= deltaTime;
        }
        else
        {
            m_creepCondition = FlagUtil::removeFlag(m_creepCondition, ELECTRIFIED);
            m_speed = m_initialSpeed;
            
            if (FlagUtil::isFlagSet(m_creepCondition, FROZEN))
            {
                m_speed /= 3;
            }
        }
    }
    
    if (FlagUtil::isFlagSet(m_creepCondition, POISONED))
    {
        if (m_poisonedTime > 0)
        {
            bool isFrozen = FlagUtil::isFlagSet(m_creepCondition, FROZEN);
            
            m_poisonedTime -= deltaTime;
            m_poisonTime += deltaTime;
            
            while (m_poisonTime > TIME_FOR_POISON_DAMAGE)
            {
                m_poisonTime -= TIME_FOR_POISON_DAMAGE;
                takeDamage(m_poisonDamage, Damage_Type::ACID);
            }
            
            if (m_isGrowingDueToPoison)
            {
                m_fWidth += deltaTime * (isFrozen ? 0.1f : 0.5f);
                m_fHeight += deltaTime * (isFrozen ? 0.1f : 0.5f);
                if (m_fWidth > m_maxSize)
                {
                    m_fWidth = m_maxSize;
                    m_fHeight = m_maxSize;
                    m_isGrowingDueToPoison = false;
                }
            }
            else
            {
                m_fWidth -= deltaTime * (isFrozen ? 0.1f : 0.5f);
                m_fHeight -= deltaTime * (isFrozen ? 0.1f : 0.5f);
                if (m_fWidth < m_halfSize)
                {
                    m_fWidth = m_halfSize;
                    m_fHeight = m_halfSize;
                    m_isGrowingDueToPoison = true;
                }
            }
        }
        else
        {
            m_creepCondition = FlagUtil::removeFlag(m_creepCondition, POISONED);
            m_fWidth = m_defaultSize;
            m_fHeight = m_defaultSize;
        }
        
        resetBounds(m_fWidth * SIZE_TO_BOUNDS_RATIO, m_fHeight * SIZE_TO_BOUNDS_RATIO);
    }
    
    if (FlagUtil::isFlagSet(m_creepCondition, FROZEN))
    {
        if (m_frozenTime > 0)
        {
            m_frozenTime -= deltaTime;
            m_fRed += m_frozenRecoveryRate * deltaTime;
            m_fGreen = m_fRed;
        }
        else
        {
            thaw();
        }
    }
    else if (FlagUtil::isFlagSet(m_creepCondition, ON_FIRE))
    {
        if (m_burnTime > 0)
        {
            m_burnTime -= deltaTime;
        }
        else
        {
            m_creepCondition = FlagUtil::removeFlag(m_creepCondition, ON_FIRE);
            m_creepCondition = FlagUtil::setFlag(m_creepCondition, FIRE_RECOVERY);
        }
    }
    else if (FlagUtil::isFlagSet(m_creepCondition, FIRE_RECOVERY))
    {
        m_fRed += 1.5f * deltaTime;
        m_fGreen = m_fRed;
        m_fBlue = m_fRed;
        
        if (m_fRed > 1)
        {
            m_creepCondition = FlagUtil::removeFlag(m_creepCondition, FIRE_RECOVERY);
            resetColor();
        }
    }
    
    m_deltaX = m_velocity->getX() * deltaTime;
    m_deltaY = m_velocity->getY() * deltaTime;
    m_position->add(m_deltaX, m_deltaY);
    m_direction = calcDirection();
    updateBounds();
}
예제 #23
0
/**
 * Process per-frame actions
 */
void StatBlock::logic() {
	if (hp <= 0 && !effects.triggered_death && !effects.revive) alive = false;
	else alive = true;

	// handle effect timers
	effects.logic();

	// apply bonuses from items/effects to base stats
	applyEffects();

	// preserve ratio on maxmp and maxhp changes
	float ratio;
	if (prev_maxhp != get(STAT_HP_MAX)) {
		ratio = (float)pres_hp / (float)prev_maxhp;
		hp = (int)(ratio * get(STAT_HP_MAX));
	}
	if (prev_maxmp != get(STAT_MP_MAX)) {
		ratio = (float)pres_mp / (float)prev_maxmp;
		mp = (int)(ratio * get(STAT_MP_MAX));
	}

	// handle cooldowns
	if (cooldown_ticks > 0) cooldown_ticks--; // global cooldown

	for (int i=0; i<POWERSLOT_COUNT; i++) { // NPC/enemy powerslot cooldown
		if (power_ticks[i] > 0) power_ticks[i]--;
	}

	// HP regen
	if (get(STAT_HP_REGEN) > 0 && hp < get(STAT_HP_MAX) && hp > 0) {
		hp_ticker++;
		if (hp_ticker >= (60 * MAX_FRAMES_PER_SEC)/get(STAT_HP_REGEN)) {
			hp++;
			hp_ticker = 0;
		}
	}

	// MP regen
	if (get(STAT_MP_REGEN) > 0 && mp < get(STAT_MP_MAX) && hp > 0) {
		mp_ticker++;
		if (mp_ticker >= (60 * MAX_FRAMES_PER_SEC)/get(STAT_MP_REGEN)) {
			mp++;
			mp_ticker = 0;
		}
	}

	// handle buff/debuff durations
	if (transform_duration > 0)
		transform_duration--;

	// apply bleed
	if (effects.damage > 0 && hp > 0) {
		takeDamage(effects.damage);
		comb->addMessage(effects.damage, pos, COMBAT_MESSAGE_TAKEDMG);
	}
	if (effects.damage_percent > 0 && hp > 0) {
		int damage = (get(STAT_HP_MAX)*effects.damage_percent)/100;
		takeDamage(damage);
		comb->addMessage(damage, pos, COMBAT_MESSAGE_TAKEDMG);
	}

	if(effects.death_sentence)
		hp = 0;

	if(cooldown_hit_ticks > 0)
		cooldown_hit_ticks--;

	// apply healing over time
	if (effects.hpot > 0) {
		comb->addMessage(msg->get("+%d HP",effects.hpot), pos, COMBAT_MESSAGE_BUFF);
		hp += effects.hpot;
		if (hp > get(STAT_HP_MAX)) hp = get(STAT_HP_MAX);
	}
	if (effects.hpot_percent > 0) {
		int hpot = (get(STAT_HP_MAX)*effects.hpot_percent)/100;
		comb->addMessage(msg->get("+%d HP",hpot), pos, COMBAT_MESSAGE_BUFF);
		hp += hpot;
		if (hp > get(STAT_HP_MAX)) hp = get(STAT_HP_MAX);
	}
	if (effects.mpot > 0) {
		comb->addMessage(msg->get("+%d MP",effects.mpot), pos, COMBAT_MESSAGE_BUFF);
		mp += effects.mpot;
		if (mp > get(STAT_MP_MAX)) mp = get(STAT_MP_MAX);
	}
	if (effects.mpot_percent > 0) {
		int mpot = (get(STAT_MP_MAX)*effects.mpot_percent)/100;
		comb->addMessage(msg->get("+%d MP",mpot), pos, COMBAT_MESSAGE_BUFF);
		mp += mpot;
		if (mp > get(STAT_MP_MAX)) mp = get(STAT_MP_MAX);
	}

	// set movement type
	// some creatures may shift between movement types
	if (intangible) movement_type = MOVEMENT_INTANGIBLE;
	else if (flying) movement_type = MOVEMENT_FLYING;
	else movement_type = MOVEMENT_NORMAL;

	if (hp == 0)
		removeSummons();
}
예제 #24
0
파일: Actor.cpp 프로젝트: vesabios/matador
void Actor::takeDamageFrom(int dmg, Actor * a) {
    takeDamage(dmg);
    if (data.hp<=0) {
        a->awardExperienceForKilling(this);
    }
}