Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F86226
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/src/CauldronEntity.cpp b/src/CauldronEntity.cpp
index 88e5d1e..29d9a99 100644
--- a/src/CauldronEntity.cpp
+++ b/src/CauldronEntity.cpp
@@ -1,248 +1,250 @@
#include "CauldronEntity.h"
#include "SlimeEntity.h"
#include "ExplosionEntity.h"
#include "PlayerEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
CauldronEntity::CauldronEntity(float x, float y, cauldronTypeEnum cauldronType)
: EnemyEntity (ImageManager::getInstance().getImage(IMAGE_CAULDRON), x, y)
{
creatureSpeed = 0.0f;
velocity = Vector2D(0.0f, 0.0f);
hp = CAULDRON_HP;
hpMax = hp;
meleeDamages = 0;
this->cauldronType = cauldronType;
bloodColor = BloodNone;
invokeDelay = 2.5f;
bubbleDelay = 0.0f;
shadowFrame = 2;
sprite.setOrigin(32, 28);
imagesProLine = 2;
deathFrame = FRAME_CORPSE_CAULDRON;
dyingSound = SOUND_CAULDRON_DIE;
if (cauldronType == CauldronTypeElemental)
{
enemyType = EnemyTypeCauldronElemental;
colorChangeDelay = 4.0f + rand()% 40 * 0.1f;
colorState = rand() % 3;
}
else
{
enemyType = EnemyTypeCauldron;
}
enemyType = cauldronType == CauldronTypeStandard ? EnemyTypeCauldron : EnemyTypeCauldronElemental;
resistance[ResistanceRecoil] = ResistanceVeryHigh;
resistance[ResistancePoison] = ResistanceImmune;
canExplode = false;
}
void CauldronEntity::animate(float delay)
{
if (isAgonising)
{
agonizingDelay -= delay;
if (agonizingDelay <= 0.0f)
{
isDying = true;
game().addCorpse(x, y, deathFrame);
}
}
else
{
SoundManager::getInstance().playSound(SOUND_CAULDRON, false);
invokeDelay -= delay;
if (invokeDelay < 0.0f)
{
if (cauldronType == CauldronTypeElemental)
{
if (game().getEnemyCount() < 9)
{
slimeTypeEnum slimeType = SlimeTypeStandard;
switch (colorState)
{
case 0: slimeType = SlimeTypeBlue; break;
case 1: slimeType = SlimeTypeRed; break;
case 2: slimeType = SlimeTypeStandard; break;
}
- new SlimeEntity(x, y, slimeType, true);
+ SlimeEntity* slime = new SlimeEntity(x, y, slimeType, true);
+ slime->disableCollidingTemporary();
invokeDelay = 3.75f + (float)(rand() % 3000) / 1000.0f;
}
}
else
{
- new SlimeEntity(x, y, SlimeTypeViolet, true);
+ SlimeEntity* slime = new SlimeEntity(x, y, SlimeTypeViolet, true);
+ slime->disableCollidingTemporary();
invokeDelay = 1.5f + (float)(rand() % 2500) / 1000.0f;
}
}
if (cauldronType == CauldronTypeElemental)
{
colorChangeDelay -= delay;
if (colorChangeDelay < 0.0f)
{
colorChangeDelay = 4.0f + rand()% 50 * 0.1f;
if (rand() % 2 == 0)
{
colorState++;
if (colorState > 2) colorState = 0;
}
else
{
colorState--;
if (colorState < 0) colorState = 2;
}
}
}
bubbleDelay -= delay;
if (bubbleDelay < 0.0f)
{
bubbleDelay = 0.3f;
int bubbleFrame = 32;
if (cauldronType == CauldronTypeElemental)
{
switch (colorState)
{
case 0: bubbleFrame = 33; break;
case 1: bubbleFrame = 34; break;
case 2: bubbleFrame = 35; break;
}
}
for (int i=0; i < 2; i++)
{
float xBub = x - 16 + rand() % 32;
SpriteEntity* bubble = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_CAULDRON), xBub, y - 20, 8, 8);
bubble->setZ(z);
bubble->setFrame(bubbleFrame);
bubble->setType(ENTITY_EFFECT);
bubble->setWeight(-20 - rand() % 40);
bubble->setLifetime(2.0f);
float bloodScale = 0.3f + (rand() % 20) * 0.1f;
bubble->setScale(bloodScale, bloodScale);
}
}
frame = hp > hpMax / 2 ? 0 : 1;
if (cauldronType == CauldronTypeElemental)
{
switch (colorState)
{
case 0: frame += 2; break;
case 1: frame += 4; break;
case 2: frame += 6; break;
}
}
EnemyEntity::animate(delay);
}
}
void CauldronEntity::readCollidingEntity(CollidingSpriteEntity* entity)
{
if (!isDying && !isAgonising && collideWithEntity(entity))
{
if (entity->getType() == ENTITY_PLAYER || entity->getType() == ENTITY_BOLT )
{
PlayerEntity* playerEntity = dynamic_cast<PlayerEntity*>(entity);
BoltEntity* boltEntity = dynamic_cast<BoltEntity*>(entity);
if (playerEntity != NULL && !playerEntity->isDead())
{
inflictsRecoilTo(playerEntity);
}
else if (boltEntity != NULL && !boltEntity->getDying() && boltEntity->getAge() > 0.05f)
{
collideWithBolt(boltEntity);
}
}
else // collision with other enemy ?
{
if (entity->getType() >= ENTITY_ENEMY && entity->getType() <= ENTITY_ENEMY_MAX)
{
if (this != entity)
{
EnemyEntity* enemyEntity = static_cast<EnemyEntity*>(entity);
if (enemyEntity->canCollide()) collideWithEnemy(enemyEntity);
}
}
}
}
}
void CauldronEntity::calculateBB()
{
boundingBox.left = (int)x - 25;
boundingBox.width = 50;
boundingBox.top = (int)y - 10;
boundingBox.height = 42;
}
void CauldronEntity::collideMapRight()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
}
void CauldronEntity::collideMapLeft()
{
velocity.x = -velocity.x;
if (recoil.active) recoil.velocity.x = -recoil.velocity.x;
}
void CauldronEntity::collideMapTop()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
}
void CauldronEntity::collideMapBottom()
{
velocity.y = -velocity.y;
if (recoil.active) recoil.velocity.y = -recoil.velocity.y;
}
void CauldronEntity::collideWithEnemy(EnemyEntity* entity)
{
if (entity->getMovingStyle() != movFlying)
inflictsRecoilTo(entity);
}
void CauldronEntity::dying()
{
new ExplosionEntity(x, y, ExplosionTypeViolet, 0, EnemyTypeNone, true);
if (cauldronType == CauldronTypeElemental)
{
switch (colorState)
{
case 0: deathFrame = FRAME_CORPSE_CAULDRON_RED; break;
case 1: deathFrame = FRAME_CORPSE_CAULDRON_BLUE; break;
case 2: deathFrame = FRAME_CORPSE_CAULDRON_GREEN; break;
}
}
EnemyEntity::dying();
return;
}
void CauldronEntity::drop()
{
EnemyEntity::drop();
}
void CauldronEntity::inflictsRecoilTo(BaseCreatureEntity* targetEntity)
{
Vector2D recoilVector = Vector2D(x, y).vectorTo(Vector2D(targetEntity->getX(), targetEntity->getY()), 200.0f );
targetEntity->giveRecoil(false, recoilVector, 0.1f);
}
diff --git a/src/SlimeEntity.cpp b/src/SlimeEntity.cpp
index 8a1b626..127ee17 100644
--- a/src/SlimeEntity.cpp
+++ b/src/SlimeEntity.cpp
@@ -1,403 +1,416 @@
#include "SlimeEntity.h"
#include "PlayerEntity.h"
#include "EnemyBoltEntity.h"
#include "ExplosionEntity.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
SlimeEntity::SlimeEntity(float x, float y, slimeTypeEnum slimeType, bool invocated)
: EnemyEntity (ImageManager::getInstance().getImage(IMAGE_SLIME), x, y)
{
creatureSpeed = 0.0f;
velocity = Vector2D(0.0f, 0.0f);
hp = SLIME_HP;
meleeDamages = SLIME_DAMAGES;
this->slimeType = slimeType;
this->invocated = invocated;
if (invocated)
{
type = ENTITY_ENEMY_INVOCATED;
jumpingDelay = 0.1f;
age = 0.0f;
}
else
{
jumpingDelay = 0.6f + 0.1f * (rand() % 20);
}
if (slimeType == SlimeTypeBlue)
{
resistance[ResistanceFrozen] = ResistanceImmune;
resistance[ResistanceIce] = ResistanceVeryHigh;
resistance[ResistanceFire] = ResistanceVeryLow;
enemyType = invocated ? EnemyTypeSlimeBlue_invocated : EnemyTypeSlimeBlue;
deathFrame = FRAME_CORPSE_SLIME_BLUE;
}
else if (slimeType == SlimeTypeRed)
{
resistance[ResistanceIce] = ResistanceVeryLow;
resistance[ResistanceFire] = ResistanceVeryHigh;
enemyType = invocated ? EnemyTypeSlimeRed_invocated : EnemyTypeSlimeRed;
deathFrame = FRAME_CORPSE_SLIME_RED;
}
else if (slimeType == SlimeTypeViolet)
{
enemyType = invocated ? EnemyTypeSlimeViolet_invocated : EnemyTypeSlimeViolet;
canExplode = false;
deathFrame = FRAME_CORPSE_SLIME_VIOLET;
}
else
{
enemyType = invocated ? EnemyTypeSlime_invocated : EnemyTypeSlime;
deathFrame = FRAME_CORPSE_SLIME;
}
bloodColor = BloodGreen;
frame = 0;
shadowFrame = 3;
imagesProLine = 4;
isJumping = false;
h = 0.0f;
viscosity = 0.98f;
sprite.setOrigin(32, 44);
isPet = false;
willExplode = false;
+ noCollisionTimer = -1.0f;
+}
+
+void SlimeEntity::setH(float h)
+{
+ this->h = h;
}
void SlimeEntity::animate(float delay)
{
+ if (noCollisionTimer > 0.0f) noCollisionTimer -= delay;
float slimeDelay = delay;
if (specialState[SpecialStateIce].active) slimeDelay = delay * specialState[SpecialStateIce].param1;
if (isJumping)
{
hVelocity -= 700.0f * slimeDelay;
h += hVelocity * slimeDelay;
bool firstTimeGround = false;
if (h <= 0.0f)
{
if (hp <= 0)
dying();
else
{
h = 0.0f;
if (isFirstJumping)
{
isFirstJumping = false;
firstTimeGround = true;
hVelocity = 160.0f;
SoundManager::getInstance().playSound(SOUND_SLIME_IMAPCT);
if (slimeType == SlimeTypeBlue || slimeType == SlimeTypeRed)
fire();
else if (slimeType == SlimeTypeViolet)
{
hp = 0;
dying();
}
}
else
{
jumpingDelay = 0.4f + 0.1f * (rand() % 20);
isJumping = false;
SoundManager::getInstance().playSound(SOUND_SLIME_IMAPCT_WEAK);
}
}
}
if (firstTimeGround) frame = 0;
else if (hVelocity > -190.0f) frame = 2;
else frame = 1;
}
else
{
jumpingDelay -= slimeDelay;
if (jumpingDelay < 0.0f)
{
SoundManager::getInstance().playSound(SOUND_SLIME_JUMP);
hVelocity = 350.0f + rand() % 300;
isJumping = true;
isFirstJumping = true;
float randVel = 250.0f + rand() % 250;
if (!game().getPlayer()->isEquiped(EQUIP_MANUAL_SLIMES) && rand() % 2 == 0)
{
setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), randVel ));
}
else
velocity = Vector2D(randVel);
}
else if (jumpingDelay < 0.1f)
frame = 1;
else frame = 0;
}
EnemyEntity::animate(delay);
z = y + 14;
}
void SlimeEntity::makeExplode()
{
if (isJumping)
willExplode = true;
else
BaseCreatureEntity::makeExplode();
}
void SlimeEntity::readCollidingEntity(CollidingSpriteEntity* entity)
{
if (!isDying && !isAgonising && collideWithEntity(entity))
{
if (!isPet && (entity->getType() == ENTITY_PLAYER || entity->getType() == ENTITY_BOLT ) )
{
PlayerEntity* playerEntity = dynamic_cast<PlayerEntity*>(entity);
BoltEntity* boltEntity = dynamic_cast<BoltEntity*>(entity);
if (playerEntity != NULL && !playerEntity->isDead())
{
if (playerEntity->hurt(getHurtParams(meleeDamages, meleeType, meleeDamages, false, SourceTypeMelee, enemyType, false)))
{
float xs = (x + playerEntity->getX()) / 2;
float ys = (y + playerEntity->getY()) / 2;
SpriteEntity* star = new SpriteEntity(ImageManager::getInstance().getImage(IMAGE_HURT_IMPACT), xs, ys);
star->setFading(true);
star->setZ(y+ 100);
star->setLifetime(0.7f);
star->setType(ENTITY_EFFECT);
star->setSpin(400.0f);
}
inflictsRecoilTo(playerEntity);
}
else if (boltEntity != NULL && !boltEntity->getDying() && boltEntity->getAge() > 0.05f)
{
collideWithBolt(boltEntity);
}
}
else // collision with other enemy ?
{
if (entity->getType() >= ENTITY_ENEMY && entity->getType() <= ENTITY_ENEMY_MAX_COUNT)
{
if (this != entity)
{
EnemyEntity* enemyEntity = static_cast<EnemyEntity*>(entity);
if (enemyEntity->canCollide()) collideWithEnemy(enemyEntity);
}
}
}
}
}
void SlimeEntity::render(sf::RenderTarget* app)
{
if (!isDying && shadowFrame > -1)
{
// shadow
sprite.setPosition(x, y);
sprite.setTextureRect(sf::IntRect(shadowFrame * width, 0, width, height));
app->draw(sprite);
}
sprite.setPosition(x, y - h);
sprite.setTextureRect(sf::IntRect(frame * width, slimeType * height, width, height));
app->draw(sprite);
if (game().getShowLogical())
{
displayBoundingBox(app);
displayCenterAndZ(app);
}
}
void SlimeEntity::calculateBB()
{
if (isPet)
{
boundingBox.left = (int)x - 1;
boundingBox.width = 2;
boundingBox.top = (int)y - 1;
boundingBox.height = 2;
}
else
{
boundingBox.left = (int)x - width / 2 + SLIME_BB_LEFT;
boundingBox.width = width - SLIME_BB_WIDTH_DIFF;
boundingBox.top = (int)y - height / 2 + SLIME_BB_TOP - 15;
boundingBox.height = height - SLIME_BB_HEIGHT_DIFF;
}
}
void SlimeEntity::collideMapRight()
{
// if (x > OFFSET_X + MAP_WIDTH * TILE_WIDTH)
velocity.x = -velocity.x * 0.8f;
}
void SlimeEntity::collideMapLeft()
{
// if (x < OFFSET_X + MAP_WIDTH )
velocity.x = -velocity.x * 0.8f;
}
void SlimeEntity::collideMapTop()
{
// if (y > OFFSET_Y + MAP_HEIGHT * TILE_HEIGHT)
velocity.y = -velocity.y * 0.8f;
}
void SlimeEntity::collideMapBottom()
{
// if (y < OFFSET_Y + MAP_HEIGHT )
velocity.y = -velocity.y * 0.8f;
}
void SlimeEntity::collideWithEnemy(EnemyEntity* entity)
{
if (recoil.active && recoil.stun) return;
if (entity->getMovingStyle() == movWalking)
{
Vector2D vel = Vector2D(entity->getX(), entity->getY()).vectorTo(Vector2D(x, y), 100.0f );
giveRecoil(false, vel, 0.3f);
computeFacingDirection();
}
}
bool SlimeEntity::collideWithMap(int direction)
{
calculateBB();
int xTile0 = (boundingBox.left - offsetX) / tileWidth;
int xTilef = (boundingBox.left + boundingBox.width - offsetX) / tileWidth;
int yTile0 = (boundingBox.top - offsetY) / tileHeight;
int yTilef = (boundingBox.top + boundingBox.height - offsetY) / tileHeight;
if (boundingBox.top < 0) yTile0 = -1;
for (int xTile = xTile0; xTile <= xTilef; xTile++)
for (int yTile = yTile0; yTile <= yTilef; yTile++)
{
if (!game().getCurrentMap()->isFlyable(xTile, yTile))
{
switch (direction)
{
case DIRECTION_LEFT:
if (map->isLeftBlocking(xTile, yTile)) return true;
break;
case DIRECTION_RIGHT:
if (map->isRightBlocking(xTile, yTile)) return true;
break;
case DIRECTION_TOP:
if (map->isUpBlocking(xTile, yTile)) return true;
break;
case DIRECTION_BOTTOM:
if (map->isDownBlocking(xTile, yTile)) return true;
break;
}
}
}
return false;
}
void SlimeEntity::dying()
{
if (slimeType == SlimeTypeViolet) explode();
else if (willExplode) BaseCreatureEntity::makeExplode();
EnemyEntity::dying();
}
void SlimeEntity::prepareDying()
{
if (!isJumping)
dying();
}
bool SlimeEntity::canCollide()
{
+ if (noCollisionTimer > 0.0f) return false;
return h <= 70.0f && hp > 0;
}
+void SlimeEntity::disableCollidingTemporary()
+{
+ noCollisionTimer = 0.8f;
+}
+
BaseCreatureEntity::enumMovingStyle SlimeEntity::getMovingStyle()
{
if (h <= 70.0f)
return movWalking;
else
return movFlying;
}
void SlimeEntity::fire()
{
for (int i = 0; i < 4; i++)
{
EnemyBoltEntity* bolt;
if (slimeType == SlimeTypeBlue)
{
bolt = new EnemyBoltEntity(x, y, ShotTypeIce, 0, enemyType);
bolt->setDamages(5);
}
else if (slimeType == SlimeTypeRed)
{
bolt = new EnemyBoltEntity(x, y, ShotTypeFire, 0, enemyType);
bolt->setDamages(8);
}
else
return;
switch (i)
{
case 0: bolt->setVelocity(Vector2D(SLIME_FIRE_VELOCITY, 0)); break;
case 1: bolt->setVelocity(Vector2D(-SLIME_FIRE_VELOCITY, 0)); break;
case 2: bolt->setVelocity(Vector2D(0, SLIME_FIRE_VELOCITY)); break;
case 3: bolt->setVelocity(Vector2D(0, -SLIME_FIRE_VELOCITY)); break;
}
}
if (slimeType == SlimeTypeBlue) SoundManager::getInstance().playSound(SOUND_BLAST_ICE);
else if (slimeType == SlimeTypeRed) SoundManager::getInstance().playSound(SOUND_BLAST_FIRE);
else SoundManager::getInstance().playSound(SOUND_BLAST_FLOWER);
}
void SlimeEntity::explode()
{
int damage = 12;
if (isPet) damage = game().getPlayer()->isEquiped(EQUIP_BOOK_MAGIC_II) ? 24 : 18;
new ExplosionEntity(x, y, ExplosionTypeStandard, damage, enemyType, true);
game().makeShake(1.0f);
SoundManager::getInstance().playSound(SOUND_BOOM_00);
}
void SlimeEntity::makePet(int direction)
{
isPet = true;
hVelocity = 450.0f;
SoundManager::getInstance().playSound(SOUND_SLIME_JUMP);
isJumping = true;
isFirstJumping = true;
switch (direction)
{
case 4: velocity.x = -350.0f; velocity.y = -0; break;
case 6: velocity.x = 350.0f; velocity.y = -0; break;
case 2: velocity.y = 350.0f; velocity.x = -0; break;
default: velocity.y = -350.0f; velocity.x = -0; break;
}
}
void SlimeEntity::drop()
{
if (!invocated) EnemyEntity::drop();
}
diff --git a/src/SlimeEntity.h b/src/SlimeEntity.h
index 70d8782..b10dbf4 100644
--- a/src/SlimeEntity.h
+++ b/src/SlimeEntity.h
@@ -1,49 +1,52 @@
#ifndef SLIMESPRITE_H
#define SLIMESPRITE_H
#include "EnemyEntity.h"
#include "PlayerEntity.h"
enum slimeTypeEnum { SlimeTypeStandard, SlimeTypeRed, SlimeTypeBlue, SlimeTypeViolet };
class SlimeEntity : public EnemyEntity
{
public:
SlimeEntity(float x, float y, slimeTypeEnum slimeType, bool invocated);
virtual void animate(float delay);
virtual void render(sf::RenderTarget* app);
virtual void calculateBB();
virtual bool canCollide();
void makePet(int direction);
+ void setH(float h);
+ void disableCollidingTemporary();
protected:
virtual bool collideWithMap(int direction);
virtual void collideMapRight();
virtual void collideMapLeft();
virtual void collideMapTop();
virtual void collideMapBottom();
virtual void readCollidingEntity(CollidingSpriteEntity* entity);
virtual void collideWithEnemy(EnemyEntity* entity) override;
virtual void dying();
virtual void prepareDying();
virtual void drop();
virtual enumMovingStyle getMovingStyle();
virtual void makeExplode();
private:
float jumpingDelay;
+ float noCollisionTimer;
bool isJumping;
bool isPet;
bool isFirstJumping;
bool invocated;
slimeTypeEnum slimeType;
void fire();
void explode();
bool willExplode;
};
#endif // SLIMESPRITE_H
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Sep 12, 12:36 AM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
42757
Default Alt Text
(19 KB)
Attached To
Mode
R78 witchblast
Attached
Detach File
Event Timeline
Log In to Comment