Exemplo n.º 1
0
void Player::contact(Entity* e) {
  //not exactly elegant, but oh well.
  if(e->getType() == ET_ENTITY || e->getType() == ET_SPACESHIP_A || e->getType() == ET_SPACESHIP_B || e->getType() == ET_SPACESHIP_C || e->getType() == ET_SPACESHIP_D) {
    if(e->isDead()) { //if it's dead, we don't care about this collision
      return;
    }
    
    applyDamage(e->getCollisionDamage()); //apply collision damage to player
    e->setHealth(0); //kill entity

    _game->getGameplayScreen()->addScore(50);
    _game->getGameplayScreen()->addEnemyShot();

    _game->getGameplayScreen()->getEntityManager()->deleteEntity(e->getId(), true); //schedule deletion
  }

  if(e->getType() == ET_POWERUP) {
    Powerup* powerup = static_cast <Powerup*> (e);
    std::string powerupType = powerup->getPowerupType();

    if(powerupType == "hp") {
      _game->getGameplayScreen()->addHealth(100);
    } else if(powerupType == "score") {
      _game->getGameplayScreen()->addScore(50);
    } else if(powerupType == "dmg") {
      applyDamage(50);
    }

    powerup->setHealth(0);
  }
}
Exemplo n.º 2
0
void CollisionListener::PostSolve(b2Contact* theContact, const b2ContactImpulse* theImpulse)
{
   auto anCollideEntityA = static_cast<GQE::IEntity*>(theContact->GetFixtureA()->GetBody()->GetUserData());
   auto anCollideEntityB = static_cast<GQE::IEntity*>(theContact->GetFixtureB()->GetBody()->GetUserData());

   float aImpactStrength = theImpulse->normalImpulses[0];

   applyDamage(anCollideEntityA, aImpactStrength);
   applyDamage(anCollideEntityB, aImpactStrength);
}
Exemplo n.º 3
0
void Creep::takeDamage(int damage, Damage_Type damageType)
{
    if (applyDamage(damage, damageType))
    {
        displayHealthBar();
    }
    
    if (m_health <= 0)
    {
        kill(damageType);
    }
}
Exemplo n.º 4
0
void Player::handleEvent(sf::Event e){
	m_joystick = -1;
	for (int i = 0; i < 6 && m_joystick == -1; i++){
		if (sf::Joystick::isConnected(i))
			m_joystick = i;
	}
	if (e.type == sf::Event::JoystickButtonPressed){
		int buttonId = e.joystickButton.button;
		if (buttonId < 4){
			bool addCombo = false;
			if (!m_currentActions.empty() && m_actionToPlay == false){
				if (m_animatedSprite.getFrame() > m_currentActions.front()->getMinFrame() &&
					m_animatedSprite.getFrame() < m_currentActions.front()->getMaxFrame()){
					m_currentActions.push(&m_actions[buttonId]);
					m_actionToPlay = true;
					addCombo = true;
				}
			}
			else if (m_actionToPlay == false){
				m_currentActions.push(&m_actions[buttonId]);
				addCombo = true;
				currentAnim = &m_anims[m_currentActions.back()->getAnimName()];
				m_animatedSprite.play(*currentAnim);
				m_animatedSprite.setLooped(false);
				applyDamage();
			}

			if (addCombo){
				switch (buttonId)
				{
				case 0:
					m_comboString += 'A';
					break;
				case 1:
					m_comboString += 'B';
					break;
				case 2:
					m_comboString += 'X';
					break;
				case 3:
					m_comboString += 'Y';
					break;
				}
			}
		}
	}
}
Exemplo n.º 5
0
void Player::behaviour(){
	for (const Character* e : attackableEnemies){
		if (e->getAlive() == false){
			attackableEnemies.erase(std::find(attackableEnemies.begin(), attackableEnemies.end(), e));
			break;
		}
	}
	if (m_actionToPlay && m_animatedSprite.getFrame() == m_currentActions.front()->getMaxFrame()){
		m_currentActions.pop();
		m_animatedSprite.play(m_anims[m_currentActions.front()->getAnimName()]);
		m_animatedSprite.setLooped(false);
		m_actionToPlay = false;
		applyDamage();
	}

	//if all animations have stopped playing then reset 
	if (m_animatedSprite.isPlaying() == false || (currentAnim == &m_anims["run"]  && m_velocity == sf::Vector2f())
		|| (m_comboTriggered && m_currentActions.size() > 0 && m_animatedSprite.getFrame() == m_currentActions.front()->getMaxFrame())){
		comboFinished();
	}
	else if (currentAnim != &m_anims["run"]){
		m_speed = 0;
	}

	float xPos = sf::Joystick::getAxisPosition(m_joystick, sf::Joystick::Axis::X);
	float yPos = sf::Joystick::getAxisPosition(m_joystick, sf::Joystick::Axis::Y);
	if ((xPos < 10 && xPos > -10) &&
		(yPos < 10 && yPos > -10)){
		m_velocity.x = 0;
		m_velocity.y = 0;
		sndMgr->stopSound("walking_grass");
		return;
	}
	sndMgr->playSound("walking_grass", true);
	xPos = (xPos / 100) * m_speed;
	yPos = (yPos / 100) * m_speed;
	if (m_speed > 0 && currentAnim != &m_anims["run"]){
		currentAnim = &m_anims["run"];
		m_animatedSprite.play(*currentAnim);
		m_animatedSprite.setLooped(false);
	}

	m_velocity = sf::Vector2f(xPos, yPos);
}
Exemplo n.º 6
0
void Player::comboFinished(){
	m_comboTriggered = true;
	if (m_comboString == "BX"){
		std::cout << "BX combo triggered" << '\n';
		m_currentActions.pop();
		m_currentActions.push(&m_actions[4]);
		currentAnim = &m_anims[m_currentActions.back()->getAnimName()];
		m_animatedSprite.play(*currentAnim);
		m_animatedSprite.setLooped(false);
		m_actionToPlay = false;
		applyDamage(2.f);
	}
	else{
		m_comboTriggered = false;
		m_speed = max_speed;
		currentAnim = &m_anims["idle"];
		m_animatedSprite.play(*currentAnim);
		m_animatedSprite.setLooped(false);
		m_actionToPlay = false;
		m_currentActions.swap(std::queue<Action*>()); //empty the queue
	}
	m_comboString = "";
}
Exemplo n.º 7
0
void BattleHazard::applyEffect(GameState &state)
{
	auto tile = tileObject->getOwningTile();

	auto set = tile->ownedObjects;
	for (auto obj : set)
	{
		if (tile->ownedObjects.find(obj) == tile->ownedObjects.end())
		{
			continue;
		}
		if (obj->getType() == TileObject::Type::Ground ||
		    obj->getType() == TileObject::Type::Feature ||
		    obj->getType() == TileObject::Type::LeftWall ||
		    obj->getType() == TileObject::Type::RightWall)
		{
			auto mp = std::static_pointer_cast<TileObjectBattleMapPart>(obj)->getOwner();
			switch (damageType->effectType)
			{
				case DamageType::EffectType::Fire:
					LogWarning("Set map part on fire!");
					break;
				default:
					mp->applyDamage(state, power, damageType);
					break;
			}
		}
		else if (obj->getType() == TileObject::Type::Unit)
		{
			StateRef<BattleUnit> u = {
			    &state, std::static_pointer_cast<TileObjectBattleUnit>(obj)->getUnit()->id};
			switch (damageType->effectType)
			{
				case DamageType::EffectType::Fire:
					LogWarning("Set unit on fire!");
					break;
				default:
				{
					// Determine direction of hit
					Vec3<float> velocity = -position;
					velocity -= Vec3<float>{0.5f, 0.5f, 0.5f};
					velocity += u->position;
					if (velocity.x == 0.0f && velocity.y == 0.0f)
					{
						velocity.z = 1.0f;
					}
					// Determine wether to hit head, legs or torso
					auto cposition = u->position;
					// Hit torso
					if (sqrtf(velocity.x * velocity.x + velocity.y * velocity.y) >
					    std::abs(velocity.z))
					{
						cposition.z += (float)u->getCurrentHeight() / 2.0f / 40.0f;
					}
					// Hit head
					else if (velocity.z < 0)
					{
						cposition.z += (float)u->getCurrentHeight() / 40.0f;
					}
					else
					{
						// Legs are defeault already
					}
					// Apply
					u->applyDamage(state, power, damageType,
					               u->determineBodyPartHit(damageType, cposition, velocity));
				}
				break;
			}
		}
	}
}
Exemplo n.º 8
0
void BattleHazard::applyEffect(GameState &state)
{
	auto tile = tileObject->getOwningTile();

	auto set = tile->ownedObjects;
	for (auto &obj : set)
	{
		if (tile->ownedObjects.find(obj) == tile->ownedObjects.end())
		{
			continue;
		}
		if (obj->getType() == TileObject::Type::Ground ||
		    obj->getType() == TileObject::Type::Feature ||
		    obj->getType() == TileObject::Type::LeftWall ||
		    obj->getType() == TileObject::Type::RightWall)
		{
			auto mp = std::static_pointer_cast<TileObjectBattleMapPart>(obj)->getOwner();
			switch (damageType->effectType)
			{
				case DamageType::EffectType::Fire:
					if (mp->applyBurning(state, age))
					{
						// Map part burned and provided fuel for our fire, keep the fire raging
						if (power < 0 && age > 10)
						{
							power = -power;
						}
					}
					break;
				default:
					switch (damageType->blockType)
					{
						case DamageType::BlockType::Gas:
						case DamageType::BlockType::Psionic:
							break;
						default:
							mp->applyDamage(state, power, damageType);
							break;
					}
					break;
			}
		}
		else if (obj->getType() == TileObject::Type::Item)
		{
			if (damageType->effectType == DamageType::EffectType::Fire)
			{
				// It was observed that armor resists fire damage deal to it
				// It also appears that damage is applied gradually at a rate of around 1 damage per
				// second
				// In tests, marsec armor (20% modifier) was hurt by fire but X-Com armor (10%
				// modifier) was not
				// If we apply damage once per turn, we apply 4 at once. Since we round down, 4 *
				// 20% will be rounded to 0
				// while it should be 1. So we add 1 here
				auto i = std::static_pointer_cast<TileObjectBattleItem>(obj)->getItem();
				i->applyDamage(state, 2 * TICKS_PER_HAZARD_UPDATE / TICKS_PER_SECOND + 1,
				               damageType);
			}
		}
		else if (obj->getType() == TileObject::Type::Unit)
		{
			StateRef<BattleUnit> u = {
			    &state, std::static_pointer_cast<TileObjectBattleUnit>(obj)->getUnit()->id};
			// Determine direction of hit
			Vec3<float> velocity = -position;
			velocity -= Vec3<float>{0.5f, 0.5f, 0.5f};
			velocity += u->position;
			if (velocity.x == 0.0f && velocity.y == 0.0f)
			{
				velocity.z = 1.0f;
			}
			// Determine wether to hit head, legs or torso
			auto cposition = u->position;
			// Hit torso
			if (sqrtf(velocity.x * velocity.x + velocity.y * velocity.y) > std::abs(velocity.z))
			{
				cposition.z += (float)u->getCurrentHeight() / 2.0f / 40.0f;
			}
			// Hit head
			else if (velocity.z < 0)
			{
				cposition.z += (float)u->getCurrentHeight() / 40.0f;
			}
			else
			{
				// Legs are defeault already
			}
			// Apply
			u->applyDamage(state, power, damageType,
			               u->determineBodyPartHit(damageType, cposition, velocity),
			               DamageSource::Hazard);
		}
	}
}
Exemplo n.º 9
0
void main_loop(Player &player1, Player &player2)
{
  
  srand (time(NULL));
  int random_num;
  std::string weather;
  player1.active = player1.pokemons[0];
  player2.active = player2.pokemons[0];
  
  player1.active_ability = player1.active->getAbility();
  player2.active_ability = player2.active->getAbility();
  field = {false, false, false, false, CLEAR};

  switchin_abilities(player1.active_ability->name);
  switchin_abilitiies(player2.active_ability->name);

  Attack* attack1, attack2;
  int turn;
  bool bypass = false;
  while(!player1.forfeit || !player2.forfeit) //change this conditional to faints instead
    {
      //getPlayers actions here
      parseActions(player1);
      parseActions(player2);
     

      if(player1.action == SWITCH)
	{
	  bypass = false;
	  if(player2.action == FIGHT && player2.using_attack->name == "Pursuit")
	    {
	      applyDamage(player2.active, player1.active, player2.using_attack);
	      bypass = true;
	    }
	  Switch(player1.active, player1.switchTo);
	  active_ability1 = player1.active->getAbility();
	  switching_abilities(player1.active_ability->name);
	  if(bypass)
	    {
	      //skip to next turn
	      continue;
	    }
	}
      if(player2.action == SWITCH)
	{
	  bypass = false;
	  if(player1.action == FIGHT && player1.using_attack->name == "Pursuit")
	    {	       
	      applyDamage(player1.active, player2.active, player1.using_attack);
	      bypass = true;
	    }
	  Switch(player2.active, player2.switchTo);
	  active_ability2 = player2.active->getAbility();
	  switching_abilities(player2.active_ability->name);
	  // REMEMBER to apply spikes damages and shit
	  if(bypass)
	    {
	      //skip to next turn
	      continue;
	    }
	}
      
      //apply damages
      turn = compareSpeed(player1.active, player2.active);
      switch(turn)
      {
      case -1:
	applyDamage(player2.active, player1.active, player2.using_attack);
	checkIsFaint(player1);
	applyDamage(player1.active, player2.active, player1.using_attack);
	checkIsFaint(player2);
	break;

      case 1:
	applyDamage(player1.active, player2.active, player1.using_attack);
	checkIsFaint(player2);
	applyDamage(player2.active, player1.active, player2.using_attack);
	checkIsFaint(player1);
	break;

      case 0:
	random_num = rand()%101;
	if(random_num < 50)
	  {
	    applyDamage(player1.active, player2.active, player1.using_attack);
	    checkIsFaint(player2);
	    applyDamage(player2.active, player1.active, player2.using_attack);
	    checkIsFaint(player1);
	  }
	else
	  {
	    applyDamage(player1.active, player2.active, player1.using_attack);
	    checkIsFaint(player2);
	    applyDamage(player2.active, player1.active, player2.using_attack);
	    checkIsFaint(player1);
	  }
	break;
      }
      
      afterBattleAbility(player1.active_ability->name);
      checkIsFaint(player1);
      checkIsFaint(player2);
      afterBattleAbility(player2.active_ability->name);
      checkIsFaint(player1);
      checkIsFaint(player2);
    }
}
Exemplo n.º 10
0
bool Npc::die() {
	return applyDamage(nullptr, _attribs.getCurrent(attrib::Types::HEALTH)) > 0.0;
}
Exemplo n.º 11
0
// Check collision 
void UFO::checkCollision(Handlers* handlers){
	// Make sure UFO cannot leave level on left or right side

	LevelProperties* lp = (LevelProperties*)(handlers->levelProps);

	if (nextX - 50.0f < lp->getLevelLeft())
		nextX = lp->getLevelLeft() + 50.0f;
	if (nextX + 50.0f > lp->getLevelRight())
		nextX = lp->getLevelRight() - 50.0f;

	// Keep UFO from leaving top of level

	if (nextY < lp->getLevelTop())
		nextY = lp->getLevelTop();

	// ----------------------------------
	// Check UFO collision with ground 
	// Push UFO away from ground if too close 
	// ----------------------------------
	
	// Point used during collision detection 
	Point p;
	Point* itr;

	// Setup vertical line segment 
	vertA.setLocation(nextX, nextY);
	vertB.setLocation(nextX, nextY + minDistFromGround);

	// Normal ground check: 
	itr = handlers->ground->getPoints();
	if (itr != NULL){
		while (itr->next != NULL){
			// Check if player is close to point
			if ((*itr).getX() <= nextX && (*(itr->next)).getX() >= nextX){
				if (checkSegSeg(vertA, vertB, *itr, *(itr->next), &p)){
					nextX = p.getX();
					nextY = p.getY() - minDistFromGround;
					break;
				}
			}
			itr = itr->next;
		}
	}

	// ---------------------------------------------
	// Check ufo collision with enemy projectiles  
	// ---------------------------------------------
	// Fix collision rectangle for next step
	collisionArea.setLocation(locX - originX, locY - originY);
	collisionArea.setSize(width, height);

	Projectile** projs = ((ProjectileHandler*)handlers->projHandler)->getProjList();
	Point projp;

	// Check all projectiles for collision 
	for (int i = 0; i <= ((ProjectileHandler*)handlers->projHandler)->getLastActive(); i++){
		// Null check 
		if (projs[i] != NULL && projs[i]->getAlive() && projs[i]->getFiredBy() == PFB_ENEMY){
			// Quick distance check 
			if (dist(nextX, nextY,projs[i]->getCurrentX(), projs[i]->getCurrentY()) <100){ 
				// Check for collision 
				if (checkRecSeg(&collisionArea, 
					projs[i]->getCurrentX(), projs[i]->getCurrentY(), 
					projs[i]->getPrevX(), projs[i]->getPrevY(), &projp)){

					// Tell projectile we had a player collision 
					projs[i]->collide(&projp, handlers, P_PLAYER_COLL);

					// Apply projectile damage to player
					((SoundHandler*)handlers->soundHandler)->playSoundEffect(SE_UFO_HIT);
					applyDamage(projs[i]->getDamage());
				}
			}
		}
	}

	// ---------------------------------------------
	// Check ufo collision with enemy explosions  
	// ---------------------------------------------

	Explosion* expls = ((ExplHandler*)handlers->explHander)->getExpls();

	for (int i = 0; i <= ((ExplHandler*)handlers->explHander)->getLastActive(); i++){
		if (expls[i].isValid()){
			if (expls[i].firedByEnemy() && expls[i].inRadius(&collisionArea)){
				applyDamage(expls[i].getDamage());
			}
		}
	}
}
Exemplo n.º 12
0
void BattleExplosion::damage(GameState &state, const TileMap &map, Vec3<int> pos, int damage)
{
	auto tile = map.getTile(pos);
	// Explosions with no hazard spawn smoke with half ttl
	if (!damageType->hazardType)
	{
		StateRef<DamageType> dtSmoke = {&state, "DAMAGETYPE_SMOKE"};
		state.current_battle->placeHazard(state, ownerOrganisation, ownerUnit, dtSmoke, pos,
		                                  dtSmoke->hazardType->getLifetime(state), damage, 2,
		                                  false);
	}
	// Explosions with no custom explosion doodad spawn hazards when dealing damage
	else if (!damageType->explosionDoodad)
	{
		state.current_battle->placeHazard(state, ownerOrganisation, ownerUnit, damageType, pos,
		                                  damageType->hazardType->getLifetime(state), damage, 1,
		                                  false);
	}
	// Gas does no direct damage
	if (damageType->doesImpactDamage())
	{
		auto set = tile->ownedObjects;
		for (auto &obj : set)
		{
			if (tile->ownedObjects.find(obj) == tile->ownedObjects.end())
			{
				continue;
			}
			if (obj->getType() == TileObject::Type::Ground ||
			    obj->getType() == TileObject::Type::Feature ||
			    obj->getType() == TileObject::Type::LeftWall ||
			    obj->getType() == TileObject::Type::RightWall)
			{
				auto mp = std::static_pointer_cast<TileObjectBattleMapPart>(obj)->getOwner();
				switch (damageType->effectType)
				{
					case DamageType::EffectType::Fire:
						// Nothing, map parts are not damaged by fire at explosion time
						break;
					default:
						mp->applyDamage(state, damage, damageType);
						break;
				}
			}
			else if (obj->getType() == TileObject::Type::Unit)
			{
				StateRef<BattleUnit> u = {
				    &state, std::static_pointer_cast<TileObjectBattleUnit>(obj)->getUnit()->id};
				if (affectedUnits.find(u) != affectedUnits.end())
				{
					continue;
				}
				affectedUnits.insert(u);
				// Determine direction of hit
				Vec3<float> velocity = -position;
				velocity -= Vec3<float>{0.5f, 0.5f, 0.5f};
				velocity += u->position;
				if (velocity.x == 0.0f && velocity.y == 0.0f)
				{
					velocity.z = 1.0f;
				}
				// Determine wether to hit head, legs or torso
				auto cposition = u->position;
				// Hit torso if coming from the side, not from above or below
				if (sqrtf(velocity.x * velocity.x + velocity.y * velocity.y) > std::abs(velocity.z))
				{
					cposition.z += (float)u->getCurrentHeight() / 2.0f / 40.0f;
				}
				// Hit head if coming from above
				else if (velocity.z < 0)
				{
					cposition.z += (float)u->getCurrentHeight() / 40.0f;
				}
				// Hit legs if coming from below
				else
				{
					// Legs are defeault already
				}
				// Apply
				u->applyDamage(state, damage, damageType,
				               u->determineBodyPartHit(damageType, cposition, velocity),
				               DamageSource::Impact, ownerUnit);
			}
			else if (obj->getType() == TileObject::Type::Item)
			{
				// Special effects do not damage items, fire damages items differently and not on
				// explosion impact
				if (damageType->effectType == DamageType::EffectType::None)
				{
					auto i = std::static_pointer_cast<TileObjectBattleItem>(obj)->getItem();
					i->applyDamage(state, damage, damageType);
				}
			}
		}
	}
}
Exemplo n.º 13
0
bool PlayerBullet::onImpact(Entity* hit)
{
	auto impact = GameGlobals::get()->impact;

	auto position = getComponent<sz::Transform>()->getPosition();

	auto color = getComponent<sz::Renderer>()->getColor();

	impact->setColor(color);
	if(bulletStance == PlayerEntity::Stance::Offensive)
		impact->setScale(0.6f, 1.f + (thor::random(0, 10) >= 9 ? 1.5f : 0.f));
	else
		impact->setScale(0.3f, 0.6f + (thor::random(0, 10) >= 9 ? 0.6f : 0.f));

	impact->setPosition(position);
	impact->emit(1);

	auto bits = GameGlobals::get()->impactbits;

	bits->setColor(color);
	bits->setScale(0.02f, 0.1f);
	bits->setPosition(position);

	for(int i=0; i < 50; ++i)
	{
		float v = thor::random(0.f, 250.f);

		bits->setVelocityCone(v, m_angle + (thor::random(0, 2) == 0 ? -PI : 0.f), thor::random(0.f, 50.f));
		bits->emit(1);
	}

	if(bulletStance == PlayerEntity::Stance::Offensive)
	{
		auto close = getComponent<sz::Physics>()->queryRadius(150.f);

		for(auto it = close.begin(); it != close.end(); ++it)
		{
			auto enemy = dynamic_cast<EnemyEntityBase*>(*it);
			if(!enemy || enemy == hit || enemy->isBoss()) continue;

			auto enemyPos = enemy->call(&sz::Transform::getPosition);
			float dist = sz::distance(position, enemyPos) / 22500.f;
			dist = std::min(1.f, dist);
			float falloff = (1.f - (dist * dist)) * 0.65f;

			float angle = sz::getAngle(position, enemyPos);

			enemy->applyDamage(DamageReport(m_shooter, m_damage * falloff, angle)); 
		}
	}

	auto enemy = dynamic_cast<EnemyEntityBase*>(hit);

	if(enemy)
	{
		auto pos = enemy->getTransform->getPosition();

		if(!enemy->isBoss())
		{
			impact->setColor(sf::Color::White);
			impact->setScale(0.3f, 0.4f + (thor::random(0, 10) >= 9 ? 0.3f : 0.f));
		}
		else
		{
			impact->setColor(color);
			impact->setScale(1.f, 1.4f + (thor::random(0, 10) >= 9 ? 0.4f : 0.f));
		}

		impact->setPosition(pos + sf::Vector2f(thor::random(-30.f, 30.f), thor::random(-30.f, 30.f)));
		impact->emit(1);

		impact->setPosition(pos + sf::Vector2f(thor::random(-30.f, 30.f), thor::random(-30.f, 30.f)));
		impact->emit(1);
	}

	{
		auto boss = dynamic_cast<EnemyBossRed*>(hit);
		if(boss)
		{
			boss->increaseDmgMod(0.2f);
		}
	}

	return true;
}