Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F125849
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
105 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/BatEntity.cpp b/src/BatEntity.cpp
index f03d4e2..f9187a8 100644
--- a/src/BatEntity.cpp
+++ b/src/BatEntity.cpp
@@ -1,85 +1,87 @@
#include "BatEntity.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"
BatEntity::BatEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_BAT), x, y)
{
creatureSpeed = BAT_SPEED;
velocity = Vector2D(creatureSpeed);
hp = BAT_HP;
meleeDamages = BAT_DAMAGES;
type = ENTITY_ENNEMY;
bloodColor = bloodRed;
changingDelay = -0.5f;
shadowFrame = 3;
movingStyle = movFlying;
dyingFrame = 2;
deathFrame = FRAME_CORPSE_BAT;
agonizingSound = SOUND_BAT_DYING;
+
+ enemyType = EnemyTypeBat;
}
void BatEntity::animate(float delay)
{
changingDelay -= delay;
if (changingDelay < 0.0f)
{
velocity = Vector2D(creatureSpeed);
changingDelay = 0.5f + (float)(rand() % 2500) / 1000.0f;
}
if (age < 0.0f)
frame = 1;
else
frame = ((int)(age * 5.0f)) % 2;
EnnemyEntity::animate(delay);
}
void BatEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + BAT_BB_LEFT;
boundingBox.width = width - BAT_BB_WIDTH_DIFF;
boundingBox.top = (int)y - height / 2 + BAT_BB_TOP;
boundingBox.height = height - BAT_BB_HEIGHT_DIFF;
}
void BatEntity::collideMapRight()
{
velocity.x = -velocity.x;
}
void BatEntity::collideMapLeft()
{
velocity.x = -velocity.x;
}
void BatEntity::collideMapTop()
{
velocity.y = -velocity.y;
}
void BatEntity::collideMapBottom()
{
velocity.y = -velocity.y;
}
void BatEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movFlying)
{
setVelocity(Vector2D(entity->getX(), entity->getY()).vectorTo(Vector2D(x, y), BAT_SPEED ));
}
}
void BatEntity::dying()
{
EnnemyEntity::dying();
h = 25.0f;
}
diff --git a/src/BlackRatEntity.cpp b/src/BlackRatEntity.cpp
index f38f992..0999453 100644
--- a/src/BlackRatEntity.cpp
+++ b/src/BlackRatEntity.cpp
@@ -1,192 +1,193 @@
#include "BlackRatEntity.h"
#include "BoltEntity.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"
#include <iostream>
BlackRatEntity::BlackRatEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_RAT), x, y),
currentTile(0, 0),
targetTile(0, 0)
{
imagesProLine = 8;
creatureSpeed = BLACK_RAT_SPEED;
hp = BLACK_RAT_HP;
meleeDamages = BLACK_RAT_DAMAGES;
type = ENTITY_ENNEMY;
bloodColor = bloodRed;
shadowFrame = 7;
frame = 16;
dyingFrame = 22;
deathFrame = FRAME_CORPSE_BLACK_RAT;
agonizingSound = SOUND_RAT_DYING;
+ enemyType = EnemyTypeRatBlack;
currentDirection = 0;
findNextGoal();
}
void BlackRatEntity::animate(float delay)
{
if (age > 0.0f && !isAgonising)
{
// goal reached ?
if (currentDirection == 6 && x > (targetTile.x * TILE_WIDTH + TILE_WIDTH / 2 + OFFSET_X) ) findNextGoal();
else if (currentDirection == 4 && x < (targetTile.x * TILE_WIDTH + TILE_WIDTH / 2 + OFFSET_X) ) findNextGoal();
else if (currentDirection == 2 && y > (targetTile.y * TILE_HEIGHT + TILE_HEIGHT / 2 + OFFSET_Y - 5) ) findNextGoal();
else if (currentDirection == 8 && y < (targetTile.y * TILE_HEIGHT + TILE_HEIGHT / 2 + OFFSET_Y - 5) ) findNextGoal();
frame = 16 + ((int)(age * 5.0f)) % 2;
if (facingDirection == 4 || facingDirection == 6) frame += 2;
isMirroring = (facingDirection == 4 );
if (facingDirection == 8) frame += 4;
}
EnnemyEntity::animate(delay);
}
void BlackRatEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + RAT_BB_LEFT;
boundingBox.width = width - RAT_BB_WIDTH_DIFF;
boundingBox.top = (int)y - height / 2 + RAT_BB_TOP;
boundingBox.height = height - RAT_BB_HEIGHT_DIFF;
}
void BlackRatEntity::collideMapRight()
{
findNextGoal();
}
void BlackRatEntity::collideMapLeft()
{
findNextGoal();
}
void BlackRatEntity::collideMapTop()
{
findNextGoal();
}
void BlackRatEntity::collideMapBottom()
{
findNextGoal();
}
void BlackRatEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movWalking)
{
if (currentDirection == 6 && entity->getX() > x)
{
currentDirection = 4;
targetTile = IntCoord(currentTile.x - 1, currentTile.y);
}
else if (currentDirection == 4 && entity->getX() < x)
{
currentDirection = 6;
targetTile = IntCoord(currentTile.x + 1, currentTile.y);
}
else if (currentDirection == 8 && entity->getY() < y)
{
currentDirection = 2;
targetTile = IntCoord(currentTile.x, currentTile.y + 1);
}
else if (currentDirection == 2 && entity->getY() > y)
{
currentDirection = 8;
targetTile = IntCoord(currentTile.x, currentTile.y - 1);
}
switch (currentDirection)
{
case 4: velocity.x = - BLACK_RAT_SPEED; velocity.y = 0.0f; break;
case 6: velocity.x = + BLACK_RAT_SPEED; velocity.y = 0.0f; break;
case 2: velocity.y = + BLACK_RAT_SPEED; velocity.x = 0.0f; break;
case 8: velocity.y = - BLACK_RAT_SPEED; velocity.x = 0.0f; break;
default: break;
}
facingDirection = currentDirection;
}
}
void BlackRatEntity::findNextGoal()
{
currentTile = getCurrentTile();
int backDirection = 0;
switch (currentDirection)
{
case 4: backDirection = 6; break;
case 6: backDirection = 4; break;
case 2: backDirection = 8; break;
case 8: backDirection = 2; break;
default: break;
}
{
bool ok = false;
int r = 0;
while (!ok)
{
r++;
if (r == 150) // watchdog
ok = true;
int newDir = rand() % 4;
if (newDir == 0)
{
if (backDirection != 4 && currentTile.x > 2 && (currentTile.y % 2 != 0))
{
currentDirection = 4;
targetTile = IntCoord(currentTile.x - 2, currentTile.y);
ok = true;
}
}
else if (newDir == 1)
{
if (backDirection != 6 && currentTile.x < MAP_WIDTH - 2 && (currentTile.y % 2 != 0))
{
currentDirection = 6;
targetTile = IntCoord(currentTile.x + 2, currentTile.y);
ok = true;
}
}
else if (newDir == 2)
{
if (backDirection != 8 && currentTile.y > 1 && (currentTile.x % 2 != 0))
{
currentDirection = 8;
targetTile = IntCoord(currentTile.x, currentTile.y - 2);
ok = true;
}
}
else
{
if (backDirection != 2 && currentTile.y < MAP_HEIGHT - 2 && (currentTile.x % 2 != 0))
{
currentDirection = 2;
targetTile = IntCoord(currentTile.x, currentTile.y + 2);
ok = true;
}
}
}
}
switch (currentDirection)
{
case 4: velocity.x = - BLACK_RAT_SPEED; velocity.y = 0.0f; break;
case 6: velocity.x = + BLACK_RAT_SPEED; velocity.y = 0.0f; break;
case 2: velocity.y = + BLACK_RAT_SPEED; velocity.x = 0.0f; break;
case 8: velocity.y = - BLACK_RAT_SPEED; velocity.x = 0.0f; break;
default: break;
}
facingDirection = currentDirection;
}
diff --git a/src/ButcherEntity.cpp b/src/ButcherEntity.cpp
index 6be30b8..1cafdd7 100644
--- a/src/ButcherEntity.cpp
+++ b/src/ButcherEntity.cpp
@@ -1,153 +1,154 @@
#include "ButcherEntity.h"
#include "BoltEntity.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"
ButcherEntity::ButcherEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_BUTCHER), x, y)
{
width = 128;
height = 128;
sprite.setOrigin((float)(this->width / 2), (float)(this->height / 2));
creatureSpeed = BUTCHER_VELOCITY;
velocity = Vector2D(creatureSpeed);
computeFacingDirection();
hp = BUTCHER_HP;
hpMax = BUTCHER_HP;
hpDisplay = BUTCHER_HP;
meleeDamages = BUTCHER_DAMAGES;
type = ENTITY_ENNEMY_BOSS;
bloodColor = bloodRed;
shadowFrame = 5;
dyingFrame = 3;
deathFrame = FRAME_CORPSE_BUTCHER;
agonizingSound = SOUND_BUTCHER_DIE;
hurtingSound = SOUND_BUTCHER_HURT;
+ enemyType = EnemyTypeButcher;
timer = (rand() % 50) / 10.0f;
age = -1.5f;
frame = 0;
resistance[ResistanceFrozen] = ResistanceHigh;
resistance[ResistanceRecoil] = ResistanceHigh;
}
void ButcherEntity::animate(float delay)
{
if (age > 0.0f && !isAgonising)
{
sprite.setColor(sf::Color(255,255,255,255));
timer = timer - delay;
if (timer <= 0.0f)
{
creatureSpeed = BUTCHER_VELOCITY + hpMax - hp;
timer = (rand() % 50) / 10.0f;
setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), creatureSpeed ));
if (rand()%2 == 0)
SoundManager::getSoundManager()->playSound(SOUND_BUTCHER_00);
else
SoundManager::getSoundManager()->playSound(SOUND_BUTCHER_01);
}
frame = ((int)(age * creatureSpeed / 25)) % 4;
if (frame == 2) frame = 0;
else if (frame == 3) frame = 2;
if (velocity.x > 1.0f) isMirroring = true;
else if (velocity.x < -1.0f) isMirroring = false;
}
EnnemyEntity::animate(delay);
z = y + 55;
}
void ButcherEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + 45;
boundingBox.width = 44;
boundingBox.top = (int)y - height / 2 + 48;
boundingBox.height = 72;
}
void ButcherEntity::collideMapRight()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
}
void ButcherEntity::collideMapLeft()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
}
void ButcherEntity::collideMapTop()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
}
void ButcherEntity::collideMapBottom()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
}
void ButcherEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
if (recoil.active && recoil.stun) return;
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movWalking )
{
Vector2D vel = Vector2D(entity->getX(), entity->getY()).vectorTo(Vector2D(x, y), 100.0f );
giveRecoil(false, vel, 0.3f);
}
}
void ButcherEntity::drop()
{
ItemEntity* newItem = new ItemEntity(ItemSilverCoin, x, y);
newItem->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
newItem->setVelocity(Vector2D(100.0f + rand()% 250));
newItem->setViscosity(0.96f);
}
void ButcherEntity::render(sf::RenderTarget* app)
{
EnnemyEntity::render(app);
float l = hpDisplay * ((MAP_WIDTH - 1) * TILE_WIDTH) / hpMax;
sf::RectangleShape rectangle(sf::Vector2f((MAP_WIDTH - 1) * TILE_WIDTH, 25));
rectangle.setFillColor(sf::Color(0, 0, 0,128));
rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT));
app->draw(rectangle);
rectangle.setSize(sf::Vector2f(l, 25));
rectangle.setFillColor(sf::Color(190, 20, 20));
rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT));
app->draw(rectangle);
game().write( "Pigman Butcher",
18,
OFFSET_X + TILE_WIDTH / 2 + 10.0f,
OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT + 1.0f,
ALIGN_LEFT,
sf::Color(255, 255, 255),
app, 0 , 0);
}
bool ButcherEntity::hurt(int damages, enumShotType hurtingType, int level)
{
creatureSpeed = BUTCHER_VELOCITY + hpMax - hp;
setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), creatureSpeed ));
return EnnemyEntity::hurt(damages, hurtingType, level);
}
diff --git a/src/CyclopEntity.cpp b/src/CyclopEntity.cpp
index 88a4ffd..04e1d6c 100644
--- a/src/CyclopEntity.cpp
+++ b/src/CyclopEntity.cpp
@@ -1,379 +1,380 @@
#include "CyclopEntity.h"
#include "BoltEntity.h"
#include "PlayerEntity.h"
#include "RockMissileEntity.h"
#include "FallingRockEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
#include <iostream>
CyclopEntity::CyclopEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_CYCLOP), x, y)
{
width = 128;
height = 192;
creatureSpeed = CYCLOP_SPEED[0];
velocity = Vector2D(creatureSpeed);
hp = CYCLOP_HP;
hpDisplay = CYCLOP_HP;
hpMax = CYCLOP_HP;
meleeDamages = CYCLOP_DAMAGES;
type = ENTITY_ENNEMY_BOSS;
bloodColor = bloodRed;
shadowFrame = 8;
dyingFrame = 5;
deathFrame = FRAME_CORPSE_CYCLOP;
dyingSound = SOUND_CYCLOP_DIE;
frame = 0;
if (game().getPlayerPosition().x > x) isMirroring = true;
sprite.setOrigin(64.0f, 128.0f);
nextRockMissile = 0;
destroyLevel = 0;
state = 0;
timer = 2.0f;
counter = 10;
age = -1.5f;
+ enemyType = EnemyTypeCyclops;
resistance[ResistanceFrozen] = ResistanceVeryHigh;
resistance[ResistanceRecoil] = ResistanceVeryHigh;
}
int CyclopEntity::getHealthLevel()
{
int healthLevel = 0;
if (hp <= hpMax * 0.25) healthLevel = 3;
else if (hp <= hpMax * 0.5) healthLevel = 2;
else if (hp <= hpMax * 0.75) healthLevel = 1;
return healthLevel;
}
void CyclopEntity::fire()
{
new RockMissileEntity(x, y - 62, nextRockMissile);
SoundManager::getSoundManager()->playSound(SOUND_THROW);
}
void CyclopEntity::initFallingGrid()
{
for (int i = 0; i < MAP_WIDTH; i++)
for (int j = 0; j < MAP_HEIGHT; j++)
fallingGrid[i][j] = false;
}
void CyclopEntity::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 + OFFSET_X + TILE_WIDTH / 2,
ry * TILE_HEIGHT + OFFSET_Y + TILE_HEIGHT / 2,
rand() % 3);
}
void CyclopEntity::computeNextRockMissile()
{
if (getHealthLevel() == 0)
nextRockMissile = rand()%5 == 0 ? 1 : 0;
else if (getHealthLevel() == 1)
nextRockMissile = rand()%3 == 0 ? 1 : 0;
else if (getHealthLevel() == 2)
nextRockMissile = rand()%2 == 0 ? 0 : 1;
else
nextRockMissile = rand()%3 == 0 ? 0 : 1;
}
void CyclopEntity::computeStates(float delay)
{
timer -= delay;
if (timer <= 0.0f)
{
if (state == 0) // walking
{
if (counter > 0)
{
counter--;
timer = 0.5f;
creatureSpeed = CYCLOP_SPEED[getHealthLevel()];
setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), creatureSpeed ));
}
else
{
velocity.x = 0.0f;
velocity.y = 0.0f;
if (destroyLevel < getHealthLevel())
{
state = 3; // charge to destroy
destroyLevel++;
counter = destroyLevel + 1;
timer = 0.9f;
SoundManager::getSoundManager()->playSound(SOUND_CYCLOP_00);
initFallingGrid();
}
else
{
state = 1; // charge to fire
timer = 0.9f;
counter = CYCLOP_NUMBER_ROCKS[getHealthLevel()];
SoundManager::getSoundManager()->playSound(SOUND_CYCLOP_00);
computeNextRockMissile();
}
}
}
else if (state == 1) // fire
{
state = 2;
fire();
timer = CYCLOP_FIRE_DELAY[getHealthLevel()];
}
else if (state == 2) // fire end
{
if (counter <= 1)
{
state = 0;
timer = 0.2f;
counter = 10;
}
else
{
counter--;
state = 1;
timer = 0.2f;
computeNextRockMissile();
}
}
else if (state == 3)
{
state = 4; // destroy
timer = 0.2;
game().makeShake(0.4f);
SoundManager::getSoundManager()->playSound(SOUND_WALL_IMPACT);
for (int i = 0; i < 10 ; i++) fallRock();
}
else if (state == 4)
{
if (counter <= 1)
{
state = 0;
timer = 0.2f;
counter = 10;
}
else
{
counter--;
state = 3;
timer = 0.3f;
}
}
}
}
void CyclopEntity::animate(float delay)
{
if (age <= 0.0f)
{
age += delay;
return;
}
if (isAgonising)
{
if (h < -0.01f)
{
isDying = true;
SpriteEntity* corpse;
corpse = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES_BIG), x, y, 128, 128);
corpse->setFrame(deathFrame - FRAME_CORPSE_KING_RAT);
corpse->setZ(OFFSET_Y);
corpse->setType(ENTITY_CORPSE);
if (dyingSound != SOUND_NONE) SoundManager::getSoundManager()->playSound(dyingSound);
}
else
{
frame = dyingFrame;
hVelocity -= 700.0f * delay;
h += hVelocity * delay;
}
return;
}
// special states
if (specialState[SpecialStateIce].active) delay *= specialState[SpecialStateIce].parameter;
// IA
computeStates(delay);
// collisions
if (canCollide()) testSpriteCollisions();
BaseCreatureEntity::animate(delay);
// current frame
if (state == 0)
{
int r = ((int)(age * 5.0f)) % 4;
if (r == 2) frame = 0;
else if (r == 3) frame = 2;
else frame = r;
}
else if (state == 1)
{
isMirroring = game().getPlayer()->getX() > x;
frame = 3;
}
else if (state == 2)
{
frame = 4;
}
else if (state == 3)
{
frame = 6;
}
else if (state == 4)
{
frame = 7;
}
// frame's mirroring
if (velocity.x > 1.0f)
isMirroring = true;
else if (velocity.x < -1.0f)
isMirroring = false;
z = OFFSET_Y + y + 46;
}
bool CyclopEntity::hurt(int damages, enumShotType hurtingType, int level)
{
if (destroyLevel < getHealthLevel()) damages /= 3;
return EnnemyEntity::hurt(damages, hurtingType, level);
}
void CyclopEntity::calculateBB()
{
boundingBox.left = OFFSET_X + (int)x - 32;
boundingBox.width = 58;
boundingBox.top = OFFSET_Y + (int)y - 42;
boundingBox.height = 90;
}
void CyclopEntity::afterWallCollide()
{
}
void CyclopEntity::collideMapRight()
{
velocity.x = -velocity.x;
afterWallCollide();
}
void CyclopEntity::collideMapLeft()
{
velocity.x = -velocity.x;
afterWallCollide();
}
void CyclopEntity::collideMapTop()
{
velocity.y = -velocity.y;
afterWallCollide();
}
void CyclopEntity::collideMapBottom()
{
velocity.y = -velocity.y;
afterWallCollide();
}
void CyclopEntity::dying()
{
EnnemyEntity::dying();
}
void CyclopEntity::drop()
{
ItemEntity* newItem = new ItemEntity(itemBossHeart, x, y);
newItem->setVelocity(Vector2D(100.0f + rand()% 250));
newItem->setViscosity(0.96f);
}
void CyclopEntity::render(sf::RenderTarget* app)
{
EnnemyEntity::render(app);
// stones
if (state == 1)
{
if (nextRockMissile == 0) // small rock
{
sprite.setTextureRect(sf::IntRect(1152, 0, 64, 64));
if (isMirroring)
sprite.setPosition(x + 60, y);
else
sprite.setPosition(x + 4, y);
}
else // medium rock
{
sprite.setTextureRect(sf::IntRect(1152, 64, 64, 64));
if (isMirroring)
sprite.setPosition(x + 60, y - 12);
else
sprite.setPosition(x + 4, y - 12);
}
app->draw(sprite);
sprite.setPosition(x, y);
}
float l = hpDisplay * ((MAP_WIDTH - 1) * TILE_WIDTH) / hpMax;
sf::RectangleShape rectangle(sf::Vector2f((MAP_WIDTH - 1) * TILE_WIDTH, 25));
rectangle.setFillColor(sf::Color(0, 0, 0,128));
rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT));
app->draw(rectangle);
rectangle.setSize(sf::Vector2f(l, 25));
rectangle.setFillColor(sf::Color(190, 20, 20));
rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT));
app->draw(rectangle);
game().write( "Cimmerian Cyclops",
18,
OFFSET_X + TILE_WIDTH / 2 + 10.0f,
OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT + 1.0f,
ALIGN_LEFT,
sf::Color(255, 255, 255),
app, 0 , 0);
}
void CyclopEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movWalking)
{
inflictsRecoilTo(entity);
}
}
void CyclopEntity::inflictsRecoilTo(BaseCreatureEntity* targetEntity)
{
}
diff --git a/src/EnnemyEntity.cpp b/src/EnnemyEntity.cpp
index 255be80..1da7dfa 100644
--- a/src/EnnemyEntity.cpp
+++ b/src/EnnemyEntity.cpp
@@ -1,288 +1,290 @@
#include "EnnemyEntity.h"
#include "BoltEntity.h"
#include "PlayerEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include <iostream>
#include "WitchBlastGame.h"
EnnemyEntity::EnnemyEntity(sf::Texture* image, float x, float y)
: BaseCreatureEntity (image, x, y, 64, 64)
{
type = ENTITY_ENNEMY;
bloodColor = bloodRed;
z = y;
h = 0;
age = -0.001f * (rand()%800) - 0.4f;
deathFrame = -1;
dyingFrame = -1;
dyingSound = SOUND_ENNEMY_DYING;
agonizingSound = SOUND_NONE;
hurtingSound = SOUND_NONE;
isAgonising = false;
+
+ enemyType = NB_ENEMY;
}
void EnnemyEntity::animate(float delay)
{
if (isAgonising)
{
if (h < -0.01f)
{
isDying = true;
SpriteEntity* corpse;
if (deathFrame >= FRAME_CORPSE_KING_RAT)
{
corpse = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES_BIG), x, y, 128, 128);
corpse->setFrame(deathFrame - FRAME_CORPSE_KING_RAT);
}
else
{
corpse = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES), x, y, 64, 64);
corpse->setFrame(deathFrame);
corpse->setImagesProLine(10);
}
corpse->setZ(OFFSET_Y);
corpse->setType(ENTITY_CORPSE);
if (dyingSound != SOUND_NONE) SoundManager::getSoundManager()->playSound(dyingSound);
}
else
{
frame = dyingFrame;
hVelocity -= 700.0f * delay;
h += hVelocity * delay;
}
return;
}
if (canCollide()) testSpriteCollisions();
if (age > 0.0f)
BaseCreatureEntity::animate(delay);
else
age += delay;
}
void EnnemyEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2;
boundingBox.width = width;
boundingBox.top = (int)y - height / 2;
boundingBox.height = height;
}
void EnnemyEntity::collideMapRight()
{
velocity.x = 0.0f;
}
void EnnemyEntity::collideMapLeft()
{
velocity.x = 0.0f;
}
void EnnemyEntity::collideMapTop()
{
velocity.y = 0.0f;
}
void EnnemyEntity::collideMapBottom()
{
velocity.y = 0.0f;
}
void EnnemyEntity::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())
{
if (playerEntity->hurt(meleeDamages, ShotTypeStandard, 0))
{
float xs = (x + playerEntity->getX()) / 2;
float ys = (y + playerEntity->getY()) / 2;
SpriteEntity* star = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_STAR_2), xs, ys);
star->setFading(true);
star->setZ(y+ 100);
star->setLifetime(0.7f);
star->setType(16);
star->setSpin(400.0f);
}
inflictsRecoilTo(playerEntity);
}
else if (boltEntity != NULL && !boltEntity->getDying() && boltEntity->getAge() > 0.05f)
{
float xs = (x + boltEntity->getX()) / 2;
float ys = (y + boltEntity->getY()) / 2;
boltEntity->collide();
hurt(boltEntity->getDamages(), boltEntity->getBoltType(), boltEntity->getLevel());
if (bloodColor > bloodNone) game().generateBlood(x, y, bloodColor);
SoundManager::getSoundManager()->playSound(SOUND_IMPACT);
SpriteEntity* star = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_STAR_2), xs, ys);
star->setFading(true);
star->setZ(y+ 100);
star->setLifetime(0.7f);
star->setType(16);
star->setSpin(400.0f);
if (boltEntity->getBoltType() == ShotTypeStone)
{
float recoilVelocity = STONE_DECOIL_VELOCITY[boltEntity->getLevel()];
float recoilDelay = STONE_DECOIL_DELAY[boltEntity->getLevel()];
if (resistance[ResistanceRecoil] == ResistanceHigh)
{
recoilVelocity *= 0.75f;
recoilDelay *= 0.75f;
}
else if (resistance[ResistanceRecoil] == ResistanceVeryHigh)
{
recoilVelocity *= 0.5f;
recoilDelay *= 0.5f;
}
Vector2D recoilVector = Vector2D(0, 0).vectorTo(boltEntity->getVelocity(),
recoilVelocity );
giveRecoil(true, recoilVector, recoilDelay);
}
}
}
else // collision with other enemy ?
{
if (entity->getType() >= ENTITY_ENNEMY && entity->getType() <= ENTITY_ENNEMY_MAX)
{
if (this != entity)
{
EnnemyEntity* ennemyEntity = static_cast<EnnemyEntity*>(entity);
if (ennemyEntity->canCollide()) collideWithEnnemy(entity);
}
}
}
}
}
void EnnemyEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
// To implement the behaviour when colliding with another ennemy
}
bool EnnemyEntity::hurt(int damages, enumShotType hurtingType, int level)
{
bool hurted = BaseCreatureEntity::hurt(damages, hurtingType, level);
if (hurted && hurtingSound != SOUND_NONE && hp > 0)
SoundManager::getSoundManager()->playSound(hurtingSound);
return hurted;
}
void EnnemyEntity::dying()
{
if (dyingFrame == -1)
{
isDying = true;
SpriteEntity* corpse = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES), x, y, 64, 64);
corpse->setZ(OFFSET_Y);
corpse->setImagesProLine(10);
corpse->setFrame(deathFrame);
corpse->setType(ENTITY_CORPSE);
if (dyingSound != SOUND_NONE) SoundManager::getSoundManager()->playSound(dyingSound);
}
else
{
isAgonising = true;
hVelocity = 200.0f;
if (agonizingSound != SOUND_NONE) SoundManager::getSoundManager()->playSound(agonizingSound);
}
if (bloodColor != bloodNone) for (int i = 0; i < 4; i++) game().generateBlood(x, y, bloodColor);
drop();
}
void EnnemyEntity::drop()
{
if (rand() % 5 == 0)
{
ItemEntity* newItem = new ItemEntity(ItemCopperCoin, x, y);
newItem->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
newItem->setVelocity(Vector2D(100.0f + rand()% 250));
newItem->setViscosity(0.96f);
}
if (rand() % 25 == 0)
{
ItemEntity* newItem = new ItemEntity(itemHealthVerySmall, x, y);
newItem->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
newItem->setVelocity(Vector2D(100.0f + rand()% 250));
newItem->setViscosity(0.96f);
}
}
bool EnnemyEntity::canCollide()
{
return (!isAgonising);
}
void EnnemyEntity::render(sf::RenderTarget* app)
{
if (isAgonising || (isDying && dyingFrame > -1))
{
if (shadowFrame > -1)
{
// shadow
sprite.setPosition(x, y);
sprite.setTextureRect(sf::IntRect(shadowFrame * width, 0, width, height));
app->draw(sprite);
}
int nx = dyingFrame;
int ny = 0;
if (imagesProLine > 0)
{
nx = dyingFrame % imagesProLine;
ny = dyingFrame / imagesProLine;
}
sprite.setPosition(x, y - h);
if (isMirroring)
sprite.setTextureRect(sf::IntRect(nx * width + width, ny * height, -width, height));
else
sprite.setTextureRect(sf::IntRect(nx * width, ny * height, width, height));
app->draw(sprite);
}
else
BaseCreatureEntity::render(app);
}
void EnnemyEntity::displayLifeBar(std::string name, float posY, sf::RenderTarget* app)
{
float l = hpDisplay * ((MAP_WIDTH - 1) * TILE_WIDTH) / hpMax;
sf::RectangleShape rectangle(sf::Vector2f((MAP_WIDTH - 1) * TILE_WIDTH, 25));
rectangle.setFillColor(sf::Color(0, 0, 0,128));
rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, posY));
app->draw(rectangle);
rectangle.setSize(sf::Vector2f(l, 25));
rectangle.setFillColor(sf::Color(190, 20, 20));
rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, posY));
app->draw(rectangle);
game().write( name,
18,
OFFSET_X + TILE_WIDTH / 2 + 10.0f,
posY + 1.0f,
ALIGN_LEFT,
sf::Color(255, 255, 255),
app, 0, 0);
}
diff --git a/src/EnnemyEntity.h b/src/EnnemyEntity.h
index 629d194..56722dc 100644
--- a/src/EnnemyEntity.h
+++ b/src/EnnemyEntity.h
@@ -1,43 +1,80 @@
#ifndef ENNEMYPRITE_H
#define ENNEMYPRITE_H
#include "BaseCreatureEntity.h"
+enum enemyTypeEnum
+{
+ // normal
+ EnemyTypeBat,
+ EnemyTypeRat,
+ EnemyTypeRatBlack,
+ EnemyTypeEvilFlower,
+ EnemyTypeSlime,
+ EnemyTypeSlimeRed,
+ EnemyTypeSlimeBlue,
+ EnemyTypeImpBlue,
+ EnemyTypeImpRed,
+
+ // boss
+ EnemyTypeButcher,
+ EnemyTypeSlimeBoss,
+ EnemyTypeRatKing,
+ EnemyTypeCyclops,
+ EnemyTypeSpiderGiant,
+
+ // invocated
+ EnemyTypeRatGreen,
+ EnemyTypeRockFalling,
+ EnemyTypeRockMissile,
+ EnemyTypeSlime_invocated,
+ EnemyTypeSlimeRed_invocated,
+ EnemyTypeSlimeBlue_invocated,
+ EnemyTypeSpiderEgg_invocated,
+ EnemyTypeSpiderLittle_invocated,
+ EnemyTypeSpiderWeb,
+
+ NB_ENEMY // = no enemy
+};
+
class EnnemyEntity : public BaseCreatureEntity
{
- public:
- EnnemyEntity(sf::Texture* image, float x, float y);
- virtual void animate(float delay);
- virtual void calculateBB();
- virtual void render(sf::RenderTarget* app);
- void displayLifeBar(std::string name, float posY, sf::RenderTarget* app);
- protected:
- virtual void collideMapRight();
- virtual void collideMapLeft();
- virtual void collideMapTop();
- virtual void collideMapBottom();
-
- virtual void readCollidingEntity(CollidingSpriteEntity* entity);
- virtual void dying();
- virtual void drop();
- virtual void collideWithEnnemy(GameEntity* collidingEntity);
- virtual bool hurt(int damages, enumShotType hurtingType, int level);
-
- virtual bool canCollide();
-
- int meleeDamages;
-
- float h;
- float hVelocity;
-
- int dyingFrame;
- int deathFrame;
- bool isAgonising;
- sound_resources hurtingSound;
- sound_resources dyingSound;
- sound_resources agonizingSound;
-
- private:
+public:
+ EnnemyEntity(sf::Texture* image, float x, float y);
+ virtual void animate(float delay);
+ virtual void calculateBB();
+ virtual void render(sf::RenderTarget* app);
+ void displayLifeBar(std::string name, float posY, sf::RenderTarget* app);
+
+protected:
+ virtual void collideMapRight();
+ virtual void collideMapLeft();
+ virtual void collideMapTop();
+ virtual void collideMapBottom();
+
+ virtual void readCollidingEntity(CollidingSpriteEntity* entity);
+ virtual void dying();
+ virtual void drop();
+ virtual void collideWithEnnemy(GameEntity* collidingEntity);
+ virtual bool hurt(int damages, enumShotType hurtingType, int level);
+
+ virtual bool canCollide();
+
+ int meleeDamages;
+
+ float h;
+ float hVelocity;
+
+ int dyingFrame;
+ int deathFrame;
+ bool isAgonising;
+ sound_resources hurtingSound;
+ sound_resources dyingSound;
+ sound_resources agonizingSound;
+
+ enemyTypeEnum enemyType;
+
+private:
};
#endif // ENNEMYPRITE_H
diff --git a/src/EvilFlowerEntity.cpp b/src/EvilFlowerEntity.cpp
index 5905d87..89434d9 100644
--- a/src/EvilFlowerEntity.cpp
+++ b/src/EvilFlowerEntity.cpp
@@ -1,100 +1,100 @@
#include "EvilFlowerEntity.h"
#include "BoltEntity.h"
#include "EnnemyBoltEntity.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"
#include <math.h>
EvilFlowerEntity::EvilFlowerEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_FLOWER), x, y)
{
hp = EVIL_FLOWER_HP;
meleeDamages = EVIL_FLOWER_MELEE_DAMAGES;
setSpin(50.0f);
frame = 0;
type = 23;
bloodColor = bloodGreen;
- //shadowFrame = 2;
+ enemyType = EnemyTypeEvilFlower;
fireDelay = EVIL_FLOWER_FIRE_DELAY;
age = -1.0f + (rand() % 2500) * 0.001f;
}
void EvilFlowerEntity::animate(float delay)
{
float flowerDelay = delay;
if (specialState[SpecialStateIce].active) flowerDelay = delay * specialState[SpecialStateIce].parameter;
if (fireDelay < 0.7f) setSpin(500.0f);
else if (fireDelay < 1.4f) setSpin(120.0f);
else setSpin(50.0f);
EnnemyEntity::animate(delay);
angle += spin * flowerDelay;
if (age > 0.0f)
{
fireDelay -= flowerDelay;
if (fireDelay <= 0.0f)
{
fireDelay = EVIL_FLOWER_FIRE_DELAY;
fire();
}
}
}
void EvilFlowerEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + EVIL_FLOWER_BB_LEFT;
boundingBox.width = width - EVIL_FLOWER_BB_WIDTH_DIFF;
boundingBox.top = (int)y - height / 2 + EVIL_FLOWER_BB_TOP;
boundingBox.height = height - EVIL_FLOWER_BB_HEIGHT_DIFF;
}
void EvilFlowerEntity::dying()
{
isDying = true;
SpriteEntity* deadFlower = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES), x, y, 64, 64);
deadFlower->setZ(OFFSET_Y);
deadFlower->setFrame(FRAME_CORPSE_FLOWER);
deadFlower->setType(ENTITY_CORPSE);
for (int i = 0; i < 4; i++) game().generateBlood(x, y, bloodColor);
drop();
SoundManager::getSoundManager()->playSound(SOUND_ENNEMY_DYING);
}
void EvilFlowerEntity::fire()
{
SoundManager::getSoundManager()->playSound(SOUND_BLAST_FLOWER);
EnnemyBoltEntity* bolt = new EnnemyBoltEntity
(x, y + 10, ShotTypeStandard, 0);
bolt->setFrame(1);
bolt->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
float flowerFireVelocity = EVIL_FLOWER_FIRE_VELOCITY;
if (specialState[SpecialStateIce].active) flowerFireVelocity *= 0.5f;
bolt->setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), flowerFireVelocity ));
}
void EvilFlowerEntity::render(sf::RenderTarget* app)
{
sprite.setPosition(x, y);
float savedAngle = sprite.getRotation();
sprite.setRotation(0.0f);
// shadow
sprite.setTextureRect(sf::IntRect(width * 2, 0, width, height));
app->draw(sprite);
sprite.setTextureRect(sf::IntRect(width, 0, width, height));
app->draw(sprite);
sprite.setRotation(savedAngle);
EnnemyEntity::render(app);
}
diff --git a/src/FallingRockEntity.cpp b/src/FallingRockEntity.cpp
index 08a3ec9..8b9569e 100644
--- a/src/FallingRockEntity.cpp
+++ b/src/FallingRockEntity.cpp
@@ -1,129 +1,130 @@
#include "FallingRockEntity.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"
FallingRockEntity::FallingRockEntity(float x, float y, int rockType)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_CYCLOP), x, y)
{
imagesProLine = 20;
type = ENTITY_ENNEMY;
movingStyle = movFlying;
bloodColor = bloodNone; // stones don't bleed
age = 0.0f;
h = 1800 + rand() % 1000;
hp = 24;
jumping = false;
hVelocity = 0.0f;
this->rockType = rockType;
+ enemyType = EnemyTypeRockFalling;
switch (rockType)
{
case 0: meleeDamages = 8; frame = 18; break;
case 1: meleeDamages = 10; frame = 38; break;
case 2: meleeDamages = 12; frame = 58; break;
}
}
void FallingRockEntity::animate(float delay)
{
if (jumping)
{
hVelocity -= 700.0f * delay;
h += hVelocity * delay;
if (h <= 0.0f) dying();
}
else
{
h -= delay * 750.0f;
if (canCollide()) testSpriteCollisions();
if (h <= 0.0f)
{
hVelocity = 250.0f;
jumping = true;
}
}
}
void FallingRockEntity::render(sf::RenderTarget* app)
{
int nx = frame % imagesProLine;
int ny = frame / imagesProLine;
// shadow
if (h <= 1600)
{
int f = 1600 - h;
if (f > 255) f = 255;
sprite.setColor(sf::Color(255, 255, 255, f));
sprite.setPosition(x, y);
sprite.setTextureRect(sf::IntRect((nx + 1) * width, ny * height, width, height));
app->draw(sprite);
sprite.setColor(sf::Color(255, 255, 255, 255));
}
sprite.setPosition(x, y - h);
sprite.setTextureRect(sf::IntRect(nx * width, ny * height, width, height));
app->draw(sprite);
#ifdef SHOW_BOUNDING_BOX
sf::Vertex line[] =
{
sf::Vertex(sf::Vector2f(boundingBox.left, boundingBox.top)),
sf::Vertex(sf::Vector2f(boundingBox.left + boundingBox.width, boundingBox.top)),
sf::Vertex(sf::Vector2f(boundingBox.left + boundingBox.width, boundingBox.top)),
sf::Vertex(sf::Vector2f(boundingBox.left + boundingBox.width, boundingBox.top + boundingBox.height)),
sf::Vertex(sf::Vector2f(boundingBox.left + boundingBox.width, boundingBox.top + boundingBox.height)),
sf::Vertex(sf::Vector2f(boundingBox.left, boundingBox.top + boundingBox.height)),
sf::Vertex(sf::Vector2f(boundingBox.left, boundingBox.top + boundingBox.height)),
sf::Vertex(sf::Vector2f(boundingBox.left, boundingBox.top))
};
app->draw(line, 8, sf::Lines);
#endif
}
void FallingRockEntity::calculateBB()
{
int w = 30;
if (rockType == 1) w = 40;
else if (rockType == 2) w = 50;
boundingBox.left = (int)x - w / 2;
boundingBox.width = w;
boundingBox.top = (int)y - w / 2;
boundingBox.height = w;
}
bool FallingRockEntity::canCollide()
{
return h < 70;
}
void FallingRockEntity::dying()
{
isDying = true;
SoundManager::getSoundManager()->playSound(SOUND_ROCK_IMPACT);
game().makeShake(0.1f);
for (int i = 0; i < 4; i++)
{
SpriteEntity* blood = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_BLOOD), x, y, 16, 16, 6);
blood->setZ(OFFSET_Y - 1);
blood->setFrame(12 + rand()%6);
blood->setType(ENTITY_BLOOD);
blood->setVelocity(Vector2D(rand()%150));
blood->setViscosity(0.95f);
float bloodScale = 1.0f + (rand() % 10) * 0.1f;
blood->setScale(bloodScale, bloodScale);
}
}
diff --git a/src/GiantSlimeEntity.cpp b/src/GiantSlimeEntity.cpp
index 51a7bc3..6a64ab3 100644
--- a/src/GiantSlimeEntity.cpp
+++ b/src/GiantSlimeEntity.cpp
@@ -1,466 +1,467 @@
#include "GiantSlimeEntity.h"
#include "BoltEntity.h"
#include "EnnemyBoltEntity.h"
#include "PlayerEntity.h"
#include "SlimeEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
#include <iostream>
GiantSlimeEntity::GiantSlimeEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_GIANT_SLIME), x, y)
{
width = 128;
height = 128;
creatureSpeed = GIANT_SLIME_SPEED;
velocity = Vector2D(creatureSpeed);
hp = GIANT_SLIME_HP;
hpDisplay = hp;
hpMax = GIANT_SLIME_HP;
meleeDamages = GIANT_SLIME_DAMAGES;
missileDelay = GIANT_SLIME_MISSILE_DELAY;
type = ENTITY_ENNEMY_BOSS;
+ enemyType = EnemyTypeSlimeBoss;
bloodColor = bloodGreen;
shadowFrame = 3;
frame = 0;
sprite.setOrigin(64.0f, 64.0f);
h = 0.0f;
age = -2.0f;
changeToState(0);
slimeCounter = 0;
slimeTimer =5.0f;
resistance[ResistanceFrozen] = ResistanceVeryHigh;
resistance[ResistanceRecoil] = ResistanceVeryHigh;
sprite.setOrigin(64, 84);
}
void GiantSlimeEntity::changeToState(int n)
{
if (n == 0) // walking
{
state = 0;
counter = 8 + rand() % 7;
timer = -1.0f;
viscosity = 1.0f;
}
else if (n == 1 || n == 3 || n == 5 || n == 8) // waiting
{
state = n;
timer = 1.2f;
setVelocity(Vector2D(0.0f, 0.0f));
}
else if (n == 2) // jumping
{
state = 2;
timer = 4.0f;
viscosity = 0.991f;
SoundManager::getSoundManager()->playSound(SOUND_SLIME_JUMP);
hVelocity = 420.0f + rand() % 380;
isFirstJumping = true;
float randVel = 350.0f + rand() % 200;
if (rand() % 2 == 0)
{
float tan = (game().getPlayer()->getX() - x) / (game().getPlayer()->getY() - y);
float angle = atan(tan);
if (game().getPlayer()->getY() > y)
setVelocity(Vector2D(sin(angle) * randVel,
cos(angle) * randVel));
else
setVelocity(Vector2D(-sin(angle) * randVel,
-cos(angle) * randVel));
}
else
velocity = Vector2D(randVel);
}
else if (n == 4) // walking
{
state = 4;
if (hp <= hpMax / 4)
counter = 26;
if (hp <= hpMax / 2)
counter = 18;
else
counter = 12;
timer = GIANT_SLIME_MISSILE_DELAY;
}
else if (n == 6) // jumping
{
state = 6;
timer = 1.2f;
viscosity = 1.0f;
SoundManager::getSoundManager()->playSound(SOUND_SLIME_JUMP);
hVelocity = 1200.0f;
}
else if (n == 7) // falling
{
isFalling = false;
state = 7;
timer = 4.0f;
hVelocity = -1500.0f;
h = 1500;
}
}
void GiantSlimeEntity::animate(float delay)
{
slimeTimer -= delay;
if (slimeTimer <= 0.0f)
{
switch (slimeCounter)
{
case 0: new SlimeEntity(OFFSET_X + TILE_WIDTH * 1.5f, OFFSET_Y + TILE_HEIGHT * 1.5f, SlimeTypeStandard, true); break;
case 1: new SlimeEntity(OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 2) + TILE_WIDTH * 0.5f, OFFSET_Y + TILE_HEIGHT * 1.5f, SlimeTypeStandard, true); break;
case 2: new SlimeEntity(OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 2) + TILE_WIDTH * 0.5f, OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 2) + TILE_HEIGHT * 0.5f, SlimeTypeStandard, true); break;
case 3: new SlimeEntity(OFFSET_X + TILE_WIDTH * 1.5f, OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 2) + TILE_HEIGHT * 0.5f, SlimeTypeStandard, true); break;
}
slimeTimer = 7.0f;
slimeCounter ++;
if (slimeCounter == 4) slimeCounter = 0;
}
if (age <= 0.0f)
{
age += delay;
return;
}
EnnemyEntity::animate(delay);
if (specialState[SpecialStateIce].active) delay *= specialState[SpecialStateIce].parameter;
timer -= delay;
if (timer <= 0.0f)
{
if (state == 0) // walking
{
counter--;
if (counter >= 0)
{
timer = 0.5f;
if (hp <= hpMax / 4)
creatureSpeed = GIANT_SLIME_SPEED * 1.4f;
if (hp <= hpMax / 2)
creatureSpeed = GIANT_SLIME_SPEED * 1.2f;
else
creatureSpeed = GIANT_SLIME_SPEED;
setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), GIANT_SLIME_SPEED ));
}
else
{
int r = rand() % 3;
if (r == 0) changeToState(1);
else if (r == 1) changeToState(3);
else changeToState(5);
}
}
else if (state == 1) // waiting for jumping
{
changeToState(2);
}
else if (state == 2) // jumping
{
changeToState(8);
}
else if (state == 3)
{
changeToState(4);
}
else if (state == 4) // walking
{
counter--;
if (counter >= 0)
{
if (hp <= hpMax / 4)
timer = missileDelay * 0.6f;
if (hp <= hpMax / 2)
timer = missileDelay * 0.8f;
else
timer = missileDelay;
fire();
}
else
{
changeToState(8);
}
}
else if (state == 5)
{
changeToState(6);
}
else if (state == 6) // jump
{
changeToState(7); // fall
}
else if (state == 7) // jump
{
}
else if (state == 8) // jump
{
changeToState(0); // fall
}
}
if (state == 0) // walking
{
frame = ((int)(age * 2.0f)) % 2;
}
else if (state == 1 || state == 5) // waiting to jump
{
if (timer < 0.25f)
frame = 1;
else
frame = 0;
}
else if (state == 2) // jumping
{
hVelocity -= 700.0f * delay;
h += hVelocity * delay;
if (h <= 0.0f)
{
if (hp <= 0)
dying();
else
{
h = 0.0f;
if (isFirstJumping)
{
isFirstJumping = false;
hVelocity = 160.0f;
SoundManager::getSoundManager()->playSound(SOUND_SLIME_IMAPCT);
}
else
{
SoundManager::getSoundManager()->playSound(SOUND_SLIME_IMAPCT_WEAK);
viscosity = 0.96f;
changeToState(0);
}
}
}
if (hVelocity > 0.0f) frame = 2;
else frame = 0;
}
else if (state == 6) // ultra jump
{
if (h < 2000)
h += hVelocity * delay;
}
else if (state == 7) // ultra jump
{
if (!isFalling && timer <= 2.2f)
{
isFalling = true;
x = game().getPlayer()->getX();
y = game().getPlayer()->getY();
// to prevent collisions
float x0 = OFFSET_X + TILE_WIDTH + 1;
float xf = OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 1) - 1;
float y0 = OFFSET_Y + TILE_HEIGHT + 1;
float yf = OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 1) - 1;
calculateBB();
if (boundingBox.left < x0) x += (x0 - boundingBox.left);
else if (boundingBox.left + boundingBox.width > xf) x -= (boundingBox.left + boundingBox.width - xf);
if (boundingBox.top < y0) y += (y0 - boundingBox.top);
else if (boundingBox.top + boundingBox.height > yf) y -= (boundingBox.top + boundingBox.height - yf);
}
if (timer < 2.3f)
{
h += hVelocity * delay;
if (h <= 0)
{
h = 0;
changeToState(8);
game().makeShake(0.8f);
SoundManager::getSoundManager()->playSound(SOUND_WALL_IMPACT);
}
}
}
if (state == 6 && timer < 0.5f)
{
int fade = timer * 512;
if (fade < 0) fade = 0;
sprite.setColor(sf::Color(255, 255, 255, fade));
}
else if (state == 7 && timer < 1.5f)
sprite.setColor(sf::Color(255, 255, 255, 255));
else if (state == 7 && timer < 2.0f)
sprite.setColor(sf::Color(255, 255, 255, (2.0f - timer) * 512));
else if (state == 7)
sprite.setColor(sf::Color(255, 255, 255, 0));
z = y + 26;
}
void GiantSlimeEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + GIANT_SLIME_BB_LEFT;
boundingBox.width = width - GIANT_SLIME_BB_WIDTH_DIFF;
boundingBox.top = (int)y - height / 2 + 40;
boundingBox.height = height - 76;
}
void GiantSlimeEntity::collideMapRight()
{
velocity.x = -velocity.x;
}
void GiantSlimeEntity::collideMapLeft()
{
velocity.x = -velocity.x;
}
void GiantSlimeEntity::collideMapTop()
{
velocity.y = -velocity.y;
}
void GiantSlimeEntity::collideMapBottom()
{
velocity.y = -velocity.y;
}
void GiantSlimeEntity::dying()
{
isDying = true;
SpriteEntity* deadRat = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES_BIG), x, y, 128, 128);
deadRat->setZ(OFFSET_Y);
deadRat->setFrame(FRAME_CORPSE_GIANT_SLIME - FRAME_CORPSE_KING_RAT);
deadRat->setType(ENTITY_CORPSE);
float xSlime = x;
float ySlime = y;
if (x <= OFFSET_X + 1.5 * TILE_WIDTH) x = OFFSET_X + 1.5f * TILE_WIDTH + 2;
else if (x >= OFFSET_X + TILE_WIDTH * MAP_WIDTH - 1.5f * TILE_WIDTH) x = OFFSET_X + TILE_WIDTH * MAP_WIDTH - 1.5f * TILE_WIDTH -3;
if (y <= OFFSET_Y + 1.5 * TILE_HEIGHT) y = OFFSET_Y + 1.5 * TILE_HEIGHT + 2;
else if (y >= OFFSET_Y + TILE_HEIGHT * MAP_HEIGHT - 1.5f * TILE_HEIGHT) x = OFFSET_Y + TILE_HEIGHT * MAP_HEIGHT - 1.5f * TILE_HEIGHT -3;
for (int i = 0; i < 9; i++)
{
game().generateBlood(xSlime, ySlime, bloodColor);
new SlimeEntity(x, y, SlimeTypeStandard, true);
}
game().makeShake(1.0f);
SoundManager::getSoundManager()->playSound(SOUND_SLIME_SMASH);
ItemEntity* newItem = new ItemEntity(itemBossHeart, x, y);
newItem->setVelocity(Vector2D(100.0f + rand()% 250));
newItem->setViscosity(0.96f);
SpriteEntity* star = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_GIANT_SLIME), x, y, 128, 128, 8);
star->setFrame(4);
star->setFading(true);
star->setZ(y+ 100);
star->setAge(-0.4f);
star->setLifetime(0.3f);
star->setType(16);
star->setSpin(400.0f);
}
void GiantSlimeEntity::render(sf::RenderTarget* app)
{
if (!isDying)
{
// 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, 0, width, height));
app->draw(sprite);
float l = hpDisplay * ((MAP_WIDTH - 1) * TILE_WIDTH) / GIANT_SLIME_HP;
sf::RectangleShape rectangle(sf::Vector2f((MAP_WIDTH - 1) * TILE_WIDTH, 25));
rectangle.setFillColor(sf::Color(0, 0, 0,128));
rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT));
app->draw(rectangle);
rectangle.setSize(sf::Vector2f(l, 25));
rectangle.setFillColor(sf::Color(190, 20, 20));
rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT));
app->draw(rectangle);
game().write( "Giant Slime",
18,
OFFSET_X + TILE_WIDTH / 2 + 10.0f,
OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT + 1.0f,
ALIGN_LEFT,
sf::Color(255, 255, 255),
app, 0, 0);
if (game().getShowLogical())
{
displayBoundingBox(app);
displayCenterAndZ(app);
}
}
void GiantSlimeEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movWalking)
{
inflictsRecoilTo(entity);
}
}
void GiantSlimeEntity::inflictsRecoilTo(BaseCreatureEntity* targetEntity)
{
if (state == 7)
{
Vector2D recoilVector = Vector2D(x, y).vectorTo(Vector2D(targetEntity->getX(), targetEntity->getY()), KING_RAT_RUNNING_RECOIL );
targetEntity->giveRecoil(true, recoilVector, 1.0f);
}
}
bool GiantSlimeEntity::canCollide()
{
return h <= 70.0f;
}
BaseCreatureEntity::enumMovingStyle GiantSlimeEntity::getMovingStyle()
{
if (h <= 70.0f)
return movWalking;
else
return movFlying;
}
void GiantSlimeEntity::fire()
{
SoundManager::getSoundManager()->playSound(SOUND_BLAST_FLOWER);
EnnemyBoltEntity* bolt = new EnnemyBoltEntity
(x, y + 10, ShotTypeStandard, 0);
bolt->setFrame(1);
bolt->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
bolt->setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(),GIANT_SLIME_FIRE_VELOCITY ));
}
diff --git a/src/GiantSpiderEntity.cpp b/src/GiantSpiderEntity.cpp
index bc7fcef..0a4cf82 100644
--- a/src/GiantSpiderEntity.cpp
+++ b/src/GiantSpiderEntity.cpp
@@ -1,317 +1,318 @@
#include "GiantSpiderEntity.h"
#include "EnnemyBoltEntity.h"
#include "PlayerEntity.h"
#include "SpiderEggEntity.h"
#include "SpiderWebEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
#include <iostream>
GiantSpiderEntity::GiantSpiderEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_GIANT_SPIDER), x, y)
{
width = 128;
height = 128;
creatureSpeed = GIANT_SPIDER_SPEED[0];
velocity = Vector2D(0.0f, 0.0f);
hp = GIANT_SPIDER_HP;
hpMax = hp;
hpDisplay = hp;
meleeDamages = GIANT_SPIDER_DAMAGE;
type = ENTITY_ENNEMY;
+ enemyType = EnemyTypeSpiderGiant;
bloodColor = bloodGreen;
shadowFrame = 3;
dyingFrame = 4;
deathFrame = FRAME_CORPSE_GIANT_SPIDER;
//agonizingSound = SOUND_RAT_DYING;
sprite.setOrigin(64.0f, 64.0f);
h = 2000;
state = 0;
hurtLevel = 0;
resistance[ResistanceFrozen] = ResistanceVeryHigh;
resistance[ResistanceRecoil] = ResistanceVeryHigh;
creatureName = "???";
}
void GiantSpiderEntity::animate(float delay)
{
if (age <= 0.0f)
{
age += delay;
return;
}
if (!isAgonising)
{
if (state == 0) // falling
{
h -= delay * 300.0f;
if (h <= 0.0f)
{
h = 0;
state = 1;
timer = 1.0f;
creatureName = "Giant Spider";
}
}
else if (state == 1) // wait after falling
{
timer -= delay;
if (timer <= 0.0f)
{
state = 2;
velocity = Vector2D(creatureSpeed);
timer = 10.0f;
fireDelay = 0.5f;
}
}
else if (state == 2) // moving
{
fireDelay -= delay;
if (fireDelay <= 0.0f)
{
if (rand() % 12 == 0)
{
for (int i = 0; i < 3; i++) new SpiderWebEntity(x, y);
}
else
{
for (int i = 0; i < 3; i++) fire(i == 0 ? 1 : 0);
}
fireDelay = GIANT_SPIDER_FIRE_DELAY[hurtLevel];
}
timer -= delay;
if (getHealthLevel() > hurtLevel)
{
hurtLevel++;
state = 3;
velocity = Vector2D(0.0f, 0.0f);
timer = 1.0f;
creatureSpeed = GIANT_SPIDER_SPEED[hurtLevel];
}
}
else if (state == 3) // wait after falling
{
timer -= delay;
if (timer <= 0.0f) state = 4;
}
else if (state == 4) // moving up
{
h += delay * 300.0f;
if (h >= 1500.0f)
{
state = 5;
timer = 6.0f;
for (int i = 0; i < GIANT_SPIDER_NUMBER_EGGS[hurtLevel]; i++)
{
new SpiderEggEntity(OFFSET_X + TILE_WIDTH * 1.5f + rand() % (TILE_WIDTH * 12),
OFFSET_Y + TILE_HEIGHT * 1.5f + rand() % (TILE_HEIGHT * 6));
}
}
}
else if (state == 5) // waiting to fall
{
timer -= delay;
if (timer <= 0.0f)
state = 0;
}
// frame
frame = 0;
if (state == 2)
{
frame = ((int)(age * 6.0f)) % 4;
if (frame == 2) frame = 0;
else if (frame == 3) frame = 2;
}
}
EnnemyEntity::animate(delay);
z = y + 40;
}
bool GiantSpiderEntity::hurt(int damages, enumShotType hurtingType, int level)
{
if (hurtLevel < getHealthLevel()) damages /= 5;
return EnnemyEntity::hurt(damages, hurtingType, level);
}
void GiantSpiderEntity::calculateBB()
{
boundingBox.left = (int)x - 45;
boundingBox.width = 90;
boundingBox.top = (int)y - 25;
boundingBox.height = 65;
}
void GiantSpiderEntity::collideMapRight()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
}
void GiantSpiderEntity::collideMapLeft()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
}
void GiantSpiderEntity::collideMapTop()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
}
void GiantSpiderEntity::collideMapBottom()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
}
void GiantSpiderEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movWalking)
{
Vector2D v = Vector2D(x, y).vectorTo(Vector2D(entity->getX(), entity->getY()), 150.0f);
entity->giveRecoil(false, v, 0.5f);
}
}
void GiantSpiderEntity::calculateRotation()
{
float h0 = 100;
float hf = 18;
if (state == 0)
{
if (h > h0) sprite.setRotation(180);
else if (h < hf) sprite.setRotation(0);
else
{
sprite.setRotation(180 + (h0 - h) * 180 / (h0 - hf));
}
}
if (state == 4)
{
if (h > h0) sprite.setRotation(180);
else if (h < hf) sprite.setRotation(0);
else
{
sprite.setRotation(180 - (h0 - h) * 180 / (h0 - hf));
}
}
else if (state == 2) sprite.setRotation(0);
}
void GiantSpiderEntity::render(sf::RenderTarget* app)
{
if (!isDying)
{
// shadow
sprite.setRotation(0.0f);
if (state == 0 || state == 4 || state == 5)
{
int h0 = 850;
int hf = 600;
int fade = 0;
if (h < h0)
{
if (h < hf) fade = 255;
else
{
fade = (h0 - h) * 255 / (h0 - hf);
if (fade < 0) fade = 0;
else if (fade > 255) fade = 255;
}
sprite.setColor(sf::Color(255, 255, 255, fade));
sprite.setPosition(x, y);
sprite.setTextureRect(sf::IntRect(shadowFrame * width, 0, width, height));
app->draw(sprite);
sprite.setColor(sf::Color(255, 255, 255, 255));
}
}
else
{
sprite.setPosition(x, y);
sprite.setTextureRect(sf::IntRect(shadowFrame * width, 0, width, height));
app->draw(sprite);
}
}
calculateRotation();
if (state == 0 || state == 1 || state == 3 || state == 4)
{
if (y - h > 0)
{
int fade = 255;
if (state == 1) fade = 255 * timer;
else if (state == 3) fade = 255 * (1.0f - timer);
sf::RectangleShape line(sf::Vector2f(2, y - h));
line.setPosition(x - 1, 0);
line.setFillColor(sf::Color(255, 255, 255, fade));
app->draw(line);
}
}
sprite.setPosition(x, y - h);
sprite.setTextureRect(sf::IntRect(frame * width, 0, width, height));
app->draw(sprite);
displayLifeBar(creatureName, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT, app);
if (game().getShowLogical())
{
displayBoundingBox(app);
displayCenterAndZ(app);
}
}
bool GiantSpiderEntity::canCollide()
{
return h <= 70.0f;
}
void GiantSpiderEntity::fire(int fireType)
{
SoundManager::getSoundManager()->playSound(SOUND_BLAST_FLOWER);
EnnemyBoltEntity* bolt;
bolt = new EnnemyBoltEntity(x, y, ShotTypeStandard, 0);
bolt->setDamages(5);
float fireVelocity = 180.0f;
if (specialState[SpecialStateIce].active) fireVelocity *= 0.5f;
bolt->setVelocity(Vector2D(fireVelocity));
//bolt->setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), fireVelocity ));
}
int GiantSpiderEntity::getHealthLevel()
{
int healthLevel = 0;
if (hp <= hpMax * 0.25) healthLevel = 3;
else if (hp <= hpMax * 0.5) healthLevel = 2;
else if (hp <= hpMax * 0.75) healthLevel = 1;
return healthLevel;
}
void GiantSpiderEntity::drop()
{
ItemEntity* newItem = new ItemEntity(itemBossHeart, x, y);
newItem->setVelocity(Vector2D(100.0f + rand()% 250));
newItem->setViscosity(0.96f);
}
diff --git a/src/GreenRatEntity.cpp b/src/GreenRatEntity.cpp
index 721da0e..3fa8e66 100644
--- a/src/GreenRatEntity.cpp
+++ b/src/GreenRatEntity.cpp
@@ -1,125 +1,126 @@
#include "GreenRatEntity.h"
#include "BoltEntity.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"
GreenRatEntity::GreenRatEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_RAT), x, y)
{
imagesProLine = 8;
creatureSpeed = GREEN_RAT_SPEED;
velocity = Vector2D(creatureSpeed);
computeFacingDirection();
hp = GREEN_RAT_HP;
meleeDamages = GREEN_RAT_DAMAGES;
type = ENTITY_ENNEMY_INVOCATED;
+ enemyType = EnemyTypeRatGreen;
bloodColor = bloodRed;
shadowFrame = 7;
dyingFrame = 14;
deathFrame = FRAME_CORPSE_GREEN_RAT;
agonizingSound = SOUND_RAT_DYING;
timer = (rand() % 50) / 10.0f;
age = -GREEN_RAT_FADE;
frame = 8;
}
void GreenRatEntity::animate(float delay)
{
z = y + boundingBox.top + boundingBox.height;
if (age > 0.0f && !isAgonising)
{
sprite.setColor(sf::Color(255,255,255,255));
timer = timer - delay;
if (timer <= 0.0f)
{
timer = (rand() % 50) / 10.0f;
setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), GREEN_RAT_SPEED ));
computeFacingDirection();
}
frame = 8 + ((int)(age * 5.0f)) % 2;
if (facingDirection == 4 || facingDirection == 6) frame += 2;
isMirroring = (facingDirection == 4 );
if (facingDirection == 8) frame += 4;
}
else if (!isAgonising)
{
sprite.setColor(sf::Color(255,255,255,255 * (1.0 + age)));
}
else if (isAgonising)
{
if (hVelocity < -1.0f)
{
int fade = h * 200 / 25;
if (fade > 200) fade = 200;
else if (fade < 0) fade = 0;
sprite.setColor(sf::Color(255, 255, 255, fade));
}
}
EnnemyEntity::animate(delay);
}
void GreenRatEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + RAT_BB_LEFT;
boundingBox.width = width - RAT_BB_WIDTH_DIFF;
boundingBox.top = (int)y - height / 2 + RAT_BB_TOP;
boundingBox.height = height - RAT_BB_HEIGHT_DIFF;
}
void GreenRatEntity::collideMapRight()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
computeFacingDirection();
}
void GreenRatEntity::collideMapLeft()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
computeFacingDirection();
}
void GreenRatEntity::collideMapTop()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
computeFacingDirection();
}
void GreenRatEntity::collideMapBottom()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
computeFacingDirection();
}
void GreenRatEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
if (recoil.active && recoil.stun) return;
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movWalking )
{
Vector2D vel = Vector2D(entity->getX(), entity->getY()).vectorTo(Vector2D(x, y), 100.0f );
giveRecoil(false, vel, 0.3f);
computeFacingDirection();
}
}
void GreenRatEntity::drop()
{
// no drop
}
diff --git a/src/ImpEntity.cpp b/src/ImpEntity.cpp
index 8c3de7a..dcad5e6 100644
--- a/src/ImpEntity.cpp
+++ b/src/ImpEntity.cpp
@@ -1,246 +1,248 @@
#include "ImpEntity.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"
#include "EnnemyBoltEntity.h"
ImpEntity::ImpEntity(float x, float y, impTypeEnum impType)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_IMP), x, y)
{
// general
creatureSpeed = IMP_SPEED;
velocity = Vector2D(creatureSpeed);
hp = IMP_HP;
meleeDamages = IMP_MELEE_DAMAGES;
type = ENTITY_ENNEMY;
bloodColor = bloodRed;
changingDelay = 1.5f + (float)(rand() % 2500) / 1000.0f;
shadowFrame = 4;
movingStyle = movFlying;
imagesProLine = 5;
hurtingSound = SOUND_IMP_HURT;
agonizingSound = SOUND_IMP_DYING;
this->impType = impType;
state = 0;
// Imp-specific
if (impType == ImpTypeBlue)
{
dyingFrame = 8;
deathFrame = FRAME_CORPSE_IMP_BLUE;
resistance[ResistanceFrozen] = ResistanceImmune;
resistance[ResistanceIce] = ResistanceHigh;
resistance[ResistanceFire] = ResistanceLow;
+ enemyType = EnemyTypeImpBlue;
}
else // ImpTypeRed
{
dyingFrame = 3;
deathFrame = FRAME_CORPSE_IMP_RED;
resistance[ResistanceIce] = ResistanceLow;
resistance[ResistanceFire] = ResistanceHigh;
+ enemyType = EnemyTypeImpRed;
}
}
void ImpEntity::animate(float delay)
{
if (!isDying && !isAgonising)
{
if (age < 0.0f)
frame = 1;
else
{
changingDelay -= delay;
if (changingDelay < 0.0f)
{
if (state == 0) // flying -> pause
{
viscosity = 0.965f;
state = 1;
changingDelay = 0.5f;
}
else if (state == 1) // pause -> fire -> pause
{
changingDelay = 0.4f;
fire();
state = 2;
}
else if (state == 2) // pause -> teleport -> pause
{
teleport();
state = 3;
changingDelay = 0.4f;
}
else if (state == 3)
{
velocity = Vector2D(creatureSpeed);
changingDelay = 1.5f + (float)(rand() % 2500) / 1000.0f;
viscosity = 1.0f;
state = 0;
}
}
switch (((int)(age * 5.0f)) % 4)
{
case 0:
case 2: frame = 0; break;
case 1: frame = 1; break;
case 3: frame = 2; break;
}
}
if (impType == ImpTypeBlue) frame += 5;
}
EnnemyEntity::animate(delay);
}
void ImpEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + IMP_BB_LEFT;
boundingBox.width = width - IMP_BB_WIDTH_DIFF;
boundingBox.top = (int)y - height / 2 + IMP_BB_TOP;
boundingBox.height = height - IMP_BB_HEIGHT_DIFF;
}
void ImpEntity::collideMapRight()
{
velocity.x = -velocity.x;
}
void ImpEntity::collideMapLeft()
{
velocity.x = -velocity.x;
}
void ImpEntity::collideMapTop()
{
velocity.y = -velocity.y;
}
void ImpEntity::collideMapBottom()
{
velocity.y = -velocity.y;
}
void ImpEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movFlying)
{
setVelocity(Vector2D(entity->getX(), entity->getY()).vectorTo(Vector2D(x, y), creatureSpeed ));
}
}
bool ImpEntity::hurt(int damages, enumShotType hurtingType, int level)
{
bool result = EnnemyEntity::hurt(damages, hurtingType, level);
if (!isDying && !isAgonising)
{
teleport();
state = 3;
changingDelay = 0.4f;
}
return result;
}
void ImpEntity::dying()
{
EnnemyEntity::dying();
h = 25.0f;
}
void ImpEntity::fire()
{
SoundManager::getSoundManager()->playSound(SOUND_BLAST_FLOWER);
EnnemyBoltEntity* bolt;
if (impType == ImpTypeBlue)
{
bolt = new EnnemyBoltEntity(x, y, ShotTypeIce, 0);
bolt->setDamages(5);
}
else
{
bolt = new EnnemyBoltEntity(x, y, ShotTypeFire, 0);
bolt->setDamages(8);
}
bolt->setFlying(true);
float fireVelocity = IMP_FIRE_VELOCITY;
if (specialState[SpecialStateIce].active) fireVelocity *= 0.5f;
bolt->setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), fireVelocity ));
}
void ImpEntity::generateStar(sf::Color starColor)
{
SpriteEntity* spriteStar = new SpriteEntity(
ImageManager::getImageManager()->getImage(IMAGE_STAR_2),
x, y);
spriteStar->setScale(0.8f, 0.8f);
spriteStar->setZ(z-1.0f);
spriteStar->setLifetime(0.8f);
spriteStar->setSpin(-100 + rand()%200);
spriteStar->setVelocity(Vector2D(10 + rand()%40));
spriteStar->setWeight(-150);
spriteStar->setFading(true);
spriteStar->setColor(starColor);
spriteStar->setType(ENTITY_EFFECT);
}
void ImpEntity::teleport()
{
bool ok = false;
int xm, ym;
float xMonster, yMonster;
for(int i=0; i < 6; i++)
{
if (impType == ImpTypeBlue)
{
generateStar(sf::Color(50, 50, 255, 255));
generateStar(sf::Color(200, 200, 255, 255));
}
else
{
generateStar(sf::Color(255, 50, 50, 255));
generateStar(sf::Color(255, 200, 200, 255));
}
}
int counter = 50;
while (!ok && counter > 0)
{
counter--;
xm = 1 +rand() % (MAP_WIDTH - 3);
ym = 1 +rand() % (MAP_HEIGHT - 3);
xMonster = OFFSET_X + xm * TILE_WIDTH + TILE_WIDTH * 0.5f;
yMonster = OFFSET_Y + ym * TILE_HEIGHT+ TILE_HEIGHT * 0.5f;
ok = (game().getPlayerPosition().distance2(Vector2D(xMonster, yMonster)) > 40000);
}
x = xMonster;
y = yMonster;
for(int i=0; i < 6; i++)
{
if (impType == ImpTypeBlue)
{
generateStar(sf::Color(50, 50, 255, 255));
generateStar(sf::Color(200, 200, 255, 255));
}
else
{
generateStar(sf::Color(255, 50, 50, 255));
generateStar(sf::Color(255, 200, 200, 255));
}
}
}
diff --git a/src/KingRatEntity.cpp b/src/KingRatEntity.cpp
index 2674696..2fc6764 100644
--- a/src/KingRatEntity.cpp
+++ b/src/KingRatEntity.cpp
@@ -1,396 +1,397 @@
#include "KingRatEntity.h"
#include "GreenRatEntity.h"
#include "BoltEntity.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"
#include <iostream>
KingRatEntity::KingRatEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_KING_RAT), x, y)
{
width = 128;
height = 128;
creatureSpeed = KING_RAT_SPEED;
velocity = Vector2D(creatureSpeed);
hp = KING_RAT_HP;
hpDisplay = hp;
hpMax = KING_RAT_HP;
meleeDamages = KING_RAT_DAMAGES;
imagesProLine = 5;
type = ENTITY_ENNEMY_BOSS;
+ enemyType = EnemyTypeRatKing;
bloodColor = bloodRed;
shadowFrame = 4;
dyingFrame = 5;
deathFrame = FRAME_CORPSE_KING_RAT;
dyingSound = SOUND_KING_RAT_DIE;
frame = 0;
if (game().getPlayerPosition().x > x) sprite.setScale(-1.0f, 1.0f);
sprite.setOrigin(64.0f, 64.0f);
state = 0;
timer = 2.0f + (rand() % 40) / 10.0f;
age = -2.0f;
berserkDelay = 1.0f + rand()%5 * 0.1f;
hasBeenBerserk = false;
resistance[ResistanceFrozen] = ResistanceVeryHigh;
resistance[ResistanceRecoil] = ResistanceVeryHigh;
}
void KingRatEntity::animate(float delay)
{
if (age <= 0.0f)
{
age += delay;
return;
}
if (isAgonising)
{
if (h < -0.01f)
{
isDying = true;
SpriteEntity* corpse;
corpse = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES_BIG), x, y + 48, 128, 128);
corpse->setFrame(deathFrame - FRAME_CORPSE_KING_RAT);
corpse->setZ(OFFSET_Y);
corpse->setType(ENTITY_CORPSE);
if (dyingSound != SOUND_NONE) SoundManager::getSoundManager()->playSound(dyingSound);
}
else
{
frame = dyingFrame;
hVelocity -= 700.0f * delay;
h += hVelocity * delay;
}
return;
}
EnnemyEntity::animate(delay);
if (specialState[SpecialStateIce].active) delay *= specialState[SpecialStateIce].parameter;
float timerMult = 1.0f;
if (hp <= hpMax / 4)
{
creatureSpeed = KING_RAT_SPEED * 1.4f;
timerMult = 0.7f;
}
else if (hp <= hpMax / 2)
{
creatureSpeed = KING_RAT_SPEED * 1.2f;
timerMult = 0.85f;
}
else
{
creatureSpeed = KING_RAT_SPEED;
}
if (state == 5)
{
velocity.x *= 0.965f;
velocity.y *= 0.965f;
}
else
{
if (velocity.x > 0.1f) sprite.setScale(-1.0f, 1.0f);
else if (velocity.x < -0.1f) sprite.setScale(1.0f, 1.0f);
}
timer -= delay;
if (timer <= 0.0f)
{
if (state == 0)
{
state = 1;
// generate rats
generateGreenRats();
SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_1);
timer = 2.0f;
velocity.x = 0.0f;
velocity.y = 0.0f;
}
else if (state == 1) // generate rats
{
// to normal or berserk
if (hp < hpMax / 4 && !hasBeenBerserk)
{
hasBeenBerserk = true;
timer = 12.0f;
state = 6;
velocity = Vector2D(KING_RAT_BERSERK_SPEED);
SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_2);
}
else
{
timer = 7.0f * timerMult;
velocity = Vector2D(creatureSpeed);
state = 2;
}
}
else if (state == 2) // normal -> rush
{
state = 3;
// angry
timer = 2.0f;
velocity.x = 0.0f;
velocity.y = 0.0f;
SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_2);
}
else if (state == 3) // normal -> rush
{
state = 4;
// rush
timer = 12.0f;
float tan = (game().getPlayer()->getX() - x) / (game().getPlayer()->getY() - y);
float angle = atan(tan);
if (game().getPlayer()->getY() > y)
setVelocity(Vector2D(sin(angle) * KING_RAT_RUNNING_SPEED,
cos(angle) * KING_RAT_RUNNING_SPEED));
else
setVelocity(Vector2D(-sin(angle) * KING_RAT_RUNNING_SPEED,
-cos(angle) * KING_RAT_RUNNING_SPEED));
}
else if (state == 5) // wall impact
{
// to normal or berserk
if (hp < hpMax / 4 && !hasBeenBerserk)
{
hasBeenBerserk = true;
timer = 12.0f;
state = 6;
velocity = Vector2D(KING_RAT_BERSERK_SPEED);
SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_2);
}
else
{
timer = 7.0f * timerMult;
velocity = Vector2D(creatureSpeed);
state = 0;
}
}
else if (state == 6)
{
timer = 7.0f * timerMult;
velocity = Vector2D(creatureSpeed);
state = 0;
}
}
if (state == 6)
{
berserkDelay -= delay;
if (berserkDelay <= 0.0f)
{
berserkDelay = 0.8f + (rand()%10) / 10.0f;
SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_2);
setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(),KING_RAT_BERSERK_SPEED ));
}
}
frame = 0;
if (state == 1)
frame = 3;
else if (state == 3 || state == 6)
{
frame = 3; //0;
int r = ((int)(age * 10.0f)) % 2;
if (r == 0)
sprite.setScale(-1.0f, 1.0f);
else
sprite.setScale(1.0f, 1.0f);
}
else if (state == 4)
{
int r = ((int)(age * 7.5f)) % 4;
if (r == 1) frame = 1;
else if (r == 3) frame = 2;
}
else if (state == 5)
{
frame = 0;
}
else
{
int r = ((int)(age * 5.0f)) % 4;
if (r == 1) frame = 1;
else if (r == 3) frame = 2;
}
z = y + 52;
}
bool KingRatEntity::hurt(int damages, enumShotType hurtingType, int level)
{
int newDamages = damages;
// berserk state protects
if (state == 6)
newDamages = damages / 4;
return EnnemyEntity::hurt(newDamages, hurtingType, level);
}
void KingRatEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + 25;
boundingBox.width = width - 50;
boundingBox.top = (int)y - height / 2 + 25;
boundingBox.height = height - 35;
}
void KingRatEntity::afterWallCollide()
{
if (state == 4)
{
state = 5;
timer = 1.4f;
velocity.x *= 0.75f;
velocity.y *= 0.75f;
SoundManager::getSoundManager()->playSound(SOUND_BIG_WALL_IMPACT);
game().makeShake(0.75f);
}
}
void KingRatEntity::collideMapRight()
{
velocity.x = -velocity.x;
afterWallCollide();
}
void KingRatEntity::collideMapLeft()
{
velocity.x = -velocity.x;
afterWallCollide();
}
void KingRatEntity::collideMapTop()
{
velocity.y = -velocity.y;
afterWallCollide();
}
void KingRatEntity::collideMapBottom()
{
velocity.y = -velocity.y;
afterWallCollide();
}
void KingRatEntity::drop()
{
ItemEntity* newItem = new ItemEntity(itemBossHeart, x, y);
newItem->setVelocity(Vector2D(100.0f + rand()% 250));
newItem->setViscosity(0.96f);
}
void KingRatEntity::generateGreenRats()
{
for (int i = 0; i < 5; i++)
{
float xr = x + -100 + rand() % 200;
float yr = y + -100 + rand() % 200;
if (xr > OFFSET_X + TILE_WIDTH * 1.5f && xr < OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 2)
&& yr > OFFSET_Y + TILE_HEIGHT * 1.5f && yr < OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 2))
{
new GreenRatEntity(xr, yr);
}
else
i--;
}
}
void KingRatEntity::render(sf::RenderTarget* app)
{
EnnemyEntity::render(app);
if (state == 6)
{
int r = ((int)(age *12.0f)) % 2;
if (r == 0)
sprite.setTextureRect(sf::IntRect(1 * width, 1 * height, width, height));
else
sprite.setTextureRect(sf::IntRect(2 * width, 1 * height, -width, height));
sprite.setPosition(x, y);
sprite.setColor(sf::Color(255, 255, 255, 190));
app->draw(sprite);
sprite.setColor(sf::Color(255, 255, 255, 255));
}
float l = hpDisplay * ((MAP_WIDTH - 1) * TILE_WIDTH) / KING_RAT_HP;
sf::RectangleShape rectangle(sf::Vector2f((MAP_WIDTH - 1) * TILE_WIDTH, 25));
rectangle.setFillColor(sf::Color(0, 0, 0,128));
rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT));
app->draw(rectangle);
rectangle.setSize(sf::Vector2f(l, 25));
rectangle.setFillColor(sf::Color(190, 20, 20));
rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT));
app->draw(rectangle);
game().write( "Rat King",
18,
OFFSET_X + TILE_WIDTH / 2 + 10.0f,
OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT + 1.0f,
ALIGN_LEFT,
sf::Color(255, 255, 255),
app, 0 , 0);
}
void KingRatEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movWalking)
{
inflictsRecoilTo(entity);
}
}
void KingRatEntity::inflictsRecoilTo(BaseCreatureEntity* targetEntity)
{
if (state == 4 || state == 6)
{
Vector2D recoilVector = Vector2D(x, y).vectorTo(Vector2D(targetEntity->getX(), targetEntity->getY()), KING_RAT_RUNNING_RECOIL );
targetEntity->giveRecoil(true, recoilVector, 1.0f);
}
if (state == 6)
{
PlayerEntity* playerEntity = dynamic_cast<PlayerEntity*>(targetEntity);
if (playerEntity != NULL && !playerEntity->isDead())
{
Vector2D recoilVector = Vector2D(targetEntity->getX(), targetEntity->getY()).vectorTo(Vector2D(x, y), KING_RAT_RUNNING_RECOIL);
giveRecoil(true, recoilVector, 1.0f);
}
}
}
diff --git a/src/LittleSpiderEntity.cpp b/src/LittleSpiderEntity.cpp
index 4360447..e343572 100644
--- a/src/LittleSpiderEntity.cpp
+++ b/src/LittleSpiderEntity.cpp
@@ -1,103 +1,104 @@
#include "LittleSpiderEntity.h"
#include "BoltEntity.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"
LittleSpiderEntity::LittleSpiderEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_LITTLE_SPIDER), x, y)
{
imagesProLine = 8;
creatureSpeed = 175.0f;
velocity = Vector2D(creatureSpeed);
hp = 16;
meleeDamages = 5;
type = ENTITY_ENNEMY_INVOCATED;
+ enemyType = EnemyTypeSpiderLittle_invocated;
bloodColor = bloodGreen;
shadowFrame = 4;
dyingFrame = 3;
deathFrame = FRAME_CORPSE_LITTLE_SPIDER;
//agonizingSound = SOUND_RAT_DYING;
timer = (rand() % 50) / 10.0f;
age = 0.0f;
frame = 8;
}
void LittleSpiderEntity::animate(float delay)
{
z = y + boundingBox.top + boundingBox.height;
if (age > 0.0f && !isAgonising)
{
timer = timer - delay;
if (timer <= 0.0f)
{
timer = (rand() % 50) / 10.0f;
setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), creatureSpeed ));
}
frame = ((int)(age * 5.0f)) % 3;
}
EnnemyEntity::animate(delay);
z = y + 25;
}
void LittleSpiderEntity::calculateBB()
{
boundingBox.left = (int)x - 20;
boundingBox.width = 40;
boundingBox.top = (int)y - 10;
boundingBox.height = 35;
}
void LittleSpiderEntity::collideMapRight()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
computeFacingDirection();
}
void LittleSpiderEntity::collideMapLeft()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
computeFacingDirection();
}
void LittleSpiderEntity::collideMapTop()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
computeFacingDirection();
}
void LittleSpiderEntity::collideMapBottom()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
computeFacingDirection();
}
void LittleSpiderEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
if (recoil.active && recoil.stun) return;
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movWalking )
{
Vector2D vel = Vector2D(entity->getX(), entity->getY()).vectorTo(Vector2D(x, y), 100.0f );
giveRecoil(false, vel, 0.3f);
computeFacingDirection();
}
}
void LittleSpiderEntity::drop()
{
// no drop
}
diff --git a/src/RatEntity.cpp b/src/RatEntity.cpp
index 916f698..bc91a07 100644
--- a/src/RatEntity.cpp
+++ b/src/RatEntity.cpp
@@ -1,84 +1,85 @@
#include "RatEntity.h"
#include "BoltEntity.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"
RatEntity::RatEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_RAT), x, y)
{
creatureSpeed = RAT_SPEED;
velocity = Vector2D(creatureSpeed);
computeFacingDirection();
hp = RAT_HP;
meleeDamages = RAT_DAMAGES;
type = ENTITY_ENNEMY;
bloodColor = bloodRed;
shadowFrame = 7;
dyingFrame = 6;
deathFrame = FRAME_CORPSE_RAT;
agonizingSound = SOUND_RAT_DYING;
+ enemyType = EnemyTypeRat;
}
void RatEntity::animate(float delay)
{
if (age > 0.0f && !isAgonising)
{
frame = ((int)(age * 5.0f)) % 2;
if (facingDirection == 4 || facingDirection == 6) frame += 2;
isMirroring = (facingDirection == 4 );
if (facingDirection == 8) frame += 4;
}
EnnemyEntity::animate(delay);
}
void RatEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2 + RAT_BB_LEFT;
boundingBox.width = width - RAT_BB_WIDTH_DIFF;
boundingBox.top = (int)y - height / 2 + RAT_BB_TOP;
boundingBox.height = height - RAT_BB_HEIGHT_DIFF;
}
void RatEntity::collideMapRight()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
else computeFacingDirection();
}
void RatEntity::collideMapLeft()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
else computeFacingDirection();
}
void RatEntity::collideMapTop()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
else computeFacingDirection();
}
void RatEntity::collideMapBottom()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
else computeFacingDirection();
}
void RatEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
if (entity->getMovingStyle() == movWalking)
{
setVelocity(Vector2D(entity->getX(), entity->getY()).vectorTo(Vector2D(x, y), creatureSpeed ));
computeFacingDirection();
}
}
diff --git a/src/RockMissileEntity.cpp b/src/RockMissileEntity.cpp
index 58d470b..2e01827 100644
--- a/src/RockMissileEntity.cpp
+++ b/src/RockMissileEntity.cpp
@@ -1,131 +1,132 @@
#include "RockMissileEntity.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"
RockMissileEntity::RockMissileEntity(float x, float y, int rockType)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_CYCLOP), x, y)
{
Vector2D targetPos = game().getPlayerPosition();
imagesProLine = 20;
collisionDirection = -1;
type = ENTITY_ENNEMY;
+ enemyType = EnemyTypeRockMissile;
movingStyle = movFlying;
bloodColor = bloodNone; // stones don't bleed
hasCollided = false;
age = 0.0f;
this->rockType = rockType;
if (rockType == 0)
{
creatureSpeed = 500.0f;
hp = 12;
meleeDamages = 8;
frame = 18;
}
else
{
creatureSpeed = 450.0f;
hp = 24;
meleeDamages = 10;
frame = 38;
}
setVelocity(Vector2D(x, y).vectorNearlyTo(targetPos, creatureSpeed, 0.4f));
}
void RockMissileEntity::animate(float delay)
{
EnnemyEntity::animate(delay);
if (x < -60 || x > 1050 || y < - 50 || y > 800) isDying = true;
}
void RockMissileEntity::calculateBB()
{
int w;
if (rockType == 0) w = 20;
else w = 24;
boundingBox.left = (int)x - w / 2;
boundingBox.width = w;
boundingBox.top = (int)y - w / 2;
boundingBox.height = w;
}
void RockMissileEntity::collideWall()
{
if (rockType == 1 && !hasCollided)
{
hasCollided = true;
if (collisionDirection == DIRECTION_RIGHT || collisionDirection == DIRECTION_LEFT) velocity.x = -velocity.x;
else velocity.y = -velocity.y;
}
else
{
dying();
}
}
void RockMissileEntity::collideMapRight()
{
collisionDirection = DIRECTION_RIGHT;
collideWall();
}
void RockMissileEntity::collideMapLeft()
{
collisionDirection = DIRECTION_LEFT;
collideWall();
}
void RockMissileEntity::collideMapTop()
{
collisionDirection = DIRECTION_TOP;
collideWall();
}
void RockMissileEntity::collideMapBottom()
{
collisionDirection = DIRECTION_BOTTOM;
collideWall();
}
void RockMissileEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
}
void RockMissileEntity::dying()
{
isDying = true;
SoundManager::getSoundManager()->playSound(SOUND_ROCK_IMPACT);
game().makeShake(0.1f);
for (int i = 0; i < 4; i++)
{
SpriteEntity* blood = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_BLOOD), x, y, 16, 16, 6);
blood->setZ(OFFSET_Y - 1);
blood->setFrame(12 + rand()%6);
blood->setType(ENTITY_BLOOD);
blood->setVelocity(Vector2D(rand()%150));
blood->setViscosity(0.95f);
float bloodScale = 1.0f + (rand() % 10) * 0.1f;
blood->setScale(bloodScale, bloodScale);
if ((collisionDirection == DIRECTION_LEFT) && (blood->getVelocity().x < 0.0f))
blood->setVelocity(Vector2D(-blood->getVelocity().x * 0.25f, blood->getVelocity().y));
else if ((collisionDirection == DIRECTION_RIGHT) && (blood->getVelocity().x > 0.0f))
blood->setVelocity(Vector2D(-blood->getVelocity().x * 0.25f, blood->getVelocity().y));
else if ((collisionDirection == DIRECTION_TOP) && (blood->getVelocity().y < 0.0f))
blood->setVelocity(Vector2D(blood->getVelocity().x, -blood->getVelocity().y * 0.25f));
else if ((collisionDirection == DIRECTION_BOTTOM) && (blood->getVelocity().y > 0.0f))
blood->setVelocity(Vector2D(blood->getVelocity().x, -blood->getVelocity().y * 0.25f));
}
}
diff --git a/src/SlimeEntity.cpp b/src/SlimeEntity.cpp
index 294f521..8cb99db 100644
--- a/src/SlimeEntity.cpp
+++ b/src/SlimeEntity.cpp
@@ -1,301 +1,308 @@
#include "SlimeEntity.h"
#include "PlayerEntity.h"
#include "EnnemyBoltEntity.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)
: EnnemyEntity (ImageManager::getImageManager()->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_ENNEMY_INVOCATED;
jumpingDelay = 0.1f;
age = 0.0f;
}
else
{
type = ENTITY_ENNEMY;
jumpingDelay = 0.6f + 0.1f * (rand() % 20);
}
if (slimeType == SlimeTypeBlue)
{
resistance[ResistanceFrozen] = ResistanceImmune;
resistance[ResistanceIce] = ResistanceHigh;
resistance[ResistanceFire] = ResistanceLow;
+ enemyType = invocated ? EnemyTypeSlimeBlue_invocated : EnemyTypeSlimeBlue;
}
else if (slimeType == SlimeTypeRed)
{
resistance[ResistanceIce] = ResistanceLow;
resistance[ResistanceFire] = ResistanceHigh;
+ enemyType = invocated ? EnemyTypeSlimeRed_invocated : EnemyTypeSlimeRed;
}
+ else
+ {
+ enemyType = invocated ? EnemyTypeSlime_invocated : EnemyTypeSlime;
+ }
+
bloodColor = bloodGreen;
frame = 0;
shadowFrame = 3;
imagesProLine = 4;
isJumping = false;
h = 0.0f;
viscosity = 0.98f;
sprite.setOrigin(32, 44);
}
void SlimeEntity::animate(float delay)
{
float slimeDelay = delay;
if (specialState[SpecialStateIce].active) slimeDelay = delay * specialState[SpecialStateIce].parameter;
if (isJumping)
{
hVelocity -= 700.0f * slimeDelay;
h += hVelocity * slimeDelay;
if (h <= 0.0f)
{
if (hp <= 0)
dying();
else
{
h = 0.0f;
if (isFirstJumping)
{
isFirstJumping = false;
hVelocity = 160.0f;
SoundManager::getSoundManager()->playSound(SOUND_SLIME_IMAPCT);
if (slimeType == SlimeTypeBlue || slimeType == SlimeTypeRed)
fire();
}
else
{
jumpingDelay = 0.4f + 0.1f * (rand() % 20);
isJumping = false;
SoundManager::getSoundManager()->playSound(SOUND_SLIME_IMAPCT_WEAK);
}
}
}
if (hVelocity > 0.0f) frame = 2;
else frame = 0;
}
else
{
jumpingDelay -= slimeDelay;
if (jumpingDelay < 0.0f)
{
SoundManager::getSoundManager()->playSound(SOUND_SLIME_JUMP);
hVelocity = 350.0f + rand() % 300;
isJumping = true;
isFirstJumping = true;
float randVel = 250.0f + rand() % 250;
if (rand() % 2 == 0)
{
float tan = (game().getPlayer()->getX() - x) / (game().getPlayer()->getY() - y);
float angle = atan(tan);
if (game().getPlayer()->getY() > y)
setVelocity(Vector2D(sin(angle) * randVel,
cos(angle) * randVel));
else
setVelocity(Vector2D(-sin(angle) * randVel,
-cos(angle) * randVel));
}
else
velocity = Vector2D(randVel);
}
else if (jumpingDelay < 0.25f)
frame = 1;
else frame = 0;
}
EnnemyEntity::animate(delay);
z = y + 14;
}
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::collideWithEnnemy(GameEntity* collidingEntity)
{
if (recoil.active && recoil.stun) return;
EnnemyEntity* entity = static_cast<EnnemyEntity*>(collidingEntity);
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 (xTile == 0 || xTile == MAP_WIDTH - 1 || yTile == 0 || yTile == MAP_HEIGHT - 1)
{
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()
{
isDying = true;
SpriteEntity* deadSlime = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES), x, y, 64, 64);
deadSlime->setZ(OFFSET_Y);
switch (slimeType)
{
case SlimeTypeStandard: deadSlime->setFrame(FRAME_CORPSE_SLIME); break;
case SlimeTypeRed: deadSlime->setFrame(FRAME_CORPSE_SLIME_RED); break;
case SlimeTypeBlue: deadSlime->setFrame(FRAME_CORPSE_SLIME_BLUE); break;
}
deadSlime->setType(ENTITY_CORPSE);
for (int i = 0; i < 4; i++) game().generateBlood(x, y, bloodColor);
if (!invocated) drop();
SoundManager::getSoundManager()->playSound(SOUND_ENNEMY_DYING);
}
void SlimeEntity::prepareDying()
{
if (!isJumping)
dying();
}
bool SlimeEntity::canCollide()
{
return h <= 70.0f;
}
BaseCreatureEntity::enumMovingStyle SlimeEntity::getMovingStyle()
{
if (h <= 70.0f)
return movWalking;
else
return movFlying;
}
void SlimeEntity::fire()
{
for (int i = 0; i < 4; i++)
{
EnnemyBoltEntity* bolt;
if (slimeType == SlimeTypeBlue)
{
bolt = new EnnemyBoltEntity(x, y, ShotTypeIce, 0);
bolt->setDamages(5);
}
else if (slimeType == SlimeTypeRed)
{
bolt = new EnnemyBoltEntity(x, y, ShotTypeFire, 0);
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;
}
}
SoundManager::getSoundManager()->playSound(SOUND_BLAST_FLOWER);
}
diff --git a/src/SpiderEggEntity.cpp b/src/SpiderEggEntity.cpp
index 0278e65..0f2a7c6 100644
--- a/src/SpiderEggEntity.cpp
+++ b/src/SpiderEggEntity.cpp
@@ -1,192 +1,193 @@
#include "SpiderEggEntity.h"
#include "PlayerEntity.h"
#include "LittleSpiderEntity.h"
#include "BoltEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
SpiderEggEntity::SpiderEggEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_SPIDER_EGG), x, y)
{
imagesProLine = 20;
type = ENTITY_ENNEMY_INVOCATED;
+ enemyType = EnemyTypeSpiderEgg_invocated;
movingStyle = movFlying;
bloodColor = bloodGreen;
deathFrame = FRAME_CORPSE_SPIDER_EGG;
age = 0.0f;
h = 1800 + rand() % 1000;
hp = 24;
jumping = false;
hVelocity = 0.0f;
lifetime = 12.0f + (rand() % 700) / 100;
}
void SpiderEggEntity::animate(float delay)
{
if (movingStyle == movFlying)
{
if (jumping)
{
hVelocity -= 300.0f * delay;
h += hVelocity * delay;
if (h <= 0.0f)
{
movingStyle = movWalking;
h = 0.0f;
}
}
else
{
h -= delay * 750.0f;
if (h < 0.0f)
{
h = 0.0f;
hVelocity = 100.0f;
jumping = true;
}
}
}
EnnemyEntity::animate(delay);
z = y + 25;
frame = 0;
if (lifetime - age < 1.0f) frame = 3;
else if (lifetime - age < 2.5f) frame = 2;
else if (lifetime - age < 5.0f) frame = 1;
}
void SpiderEggEntity::dyingFromAge()
{
new LittleSpiderEntity(x, y);
for (int i = 0; i < 4; i++)
{
SpriteEntity* blood = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_BLOOD), x, y, 16, 16, 6);
blood->setZ(OFFSET_Y - 1);
blood->setFrame(18 + rand()%6);
blood->setType(ENTITY_BLOOD);
blood->setVelocity(Vector2D(rand()%250));
blood->setViscosity(0.95f);
float bloodScale = 1.0f + (rand() % 10) * 0.1f;
blood->setScale(bloodScale, bloodScale);
}
isDying = true;
}
void SpiderEggEntity::render(sf::RenderTarget* app)
{
int nx = frame % imagesProLine;
int ny = frame / imagesProLine;
// shadow
if (h <= 1600)
{
int f = 1600 - h;
if (f > 255) f = 255;
sprite.setColor(sf::Color(255, 255, 255, f));
sprite.setPosition(x, y);
sprite.setTextureRect(sf::IntRect(4 * width, 0, width, height));
app->draw(sprite);
sprite.setColor(sf::Color(255, 255, 255, 255));
}
sprite.setPosition(x, y - h);
sprite.setTextureRect(sf::IntRect(nx * width, ny * height, width, height));
app->draw(sprite);
if (game().getShowLogical())
{
displayBoundingBox(app);
displayCenterAndZ(app);
}
}
void SpiderEggEntity::calculateBB()
{
boundingBox.left = (int)x - 20;
boundingBox.width = 40;
boundingBox.top = (int)y - 5;
boundingBox.height = 30;
}
bool SpiderEggEntity::canCollide()
{
return h < 70;
}
void SpiderEggEntity::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 (movingStyle == movFlying && playerEntity != NULL && !playerEntity->isDead())
{
if (playerEntity->hurt(meleeDamages, ShotTypeStandard, 0))
{
float xs = (x + playerEntity->getX()) / 2;
float ys = (y + playerEntity->getY()) / 2;
SpriteEntity* star = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_STAR_2), xs, ys);
star->setFading(true);
star->setZ(y+ 100);
star->setLifetime(0.7f);
star->setType(16);
star->setSpin(400.0f);
}
inflictsRecoilTo(playerEntity);
}
else if (boltEntity != NULL && !boltEntity->getDying() && boltEntity->getAge() > 0.05f)
{
float xs = (x + boltEntity->getX()) / 2;
float ys = (y + boltEntity->getY()) / 2;
boltEntity->collide();
hurt(boltEntity->getDamages(), boltEntity->getBoltType(), boltEntity->getLevel());
if (bloodColor > bloodNone) game().generateBlood(x, y, bloodColor);
SoundManager::getSoundManager()->playSound(SOUND_IMPACT);
SpriteEntity* star = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_STAR_2), xs, ys);
star->setFading(true);
star->setZ(y+ 100);
star->setLifetime(0.7f);
star->setType(16);
star->setSpin(400.0f);
if (boltEntity->getBoltType() == ShotTypeStone)
{
float recoilVelocity = STONE_DECOIL_VELOCITY[boltEntity->getLevel()];
float recoilDelay = STONE_DECOIL_DELAY[boltEntity->getLevel()];
if (resistance[ResistanceRecoil] == ResistanceHigh)
{
recoilVelocity *= 0.75f;
recoilDelay *= 0.75f;
}
else if (resistance[ResistanceRecoil] == ResistanceVeryHigh)
{
recoilVelocity *= 0.5f;
recoilDelay *= 0.5f;
}
Vector2D recoilVector = Vector2D(boltEntity->getX(),
boltEntity->getY()).vectorTo(Vector2D(x, y),
recoilVelocity );
giveRecoil(true, recoilVector, recoilDelay);
}
}
}
}
}
diff --git a/src/SpiderWebEntity.cpp b/src/SpiderWebEntity.cpp
index 7753c91..c29180c 100644
--- a/src/SpiderWebEntity.cpp
+++ b/src/SpiderWebEntity.cpp
@@ -1,146 +1,147 @@
#include "SpiderWebEntity.h"
#include "PlayerEntity.h"
#include "BoltEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
SpiderWebEntity::SpiderWebEntity(float x, float y)
: EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_SPIDER_WEB), x, y)
{
imagesProLine = 20;
- type = ENTITY_ENNEMY;
+ type = ENTITY_ENNEMY_INVOCATED;
+ enemyType = EnemyTypeSpiderWeb;
movingStyle = movFlying;
bloodColor = bloodNone; // web don't bleed
deathFrame = FRAME_CORPSE_SPIDER_WEB;
age = 0.0f;
frame = 0;
setVelocity(Vector2D(80 + rand()% 500));
width = 128.0f;
height = 128.0f;
sprite.setOrigin(64.0f, 64.0f);
viscosity = 0.97f;
hp = 40;
hpMax = 40;
// avoid collisions
calculateBB();
float x0 = OFFSET_X + TILE_WIDTH + 1;
float xf = OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 1) - 1;
float y0 = OFFSET_Y + TILE_HEIGHT + 1;
float yf = OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 1) - 1;
if (boundingBox.left < x0) this->x += (x0 - boundingBox.left);
else if (boundingBox.left + boundingBox.width > xf) this->x -= (boundingBox.left + boundingBox.width - xf);
if (boundingBox.top < y0) this->y += (y0 - boundingBox.top);
else if (boundingBox.top + boundingBox.height > yf) this->y -= (boundingBox.top + boundingBox.height - yf);
resistance[ResistanceFrozen] = ResistanceImmune;
resistance[ResistanceRecoil] = ResistanceImmune;
resistance[ResistanceFire] = ResistanceVeryLow;
resistance[ResistanceStone] = ResistanceVeryLow;
}
void SpiderWebEntity::animate(float delay)
{
EnnemyEntity::animate(delay);
if (age <= 0.5f)
{
float scale = age * 2.0f;
sprite.setScale(scale,scale);
}
else
sprite.setScale(1.0f, 1.0f);
int color = 177 + 78 * hp / hpMax;
sprite.setColor(sf::Color(color, color, color, 255));
}
void SpiderWebEntity::calculateBB()
{
boundingBox.left = (int)x - 45;
boundingBox.width = 90;
boundingBox.top = (int)y - 45;
boundingBox.height = 90;
}
void SpiderWebEntity::collideMapRight()
{
collideWall();
}
void SpiderWebEntity::collideMapLeft()
{
collideWall();
}
void SpiderWebEntity::collideMapTop()
{
collideWall();
}
void SpiderWebEntity::collideMapBottom()
{
collideWall();
}
void SpiderWebEntity::collideWall()
{
velocity.x = 0.0f;
velocity.y = 0.0f;
}
void SpiderWebEntity::collideWithEnnemy(GameEntity* collidingEntity)
{
}
void SpiderWebEntity::drop()
{
}
void SpiderWebEntity::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())
{
if (!playerEntity->isSpecialStateActive(SpecialStateSlow))
{
playerEntity->setSpecialState(SpecialStateSlow, true, 0.1f, 0.33f);
hurt(2, ShotTypeStandard, 0);
}
}
else if (boltEntity != NULL && !boltEntity->getDying() && boltEntity->getAge() > 0.05f)
{
float xs = (x + boltEntity->getX()) / 2;
float ys = (y + boltEntity->getY()) / 2;
boltEntity->collide();
hurt(boltEntity->getDamages(), boltEntity->getBoltType(), boltEntity->getLevel());
if (bloodColor > bloodNone) game().generateBlood(x, y, bloodColor);
SoundManager::getSoundManager()->playSound(SOUND_IMPACT);
SpriteEntity* star = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_STAR_2), xs, ys);
star->setFading(true);
star->setZ(y+ 100);
star->setLifetime(0.7f);
star->setType(16);
star->setSpin(400.0f);
}
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jun 11, 9:55 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68225
Default Alt Text
(105 KB)
Attached To
Mode
R78 witchblast
Attached
Detach File
Event Timeline