Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F126391
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
73 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/GameFloor.cpp b/src/GameFloor.cpp
index 648ddcd..d301662 100644
--- a/src/GameFloor.cpp
+++ b/src/GameFloor.cpp
@@ -1,292 +1,291 @@
#include "GameFloor.h"
#include <time.h>
#include <cstdlib>
#include <stdio.h>
#include <iostream>
GameFloor::GameFloor()
{
this->level = 0;
// Init maps
for (int i=0; i < FLOOR_WIDTH; i++)
for (int j=0; j < FLOOR_HEIGHT; j++)
maps[i][j] = NULL;
}
GameFloor::GameFloor(int level)
{
// Init maps
for (int i=0; i < FLOOR_WIDTH; i++)
for (int j=0; j < FLOOR_HEIGHT; j++)
maps[i][j] = NULL;
this->level = level;
- srand(time(NULL));
- createFloor();
}
GameFloor::~GameFloor()
{
// Free maps
for (int i=0; i < FLOOR_WIDTH; i++)
for (int j=0; j < FLOOR_HEIGHT; j++)
if (maps[i][j] != NULL) delete (maps[i][j]);
}
int GameFloor::getRoom(int x, int y)
{
if (x < 0 || y < 0 || x >= FLOOR_WIDTH || y >= FLOOR_HEIGHT) return 0;
return floor[x][y];
}
void GameFloor::setRoom(int x, int y, int roomType)
{
floor[x][y] = roomType;
}
DungeonMap* GameFloor::getMap(int x, int y)
{
if (x < 0 || y < 0 || x >= FLOOR_WIDTH || y >= FLOOR_HEIGHT) return NULL;
return maps[x][y];
}
void GameFloor::setMap(int x, int y, DungeonMap* map)
{
maps[x][y] = map;
}
DungeonMap* GameFloor::getAndVisitMap(int x, int y)
{
maps[x][y]->setVisited(true);
if (x > 0 && floor[x-1][y] > 0) maps[x-1][y]->setKnown(true);
if (x < FLOOR_WIDTH - 1 && floor[x+1][y] > 0) maps[x+1][y]->setKnown(true);;
if (y > 0 && floor[x][y-1] > 0) maps[x][y-1]->setKnown(true);;
if (y < FLOOR_HEIGHT - 1 && floor[x][y+1] > 0) maps[x][y+1]->setKnown(true);;
return maps[x][y];
}
void GameFloor::displayToConsole()
{
for (int j=0; j < FLOOR_HEIGHT; j++)
{
for (int i=0; i < FLOOR_WIDTH; i++)
{
switch (floor[i][j])
{
case 0: printf("."); break;
case 1: printf("#"); break;
case 2: printf("&"); break;
case 3: printf("$"); break;
case 4: printf("!"); break;
case 5: printf("*"); break;
case 6: printf("X"); break;
case 7: printf("0"); break;
}
}
printf("\n");
}
}
int GameFloor::neighboorCount(int x, int y)
{
int count = 0;
if (x > 0 && floor[x-1][y] > 0) count++;
if (x < FLOOR_WIDTH - 1 && floor[x+1][y] > 0) count++;
if (y > 0 && floor[x][y-1] > 0) count++;
if (y < FLOOR_HEIGHT - 1 && floor[x][y+1] > 0) count++;
return count;
}
bool GameFloor::isSuperIsolated(int x, int y)
{
if (neighboorCount(x, y) != 1) return false;
else
{
if (x > 0 && floor[x-1][y]==1 && neighboorCount(x-1, y) == 2)
{
floor[x-1][y] = roomTypeBoss;
floor[x][y] = roomTypeExit;
return true;
}
else if (x < FLOOR_WIDTH - 1 && floor[x+1][y]==1 && neighboorCount(x+1, y) == 2)
{
floor[x+1][y] = roomTypeBoss;
floor[x][y] = roomTypeExit;
return true;
}
else if (y < FLOOR_HEIGHT - 1 && floor[x][y+1]==1 && neighboorCount(x, y+1) == 2)
{
floor[x][y+1] = roomTypeBoss;
floor[x][y] = roomTypeExit;
return true;
}
}
return false;
}
bool GameFloor::finalize()
{
bool bKey = false;
bool bBonus = false;
bool bMerchant = false;
bool bExit = false;
for (int i=0; i < FLOOR_WIDTH; i++)
for (int j=0; j < FLOOR_HEIGHT; j++)
{
if (floor[i][j] == 1 && neighboorCount(i, j) == roomTypeStandard)
{
if (!bExit && isSuperIsolated(i, j))
{
bExit = true;
}
else
{
if (!bKey)
{
floor[i][j]= roomTypeKey;
bKey = true;
}
else if (!bBonus)
{
floor[i][j]= roomTypeBonus;
bBonus = true;
}
else if (!bMerchant)
{
floor[i][j]= roomTypeMerchant;
bMerchant = true;
}
}
}
}
return bExit && bKey && bBonus;
}
void GameFloor::createFloor()
{
+ srand(time(NULL));
bool ok=false;
while (!ok)
{
int i, j;
// Free maps
for (i=0; i < FLOOR_WIDTH; i++)
for (j=0; j < FLOOR_HEIGHT; j++)
if (maps[i][j] != NULL)
{
delete (maps[i][j]);
maps[i][j] = NULL;
}
generate();
ok = finalize();
int x0 = FLOOR_WIDTH / 2;
int y0 = FLOOR_HEIGHT / 2;
// Maps
for (i=0; i < FLOOR_WIDTH; i++)
for (j=0; j < FLOOR_HEIGHT; j++)
if (floor[i][j] > 0)
{
maps[i][j] = new DungeonMap(this, i, j);
if (i == x0 && j == y0)
maps[i][j]->setRoomType(roomTypeStarting);
else
maps[i][j]->setRoomType((roomTypeEnum)(floor[i][j]));
}
displayToConsole();
}
}
void GameFloor::generate()
{
int i, j;
int nbRooms;
int requiredRoms = 15;
// Init
for (i=0; i < FLOOR_WIDTH; i++)
for (j=0; j < FLOOR_HEIGHT; j++)
{
floor[i][j] = 0;
}
// First room
int x0 = FLOOR_WIDTH / 2;
int y0 = FLOOR_HEIGHT / 2;
floor[x0][y0] = roomTypeStarting;
nbRooms = 1;
// neighboor
while (nbRooms == 1)
{
if (rand() % 3 == 0)
{
floor[x0-1][y0] = 1;
nbRooms++;
}
if (rand() % 3 == 0)
{
floor[x0+1][y0] = 1;
nbRooms++;
}
if (rand() % 3 == 0)
{
floor[x0][y0-1] = 1;
nbRooms++;
}
if (level == 1)
{
if (rand() % 3 == 0)
{
floor[x0][y0+1] = 1;
nbRooms++;
}
}
}
// others
while (nbRooms < requiredRoms)
for (int k = 0; k < 8; k++)
{
i = rand() % FLOOR_WIDTH;
j = rand() % FLOOR_HEIGHT;
if (floor[i][j] == 0 && ( (level == 1) || (i != x0 || j != y0 + 1) ))
{
int n = neighboorCount(i, j);
switch (n)
{
case 1:
{
floor[i][j] = 1;
nbRooms++;
break;
}
case 2:
{
if (rand()% 5 == 0)
{
floor[i][j] = 1;
nbRooms++;
}
break;
}
case 3:
{
if (rand()% 20 == 0)
{
floor[i][j] = 1;
nbRooms++;
}
break;
}
}
}
}
}
diff --git a/src/PlayerEntity.cpp b/src/PlayerEntity.cpp
index dd8b566..6d83bbf 100644
--- a/src/PlayerEntity.cpp
+++ b/src/PlayerEntity.cpp
@@ -1,795 +1,795 @@
#include "PlayerEntity.h"
#include "BoltEntity.h"
#include "EnnemyBoltEntity.h"
#include "ItemEntity.h"
#include "FairyEntity.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "Constants.h"
#include "WitchBlastGame.h"
#include <iostream>
PlayerEntity::PlayerEntity(float x, float y)
: BaseCreatureEntity (ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE), x, y, 80, 128)
{
currentFireDelay = -1.0f;
canFirePlayer = true;
type = ENTITY_PLAYER;
imagesProLine = 8;
playerStatus = playerStatusPlaying;
hp = INITIAL_PLAYER_HP;
hpDisplay = hp;
hpMax = INITIAL_PLAYER_HP;
gold = 0;
boltLifeTime = INITIAL_BOLT_LIFE;
specialBoltTimer = -1.0f;
bloodColor = bloodRed;
// init the equipment (to empty)
for (int i = 0; i < NUMBER_EQUIP_ITEMS; i++) equip[i] = false;
collidingDirection = 0;
// init the shots (to none)
for (int i = 0; i < SPECIAL_SHOT_SLOTS; i++) specialShots[i] = ShotTypeStandard;
specialShotIndex = 0;
computePlayer();
firingDirection = 5;
facingDirection = 2;
}
void PlayerEntity::moveTo(float newX, float newY)
{
float dx = newX - x;
float dy = newY - y;
x = newX;
y = newY;
if (equip[EQUIP_FAIRY])
{
fairy->setX(fairy->getX() + dx);
fairy->setY(fairy->getY() + dy);
}
}
int PlayerEntity::getFacingDirection()
{
return facingDirection;
}
float PlayerEntity::getPercentFireDelay()
{
if (canFirePlayer) return 1.0f;
else return (1.0f - currentFireDelay / fireDelay);
}
int PlayerEntity::getCollidingDirection()
{
return collidingDirection;
}
PlayerEntity::playerStatusEnum PlayerEntity::getPlayerStatus()
{
return playerStatus;
}
void PlayerEntity::setPlayerStatus(PlayerEntity::playerStatusEnum playerStatus)
{
this->playerStatus = playerStatus;
}
bool PlayerEntity::isDead()
{
return playerStatus==playerStatusDead;
}
void PlayerEntity::setEntering()
{
playerStatus = playerStatusEntering;
}
void PlayerEntity::setLeavingLevel()
{
playerStatus = playerStatusGoingUp;
}
void PlayerEntity::pay(int price)
{
gold -= price;
if (gold < 0) gold = 0;
SoundManager::getSoundManager()->playSound(SOUND_PAY);
}
void PlayerEntity::animate(float delay)
{
if (specialBoltTimer >= 0.0f)
{
specialBoltTimer -= delay;
if (specialBoltTimer <= 0.0f)
{
if (getShotType() == ShotTypeIce) SoundManager::getSoundManager()->playSound(SOUND_ICE_CHARGE);
}
}
// rate of fire
if (!canFirePlayer)
{
currentFireDelay -= delay;
canFirePlayer = (currentFireDelay <= 0.0f);
}
// acquisition animation
if (playerStatus == playerStatusAcquire)
{
acquireDelay -= delay;
if (acquireDelay <= 0.0f)
{
equip[acquiredItem] = true;
playerStatus = playerStatusPlaying;
int itemID = acquiredItem + FirstEquipItem;
if (acquiredItem == (int)EQUIP_FAIRY)
fairy = new FairyEntity(x, y - 50.0f, this);
if (items[itemID].specialShot != (ShotTypeStandard))
registerSpecialShot(itemID);
computePlayer();
}
}
// unlocking animation
else if (playerStatus == playerStatusUnlocking)
{
acquireDelay -= delay;
if (acquireDelay <= 0.0f)
{
playerStatus = playerStatusPlaying;
}
}
//z = y;
if (playerStatus != playerStatusDead) testSpriteCollisions();
collidingDirection = 0;
BaseCreatureEntity::animate(delay);
if (firingDirection != 5)
facingDirection = firingDirection;
firingDirection = 5;
if (isMoving())
{
frame = ((int)(age * 5.0f)) % 4;
if (frame == 3) frame = 1;
SoundManager::getSoundManager()->playSound(SOUND_STEP);
}
else if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking)
frame = 0;
else if (playerStatus == playerStatusDead)
frame = 0;
else // standing
{
frame = 1;
}
if (x < OFFSET_X)
game().moveToOtherMap(4);
else if (x > OFFSET_X + MAP_WIDTH * TILE_WIDTH)
game().moveToOtherMap(6);
else if (y < OFFSET_Y)
game().moveToOtherMap(8);
- else if (y > OFFSET_Y + MAP_HEIGHT * TILE_HEIGHT - 20)
+ else if (y > OFFSET_Y + MAP_HEIGHT * TILE_HEIGHT - 15)
game().moveToOtherMap(2);
if (playerStatus == playerStatusEntering)
{
if (boundingBox.left > OFFSET_X + TILE_WIDTH
&& (boundingBox.left + boundingBox.width) < OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 1)
&& boundingBox.top > OFFSET_Y + TILE_HEIGHT
&& (boundingBox.top + boundingBox.height) < OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 1))
{
playerStatus = playerStatusPlaying;
game().closeDoors();
}
}
if (playerStatus == playerStatusDead)
{
z = OFFSET_Y - 2;
}
}
void PlayerEntity::renderHead(sf::RenderWindow* app)
{
if (playerStatus != playerStatusDead)
{
sprite.setTextureRect(sf::IntRect( (frame / 3 + spriteDx) * width, 0, width, height));
app->draw(sprite);
if (equip[EQUIP_ENCHANTER_HAT])
{
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_EQUIP));
if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking)
sprite.setTextureRect(sf::IntRect( 0, 0, width, height));
else
sprite.setTextureRect(sf::IntRect( (frame / 3 + spriteDx) * width, 0, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE));
}
}
}
void PlayerEntity::renderBody(sf::RenderWindow* app)
{
sprite.setTextureRect(sf::IntRect( (frame + spriteDx) * width, height, width, height));
app->draw(sprite);
if (equip[EQUIP_CONCENTRATION_AMULET])
{
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_COLLAR));
if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking)
sprite.setTextureRect(sf::IntRect( 0, 0, width, height));
else
sprite.setTextureRect(sf::IntRect( (spriteDx / 3) * width, 0, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE));
}
if (equip[EQUIP_LEATHER_BELT])
{
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_EQUIP));
sprite.setTextureRect(sf::IntRect( (frame + spriteDx) * width, height, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE));
}
}
void PlayerEntity::renderHands(sf::RenderWindow* app)
{
if (equip[EQUIP_VIBRATION_GLOVES]) sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_EQUIP));
sprite.setTextureRect(sf::IntRect( (frame + spriteDx) * width, height * 3, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE));
}
void PlayerEntity::renderFeet(sf::RenderWindow* app)
{
if (equip[EQUIP_LEATHER_BOOTS]) sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_EQUIP));
sprite.setTextureRect(sf::IntRect( (frame + spriteDx) * width, height * 2, width, height));
app->draw(sprite);
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE));
}
void PlayerEntity::renderStaff(sf::RenderWindow* app)
{
if (equip[EQUIP_MAHOGANY_STAFF]) sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_EQUIP));
int xSnake, ySnake;
if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking)
{
sprite.setTextureRect(sf::IntRect( 12 * width, height * 4, width, height));
app->draw(sprite);
xSnake = 13 * width;
ySnake = height * 4;
}
else if (isMoving() || firingDirection != 5)
{
sprite.setTextureRect(sf::IntRect( (frame / 3 + spriteDx) * width, height * 4, width, height));
app->draw(sprite);
xSnake = (frame / 3 + spriteDx + 1) * width;
ySnake = height * 4;
}
else
{
sprite.setTextureRect(sf::IntRect( (spriteDx / 3 + 14) * width, height * 4, width, height));
app->draw(sprite);
xSnake = (spriteDx / 3 + 14) * width;
ySnake = 0;
}
if (equip[EQUIP_BLOOD_SNAKE])
{
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_EQUIP));
sprite.setTextureRect(sf::IntRect( xSnake, ySnake, width, height));
app->draw(sprite);
}
sprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE));
}
void PlayerEntity::render(sf::RenderWindow* app)
{
sprite.setPosition(x, y);
spriteDx = 0;
if (facingDirection == 8) spriteDx = 3;
if (facingDirection == 4) spriteDx = 6;
if (facingDirection == 6) spriteDx = 9;
if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking) spriteDx = 12;
if (playerStatus == playerStatusDead)
{
spriteDx = 13;
// blood
sprite.setTextureRect(sf::IntRect( width, 0, width, height));
app->draw(sprite);
}
else
{
// shadow
sprite.setTextureRect(sf::IntRect( 2 * width, 0, width, height));
app->draw(sprite);
}
if (facingDirection == 8 || facingDirection == 4)
{
renderStaff(app);
renderHead(app);
renderBody(app);
renderFeet(app);
renderHands(app);
}
else
{
renderBody(app);
renderHead(app);
renderFeet(app);
renderStaff(app);
renderHands(app);
}
// ice gem
if (getShotType() == ShotTypeIce)
{
int fade;
if (specialBoltTimer <= 0.0f) fade = 255;
else fade = ((STATUS_FROZEN_BOLT_DELAY - specialBoltTimer) / STATUS_FROZEN_BOLT_DELAY) * 128;
sprite.setTextureRect(sf::IntRect(320, 0, 20, 20));
sprite.setColor(sf::Color(255, 255, 255, fade));
if (isMoving())
{
if (facingDirection == 2 )
sprite.setPosition(x + 16, y + 36);
else if (facingDirection == 8 )
sprite.setPosition(x + 43, y + 36);
else if (facingDirection == 4 )
sprite.setPosition(x - 3 , y + 41);
else
sprite.setPosition(x + 63, y + 41);
}
else if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking)
{
sprite.setPosition(x + 57, y + 18);
}
else
{
if (facingDirection == 2 )
sprite.setPosition(x + 16, y + 36);
else if (facingDirection == 8 )
sprite.setPosition(x + 43, y + 29);
else if (facingDirection == 4 )
sprite.setPosition(x + 13, y + 35);
else
sprite.setPosition(x + 46, y + 35);
}
sf::RenderStates r;
r.blendMode = sf::BlendAdd;
app->draw(sprite, r);
sprite.setPosition(x, y);
sprite.setColor(sf::Color(255, 255, 255, 255));
}
}
void PlayerEntity::calculateBB()
{
boundingBox.left = (int)x - width / 2;
boundingBox.width = width;
boundingBox.top = (int)y - height / 2;
boundingBox.height = height;
boundingBox.left += 25;
boundingBox.width -= 50;
boundingBox.top += 80.0f;
boundingBox.height = boundingBox.height - 90.0f;
}
void PlayerEntity::readCollidingEntity(CollidingSpriteEntity* entity)
{
EnnemyBoltEntity* boltEntity = dynamic_cast<EnnemyBoltEntity*>(entity);
if (collideWithEntity(entity))
{
if (boltEntity != NULL && !boltEntity->getDying())
{
boltEntity->collide();
hurt(boltEntity->getDamages(), ShotTypeStandard);
game().generateBlood(x, y, bloodColor);
}
}
}
void PlayerEntity::move(int direction)
{
if (playerStatus == playerStatusPlaying)
{
float speedx = 0.0f, speedy = 0.0f;
if (direction == 1 || direction == 4 || direction == 7)
speedx = - creatureSpeed;
else if (direction == 3 || direction == 6 || direction == 9)
speedx = creatureSpeed;
if (direction == 1 || direction == 2 || direction == 3)
speedy = creatureSpeed;
else if (direction == 7 || direction == 8 || direction == 9)
speedy = - creatureSpeed;
setVelocity(Vector2D(speedx, speedy));
{
switch (direction)
{
case 8: facingDirection = 8; break;
case 2: facingDirection = 2; break;
case 4: facingDirection = 4; break;
case 6: facingDirection = 6; break;
case 7: if (facingDirection != 4 && facingDirection != 8) facingDirection = 4; break;
case 1: if (facingDirection != 4 && facingDirection != 2) facingDirection = 4; break;
case 9: if (facingDirection != 6 && facingDirection != 8) facingDirection = 6; break;
case 3: if (facingDirection != 6 && facingDirection != 2) facingDirection = 6; break;
}
}
}
}
bool PlayerEntity::isMoving()
{
if (velocity.x < -1.0f || velocity.x > 1.0f) return true;
if (velocity.y < -1.0f || velocity.y > 1.0f) return true;
return false;
}
bool PlayerEntity::isEquiped(int eq)
{
return equip[eq];
}
void PlayerEntity::setEquiped(int item, bool eq)
{
equip[item] = eq;
if (eq && item == (int)EQUIP_FAIRY)
{
fairy = new FairyEntity(x, y - 50.0f, this);
}
computePlayer();
}
void PlayerEntity::generateBolt(float velx, float vely)
{
enumShotType boltType = ShotTypeStandard;
switch (getShotType())
{
case ShotTypeIce:
if (getShotType() == ShotTypeIce)
{
if (specialBoltTimer <= 0.0f)
{
boltType = ShotTypeIce;
initShotType();
}
else boltType = ShotTypeStandard;
}
break;
case ShotTypeStandard:
case ShotTypeIllusion:
boltType = getShotType(); break;
}
BoltEntity* bolt = new BoltEntity(ImageManager::getImageManager()->getImage(1), x, y + 30, boltLifeTime, boltType);
bolt->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
bolt->setDamages(fireDamages);
bolt->setVelocity(Vector2D(velx, vely));
}
void PlayerEntity::fire(int direction)
{
firingDirection = direction;
if (equip[EQUIP_FAIRY] && playerStatus != playerStatusDead)
fairy->fire(direction, map);
if (canFirePlayer && playerStatus != playerStatusDead)
{
SoundManager::getSoundManager()->playSound(SOUND_BLAST_STANDARD);
if (equip[EQUIP_BOOK_DUAL])
{
float shoot_angle = 0.2f;
if ((direction == 4 && velocity.x < -1.0f) || (direction == 6 && velocity.x > 1.0f)
|| (direction == 8 && velocity.y < -1.0f) || (direction == 2 && velocity.y > 1.0f))
shoot_angle = 0.1f;
else if ((direction == 6 && velocity.x < -1.0f) || (direction == 4 && velocity.x > 1.0f)
|| (direction == 2 && velocity.y < -1.0f) || (direction == 8 && velocity.y > 1.0f))
shoot_angle = 0.35f;
if (equip[EQUIP_VIBRATION_GLOVES]) shoot_angle += (1000 - rand() % 2000) * 0.0001f;
switch(direction)
{
case 4: generateBolt(-fireVelocity * cos(shoot_angle), fireVelocity * sin(shoot_angle));
generateBolt(-fireVelocity * cos(shoot_angle), - fireVelocity * sin(shoot_angle));break;
case 6: generateBolt(fireVelocity * cos(shoot_angle), fireVelocity * sin(shoot_angle));
generateBolt(fireVelocity * cos(shoot_angle), - fireVelocity * sin(shoot_angle));break;
case 8: generateBolt(fireVelocity * sin(shoot_angle), -fireVelocity * cos(shoot_angle));
generateBolt(-fireVelocity * sin(shoot_angle), - fireVelocity * cos(shoot_angle));break;
case 2: generateBolt(fireVelocity * sin(shoot_angle), fireVelocity * cos(shoot_angle));
generateBolt(-fireVelocity * sin(shoot_angle), fireVelocity * cos(shoot_angle));break;
}
}
else
{
if (equip[EQUIP_VIBRATION_GLOVES])
{
float shoot_angle = (1000 - rand() % 2000) * 0.0001f;
switch(direction)
{
case 4: generateBolt(-fireVelocity * cos(shoot_angle), fireVelocity * sin(shoot_angle)); break;
case 6: generateBolt(fireVelocity * cos(shoot_angle), fireVelocity * sin(shoot_angle)); break;
case 8: generateBolt(fireVelocity * sin(shoot_angle), -fireVelocity * cos(shoot_angle)); break;
case 2: generateBolt(fireVelocity * sin(shoot_angle), fireVelocity * cos(shoot_angle)); break;
}
}
else
{
switch(direction)
{
case 4: generateBolt(-fireVelocity, 0.0f); break;
case 6: generateBolt(fireVelocity, 0.0f); break;
case 8: generateBolt(0.0f, -fireVelocity); break;
case 2: generateBolt(0.0f, fireVelocity); break;
}
}
}
canFirePlayer = false;
currentFireDelay = fireDelay;
}
}
bool PlayerEntity::canMove()
{
return (playerStatus == playerStatusPlaying);
}
bool PlayerEntity::hurt(int damages, enumShotType hurtingType)
{
if (!hurting)
{
SoundManager::getSoundManager()->playSound(SOUND_PLAYER_HIT);
BaseCreatureEntity::hurt(damages, ShotTypeStandard);
game().generateBlood(x, y, bloodColor);
game().generateBlood(x, y, bloodColor);
return true;
}
return false;
}
void PlayerEntity::loseItem(enumItemType itemType, bool isEquip)
{
CollidingSpriteEntity* itemSprite
= new CollidingSpriteEntity(ImageManager::getImageManager()->getImage(isEquip ? IMAGE_ITEMS_EQUIP : IMAGE_ITEMS), x, y, 32, 32);
itemSprite->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
itemSprite->setZ(OFFSET_Y - 1);
itemSprite->setFrame(itemType);
itemSprite->setImagesProLine(10);
itemSprite->setType(ENTITY_BLOOD);
itemSprite->setVelocity(Vector2D(rand()%450));
itemSprite->setViscosity(0.95f);
itemSprite->setSpin( (rand() % 700) - 350.0f);
}
void PlayerEntity::dying()
{
playerStatus = playerStatusDead;
hp = 0;
SoundManager::getSoundManager()->playSound(SOUND_PLAYER_DIE);
setVelocity(Vector2D(0.0f, 0.0f));
int i;
for (i = 0; i < gold; i++) loseItem(ItemCopperCoin, false);
for (i = 0; i < NUMBER_EQUIP_ITEMS; i++)
if (equip[i]) loseItem(enumItemType(i), true);
for (i = 0; i < 8; i++) game().generateBlood(x, y, bloodColor);
CollidingSpriteEntity* itemSprite
= new CollidingSpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_PLAYER_BASE), x, y, 80, 120);
itemSprite->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
itemSprite->setZ(OFFSET_Y - 1);
itemSprite->setImagesProLine(14);
itemSprite->setFrame(13);
itemSprite->setType(ENTITY_BLOOD);
itemSprite->setVelocity(Vector2D(rand()%450));
itemSprite->setViscosity(0.95f);
itemSprite->setSpin( (rand() % 700) - 350.0f);
}
void PlayerEntity::acquireItem(enumItemType type)
{
if (type >= FirstEquipItem) acquireStance(type);
else switch (type)
{
case ItemCopperCoin: gold++;
SoundManager::getSoundManager()->playSound(SOUND_COIN_PICK_UP);
break;
case ItemSilverCoin: gold = gold + 5; break;
case ItemGoldCoin: gold = gold + 10; break;
case itemHealth: hp += 15;
SoundManager::getSoundManager()->playSound(SOUND_DRINK);
if (hp > hpMax) hp = hpMax; break;
default: break;
}
}
void PlayerEntity::computePlayer()
{
float boltLifeTimeBonus = 1.0f;
float fireDelayBonus = 1.0f;
float creatureSpeedBonus = 1.0f;
float fireVelocityBonus = 1.0f;
float fireDamagesBonus = 1.0f;
if (equip[EQUIP_VIBRATION_GLOVES]) fireDelayBonus -= 0.10f;
if (equip[EQUIP_ENCHANTER_HAT]) fireDelayBonus -= 0.2f;
if (equip[EQUIP_LEATHER_BELT]) fireDelayBonus -= 0.15f;
if (equip[EQUIP_LEATHER_BOOTS]) creatureSpeedBonus += 0.15f;
if (equip[EQUIP_BOOK_DUAL]) fireDelayBonus += 0.6f;
if (equip[EQUIP_CONCENTRATION_AMULET]) boltLifeTimeBonus += 0.5f;
if (equip[EQUIP_MAHOGANY_STAFF])
{
fireVelocityBonus += 0.15f;
fireDamagesBonus += 0.5f;
}
if (equip[EQUIP_BLOOD_SNAKE]) fireDamagesBonus += 1.0f;
//if (getShotType()) boltType = BoltIce;
fireDelay = INITIAL_PLAYER_FIRE_DELAY * fireDelayBonus;
creatureSpeed = INITIAL_PLAYER_SPEED * creatureSpeedBonus;
fireVelocity = INITIAL_BOLT_VELOCITY * fireVelocityBonus;
fireDamages = INITIAL_BOLT_DAMAGES * fireDamagesBonus;
boltLifeTime = INITIAL_BOLT_LIFE * boltLifeTimeBonus;
// gems
if (getShotType() == ShotTypeIllusion) fireDamages *= 0.8f;
}
void PlayerEntity::acquireStance(enumItemType type)
{
velocity.x = 0.0f;
velocity.y = 0.0f;
playerStatus = playerStatusAcquire;
acquireDelay = ACQUIRE_DELAY;
acquiredItem = (enumItemType)(type - FirstEquipItem);
SoundManager::getSoundManager()->playSound(SOUND_BONUS);
}
void PlayerEntity::collideMapRight()
{
collidingDirection = 6;
}
void PlayerEntity::collideMapLeft()
{
collidingDirection = 4;
}
void PlayerEntity::collideMapTop()
{
collidingDirection = 8;
}
void PlayerEntity::collideMapBottom()
{
collidingDirection = 2;
}
void PlayerEntity::useBossKey()
{
velocity.x = 0.0f;
velocity.y = 0.0f;
playerStatus = playerStatusUnlocking;
acquireDelay = UNLOCK_DELAY;
acquiredItem = (enumItemType)(type - FirstEquipItem);
SoundManager::getSoundManager()->playSound(SOUND_BONUS);
equip[EQUIP_BOSS_KEY] = false;
SpriteEntity* spriteItem = new SpriteEntity(
ImageManager::getImageManager()->getImage(IMAGE_ITEMS_EQUIP),
x, y - 60.0f, ITEM_WIDTH, ITEM_HEIGHT);
spriteItem->setFrame(EQUIP_BOSS_KEY);
spriteItem->setZ(z);
spriteItem->setLifetime(UNLOCK_DELAY);
}
enumShotType PlayerEntity::getShotType()
{
return specialShots[specialShotIndex];
}
int PlayerEntity::getShotIndex()
{
return specialShotIndex;
}
void PlayerEntity::setShotIndex(int index)
{
specialShotIndex = index;
}
enumShotType PlayerEntity::getShotType(int slot)
{
return specialShots[slot];
}
void PlayerEntity::setShotType(int slot, enumShotType shotType)
{
specialShots[slot] = shotType;
}
void PlayerEntity::registerSpecialShot(int item)
{
bool found = false;
int index = 1;
while (index < SPECIAL_SHOT_SLOTS && !found)
{
found = specialShots[index] == ShotTypeStandard;
if (!found) index++;
}
if (found)
{
this->specialShots[index] = items[item].specialShot;
specialShotIndex = index;
initShotType();
}
}
void PlayerEntity::selectNextShotType()
{
int index = specialShotIndex + 1;
bool found = false;
while (index < SPECIAL_SHOT_SLOTS && !found)
{
if (specialShots[index] == ShotTypeStandard) index++;
else found = true;
}
if (found)
{
specialShotIndex = index;
initShotType();
}
else
specialShotIndex = 0;
computePlayer();
}
void PlayerEntity::initShotType()
{
specialBoltTimer = STATUS_FROZEN_BOLT_DELAY;
}
diff --git a/src/WitchBlastGame.cpp b/src/WitchBlastGame.cpp
index 47c32c0..e4748ad 100644
--- a/src/WitchBlastGame.cpp
+++ b/src/WitchBlastGame.cpp
@@ -1,1418 +1,1421 @@
#include "WitchBlastGame.h"
#include "sfml_game/SpriteEntity.h"
#include "sfml_game/TileMapEntity.h"
#include "DungeonMap.h"
#include "sfml_game/ImageManager.h"
#include "sfml_game/SoundManager.h"
#include "sfml_game/EntityManager.h"
#include "Constants.h"
#include "RatEntity.h"
#include "GreenRatEntity.h"
#include "KingRatEntity.h"
#include "BatEntity.h"
#include "SlimeEntity.h"
#include "ChestEntity.h"
#include "EvilFlowerEntity.h"
#include "ItemEntity.h"
#include "ArtefactDescriptionEntity.h"
#include "PnjEntity.h"
#include "TextEntity.h"
#include <iostream>
#include <sstream>
#include <fstream>
namespace {
WitchBlastGame* gameptr;
}
WitchBlastGame::WitchBlastGame(): Game(SCREEN_WIDTH, SCREEN_HEIGHT)
{
gameptr = this;
app->setTitle(APP_NAME + " V" + APP_VERSION);
// loading resources
ImageManager::getImageManager()->addImage((char*)"media/player_base.png");
ImageManager::getImageManager()->addImage((char*)"media/player_equip.png");
ImageManager::getImageManager()->addImage((char*)"media/player_collar.png");
ImageManager::getImageManager()->addImage((char*)"media/bolt.png");
ImageManager::getImageManager()->addImage((char*)"media/tiles.png");
ImageManager::getImageManager()->addImage((char*)"media/rat.png");
ImageManager::getImageManager()->addImage((char*)"media/minimap.png");
ImageManager::getImageManager()->addImage((char*)"media/doors.png");
ImageManager::getImageManager()->addImage((char*)"media/items.png");
ImageManager::getImageManager()->addImage((char*)"media/items_equip.png");
ImageManager::getImageManager()->addImage((char*)"media/chest.png");
ImageManager::getImageManager()->addImage((char*)"media/bat.png");
ImageManager::getImageManager()->addImage((char*)"media/evil_flower.png");
ImageManager::getImageManager()->addImage((char*)"media/slime.png");
ImageManager::getImageManager()->addImage((char*)"media/king_rat.png");
ImageManager::getImageManager()->addImage((char*)"media/blood.png");
ImageManager::getImageManager()->addImage((char*)"media/corpses.png");
ImageManager::getImageManager()->addImage((char*)"media/corpses_big.png");
ImageManager::getImageManager()->addImage((char*)"media/star.png");
ImageManager::getImageManager()->addImage((char*)"media/star2.png");
ImageManager::getImageManager()->addImage((char*)"media/interface.png");
ImageManager::getImageManager()->addImage((char*)"media/hud_shots.png");
ImageManager::getImageManager()->addImage((char*)"media/pnj.png");
ImageManager::getImageManager()->addImage((char*)"media/fairy.png");
SoundManager::getSoundManager()->addSound((char*)"media/sound/step.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/blast00.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/blast01.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/door_closing.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/door_opening.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/chest_opening.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/impact.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/bonus.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/drink.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/player_hit.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/player_die.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/ennemy_dying.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/coin.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/pay.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/wall_impact.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/big_wall_impact.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/king_rat_cry_1.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/king_rat_cry_2.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/king_rat_die.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/slime_jump.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/slime_impact.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/slime_impact_weak.ogg");
SoundManager::getSoundManager()->addSound((char*)"media/sound/ice_charge.ogg");
if (font.loadFromFile("media/DejaVuSans-Bold.ttf"))
{
myText.setFont(font);
}
miniMap = NULL;
currentMap = NULL;
currentFloor = NULL;
xGameState = xGameStateNone;
isPausing = false;
shotsSprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_HUD_SHOTS));
}
WitchBlastGame::~WitchBlastGame()
{
// cleaning all entities
EntityManager::getEntityManager()->clean();
// cleaning data
if (miniMap != NULL) delete (miniMap);
if (currentFloor != NULL) delete (currentFloor);
}
DungeonMap* WitchBlastGame::getCurrentMap()
{
return currentMap;
}
PlayerEntity* WitchBlastGame::getPlayer()
{
return player;
}
int WitchBlastGame::getLevel()
{
return level;
}
void WitchBlastGame::onUpdate()
{
float delta = getAbsolutTime() - lastTime;
lastTime = getAbsolutTime();
if (!isPausing)
{
EntityManager::getEntityManager()->animate(delta);
if (xGameState != xGameStateNone)
{
xGameTimer -= delta;
if (xGameTimer <= 0.0f)
{
if (xGameState == xGameStateFadeOut)
{
if (player->getPlayerStatus() == PlayerEntity::playerStatusGoingUp)
{
level++;
startNewLevel();
}
else
startNewGame(false);
}
else
xGameState = xGameStateNone;
}
}
if (isPlayerAlive)
{
if (player->getHp() <= 0)
{
isPlayerAlive = false;
playMusic(MusicEnding);
}
}
}
}
void WitchBlastGame::startNewGame(bool fromSaveFile)
{
gameState = gameStateInit;
level = 1;
// cleaning all entities
EntityManager::getEntityManager()->clean();
// cleaning data
if (miniMap != NULL) delete (miniMap);
if (currentFloor != NULL) delete (currentFloor);
miniMap = NULL;
currentFloor = NULL;
// current map (tiles)
currentTileMap = new TileMapEntity(ImageManager::getImageManager()->getImage(IMAGE_TILES), currentMap, 64, 64, 10);
currentTileMap->setX(OFFSET_X);
currentTileMap->setY(OFFSET_Y);
// the interface
SpriteEntity* interface = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_INTERFACE));
interface->setZ(10000.0f);
interface->removeCenter();
interface->setType(0);
// key symbol on the interface
keySprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_ITEMS_EQUIP));
keySprite.setTextureRect(sf::IntRect(ITEM_WIDTH * EQUIP_BOSS_KEY, 0, ITEM_WIDTH, ITEM_HEIGHT));
keySprite.setPosition(326, 616);
miniMap = new GameMap(FLOOR_WIDTH, FLOOR_HEIGHT);
// minimap on the interface
TileMapEntity* miniMapEntity = new TileMapEntity(ImageManager::getImageManager()->getImage(IMAGE_MINIMAP), miniMap, 15, 11, 10);
miniMapEntity->setTileBox(16, 12);
miniMapEntity->setX(407);
miniMapEntity->setY(614);
miniMapEntity->setZ(10001.0f);
// doors
doorEntity[0] = new DoorEntity(8);
doorEntity[1] = new DoorEntity(4);
doorEntity[2] = new DoorEntity(2);
doorEntity[3] = new DoorEntity(6);
if (fromSaveFile)
{
- if (!loadGame()) fromSaveFile = false;
- else playLevel();
+ if (!loadGame())
+ fromSaveFile = false;
+ else
+ playLevel();
}
if (!fromSaveFile)
{
// the player
player = new PlayerEntity(OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
OFFSET_Y + (TILE_HEIGHT * MAP_HEIGHT * 0.5f));
startNewLevel();
}
}
void WitchBlastGame::startNewLevel()
{
// create the new level
if (currentFloor != NULL) delete currentFloor;
currentFloor = new GameFloor(level);
+ currentFloor->createFloor();
// center it
floorX = FLOOR_WIDTH / 2;
floorY = FLOOR_HEIGHT / 2;
// move the player
if (level == 1)
player->moveTo(OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
OFFSET_Y + (TILE_HEIGHT * MAP_HEIGHT * 0.5f));
else
player->moveTo(OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
OFFSET_Y + (TILE_HEIGHT * MAP_HEIGHT - 3 * TILE_HEIGHT));
// the boss room is closed
bossRoomOpened = false;
playLevel();
}
void WitchBlastGame::playLevel()
{
isPlayerAlive = true;
player->setVelocity(Vector2D(0.0f, 0.0f));
player->setPlayerStatus(PlayerEntity::playerStatusPlaying);
// generate the map
refreshMap();
// items from save
currentMap->restoreMapObjects();
// first map is open
roomClosed = false;
// game time counter an state
lastTime = getAbsolutTime();
gameState = gameStatePlaying;
playMusic(MusicDungeon);
// fade in
xGameState = xGameStateFadeIn;
xGameTimer = FADE_IN_DELAY;
float x0 = OFFSET_X + MAP_WIDTH * 0.5f * TILE_WIDTH;
float y0 = OFFSET_Y + MAP_HEIGHT * 0.5f * TILE_HEIGHT + 40.0f;
std::ostringstream oss;
oss << "Level " << level;
TextEntity* text = new TextEntity(oss.str(), 30, x0, y0);
text->setAlignment(ALIGN_CENTER);
text->setLifetime(2.5f);
text->setWeight(-36.0f);
text->setZ(1000);
text->setColor(TextEntity::COLOR_FADING_WHITE);
}
void WitchBlastGame::startGame()
{
startNewGame(true);
// Start game loop
while (app->isOpen())
{
// Process events
sf::Event event;
while (app->pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
{
if (gameState == gameStatePlaying && !player->isDead() && currentMap->isCleared()) saveGame();
app->close();
}
if (event.type == sf::Event::MouseWheelMoved)
{
if (gameState == gameStatePlaying && !isPausing) player->selectNextShotType();
}
if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Escape)
{
if (gameState == gameStatePlaying && !isPausing) isPausing = true;
else if (gameState == gameStatePlaying && isPausing) isPausing = false;
}
if (event.key.code == sf::Keyboard::Tab)
{
if (gameState == gameStatePlaying && !isPausing) player->selectNextShotType();
}
if (event.key.code == sf::Keyboard::Space)
{
if (gameState == gameStatePlaying && !isPausing) firingDirection = player->getFacingDirection();
}
if (event.key.code == sf::Keyboard::X)
{
startNewGame(false);
}
if (event.key.code == sf::Keyboard::C)
{
startNewLevel();
}
}
if (event.type == sf::Event::LostFocus)
isPausing = true;
}
if (gameState == gameStatePlaying && !isPausing)
{
if (player->canMove()) player->setVelocity(Vector2D(0.0f, 0.0f));
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q) || sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Z) || sf::Keyboard::isKeyPressed(sf::Keyboard::W))
player->move(7);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
player->move(1);
else
player->move(4);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Z) || sf::Keyboard::isKeyPressed(sf::Keyboard::W))
player->move(9);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
player->move(3);
else
player->move(6);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Z) || sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
player->move(8);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
player->move(2);
}
// normal 4 directions gameplay
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
player->fire(4);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
player->fire(6);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
player->fire(8);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
player->fire(2);
// alternative "one button" gameplay
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
{
player->fire(firingDirection);
}
// alternative "firing with the mouse" gameplay
else if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
sf::Vector2i mousePosition = sf::Mouse::getPosition(*app);
int xm = mousePosition.x - player->getX();
int ym = mousePosition.y - player->getY();
if (abs(xm) >= abs(ym))
{
if (xm > 0) player->fire(6);
else player->fire(4);
}
else
{
if (ym > 0) player->fire(2);
else player->fire(8);
}
}
if (player->isDead() && xGameState == xGameStateNone && sf::Keyboard::isKeyPressed(sf::Keyboard::Return))
{
xGameState = xGameStateFadeOut;
xGameTimer = FADE_OUT_DELAY;
}
}
onUpdate();
EntityManager::getEntityManager()->sortByZ();
onRender();
verifyDoorUnlocking();
if (roomClosed)
{
if (getEnnemyCount() == 0)
{
currentMap->setCleared(true);
openDoors();
//if (currentMap->getRoomType() == roomTypeBoss)
// playMusic(MusicDungeon);
}
}
}
quitGame();
}
void WitchBlastGame::createFloor()
{
// TODO : extracts from createNewGame
}
void WitchBlastGame::closeDoors()
{
if (!currentMap->isCleared())
{
int i;
for(i = 0; i < MAP_WIDTH; i++)
{
if (currentMap->getTile(i, 0) < 4) currentMap->setTile(i, 0, MAP_DOOR);
if (currentMap->getTile(i, MAP_HEIGHT - 1) < 4) currentMap->setTile(i, MAP_HEIGHT - 1, MAP_DOOR);
}
for(i = 0; i < MAP_HEIGHT; i++)
{
if (currentMap->getTile(0, i) < 4) currentMap->setTile(0, i, MAP_DOOR);
if (currentMap->getTile(MAP_WIDTH - 1, i) < 4) currentMap->setTile(MAP_WIDTH - 1, i, MAP_DOOR);
}
roomClosed = true;
}
}
void WitchBlastGame::openDoors()
{
int i, j;
for(i = 0; i < MAP_WIDTH; i++)
for(j = 0; j < MAP_WIDTH; j++)
if (currentMap->getTile(i, j) == MAP_DOOR) currentMap->setTile(i, j, 0);
roomClosed = false;
SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
if (currentMap->hasNeighbourUp() == 2 && !bossRoomOpened)
currentMap->setTile(MAP_WIDTH/2, 0, MAP_DOOR);
else
doorEntity[0]->openDoor();
if (currentMap->hasNeighbourLeft() == 2 && !bossRoomOpened)
currentMap->setTile(0, MAP_HEIGHT / 2, MAP_DOOR);
else
doorEntity[1]->openDoor();
if (currentMap->hasNeighbourDown() == 2 && !bossRoomOpened)
currentMap->setTile(MAP_WIDTH / 2, MAP_HEIGHT - 1, MAP_DOOR);
else
doorEntity[2]->openDoor();
if (currentMap->hasNeighbourRight() == 2 && !bossRoomOpened)
currentMap->setTile(MAP_WIDTH - 1, MAP_HEIGHT / 2, MAP_DOOR);
else
doorEntity[3]->openDoor();
}
int WitchBlastGame::getEnnemyCount()
{
int n=0;
EntityManager::EntityList* entityList =EntityManager::getEntityManager()->getList();
EntityManager::EntityList::iterator it;
for (it = entityList->begin (); it != entityList->end ();)
{
GameEntity *e = *it;
it++;
if (e->getType() >= 20)
{
n++;
} // endif
} // end for
return n;
}
void WitchBlastGame::refreshMap()
{
// clean the sprites from old map
EntityManager::getEntityManager()->partialClean(10);
// if new map, it has to be randomized
bool generateMap = !(currentFloor->getMap(floorX, floorY)->isVisited());
currentMap = currentFloor->getAndVisitMap(floorX, floorY);
// load the map
currentTileMap->setMap(currentMap);
player->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
refreshMinimap();
if(generateMap)
this->generateMap();
else
{
if (currentMap->getRoomType() == roomTypeMerchant)
new PnjEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2 - 2) * TILE_HEIGHT,
0);
}
// for testing purpose (new stuff)
if (player->getAge() <2.0f)
{
/*ItemEntity* book = new ItemEntity(ItemEntity::itemHealth, player->getX(), player->getY()- 180);
book->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
book->setMerchandise(true);*/
/*int bonusType = getRandomEquipItem(true);
ItemEntity* boots = new ItemEntity((enumItemType)(itemMagicianHat + bonusType), player->getX(), player->getY()+ 180);
boots->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);*/
//ChestEntity* chest = new ChestEntity(player->getX() + 100, player->getY()+ 150, CHEST_FAIRY, false);
//chest->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
}
// check doors
doorEntity[0]->setVisible(currentMap->hasNeighbourUp() > 0);
if (currentMap->hasNeighbourUp() == 1) doorEntity[0]->setDoorType(0);
if (currentMap->hasNeighbourUp() == 2 || currentMap->getRoomType()==roomTypeBoss) doorEntity[0]->setDoorType(1);
if (currentMap->hasNeighbourUp() == 2 && !bossRoomOpened)
{
doorEntity[0]->setOpen(false);
currentMap->setTile(MAP_WIDTH/2, 0, MAP_DOOR);
}
else
doorEntity[0]->setOpen(true);
doorEntity[3]->setVisible(currentMap->hasNeighbourRight() > 0);
if (currentMap->hasNeighbourRight() == 1) doorEntity[3]->setDoorType(0);
if (currentMap->hasNeighbourRight() == 2 || currentMap->getRoomType()==roomTypeBoss) doorEntity[3]->setDoorType(1);
if (currentMap->hasNeighbourRight() == 2 && !bossRoomOpened)
{
doorEntity[3]->setOpen(false);
currentMap->setTile(MAP_WIDTH - 1, MAP_HEIGHT / 2, MAP_DOOR);
}
else
doorEntity[3]->setOpen(true);
doorEntity[2]->setVisible(currentMap->hasNeighbourDown() > 0);
if (currentMap->hasNeighbourDown() == 1) doorEntity[2]->setDoorType(0);
if (currentMap->hasNeighbourDown() == 2 || currentMap->getRoomType()==roomTypeBoss) doorEntity[2]->setDoorType(1);
if (currentMap->hasNeighbourDown() == 2 && !bossRoomOpened)
{
doorEntity[2]->setOpen(false);
currentMap->setTile(MAP_WIDTH/2, MAP_HEIGHT - 1, MAP_DOOR);
}
else
doorEntity[2]->setOpen(true);
doorEntity[1]->setVisible(currentMap->hasNeighbourLeft() > 0);
if (currentMap->hasNeighbourLeft() == 1) doorEntity[1]->setDoorType(0);
if (currentMap->hasNeighbourLeft() == 2 || currentMap->getRoomType()==roomTypeBoss) doorEntity[1]->setDoorType(1);
if (currentMap->hasNeighbourLeft() == 2 && !bossRoomOpened)
{
doorEntity[1]->setOpen(false);
currentMap->setTile(0, MAP_HEIGHT / 2, MAP_DOOR);
}
else
doorEntity[1]->setOpen(true);
}
void WitchBlastGame::refreshMinimap()
{
for (int j=0; j < FLOOR_HEIGHT; j++)
for (int i=0; i < FLOOR_WIDTH; i++)
{
int n = currentFloor->getRoom(i, j);
if (n > 0 && currentFloor->getMap(i, j)->isVisited())
{
if (currentFloor->getRoom(i, j) == roomTypeStarting
|| currentFloor->getRoom(i, j) == roomTypeBonus
|| currentFloor->getRoom(i, j) == roomTypeKey)
miniMap->setTile(i, j, roomTypeStandard);
else
miniMap->setTile(i, j, currentFloor->getRoom(i, j));
}
else if (n > 0 && currentFloor->getMap(i, j)->isKnown())
{
if (currentFloor->getRoom(i, j) == roomTypeBoss)
miniMap->setTile(i, j, 7);
else
miniMap->setTile(i, j, 9);
}
else
miniMap->setTile(i, j, 0);
}
miniMap->setTile(floorX, floorY, 8);
}
void WitchBlastGame::checkEntering()
{
if (!currentMap->isCleared())
{
player->setEntering();
SoundManager::getSoundManager()->playSound(SOUND_DOOR_CLOSING);
for (int i=0; i<4; i++)
doorEntity[i]->closeDoor();
}
}
void WitchBlastGame::saveMapItems()
{
EntityManager::EntityList* entityList = EntityManager::getEntityManager()->getList();
EntityManager::EntityList::iterator it;
for (it = entityList->begin (); it != entityList->end ();)
{
GameEntity* e = *it;
it++;
ItemEntity* itemEntity = dynamic_cast<ItemEntity*>(e);
ChestEntity* chestEntity = dynamic_cast<ChestEntity*>(e);
if (itemEntity != NULL)
{
currentMap->addItem(itemEntity->getItemType(), itemEntity->getX(), itemEntity->getY(), itemEntity->getMerchandise());
} // endif
else if (chestEntity != NULL)
{
currentMap->addChest(chestEntity->getChestType(), chestEntity->getOpened(), chestEntity->getX(), chestEntity->getY());
} // endif
else
{
SpriteEntity* spriteEntity = dynamic_cast<SpriteEntity*>(e);
if (spriteEntity != NULL && (e->getType() == ENTITY_BLOOD || e->getType() == ENTITY_CORPSE ) )
{
int spriteFrame = spriteEntity->getFrame();
if (spriteEntity->getWidth() == 128) spriteFrame += FRAME_CORPSE_KING_RAT;
currentMap->addSprite(e->getType(), spriteFrame, e->getX(), e->getY(), spriteEntity->getScaleX());
}
}
} // end for
}
void WitchBlastGame::moveToOtherMap(int direction)
{
// stairs to next level
if (direction == 8 && currentMap->getRoomType() == roomTypeExit)
{
if (player->getPlayerStatus() != PlayerEntity::playerStatusGoingUp)
{
player->setLeavingLevel();
xGameState = xGameStateFadeOut;
xGameTimer = FADE_OUT_DELAY;
player->setVelocity(Vector2D(0.0f, - INITIAL_PLAYER_SPEED / 2));
}
}
// go to another room
else
{
saveMapItems();
switch (direction)
{
case (4): floorX--; player->moveTo((OFFSET_X + MAP_WIDTH * TILE_WIDTH), player->getY()); player->move(4); break;
case (6): floorX++; player->moveTo(OFFSET_X, player->getY()); player->move(6); break;
case (8): floorY--; player->moveTo(player->getX(), OFFSET_Y + MAP_HEIGHT * TILE_HEIGHT - 20); player->move(8); break;
case (2): floorY++; player->moveTo(player->getX(), OFFSET_Y); break;
}
refreshMap();
checkEntering();
currentMap->restoreMapObjects();
}
}
void WitchBlastGame::onRender()
{
// clear the view
app->clear(sf::Color(32, 32, 32));
// render the game objects
EntityManager::getEntityManager()->render(app);
myText.setColor(sf::Color(255, 255, 255, 255));
myText.setCharacterSize(18);
std::ostringstream oss;
oss << player->getGold();
myText.setString(oss.str());
myText.setPosition(690, 612);
app->draw(myText);
myText.setColor(sf::Color(0, 0, 0, 255));
myText.setCharacterSize(16);
oss.str("");
oss << "Level " << level;
myText.setString(oss.str());
myText.setPosition(410, 692);
app->draw(myText);
sf::RectangleShape rectangle(sf::Vector2f(200, 25));
// life
if (gameState == gameStatePlaying)
{
// life and mana
rectangle.setFillColor(sf::Color(190, 20, 20));
rectangle.setPosition(sf::Vector2f(90, 622));
rectangle.setSize(sf::Vector2f(200.0f * (float)(player->getHpDisplay()) / (float)(player->getHpMax()) , 25));
app->draw(rectangle);
rectangle.setFillColor(sf::Color(255, 190, 190));
rectangle.setPosition(sf::Vector2f(90, 625));
rectangle.setSize(sf::Vector2f(200.0f * (float)(player->getHpDisplay()) / (float)(player->getHpMax()) , 2));
app->draw(rectangle);
rectangle.setFillColor(sf::Color(20, 20, 190));
rectangle.setPosition(sf::Vector2f(90, 658));
rectangle.setSize(sf::Vector2f(200.0f * player->getPercentFireDelay() , 25));
app->draw(rectangle);
rectangle.setFillColor(sf::Color(190, 190, 255));
rectangle.setPosition(sf::Vector2f(90, 661));
rectangle.setSize(sf::Vector2f(200.0f * player->getPercentFireDelay() , 2));
app->draw(rectangle);
// drawing the key on the interface
if (player->isEquiped(EQUIP_BOSS_KEY)) app->draw(keySprite);
// render the shots
renderHudShots(app);
if (isPausing)
{
rectangle.setFillColor(sf::Color(0, 0, 0, 160));
rectangle.setPosition(sf::Vector2f(OFFSET_X, OFFSET_Y));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH, MAP_HEIGHT * TILE_HEIGHT));
app->draw(rectangle);
float x0 = OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2;
int fade = 50 + 205 * (1.0f + cos(3.0f * getAbsolutTime())) * 0.5f;
myText.setColor(sf::Color(255, 255, 255, fade));
myText.setCharacterSize(40);
myText.setString("PAUSE");
myText.setPosition(x0 - myText.getLocalBounds().width / 2, 300);
app->draw(myText);
}
if (player->isDead())
{
float x0 = OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2;
int fade = 255 * (1.0f + cos(2.0f * getAbsolutTime())) * 0.5f;
myText.setColor(sf::Color(255, 255, 255, 255));
myText.setCharacterSize(25);
myText.setString("GAME OVER");
myText.setPosition(x0 - myText.getLocalBounds().width / 2, 400);
app->draw(myText);
myText.setColor(sf::Color(255, 255, 255, fade));
myText.setCharacterSize(20);
myText.setString("Press [ENTER] to play again !");
myText.setPosition(x0 - myText.getLocalBounds().width / 2, 440);
app->draw(myText);
}
else if (currentMap->getRoomType() == roomTypeExit)
{
float x0 = OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2;
myText.setColor(sf::Color(255, 255, 255, 255));
myText.setCharacterSize(25);
myText.setString("CONGRATULATIONS !\nYou've challenged this demo and\nmanaged to kill the boss !\nSee you soon for new adventures !");
myText.setPosition(x0 - myText.getLocalBounds().width / 2, 220);
app->draw(myText);
}
if (xGameState == xGameStateFadeIn)
{
// fade in
rectangle.setFillColor(sf::Color(0, 0, 0, 255 - ((FADE_IN_DELAY - xGameTimer) / FADE_IN_DELAY) * 255));
rectangle.setPosition(sf::Vector2f(OFFSET_X, OFFSET_Y));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH , MAP_HEIGHT * TILE_HEIGHT));
app->draw(rectangle);
}
else if (xGameState == xGameStateFadeOut)
{
// fade out
rectangle.setFillColor(sf::Color(0, 0, 0, ((FADE_IN_DELAY - xGameTimer) / FADE_IN_DELAY) * 255));
rectangle.setPosition(sf::Vector2f(OFFSET_X, OFFSET_Y));
rectangle.setSize(sf::Vector2f(MAP_WIDTH * TILE_WIDTH , MAP_HEIGHT * TILE_HEIGHT));
app->draw(rectangle);
}
}
app->display();
}
void WitchBlastGame::renderHudShots(sf::RenderWindow* app)
{
int xHud = 640;
int yHud = 650;
int index = 0;
for (int i = 0; i < SPECIAL_SHOT_SLOTS; i++)
{
if (i == 0 || player->getShotType(i) != ShotTypeStandard)
{
int type_shot = player->getShotType(i);
shotsSprite.setPosition(xHud + 48 * index, yHud);
if (index == player->getShotIndex())
{
shotsSprite.setTextureRect(sf::IntRect(0, 0, 48, 48));
app->draw(shotsSprite);
}
shotsSprite.setTextureRect(sf::IntRect(48 * ( 1 + type_shot), 0, 48, 48));
app->draw(shotsSprite);
index++;
}
}
}
void WitchBlastGame::generateBlood(float x, float y, BaseCreatureEntity::enumBloodColor bloodColor)
{
// double blood if the "Blood Snake3 object is equipped
int nbIt;
if (player->isEquiped(EQUIP_BLOOD_SNAKE))
nbIt = 2;
else
nbIt = 1;
for (int i=0; i < nbIt; i++)
{
SpriteEntity* blood = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_BLOOD), x, y, 16, 16, 6);
blood->setZ(OFFSET_Y - 1);
int b0 = 0;
if (bloodColor == BaseCreatureEntity::bloodGreen) b0 += 6;
blood->setFrame(b0 + 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);
}
}
void WitchBlastGame::showArtefactDescription(enumItemType itemType)
{
new ArtefactDescriptionEntity(itemType); //, &font);
}
void WitchBlastGame::generateMap()
{
if (currentMap->getRoomType() == roomTypeStandard)
generateStandardMap();
else if (currentMap->getRoomType() == roomTypeBonus)
{
currentMap->setCleared(true);
Vector2D v = currentMap->generateBonusRoom();
int bonusType = getRandomEquipItem(false);
if (bonusType == EQUIP_FAIRY)
{
new ChestEntity(v.x, v.y, CHEST_FAIRY, false);
}
else
{
new ItemEntity( (enumItemType)(FirstEquipItem + bonusType), v.x ,v.y);
}
}
else if (currentMap->getRoomType() == roomTypeKey)
{
Vector2D v = currentMap->generateKeyRoom();
new ItemEntity( (enumItemType)(ItemBossKey), v.x ,v.y);
initMonsterArray();
int x0 = MAP_WIDTH / 2;
int y0 = MAP_HEIGHT / 2;
monsterArray[x0][y0] = true;
findPlaceMonsters(MONSTER_RAT, 5);
findPlaceMonsters(MONSTER_BAT, 5);
}
else if (currentMap->getRoomType() == roomTypeMerchant)
{
currentMap->generateMerchantRoom();
ItemEntity* item1 = new ItemEntity(
itemHealth,
OFFSET_X + (MAP_WIDTH / 2 - 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT);
item1->setMerchandise(true);
int bonusType = getRandomEquipItem(true);
ItemEntity* item2 = new ItemEntity(
(enumItemType)(FirstEquipItem + bonusType),
OFFSET_X + (MAP_WIDTH / 2 + 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT);
item2->setMerchandise(true);
new PnjEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2 - 2) * TILE_HEIGHT,
0);
currentMap->setCleared(true);
}
else if (currentMap->getRoomType() == roomTypeBoss)
{
currentMap->generateRoom(0);
new KingRatEntity(OFFSET_X + (MAP_WIDTH / 2 - 2) * TILE_WIDTH + TILE_WIDTH / 2,
OFFSET_Y + (MAP_HEIGHT / 2 - 2) * TILE_HEIGHT + TILE_HEIGHT / 2);
//playMusic(MusicBoss);
}
else if (currentMap->getRoomType() == roomTypeStarting)
{
currentMap->generateRoom(0);
currentMap->setCleared(true);
int bonusType = getRandomEquipItem(false);
if (level == 1)
{
if (bonusType == EQUIP_FAIRY)
{
new ChestEntity(OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
OFFSET_Y + 120.0f + (TILE_HEIGHT * MAP_HEIGHT * 0.5f),
CHEST_FAIRY, false);
}
else
{
new ItemEntity( (enumItemType)(FirstEquipItem + bonusType),
OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
OFFSET_Y + 120.0f + (TILE_HEIGHT * MAP_HEIGHT * 0.5f));
}
}
}
else if (currentMap->getRoomType() == roomTypeExit)
{
currentMap->generateExitRoom();
currentMap->setCleared(true);
}
else
currentMap->randomize(currentMap->getRoomType());
}
void WitchBlastGame::Write(std::string str, int size, float x, float y, int align, sf::Color color)
{
myText.setString(str);
myText.setCharacterSize(size);
myText.setColor(color);
if (align == ALIGN_CENTER)
myText.setPosition(x - myText.getLocalBounds().width / 2, y);
else
myText.setPosition(x, y);
app->draw(myText);
}
void WitchBlastGame::initMonsterArray()
{
for (int i = 0; i < MAP_WIDTH; i++)
for (int j = 0; j < MAP_HEIGHT; j++)
monsterArray[i][j] = false;
}
void WitchBlastGame::addMonster(monster_type_enum monsterType, float xm, float ym)
{
switch (monsterType)
{
case MONSTER_RAT: new RatEntity(xm, ym - 2); break;
case MONSTER_BAT: new BatEntity(xm, ym); break;
case MONSTER_EVIL_FLOWER: new EvilFlowerEntity(xm, ym); break;
case MONSTER_SLIME: new SlimeEntity(xm, ym); break;
case MONSTER_KING_RAT: new KingRatEntity(xm, ym); break;
}
}
void WitchBlastGame::findPlaceMonsters(monster_type_enum monsterType, int amount)
{
// find a suitable place
bool isMonsterFlying = monsterType == MONSTER_BAT;
bool bOk;
int xm, ym;
float xMonster, yMonster;
for (int index = 0; index < amount; index++)
{
bOk = false;
while (!bOk)
{
bOk = true;
xm = 1 +rand() % (MAP_WIDTH - 3);
ym = 1 +rand() % (MAP_HEIGHT - 3);
if (monsterArray[xm][ym])
{
bOk = false;
}
if (bOk && !isMonsterFlying && !currentMap->isWalkable(xm, ym))
{
bOk = false;
}
if (bOk)
{
xMonster = OFFSET_X + xm * TILE_WIDTH + TILE_WIDTH * 0.5f;
yMonster = OFFSET_Y + ym * TILE_HEIGHT+ TILE_HEIGHT * 0.5f;
float dist2 = (xMonster - player->getX())*(xMonster - player->getX()) + (yMonster - player->getY())*(yMonster - player->getY());
if ( dist2 < 75000.0f)
{
bOk = false;
}
else
{
addMonster(monsterType, xMonster, yMonster);
monsterArray[xm][ym] = true;
}
}
}
}
}
void WitchBlastGame::generateStandardMap()
{
initMonsterArray();
int random = rand() % 100;
if (random < 16)
{
currentMap->generateRoom(rand()%3);
findPlaceMonsters(MONSTER_RAT,4);
}
else if (random < 32)
{
currentMap->generateRoom(rand()%4);
findPlaceMonsters(MONSTER_BAT,4);
}
else if (random < 48)
{
currentMap->generateRoom(rand()%4);
findPlaceMonsters(MONSTER_EVIL_FLOWER,4);
}
else if (random < 64)
{
Vector2D v = currentMap->generateBonusRoom();
new ChestEntity(v.x, v.y, CHEST_BASIC, false);
currentMap->setCleared(true);
}
else if (random < 80)
{
currentMap->generateRoom(rand()%3);
findPlaceMonsters(MONSTER_RAT,3);
findPlaceMonsters(MONSTER_BAT,3);
}
else
{
currentMap->generateRoom(rand()%3);
findPlaceMonsters(MONSTER_SLIME,8 + rand() % 5);
}
}
item_equip_enum WitchBlastGame::getRandomEquipItem(bool toSale = false)
{
std::vector<int> bonusSet;
int setSize = 0;
for (int i = 0; i < NUMBER_EQUIP_ITEMS; i++)
{
if (!player->isEquiped(i) && i != EQUIP_BOSS_KEY)
{
if (!toSale || i!= EQUIP_FAIRY)
{
bonusSet.push_back(i);
setSize++;
}
}
}
int bonusType = 0;
if (setSize > 0) bonusType = bonusSet[rand() % setSize];
return (item_equip_enum) bonusType;
}
void WitchBlastGame::verifyDoorUnlocking()
{
int collidingDirection = (player->getCollidingDirection());
if (collidingDirection > 0 && currentMap->isCleared() && !bossRoomOpened && player->isEquiped(EQUIP_BOSS_KEY))
{
int xt = (player->getX() - OFFSET_X) / TILE_WIDTH;
int yt = (player->getY() - OFFSET_Y) / TILE_HEIGHT;
if (yt <= 1 && xt >= MAP_WIDTH / 2 - 1 && xt <= MAP_WIDTH / 2 + 1 && currentMap->hasNeighbourUp() == 2)
{
doorEntity[0]->openDoor();
currentMap->setTile(MAP_WIDTH / 2, 0, 0);
SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
player->useBossKey();
bossRoomOpened = true;
}
if (yt >= MAP_HEIGHT - 2 && xt >= MAP_WIDTH / 2 - 1 &&xt <= MAP_WIDTH / 2 + 1 && currentMap->hasNeighbourDown() == 2)
{
doorEntity[2]->openDoor();
currentMap->setTile(MAP_WIDTH / 2, MAP_HEIGHT - 1, 0);
SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
player->useBossKey();
bossRoomOpened = true;
}
if (xt <= 1 && yt >= MAP_HEIGHT / 2 - 1 && yt <= MAP_HEIGHT / 2 + 1 && currentMap->hasNeighbourLeft() == 2)
{
doorEntity[1]->openDoor();
currentMap->setTile(0, MAP_HEIGHT / 2, 0);
SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
player->useBossKey();
bossRoomOpened = true;
}
if (xt >= MAP_WIDTH - 2 && yt >= MAP_HEIGHT / 2 - 1 && yt <= MAP_HEIGHT / 2 + 1 && currentMap->hasNeighbourRight() == 2)
{
doorEntity[3]->openDoor();
currentMap->setTile(MAP_WIDTH - 1, MAP_HEIGHT / 2, 0);
SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
player->useBossKey();
bossRoomOpened = true;
}
}
}
void WitchBlastGame::playMusic(musicEnum musicChoice)
{
music.stop();
music.setLoop(true);
bool ok = false;
switch (musicChoice)
{
case MusicDungeon:
ok = music.openFromFile("media/sound/track00.ogg");
music.setVolume(75);
break;
case MusicEnding:
ok = music.openFromFile("media/sound/track_ending.ogg");
music.setVolume(35);
break;
case MusicBoss:
ok = music.openFromFile("media/sound/track_boss.ogg");
music.setVolume(80);
break;
}
if (ok)
music.play();
}
void WitchBlastGame::saveGame()
{
ofstream file("game.sav", ios::out | ios::trunc);
int i, j, k, l;
if (file)
{
// floor
file << level << std::endl;
int nbRooms = 0;
for (j = 0; j < FLOOR_HEIGHT; j++)
{
for (i = 0; i < FLOOR_WIDTH; i++)
{
file << currentFloor->getRoom(i,j) << " ";
if (currentFloor->getRoom(i,j) > 0) nbRooms++;
}
file << std::endl;
}
// maps
saveMapItems();
file << nbRooms << std::endl;
for (j = 0; j < FLOOR_HEIGHT; j++)
{
for (i = 0; i < FLOOR_WIDTH; i++)
{
if (currentFloor->getRoom(i,j) > 0)
{
file << i << " " << j << " "
<< currentFloor->getMap(i, j)->getRoomType() << " "
<< currentFloor->getMap(i, j)->isKnown() << " "
<< currentFloor->getMap(i, j)->isVisited() << " "
<< currentFloor->getMap(i, j)->isCleared() << std::endl;
if (currentFloor->getMap(i, j)->isVisited())
{
for (l = 0; l < MAP_HEIGHT; l++)
{
for (k = 0; k < MAP_WIDTH; k++)
{
file << currentFloor->getMap(i, j)->getTile(k, l) << " ";
}
file << std::endl;
}
// items, etc...
std::list<DungeonMap::itemListElement> itemList = currentFloor->getMap(i, j)->getItemList();
file << itemList.size() << std::endl;
std::list<DungeonMap::itemListElement>::iterator it;
for (it = itemList.begin (); it != itemList.end ();)
{
DungeonMap::itemListElement ilm = *it;
it++;
file << ilm.type << " " << ilm.x << " " << ilm.y << " " << ilm.merch << std::endl;
}
// chests
std::list<DungeonMap::chestListElement> chestList = currentFloor->getMap(i, j)->getChestList();
file << chestList.size() << std::endl;
std::list<DungeonMap::chestListElement>::iterator itc;
for (itc = chestList.begin (); itc != chestList.end ();)
{
DungeonMap::chestListElement ilm = *itc;
itc++;
file << ilm.type << " " << ilm.x << " " << ilm.y << " " << ilm.state << std::endl;
}
// sprites
std::list<DungeonMap::spriteListElement> spriteList = currentFloor->getMap(i, j)->getSpriteList();
file << spriteList.size() << std::endl;
std::list<DungeonMap::spriteListElement>::iterator its;
for (its = spriteList.begin (); its != spriteList.end ();)
{
DungeonMap::spriteListElement ilm = *its;
its++;
file << ilm.type << " " << ilm.frame << " " << ilm.x << " " << ilm.y << " " << ilm.scale << std::endl;
}
}
}
}
file << std::endl;
}
// game
file << floorX << " " << floorY << std::endl;
file << bossRoomOpened << std::endl;
// boss door !
// player
file << player->getHp() << " " << player->getHpMax() << " " << player->getGold() << std::endl;
for (i = 0; i < NUMBER_EQUIP_ITEMS; i++) file << player->isEquiped(i) << " ";
file << std::endl;
file << player->getX() << " " << player->getY() << std::endl;
file << player->getShotIndex();
for (i = 0; i < SPECIAL_SHOT_SLOTS; i++) file << " " << player->getShotType(i);
file.close();
}
else
{
cerr << "[ERROR] Saving the game..." << endl;
}
}
bool WitchBlastGame::loadGame()
{
ifstream file("game.sav", ios::in);
if (file)
{
int i, j, k, n;
// floor
file >> level;
currentFloor = new GameFloor(level);
for (j = 0; j < FLOOR_HEIGHT; j++)
{
for (i = 0; i < FLOOR_WIDTH; i++)
{
int n;
file >> n;
currentFloor->setRoom(i, j, n);
}
}
// maps
int nbRooms;
file >> nbRooms;
for (k = 0; k < nbRooms; k++)
{
file >> i;
file >> j;
file >> n;
DungeonMap* iMap = new DungeonMap(currentFloor, i, j);
currentFloor->setMap(i, j, iMap);
iMap->setRoomType((roomTypeEnum)n);
bool flag;
file >> flag;
iMap->setKnown(flag);
file >> flag;
iMap->setVisited(flag);
file >> flag;
iMap->setCleared(flag);
if (iMap->isVisited())
{
for (j = 0; j < MAP_HEIGHT; j++)
{
for (i = 0; i < MAP_WIDTH; i++)
{
file >> n;
iMap->setTile(i, j, n);
}
}
// items int the map
file >> n;
for (i = 0; i < n; i++)
{
int t;
float x, y;
bool merc;
file >> t >> x >> y >> merc;
iMap->addItem(t, x, y, merc);
}
// chests in the map
file >> n;
for (i = 0; i < n; i++)
{
int t;
float x, y;
bool state;
file >> t >> x >> y >> state;
iMap->addChest(t, state, x, y);
}
// sprites in the map
file >> n;
for (i = 0; i < n; i++)
{
int t, f;
float x, y, scale;
file >> t >> f >> x >> y >> scale;
iMap->addSprite(t, f, x, y, scale);
}
}
}
// game
file >> floorX >> floorY;
currentMap = currentFloor->getMap(floorX, floorY);
file >> bossRoomOpened;
// player
int hp, hpMax, gold;
file >> hp >> hpMax >> gold;
player = new PlayerEntity(OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
OFFSET_Y + (TILE_HEIGHT * MAP_HEIGHT * 0.5f));
player->setHp(hp);
player->setHpMax(hpMax);
player->setGold(gold);
for (i = 0; i < NUMBER_EQUIP_ITEMS; i++)
{
bool eq;
file >> eq;
player->setEquiped(i, eq);
}
float x, y;
file >> x >> y;
player->moveTo(x, y);
file >> n;
player->setShotIndex(n);
for (i = 0; i < SPECIAL_SHOT_SLOTS; i++)
{
file >> n;
player->setShotType(i, (enumShotType)n);
}
file.close();
remove("game.sav");
}
else
{
return false;
}
return true;
}
WitchBlastGame &game()
{
return *gameptr;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jun 11, 11:28 AM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68760
Default Alt Text
(73 KB)
Attached To
Mode
R78 witchblast
Attached
Detach File
Event Timeline