Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F86233
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/media/effect_zone.png b/media/effect_zone.png
index 3d208ae..bace6f4 100644
Binary files a/media/effect_zone.png and b/media/effect_zone.png differ
diff --git a/src/BoltEntity.cpp b/src/BoltEntity.cpp
index af2fb3c..66001bd 100644
--- a/src/BoltEntity.cpp
+++ b/src/BoltEntity.cpp
@@ -1,506 +1,518 @@
#include "BoltEntity.h"
#include "ExplosionEntity.h"
#include "EffectZoneEntity.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; goThrough = level >= 2; 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())
{
onDying();
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) onDying();
}
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 == 4) game().registerAchievement(Achievement4Hits);
if (goThrough)
{
if (damages > 0)
{
if (damages > 1 && boltType == ShotTypeLightning && level == 2)
{
// bolt lvl3 effect
for (int i = 0; i < 3; i++)
{
BoltEntity* bolt = new BoltEntity(x, y, lifetime, ShotTypeLightning, 1);
bolt->setDamages(damages / 2);
float shotAngle = rand() % 360;
float fireVelocity = 400.0f;
bolt->setVelocity(Vector2D(fireVelocity * cos(shotAngle), fireVelocity * sin(shotAngle)));
}
damages /= 2;
SoundManager::getInstance().playSound(SOUND_ELECTRIC_CHARGE);
}
return;
}
}
}
onDying();
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()
{
if (!isDying)
{
isDying = true;
// special attacks
if (boltType == ShotTypeIce && level == 2)
new EffectZoneEntity(x, y, true, 5.0f, EffectZoneTypeIce);
else if (boltType == ShotTypePoison && level == 2)
{
if (!game().existsEffectZone())
new EffectZoneEntity(x, y, true, 5.0f, EffectZoneTypePoison);
}
-
}
}
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::split(int direction)
{
switch (direction)
{
case 4: x += 8; break;
case 6: x -= 8; break;
case 2: y -= 8; break;
case 8: y += 8; break;
}
float currentVelocity = velocity.norm();
lifetime *= 1.25f;
BoltEntity* bolt2 = new BoltEntity(x, y, lifetime, ShotTypeStone, 1);
level = 1;
damages *= 0.75f;
bolt2->setDamages(damages);
bolt2->setX(x);
bolt2->setY(y);
bolt2->setAge(age);
if (direction == 2 || direction == 8)
{
velocity.x = -currentVelocity;
velocity.y = 0.0f;
bolt2->setVelocity(Vector2D(currentVelocity, 0.0f));
}
else
{
velocity.y = -currentVelocity;
velocity.x = 0.0f;
bolt2->setVelocity(Vector2D(0.0f, currentVelocity));
}
SoundManager::getInstance().playSound(SOUND_STONE_HIT);
}
+void BoltEntity::collideWall()
+{
+ if (boltType == ShotTypeFire && level == 2)
+ {
+ if (!game().existsEffectZone())
+ new EffectZoneEntity(x, y, true, 5.0f, EffectZoneTypeFire, game().getPlayer()->getDamage());
+ }
+}
+
void BoltEntity::collideMapRight()
{
if (boltType == ShotTypeLightning)
{
velocity.x = -velocity.x;
}
else if (boltType == ShotTypeBomb)
{
explode();
}
else if (boltType == ShotTypeStone && level == 2)
{
split(6);
}
else
{
velocity.x = 0.0f;
onDying();
+ collideWall();
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 if (boltType == ShotTypeStone && level == 2)
{
split(4);
}
else
{
velocity.x = 0.0f;
onDying();
+ collideWall();
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 if (boltType == ShotTypeStone && level == 2)
{
split(8);
}
else
{
velocity.y = 0.0f;
onDying();
+ collideWall();
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 if (boltType == ShotTypeStone && level == 2)
{
split(2);
}
else
{
velocity.y = 0.0f;
onDying();
+ collideWall();
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()
{
onDying();
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/BoltEntity.h b/src/BoltEntity.h
index 7d8f16b..22f9c13 100644
--- a/src/BoltEntity.h
+++ b/src/BoltEntity.h
@@ -1,72 +1,73 @@
#ifndef BOLTENTITY_H
#define BOLTENTITY_H
#include "sfml_game/CollidingSpriteEntity.h"
#include "ParticleGenerator.h"
#include "Constants.h"
#include "BaseCreatureEntity.h"
/*! \class BoltEntity
* \brief bolt thrown by the player
*
* BoltEntity are the missile weapons thrown by the player.
* The can collide with an enemy (to hurt him) or with the walls.
*/
class BoltEntity : public CollidingSpriteEntity
{
public:
BoltEntity(float x, float y, float boltLifeTime, enumShotType boltType, int level);
virtual void animate(float delay);
virtual void render(sf::RenderTarget* app);
void collide();
void generateParticule(Vector2D vel);
int getDamages();
unsigned int getLevel();
void setDamages(int damages);
void loseDamages(int damages);
enumShotType getBoltType();
bool isFlying();
void setFlying(bool flying);
bool isCritical();
void setCritical(bool setCritical);
void setGoThrough(bool goThrough);
bool getGoThrough();
enemyTypeEnum getEnemyType();
void setFromPlayer(bool fromPlayer);
bool isFromPlayer();
protected:
virtual void calculateBB();
virtual void collideMapRight();
virtual void collideMapLeft();
virtual void collideMapTop();
virtual void collideMapBottom();
virtual bool collideWithMap(int direction);
+ virtual void collideWall();
virtual void onDying();
virtual void stuck();
void explode();
int damages;
float renderScale;
enumShotType boltType;
enemyTypeEnum enemyType;
ParticleGenerator particleGenerator;
private:
void split(int direction);
bool testWallsCollision;
bool flying;
bool critical;
bool goThrough;
unsigned int level;
int hitNumber;
bool fromPlayer;
};
#endif // BOLTENTITY_H
diff --git a/src/EffectZoneEntity.cpp b/src/EffectZoneEntity.cpp
index b9b017d..5777b45 100644
--- a/src/EffectZoneEntity.cpp
+++ b/src/EffectZoneEntity.cpp
@@ -1,112 +1,126 @@
#include "EffectZoneEntity.h"
#include "BaseCreatureEntity.h"
+#include "ExplosionEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "sfml_game/SpriteEntity.h"
#include "Constants.h"
#include "WitchBlastGame.h"
#include <iostream>
EffectZoneEntity::EffectZoneEntity(float x, float y, bool fromPlayer, float duration,
- EffectZoneTypeEnum effectZoneType)
+ EffectZoneTypeEnum effectZoneType, int damage)
: SpriteEntity(ImageManager::getInstance().getImage(IMAGE_EFFECT_ZONE), x, y, 64, 64)
{
type = ENTITY_EFFECT_ZONE;
this->effectZoneType = effectZoneType;
imagesProLine = 6;
lifetime = duration;
this->fromPlayer = fromPlayer;
+ this->damage = damage;
switch (effectZoneType)
{
case EffectZoneTypeIce: frame = 0; break;
case EffectZoneTypePoison: frame = 1; break;
+ case EffectZoneTypeFire: frame = 2; break;
}
z = 1500; // for flying zones
randomAngle = 5 + rand() % 15;
if (rand() % 2 == 0) randomAngle = -randomAngle;
}
void EffectZoneEntity::animate(float delay)
{
if (lifetime > 0)
{
if (age >= lifetime) isDying = true;
else if (lifetime - age < 1.0f)
{
sprite.setColor(sf::Color(255, 255, 255, 255 * (lifetime - age)));
}
}
age += delay;
angle += delay * randomAngle;
testCollisions();
}
void EffectZoneEntity::render(sf::RenderTarget* app)
{
SpriteEntity::render(app);
}
void EffectZoneEntity::dying()
{
isDying = true;
}
void EffectZoneEntity::collideIce(BaseCreatureEntity* entity)
{
entity->hurt(BaseCreatureEntity::getHurtParams(0, ShotTypeIce, 1, false, SourceTypeExplosion, EnemyTypeNone, false));
}
void EffectZoneEntity::collidePoison(BaseCreatureEntity* entity)
{
if (!entity->getSpecialState(SpecialStatePoison).active)
{
entity->hurt(BaseCreatureEntity::getHurtParams(0, ShotTypePoison, 2, false, SourceTypeExplosion, EnemyTypeNone, false));
}
}
+void EffectZoneEntity::explode()
+{
+ if (damage > 0)
+ {
+ new ExplosionEntity(x, y, ExplosionTypeStandard, damage, EnemyTypeNone, false);
+ damage = 0;
+ lifetime = age + 1.0f;
+ }
+}
+
void EffectZoneEntity::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 (fromPlayer && entity->getType() == ENTITY_PLAYER) ok = false;
if (!fromPlayer && entity->getType() != ENTITY_PLAYER) ok = false;
if (ok && entity->getHp() > 0 && entity->canCollide())
{
entity->calculateBB();
sf::IntRect bb;
- bb.left = x - 22;
- bb.width = 44;
- bb.top = y - 22;
- bb.height = 44;
+ bb.left = x - 26;
+ bb.width = 52;
+ bb.top = y - 26;
+ bb.height = 52;
if (bb.intersects(entity->getBoundingBox()))
{
switch (effectZoneType)
{
case EffectZoneTypeIce: collideIce(entity); break;
case EffectZoneTypePoison: collidePoison(entity); break;
+ case EffectZoneTypeFire: explode(); break;
}
}
}
}
}
}
diff --git a/src/EffectZoneEntity.h b/src/EffectZoneEntity.h
index 8f7d305..8625d00 100644
--- a/src/EffectZoneEntity.h
+++ b/src/EffectZoneEntity.h
@@ -1,33 +1,39 @@
#ifndef EFFECT_ZONE_ENTITY_H
#define EFFECT_ZONE_ENTITY_H
#include "sfml_game/SpriteEntity.h"
#include "BaseCreatureEntity.h"
-enum EffectZoneTypeEnum { EffectZoneTypeIce, EffectZoneTypePoison };
+enum EffectZoneTypeEnum
+{
+ EffectZoneTypeIce,
+ EffectZoneTypePoison,
+ EffectZoneTypeFire
+};
class EffectZoneEntity : public SpriteEntity
{
public:
EffectZoneEntity(float x, float y, bool fromPlayer, float duration,
- EffectZoneTypeEnum effectZoneType);
+ EffectZoneTypeEnum effectZoneType, int damage = 0);
virtual void animate(float delay);
virtual void render(sf::RenderTarget* app);
virtual void dying();
protected:
void testCollisions();
private:
int damage;
EffectZoneTypeEnum effectZoneType;
enumShotType damageType;
bool fromPlayer;
float randomAngle;
void collideIce(BaseCreatureEntity* entity);
void collidePoison(BaseCreatureEntity* entity);
+ void explode();
};
#endif // EFFECT_ZONE_ENTITY_H
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Sep 12, 12:40 AM (1 d, 2 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
42764
Default Alt Text
(19 KB)
Attached To
Mode
R78 witchblast
Attached
Detach File
Event Timeline
Log In to Comment