Page MenuHomePhabricator (Chris)

No OneTemporary

Size
38 KB
Referenced Files
None
Subscribers
None
diff --git a/src/BoltEntity.cpp b/src/BoltEntity.cpp
index 241a26e..9854da8 100644
--- a/src/BoltEntity.cpp
+++ b/src/BoltEntity.cpp
@@ -1,418 +1,418 @@
#include "BoltEntity.h"
#include "ExplosionEntity.h"
#include "Constants.h"
#include "DungeonMap.h"
#include "WitchBlastGame.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
BoltEntity::BoltEntity(float x, float y, float boltLifeTime, enumShotType boltType, int level)
: CollidingSpriteEntity (ImageManager::getInstance().getImage(IMAGE_BOLT), x, y, BOLT_WIDTH, BOLT_HEIGHT)
{
lifetime = boltLifeTime;
setDamages(INITIAL_BOLT_DAMAGES);
type = ENTITY_BOLT;
viscosity = INITIAL_BOLT_VISCOSITY;
this->level = level;
if (boltType == ShotTypeLightning) viscosity += LIGHTNING_VISCOSITY_INCREASE[level];
frame = 0;
setMap(game().getCurrentMap(), TILE_WIDTH, TILE_HEIGHT, 0, 0);
this->boltType = boltType;
enemyType = EnemyTypeNone;
goThrough = false;
hitNumber = 0;
fromPlayer = true;
switch (boltType)
{
case ShotTypeDeterministic:
case ShotTypeStandard: frame = 0; break;
case ShotTypeCold:
case ShotTypeIce: frame = 2; break;
case ShotTypeStone: frame = 4; break;
case ShotTypeLightning: frame = 5; goThrough = true; break;
case ShotTypeIllusion: frame = 3; break;
case ShotTypeFire: frame = 6; break;
case ShotTypePoison: frame = 7; break;
case ShotTypeBomb: frame = 8; damages = 0; sprite.setScale(1.0f, 1.0f); break;
}
testWallsCollision = false;
flying = false;
critical = false;
// avoid starting in wall
if (y > ((MAP_HEIGHT - 1) * TILE_HEIGHT - 16))
this->y = (MAP_HEIGHT - 1) * TILE_HEIGHT - 16;
}
int BoltEntity::getDamages()
{
return damages;
}
void BoltEntity::setFromPlayer(bool fromPlayer)
{
this->fromPlayer = fromPlayer;
}
bool BoltEntity::isFromPlayer()
{
return fromPlayer;
}
unsigned int BoltEntity::getLevel()
{
return level;
}
void BoltEntity::setDamages(int damages)
{
this->damages = damages;
if (damages <= 4) renderScale = 0.7f;
else if (damages <= 6) renderScale = 0.78f;
else if (damages <= 8) renderScale = 0.85f;
else if (damages <= 12) renderScale = 0.9f;
else if (damages <= 16) renderScale = 1.0f;
else if (damages <= 20) renderScale = 1.1f;
else if (damages <= 24) renderScale = 1.2f;
else if (damages <= 30) renderScale = 1.3f;
else renderScale = 1.4f;
sprite.scale(renderScale, renderScale);
}
void BoltEntity::loseDamages(int damages)
{
if (this->damages > damages) setDamages(this->damages - damages);
else setDamages(0);
critical = false;
}
enumShotType BoltEntity::getBoltType()
{
return boltType;
}
enemyTypeEnum BoltEntity::getEnemyType()
{
return enemyType;
}
bool BoltEntity::isFlying()
{
return flying;
}
void BoltEntity::setFlying(bool flying)
{
this->flying = flying;
}
bool BoltEntity::isCritical()
{
return critical;
}
void BoltEntity::setCritical(bool critical)
{
this->critical = critical;
}
void BoltEntity::setGoThrough(bool goThrough)
{
this->goThrough = goThrough;
}
bool BoltEntity::getGoThrough()
{
return goThrough;
}
void BoltEntity::animate(float delay)
{
if (boltType != ShotTypeBomb)
particleGenerator.GenerateParticles(frame, IMAGE_BOLT, x, y, BOLT_WIDTH, BOLT_HEIGHT,
boltType == ShotTypeLightning ? Vector2D(20.0f) : Vector2D(0.0f, 0.0f),
10, boltType == ShotTypeIce ? renderScale * 1.3f : renderScale);
z = y + height;
testWallsCollision = true;
if (isCollidingWithMap())
{
isDying = true;
SoundManager::getInstance().playSound(SOUND_WALL_IMPACT);
for (int i=0; i<5; i++) generateParticule(100.0f + rand() % 150);
}
else
{
float oldX = x;
float oldY = y;
CollidingSpriteEntity::animate(delay);
if (boltType != ShotTypeBomb && (game().getPlayer()->isEquiped(EQUIP_RAPID_SHOT) || damages < 5))
particleGenerator.GenerateParticles(frame, IMAGE_BOLT, (x + oldX) * 0.5f, (y + oldY) * 0.5f, BOLT_WIDTH, BOLT_HEIGHT,
boltType == ShotTypeLightning ? Vector2D(20.0f) : Vector2D(0.0f, 0.0f),
10, boltType == ShotTypeIce ? renderScale * 1.3f : renderScale);
}
// key room collision
if (game().getCurrentMap()->getRoomType() == roomTypeKey && !game().getCurrentMap()->isCleared())
{
sf::IntRect col1;
col1.width = 198;
col1.height = 68;
col1.top = 254;
col1.left = 380;
sf::IntRect col2;
col2.width = 68;
col2.height = 198;
col2.top = 189;
col2.left = 445;
if (boundingBox.intersects(col1) || boundingBox.intersects(col2))
{
game().activateKeyRoomEffect(false);
if (x < 390) collideMapRight();
else if (x > 565) collideMapLeft();
else if (y < 265) collideMapBottom();
else collideMapTop();
}
}
testWallsCollision = false;
calculateBB();
if (boltType != ShotTypeBomb && boltType != ShotTypeStone && (lifetime - age) < 0.2f)
{
if (age >= lifetime)
sprite.setColor(sf::Color(255, 255, 255, 0));
else
sprite.setColor(sf::Color(255, 255, 255, (sf::Uint8)((lifetime - age) / 0.2f * 255)));
}
if (((velocity.x)*(velocity.x) + (velocity.y)*(velocity.y)) < 1500.0f) isDying = true;
}
void BoltEntity::render(sf::RenderTarget* app)
{
if (boltType == ShotTypeBomb)
{
sprite.setTextureRect(sf::IntRect(8 * width, 0, width * 2, height * 2));
sprite.setPosition(x - width / 2, y - height);
app->draw(sprite);
}
else
CollidingSpriteEntity::render(app);
if (game().getShowLogical())
{
displayBoundingBox(app);
}
}
void BoltEntity::calculateBB()
{
int colSize = testWallsCollision ? 1 : 10;
boundingBox.left = x - colSize;
boundingBox.width = colSize * 2;
boundingBox.top = y - colSize;
boundingBox.height = colSize * 2;
}
void BoltEntity::collide()
{
hitNumber++;
if (fromPlayer)
{
if (hitNumber == 3) game().registerAchievement(Achievement3Hits);
- if (hitNumber > 1) std::cout << "Hit: " << hitNumber << "(dam=" << damages << ")" << std::endl;
+ if (hitNumber > 2) std::cout << "Hit: " << hitNumber << "(dam=" << damages << ")" << std::endl;
if (goThrough)
{
if (damages > 0) return;
}
}
isDying = true;
if (boltType == ShotTypeBomb)
explode();
else
{
for (int i=0; i<5; i++)
{
Vector2D vel(40.0f + rand() % 50);
generateParticule(vel);
}
}
}
void BoltEntity::generateParticule(Vector2D vel)
{
SpriteEntity* trace = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_BOLT), x, y, BOLT_WIDTH, BOLT_HEIGHT);
trace->setFading(true);
trace->setZ(y);
trace->setLifetime(0.5f);
trace->setScale(0.3f, 0.3f);
trace->setVelocity(vel);
trace->setViscosity(0.97f);
trace->setType(ENTITY_EFFECT);
trace->setFrame(frame);
}
bool BoltEntity::collideWithMap(int direction)
{
calculateBB();
int xTile0 = (boundingBox.left - offsetX) / tileWidth;
int xTilef = (boundingBox.left + boundingBox.width - offsetX) / tileWidth;
int yTile0 = (boundingBox.top - offsetY) / tileHeight;
int yTilef = (boundingBox.top + boundingBox.height - offsetY) / tileHeight;
if (boundingBox.top < 0) yTile0 = -1;
for (int xTile = xTile0; xTile <= xTilef; xTile++)
for (int yTile = yTile0; yTile <= yTilef; yTile++)
{
if (boltType != ShotTypeIllusion)
{
if (flying)
{
if ( dynamic_cast<DungeonMap*>(map)->isFlyable(xTile, yTile) == false ) return true;
}
else
{
if ( dynamic_cast<DungeonMap*>(map)->isShootable(xTile, yTile) == false ) return true;
}
}
}
return false;
}
void BoltEntity::onDying()
{
isDying = true;
}
void BoltEntity::stuck()
{
SoundManager::getInstance().playSound(SOUND_WALL_IMPACT);
if (boltType == ShotTypeBomb)
explode();
else
{
for (int i=0; i<5; i++)
{
Vector2D vel(100.0f + rand() % 150);
generateParticule(vel);
}
}
onDying();
}
void BoltEntity::collideMapRight()
{
if (boltType == ShotTypeLightning)
{
velocity.x = -velocity.x;
}
else if (boltType == ShotTypeBomb)
explode();
else
{
velocity.x = 0.0f;
isDying = true;
SoundManager::getInstance().playSound(SOUND_WALL_IMPACT);
for (int i=0; i<5; i++)
{
Vector2D vel(100.0f + rand() % 150);
if (vel.x > 0.0f) vel.x = - vel.x;
generateParticule(vel);
}
}
}
void BoltEntity::collideMapLeft()
{
if (boltType == ShotTypeLightning)
{
velocity.x = -velocity.x;
}
else if (boltType == ShotTypeBomb)
explode();
else
{
velocity.x = 0.0f;
isDying = true;
SoundManager::getInstance().playSound(SOUND_WALL_IMPACT);
for (int i=0; i<5; i++)
{
Vector2D vel(100.0f + rand() % 150);
if (vel.x < 0.0f) vel.x = - vel.x;
generateParticule(vel);
}
}
}
void BoltEntity::collideMapTop()
{
if (boltType == ShotTypeLightning)
{
velocity.y = -velocity.y;
}
else if (boltType == ShotTypeBomb)
explode();
else
{
velocity.y = 0.0f;
isDying = true;
SoundManager::getInstance().playSound(SOUND_WALL_IMPACT);
for (int i=0; i<5; i++)
{
Vector2D vel(100.0f + rand() % 150);
if (vel.y < 0.0f) vel.y = - vel.y;
generateParticule(vel);
}
}
}
void BoltEntity::collideMapBottom()
{
if (boltType == ShotTypeLightning)
{
velocity.y = -velocity.y;
}
else if (boltType == ShotTypeBomb)
explode();
else
{
velocity.y = 0.0f;
isDying = true;
SoundManager::getInstance().playSound(SOUND_WALL_IMPACT);
for (int i=0; i<5; i++)
{
Vector2D vel(100.0f + rand() % 150);
if (vel.y > 0.0f) vel.y = - vel.y;
generateParticule(vel);
}
}
}
void BoltEntity::explode()
{
isDying = true;
- new ExplosionEntity(x, y, ExplosionTypeStandard, 12, enemyType);
+ new ExplosionEntity(x, y, ExplosionTypeStandard, 12, enemyType, true);
game().makeShake(0.5f);
SoundManager::getInstance().playSound(SOUND_BOOM_00);
game().addCorpse(x, y, FRAME_CORPSE_SLIME_VIOLET);
}
diff --git a/src/CauldronEntity.cpp b/src/CauldronEntity.cpp
index f05b26a..5beb579 100644
--- a/src/CauldronEntity.cpp
+++ b/src/CauldronEntity.cpp
@@ -1,171 +1,171 @@
#include "CauldronEntity.h"
#include "SlimeEntity.h"
#include "ExplosionEntity.h"
#include "PlayerEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
CauldronEntity::CauldronEntity(float x, float y)
: EnemyEntity (ImageManager::getInstance().getImage(IMAGE_CAULDRON), x, y)
{
creatureSpeed = 0.0f;
velocity = Vector2D(0.0f, 0.0f);
hp = CAULDRON_HP;
hpMax = hp;
meleeDamages = 0;
bloodColor = BloodNone;
invokeDelay = 2.5f;
bubbleDelay = 0.0f;
shadowFrame = 2;
sprite.setOrigin(32, 28);
deathFrame = FRAME_CORPSE_CAULDRON;
dyingSound = SOUND_CAULDRON_DIE;
enemyType = EnemyTypeCauldron;
resistance[ResistanceRecoil] = ResistanceVeryHigh;
resistance[ResistancePoison] = ResistanceImmune;
canExplode = false;
}
void CauldronEntity::animate(float delay)
{
if (isAgonising)
{
agonizingDelay -= delay;
if (agonizingDelay <= 0.0f)
{
isDying = true;
game().addCorpse(x, y, deathFrame);
}
}
else
{
SoundManager::getInstance().playSound(SOUND_CAULDRON, false);
invokeDelay -= delay;
if (invokeDelay < 0.0f)
{
new SlimeEntity(x, y, SlimeTypeViolet, true);
invokeDelay = 1.5f + (float)(rand() % 2500) / 1000.0f;
}
bubbleDelay -= delay;
if (bubbleDelay < 0.0f)
{
bubbleDelay = 0.3f;
for (int i=0; i < 2; i++)
{
float xBub = x - 16 + rand() % 32;
SpriteEntity* bubble = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_CAULDRON), xBub, y - 20, 8, 8);
bubble->setZ(z);
bubble->setFrame(32);
bubble->setType(ENTITY_EFFECT);
bubble->setWeight(-20 - rand() % 40);
bubble->setLifetime(2.0f);
float bloodScale = 0.3f + (rand() % 20) * 0.1f;
bubble->setScale(bloodScale, bloodScale);
}
}
frame = hp > hpMax / 2 ? 0 : 1;
EnemyEntity::animate(delay);
}
}
void CauldronEntity::readCollidingEntity(CollidingSpriteEntity* entity)
{
if (!isDying && !isAgonising && collideWithEntity(entity))
{
if (entity->getType() == ENTITY_PLAYER || entity->getType() == ENTITY_BOLT )
{
PlayerEntity* playerEntity = dynamic_cast<PlayerEntity*>(entity);
BoltEntity* boltEntity = dynamic_cast<BoltEntity*>(entity);
if (playerEntity != NULL && !playerEntity->isDead())
{
inflictsRecoilTo(playerEntity);
}
else if (boltEntity != NULL && !boltEntity->getDying() && boltEntity->getAge() > 0.05f)
{
collideWithBolt(boltEntity);
}
}
else // collision with other enemy ?
{
if (entity->getType() >= ENTITY_ENEMY && entity->getType() <= ENTITY_ENEMY_MAX)
{
if (this != entity)
{
EnemyEntity* enemyEntity = static_cast<EnemyEntity*>(entity);
if (enemyEntity->canCollide()) collideWithEnemy(enemyEntity);
}
}
}
}
}
void CauldronEntity::calculateBB()
{
boundingBox.left = (int)x - 25;
boundingBox.width = 50;
boundingBox.top = (int)y - 10;
boundingBox.height = 42;
}
void CauldronEntity::collideMapRight()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
}
void CauldronEntity::collideMapLeft()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
}
void CauldronEntity::collideMapTop()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
}
void CauldronEntity::collideMapBottom()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
}
void CauldronEntity::collideWithEnemy(EnemyEntity* entity)
{
if (entity->getMovingStyle() != movFlying)
inflictsRecoilTo(entity);
}
void CauldronEntity::dying()
{
- new ExplosionEntity(x, y, ExplosionTypeViolet, 0, EnemyTypeNone);
+ new ExplosionEntity(x, y, ExplosionTypeViolet, 0, EnemyTypeNone, true);
SoundManager::getInstance().playSound(dyingSound);
isAgonising = true;
agonizingDelay = 0.7f;
drop();
game().addKilledEnemy(enemyType, hurtingType);
}
void CauldronEntity::drop()
{
EnemyEntity::drop();
}
void CauldronEntity::inflictsRecoilTo(BaseCreatureEntity* targetEntity)
{
Vector2D recoilVector = Vector2D(x, y).vectorTo(Vector2D(targetEntity->getX(), targetEntity->getY()), 200.0f );
targetEntity->giveRecoil(false, recoilVector, 0.1f);
}
diff --git a/src/ChestEntity.cpp b/src/ChestEntity.cpp
index 25fc5b3..374c9f7 100644
--- a/src/ChestEntity.cpp
+++ b/src/ChestEntity.cpp
@@ -1,303 +1,303 @@
#include "ChestEntity.h"
#include "PlayerEntity.h"
#include "FallingRockEntity.h"
#include "ExplosionEntity.h"
#include "SnakeEntity.h"
#include "WitchBlastGame.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "sfml_game/SpriteEntity.h"
#include "Constants.h"
#include <iostream>
ChestEntity::ChestEntity(float x, float y, int chestType, bool isOpen)
: CollidingSpriteEntity(ImageManager::getInstance().getImage(IMAGE_CHEST), x, y, 48, 64)
{
type = ENTITY_CHEST;
imagesProLine = 2;
this->isOpen = isOpen;
this->chestType = chestType;
frame = chestType * imagesProLine;
//if (chestType > ChestFairy) frame = ChestFairy * imagesProLine;
frame += (isOpen ? 1 : 0);
if (isOpen && frame > ChestFairy * imagesProLine + 1) frame = ChestFairy * imagesProLine + 1;
setMap(game().getCurrentMap(), TILE_WIDTH, TILE_HEIGHT, 0, 0);
timer = -1.0f;
appearTimer = -1.0f;
sprite.setOrigin(24, 40);
}
bool ChestEntity::getOpened()
{
return isOpen;
}
int ChestEntity::getChestType()
{
return chestType;
}
void ChestEntity::makeAppear()
{
appearTimer = CHEST_APPEAR_DELAY;
for(int i=0; i < 8; i++)
{
generateStar(sf::Color(50, 50, 255, 255));
generateStar(sf::Color(255, 50, 50, 255));
generateStar(sf::Color(50, 255, 50, 255));
generateStar(sf::Color(255, 255, 255, 255));
}
}
void ChestEntity::animate(float delay)
{
if (appearTimer >= 0.0f) appearTimer -= delay;
CollidingSpriteEntity::animate(delay);
if (!isOpen) testSpriteCollisions();
z = y + 21;
// trap
if (timer > 0.0f)
{
timer -= delay;
if (timer <= 0.0f)
{
if (trap == TrapStones)
{
initFallingGrid();
for (int i = 0; i < 22; i++) fallRock();
SoundManager::getInstance().playSound(SOUND_TRAP);
game().makeShake(0.25f);
}
else if (trap == TrapExplosion)
{
initFallingGrid();
- new ExplosionEntity(x, y, ExplosionTypeStandard, 12, EnemyTypeNone);
+ new ExplosionEntity(x, y, ExplosionTypeStandard, 12, EnemyTypeNone, true);
game().addCorpse(x, y, FRAME_CORPSE_SLIME_VIOLET);
SoundManager::getInstance().playSound(SOUND_BOOM_00);
game().makeShake(0.25f);
}
else // snakes
{
new SnakeEntity(x + 1, y, SnakeEntity::SnakeTypeNormal, true);
new SnakeEntity(x - 1, y, SnakeEntity::SnakeTypeNormal, true);
new SnakeEntity(x, y + 1, SnakeEntity::SnakeTypeNormal, true);
}
}
}
}
void ChestEntity::render(sf::RenderTarget* app)
{
if (appearTimer > 0.0f)
{
int fade = 255 * (1.0f - appearTimer / CHEST_APPEAR_DELAY);
sprite.setColor(sf::Color(255, 255, 255, fade));
}
else
sprite.setColor(sf::Color(255, 255, 255, 255));
CollidingSpriteEntity::render(app);
if (game().getShowLogical())
{
displayBoundingBox(app);
displayCenterAndZ(app);
}
}
void ChestEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2;
boundingBox.width = width;
boundingBox.top = (int)y - 24;
boundingBox.height = 46;
}
void ChestEntity::readCollidingEntity(CollidingSpriteEntity* entity)
{
if (isOpen || appearTimer > 0.5f) return;
PlayerEntity* playerEntity = dynamic_cast<PlayerEntity*>(entity);
if (collideWithEntity(entity))
{
if (playerEntity != NULL && !playerEntity->isDead())
{
open();
frame += 1;
if (frame > ChestFairy * imagesProLine + 1) frame = ChestFairy * imagesProLine + 1;
}
}
}
void ChestEntity::dropItem(enumItemType item)
{
ItemEntity* newItem = new ItemEntity(item, x, y);
newItem->setVelocity(Vector2D(50.0f + rand()% 150));
if (newItem->getVelocity().y < 0.0f) newItem->setVelocity(Vector2D(newItem->getVelocity().x, -newItem->getVelocity().y));
newItem->setViscosity(0.96f);
}
void ChestEntity::open()
{
isOpen = true;
if (chestType >= ChestFairy)
SoundManager::getInstance().playSound(SOUND_GLASS);
else
SoundManager::getInstance().playSound(SOUND_CHEST_OPENING);
if (chestType == ChestBasic)
{
int r = rand()% 50;
if (r == 0 && !game().getPlayer()->isEquiped(EQUIP_FLOOR_MAP))
dropItem(ItemFloorMap);
else if (r == 1 && !game().getPlayer()->isEquiped(EQUIP_ALCOHOL))
dropItem(ItemAlcohol);
else if (r == 2 && !game().getPlayer()->isEquiped(EQUIP_LUCK))
dropItem(ItemLuck);
else if (r == 3 && !game().getPlayer()->isEquiped(EQUIP_FAIRY_POWDER) && game().getPlayer()->getFairieNumber() > 0)
dropItem(ItemFairyPowder);
else
{
// gold
int r = 2 + rand() % 6;
if (game().getPlayer()->isEquiped(EQUIP_LUCK)) r += rand() % 6;
for (int i = 0; i < r; i++)
{
ItemEntity* newItem = new ItemEntity(ItemCopperCoin, x, y);
newItem->setVelocity(Vector2D(50.0f + rand()% 150));
if (newItem->getVelocity().y < 0.0f) newItem->setVelocity(Vector2D(newItem->getVelocity().x, -newItem->getVelocity().y));
newItem->setViscosity(0.96f);
}
}
// trap !
if (game().getLevel() >= 2 && !game().getPlayer()->isEquiped(EQUIP_GLOVES_ADVANCED))
{
if (rand() % 6 == 0) // trap
{
int r = rand() % 3;
if (r == 0)
{
timer = 1.0f;
trap = TrapExplosion;
}
else if (r == 1)
{
timer = 1.0f;
trap = TrapSnakes;
}
else
{
timer = 0.5f;
trap = TrapStones;
}
}
}
}
else if (chestType >= ChestFairy)
{
enumItemType itemType = ItemFairy;
switch (chestType - ChestFairy)
{
case FamiliarFairy: itemType = ItemFairy; break;
case FamiliarFairyIce: itemType = ItemFairyIce; break;
case FamiliarFairyFire: itemType = ItemFairyFire; break;
case FamiliarFairyTarget: itemType = ItemFairyTarget; break;
case FamiliarFairyPoison: itemType = ItemFairyPoison; break;
}
ItemEntity* newItem = new ItemEntity(itemType, x, y);
newItem->setVelocity(Vector2D(50.0f + rand()% 150));
newItem->setViscosity(0.96f);
}
else if (chestType == ChestExit)
{
int r = rand() % 3;
if (r == 0)
{
for (int i = 0; i < 5; i++)
{
ItemEntity* newItem = new ItemEntity(ItemSilverCoin, x, y);
newItem->setVelocity(Vector2D(90.0f + rand()% 150));
if (newItem->getVelocity().y < 0.0f) newItem->setVelocity(Vector2D(newItem->getVelocity().x, -newItem->getVelocity().y));
newItem->setViscosity(0.96f);
}
}
else if (r == 1)
{
for (int i = 0; i < 3; i++)
{
ItemEntity* newItem = new ItemEntity(ItemSilverCoin, x, y);
newItem->setVelocity(Vector2D(90.0f + rand()% 150));
if (newItem->getVelocity().y < 0.0f) newItem->setVelocity(Vector2D(newItem->getVelocity().x, -newItem->getVelocity().y));
newItem->setViscosity(0.96f);
}
ItemEntity* newItem = new ItemEntity(ItemHealth, x, y);
newItem->setVelocity(Vector2D(90.0f + rand()% 150));
if (newItem->getVelocity().y < 0.0f) newItem->setVelocity(Vector2D(newItem->getVelocity().x, -newItem->getVelocity().y));
newItem->setViscosity(0.96f);
}
else
{
int bonusType = game().getRandomEquipItem(false, true);
ItemEntity* newItem;
if (game().getPlayer()->isEquiped(bonusType))
newItem = new ItemEntity( (enumItemType)(ItemBonusHealth), x ,y);
else
newItem = new ItemEntity( (enumItemType)(FirstEquipItem + bonusType), x ,y);
newItem->setVelocity(Vector2D(160.0f + rand()% 80));
if (newItem->getVelocity().y < 0.0f) newItem->setVelocity(Vector2D(newItem->getVelocity().x, -newItem->getVelocity().y));
newItem->setViscosity(0.96f);
}
}
else if (chestType == ChestChallenge)
{
game().generateChallengeBonus(x, y);
}
}
void ChestEntity::initFallingGrid()
{
for (int i = 0; i < MAP_WIDTH; i++)
for (int j = 0; j < MAP_HEIGHT; j++)
fallingGrid[i][j] = false;
}
void ChestEntity::fallRock()
{
int rx, ry;
do
{
rx = 1 + rand() % (MAP_WIDTH - 2);
ry = 1 + rand() % (MAP_HEIGHT - 2);
}
while (fallingGrid[rx][ry]);
fallingGrid[rx][ry] = true;
new FallingRockEntity(rx * TILE_WIDTH + TILE_WIDTH / 2,
ry * TILE_HEIGHT + TILE_HEIGHT / 2,
rand() % 3,
true);
}
void ChestEntity::generateStar(sf::Color starColor)
{
SpriteEntity* spriteStar = new SpriteEntity(
ImageManager::getInstance().getImage(IMAGE_STAR_2),
x - 15 + rand() % 30, y - 10 + rand() % 30);
spriteStar->setScale(0.8f, 0.8f);
spriteStar->setZ(1000.0f);
spriteStar->setSpin(-100 + rand()%200);
spriteStar->setVelocity(Vector2D(50 + rand()%40));
spriteStar->setWeight(-130);
spriteStar->setFading(true);
spriteStar->setAge(-0.8f);
spriteStar->setLifetime(0.2f + (rand() % 100) * 0.005f );
spriteStar->setColor(starColor);
spriteStar->setType(ENTITY_EFFECT);
spriteStar->setRenderAdd();
}
diff --git a/src/ExplosionEntity.cpp b/src/ExplosionEntity.cpp
index 130a41d..9209cf2 100644
--- a/src/ExplosionEntity.cpp
+++ b/src/ExplosionEntity.cpp
@@ -1,102 +1,102 @@
#include "ExplosionEntity.h"
#include "BaseCreatureEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "sfml_game/SpriteEntity.h"
#include "Constants.h"
#include "WitchBlastGame.h"
#include <iostream>
-ExplosionEntity::ExplosionEntity(float x, float y, explosionTypeEnum explosionType, int damage, enemyTypeEnum enemyType)
+ExplosionEntity::ExplosionEntity(float x, float y, explosionTypeEnum explosionType, int damage, enemyTypeEnum enemyType, bool canHurtPlayer)
: SpriteEntity(ImageManager::getInstance().getImage(IMAGE_EXPLOSION), x, y, 100, 100)
{
type = ENTITY_EXPLOSION;
this->explosionType = explosionType;
imagesProLine = 6;
lifetime = 0.6f;
- canHurtPlayer = false;
+ this->canHurtPlayer = canHurtPlayer;
this->damage = damage;
switch (explosionType)
{
case ExplosionTypeStandard: frame = 0; break;
case ExplosionTypeViolet: frame = 6; break;
}
sprite.setOrigin(50, 50);
testCollisions();
}
void ExplosionEntity::setCanHurtPlayer(bool can)
{
canHurtPlayer = can;
}
void ExplosionEntity::animate(float delay)
{
if (lifetime > 0)
{
if (age >= lifetime) isDying = true;
}
age += delay;
z = y + height / 2;
frame = age / lifetime * 6;
if (frame > 5) frame = 5;
switch (explosionType)
{
case ExplosionTypeStandard: break;
case ExplosionTypeViolet: frame += 6; break;
}
}
void ExplosionEntity::render(sf::RenderTarget* app)
{
SpriteEntity::render(app);
}
void ExplosionEntity::dying()
{
isDying = true;
}
void ExplosionEntity::testCollisions()
{
EntityManager::EntityList* entityList =EntityManager::getInstance().getList();
EntityManager::EntityList::iterator it;
for (it = entityList->begin (); it != entityList->end ();)
{
GameEntity *e = *it;
it++;
BaseCreatureEntity* entity = dynamic_cast<BaseCreatureEntity*>(e);
if (entity != NULL)
{
bool ok = true;
if (!canHurtPlayer && entity->getType() == ENTITY_PLAYER) ok = false;
if (ok && entity->getHp() > 0 && entity->canCollide())
{
entity->calculateBB();
sf::IntRect bb;
bb.left = x - 90;
bb.width = 180;
bb.top = y - 90;
bb.height = 180;
if (bb.intersects(entity->getBoundingBox()))
{
// TODO explosion type
if (damage > 0) entity->hurt(BaseCreatureEntity::getHurtParams(damage, ShotTypeFire, 0, false, SourceTypeExplosion, enemyType, false));
Vector2D recoilVector = Vector2D(x, y).vectorTo(Vector2D(entity->getX(), entity->getY()), 800.0f );
entity->giveRecoil(true, recoilVector, 1.0f);
}
}
}
}
}
diff --git a/src/ExplosionEntity.h b/src/ExplosionEntity.h
index ae00d76..be305c5 100644
--- a/src/ExplosionEntity.h
+++ b/src/ExplosionEntity.h
@@ -1,32 +1,32 @@
#ifndef EXPLOSIONENTITY_H
#define EXPLOSIONENTITY_H
#include "sfml_game/SpriteEntity.h"
#include "BaseCreatureEntity.h"
enum explosionTypeEnum { ExplosionTypeStandard, ExplosionTypeViolet };
class ExplosionEntity : public SpriteEntity
{
public:
- ExplosionEntity(float x, float y, explosionTypeEnum explosionType, int damage, enemyTypeEnum enemyType);
+ ExplosionEntity(float x, float y, explosionTypeEnum explosionType, int damage, enemyTypeEnum enemyType, bool canHurtPlayer);
virtual void animate(float delay);
virtual void render(sf::RenderTarget* app);
virtual void dying();
void setCanHurtPlayer(bool can);
//enemyTypeEnum getEnemyType();
protected:
void testCollisions();
private:
int damage;
explosionTypeEnum explosionType;
enemyTypeEnum enemyType;
bool canHurtPlayer;
};
#endif // EXPLOSIONENTITY_H
diff --git a/src/SlimeEntity.cpp b/src/SlimeEntity.cpp
index 44c5e42..a235b3f 100644
--- a/src/SlimeEntity.cpp
+++ b/src/SlimeEntity.cpp
@@ -1,393 +1,393 @@
#include "SlimeEntity.h"
#include "PlayerEntity.h"
#include "EnemyBoltEntity.h"
#include "ExplosionEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
SlimeEntity::SlimeEntity(float x, float y, slimeTypeEnum slimeType, bool invocated)
: EnemyEntity (ImageManager::getInstance().getImage(IMAGE_SLIME), x, y)
{
creatureSpeed = 0.0f;
velocity = Vector2D(0.0f, 0.0f);
hp = SLIME_HP;
meleeDamages = SLIME_DAMAGES;
this->slimeType = slimeType;
this->invocated = invocated;
if (invocated)
{
type = ENTITY_ENEMY_INVOCATED;
jumpingDelay = 0.1f;
age = 0.0f;
}
else
{
jumpingDelay = 0.6f + 0.1f * (rand() % 20);
}
if (slimeType == SlimeTypeBlue)
{
resistance[ResistanceFrozen] = ResistanceImmune;
resistance[ResistanceIce] = ResistanceVeryHigh;
resistance[ResistanceFire] = ResistanceVeryLow;
enemyType = invocated ? EnemyTypeSlimeBlue_invocated : EnemyTypeSlimeBlue;
deathFrame = FRAME_CORPSE_SLIME_BLUE;
}
else if (slimeType == SlimeTypeRed)
{
resistance[ResistanceIce] = ResistanceVeryLow;
resistance[ResistanceFire] = ResistanceVeryHigh;
enemyType = invocated ? EnemyTypeSlimeRed_invocated : EnemyTypeSlimeRed;
deathFrame = FRAME_CORPSE_SLIME_RED;
}
else if (slimeType == SlimeTypeViolet)
{
enemyType = invocated ? EnemyTypeSlimeViolet_invocated : EnemyTypeSlimeViolet;
canExplode = false;
deathFrame = FRAME_CORPSE_SLIME_VIOLET;
}
else
{
enemyType = invocated ? EnemyTypeSlime_invocated : EnemyTypeSlime;
deathFrame = FRAME_CORPSE_SLIME;
}
bloodColor = BloodGreen;
frame = 0;
shadowFrame = 3;
imagesProLine = 4;
isJumping = false;
h = 0.0f;
viscosity = 0.98f;
sprite.setOrigin(32, 44);
isPet = false;
willExplode = false;
}
void SlimeEntity::animate(float delay)
{
float slimeDelay = delay;
if (specialState[SpecialStateIce].active) slimeDelay = delay * specialState[SpecialStateIce].param1;
if (isJumping)
{
hVelocity -= 700.0f * slimeDelay;
h += hVelocity * slimeDelay;
bool firstTimeGround = false;
if (h <= 0.0f)
{
if (hp <= 0)
dying();
else
{
h = 0.0f;
if (isFirstJumping)
{
isFirstJumping = false;
firstTimeGround = true;
hVelocity = 160.0f;
SoundManager::getInstance().playSound(SOUND_SLIME_IMAPCT);
if (slimeType == SlimeTypeBlue || slimeType == SlimeTypeRed)
fire();
else if (slimeType == SlimeTypeViolet)
{
hp = 0;
dying();
}
}
else
{
jumpingDelay = 0.4f + 0.1f * (rand() % 20);
isJumping = false;
SoundManager::getInstance().playSound(SOUND_SLIME_IMAPCT_WEAK);
}
}
}
if (firstTimeGround) frame = 0;
else if (hVelocity > -190.0f) frame = 2;
else frame = 1;
}
else
{
jumpingDelay -= slimeDelay;
if (jumpingDelay < 0.0f)
{
SoundManager::getInstance().playSound(SOUND_SLIME_JUMP);
hVelocity = 350.0f + rand() % 300;
isJumping = true;
isFirstJumping = true;
float randVel = 250.0f + rand() % 250;
if (!game().getPlayer()->isEquiped(EQUIP_MANUAL_SLIMES) && rand() % 2 == 0)
{
setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), randVel ));
}
else
velocity = Vector2D(randVel);
}
else if (jumpingDelay < 0.1f)
frame = 1;
else frame = 0;
}
EnemyEntity::animate(delay);
z = y + 14;
}
void SlimeEntity::makeExplode()
{
if (isJumping)
willExplode = true;
else
BaseCreatureEntity::makeExplode();
}
void SlimeEntity::readCollidingEntity(CollidingSpriteEntity* entity)
{
if (!isDying && !isAgonising && collideWithEntity(entity))
{
if (!isPet && (entity->getType() == ENTITY_PLAYER || entity->getType() == ENTITY_BOLT ) )
{
PlayerEntity* playerEntity = dynamic_cast<PlayerEntity*>(entity);
BoltEntity* boltEntity = dynamic_cast<BoltEntity*>(entity);
if (playerEntity != NULL && !playerEntity->isDead())
{
if (playerEntity->hurt(getHurtParams(meleeDamages, meleeType, meleeDamages, false, SourceTypeMelee, enemyType, false)))
{
float xs = (x + playerEntity->getX()) / 2;
float ys = (y + playerEntity->getY()) / 2;
SpriteEntity* star = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_HURT_IMPACT), xs, ys);
star->setFading(true);
star->setZ(y+ 100);
star->setLifetime(0.7f);
star->setType(ENTITY_EFFECT);
star->setSpin(400.0f);
}
inflictsRecoilTo(playerEntity);
}
else if (boltEntity != NULL && !boltEntity->getDying() && boltEntity->getAge() > 0.05f)
{
collideWithBolt(boltEntity);
}
}
else // collision with other enemy ?
{
if (entity->getType() >= ENTITY_ENEMY && entity->getType() <= ENTITY_ENEMY_MAX_COUNT)
{
if (this != entity)
{
EnemyEntity* enemyEntity = static_cast<EnemyEntity*>(entity);
if (enemyEntity->canCollide()) collideWithEnemy(enemyEntity);
}
}
}
}
}
void SlimeEntity::render(sf::RenderTarget* app)
{
if (!isDying && shadowFrame > -1)
{
// shadow
sprite.setPosition(x, y);
sprite.setTextureRect(sf::IntRect(shadowFrame * width, 0, width, height));
app->draw(sprite);
}
sprite.setPosition(x, y - h);
sprite.setTextureRect(sf::IntRect(frame * width, slimeType * height, width, height));
app->draw(sprite);
if (game().getShowLogical())
{
displayBoundingBox(app);
displayCenterAndZ(app);
}
}
void SlimeEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + SLIME_BB_LEFT;
boundingBox.width = width - SLIME_BB_WIDTH_DIFF;
boundingBox.top = (int)y - height / 2 + SLIME_BB_TOP - 15;
boundingBox.height = height - SLIME_BB_HEIGHT_DIFF;
}
void SlimeEntity::collideMapRight()
{
// if (x > OFFSET_X + MAP_WIDTH * TILE_WIDTH)
velocity.x = -velocity.x * 0.8f;
}
void SlimeEntity::collideMapLeft()
{
// if (x < OFFSET_X + MAP_WIDTH )
velocity.x = -velocity.x * 0.8f;
}
void SlimeEntity::collideMapTop()
{
// if (y > OFFSET_Y + MAP_HEIGHT * TILE_HEIGHT)
velocity.y = -velocity.y * 0.8f;
}
void SlimeEntity::collideMapBottom()
{
// if (y < OFFSET_Y + MAP_HEIGHT )
velocity.y = -velocity.y * 0.8f;
}
void SlimeEntity::collideWithEnemy(EnemyEntity* entity)
{
if (recoil.active && recoil.stun) return;
if (entity->getMovingStyle() == movWalking)
{
Vector2D vel = Vector2D(entity->getX(), entity->getY()).vectorTo(Vector2D(x, y), 100.0f );
giveRecoil(false, vel, 0.3f);
computeFacingDirection();
}
}
bool SlimeEntity::collideWithMap(int direction)
{
calculateBB();
int xTile0 = (boundingBox.left - offsetX) / tileWidth;
int xTilef = (boundingBox.left + boundingBox.width - offsetX) / tileWidth;
int yTile0 = (boundingBox.top - offsetY) / tileHeight;
int yTilef = (boundingBox.top + boundingBox.height - offsetY) / tileHeight;
if (boundingBox.top < 0) yTile0 = -1;
for (int xTile = xTile0; xTile <= xTilef; xTile++)
for (int yTile = yTile0; yTile <= yTilef; yTile++)
{
if (!game().getCurrentMap()->isFlyable(xTile, yTile))
{
switch (direction)
{
case DIRECTION_LEFT:
if (map->isLeftBlocking(xTile, yTile)) return true;
break;
case DIRECTION_RIGHT:
if (map->isRightBlocking(xTile, yTile)) return true;
break;
case DIRECTION_TOP:
if (map->isUpBlocking(xTile, yTile)) return true;
break;
case DIRECTION_BOTTOM:
if (map->isDownBlocking(xTile, yTile)) return true;
break;
}
}
}
return false;
}
void SlimeEntity::dying()
{
if (slimeType == SlimeTypeViolet) explode();
else if (willExplode) BaseCreatureEntity::makeExplode();
EnemyEntity::dying();
}
void SlimeEntity::prepareDying()
{
if (!isJumping)
dying();
}
bool SlimeEntity::canCollide()
{
return h <= 70.0f && hp > 0;
}
BaseCreatureEntity::enumMovingStyle SlimeEntity::getMovingStyle()
{
if (h <= 70.0f)
return movWalking;
else
return movFlying;
}
void SlimeEntity::fire()
{
for (int i = 0; i < 4; i++)
{
EnemyBoltEntity* bolt;
if (slimeType == SlimeTypeBlue)
{
bolt = new EnemyBoltEntity(x, y, ShotTypeIce, 0, enemyType);
bolt->setDamages(5);
}
else if (slimeType == SlimeTypeRed)
{
bolt = new EnemyBoltEntity(x, y, ShotTypeFire, 0, enemyType);
bolt->setDamages(8);
}
else
return;
switch (i)
{
case 0: bolt->setVelocity(Vector2D(SLIME_FIRE_VELOCITY, 0)); break;
case 1: bolt->setVelocity(Vector2D(-SLIME_FIRE_VELOCITY, 0)); break;
case 2: bolt->setVelocity(Vector2D(0, SLIME_FIRE_VELOCITY)); break;
case 3: bolt->setVelocity(Vector2D(0, -SLIME_FIRE_VELOCITY)); break;
}
}
if (slimeType == SlimeTypeBlue) SoundManager::getInstance().playSound(SOUND_BLAST_ICE);
else if (slimeType == SlimeTypeRed) SoundManager::getInstance().playSound(SOUND_BLAST_FIRE);
else SoundManager::getInstance().playSound(SOUND_BLAST_FLOWER);
}
void SlimeEntity::explode()
{
int damage = 12;
if (isPet) damage = game().getPlayer()->isEquiped(EQUIP_BOOK_MAGIC_II) ? 24 : 18;
- new ExplosionEntity(x, y, ExplosionTypeStandard, damage, enemyType);
+ new ExplosionEntity(x, y, ExplosionTypeStandard, damage, enemyType, true);
game().makeShake(1.0f);
SoundManager::getInstance().playSound(SOUND_BOOM_00);
}
void SlimeEntity::makePet(int direction)
{
isPet = true;
hVelocity = 450.0f;
SoundManager::getInstance().playSound(SOUND_SLIME_JUMP);
isJumping = true;
isFirstJumping = true;
switch (direction)
{
case 4: velocity.x = -350.0f; velocity.y = -0; break;
case 6: velocity.x = 350.0f; velocity.y = -0; break;
case 2: velocity.y = 350.0f; velocity.x = -0; break;
default: velocity.y = -350.0f; velocity.x = -0; break;
}
}
void SlimeEntity::drop()
{
if (!invocated) EnemyEntity::drop();
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Jan 30, 2:32 PM (5 d, 11 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55389
Default Alt Text
(38 KB)

Event Timeline