Skip to content

Commit

Permalink
Implemented bombs and nuking via network
Browse files Browse the repository at this point in the history
Also improved some stuff related to network traffic
  • Loading branch information
MartinUbl committed Nov 4, 2012
1 parent 16f503b commit c5241be
Show file tree
Hide file tree
Showing 11 changed files with 264 additions and 10 deletions.
2 changes: 2 additions & 0 deletions include/Gameplay/GameTypes.h
Expand Up @@ -226,6 +226,8 @@ class ClassicMultiGameType: public GameTypeTemplate
void OnGameInit(ModelDisplayListRecord* pPlayerRec);
void OnGameLeave();
void OnUpdate();
void OnBombBoom(BombRecord* bomb);
void OnBoxDestroy(uint32 x, uint32 y, bool by_bomb = true);
};

#endif
10 changes: 8 additions & 2 deletions include/Gameplay/Gameplay.h
Expand Up @@ -35,7 +35,8 @@ struct BombRecord
uint32 y;
uint32 reach;
clock_t boomTime;
//pozdeji i data o vlastnikovi?

uint32 ownerId;

SoundEffectRecord* sizzleSound;
};
Expand All @@ -56,6 +57,10 @@ struct BombRecord
* \brief Cas, kdy ma bomba vybouchnout [ms]
*/

/** \var BombRecord::ownerId
* \brief ID vlastnika - aktivni pouze v multiplayer modu
*/

/** \var BombRecord::sizzleSound
* \brief Odkaz na zvukovy efekt syceni bomby, pro pripadne preruseni
*/
Expand Down Expand Up @@ -192,7 +197,8 @@ class GameplayMgr
void OnBoxDestroy(uint32 x, uint32 y, bool by_bomb = true) { if (m_game) m_game->OnBoxDestroy(x,y,by_bomb); };
void OnPlayerFieldChange(uint32 oldX, uint32 oldY, uint32 newX, uint32 newY);

bool AddBomb(uint32 x, uint32 y);
bool AddBomb(uint32 x, uint32 y, uint32 owner = 0, uint32 reach = 0);
void SendAddBomb(uint32 x, uint32 y);
void PreBoomBomb(uint32 x, uint32 y);

float GetPlayerSpeedCoef() { return IsCheatOn(CHEAT_MAX_SPEED)?2.0f:m_plSpeedCoef; };
Expand Down
7 changes: 7 additions & 0 deletions include/Network/Opcodes.h
Expand Up @@ -34,6 +34,13 @@ enum Opcodes
SMSG_MOVE_HEARTBEAT = 0x0F,
SMSG_MAP_INITIAL_DATA = 0x10,
SMSG_NEW_PLAYER = 0x11,
CMSG_PLANT_BOMB = 0x12,
SMSG_PLANT_BOMB = 0x13,
SMSG_PLAYER_DIED = 0x14,
SMSG_BOX_DESTROYED = 0x15,
SMSG_NEW_BONUS = 0x16,
CMSG_BONUS_TAKEN = 0x17,
SMSG_BONUS_TAKEN = 0x18,
MAX_OPCODE
};

Expand Down
8 changes: 7 additions & 1 deletion include/Network/PacketHandlers.h
Expand Up @@ -15,6 +15,9 @@ namespace PacketHandlers
void HandleMoveStop(SmartPacket* data);
void HandleMoveHeartbeat(SmartPacket* data);
void HandleNewPlayer(SmartPacket* data);
void HandlePlantBomb(SmartPacket* data);
void HandleBoxDestroyed(SmartPacket* data);
void HandlePlayerDied(SmartPacket* data);
};

struct OpcodeHandler
Expand All @@ -32,7 +35,10 @@ static const OpcodeHandler PacketHandlerAssign[] = {
{SMSG_MOVE_START, &PacketHandlers::HandleMoveStart},
{SMSG_MOVE_STOP, &PacketHandlers::HandleMoveStop},
{SMSG_MOVE_HEARTBEAT, &PacketHandlers::HandleMoveHeartbeat},
{SMSG_NEW_PLAYER, &PacketHandlers::HandleNewPlayer}
{SMSG_NEW_PLAYER, &PacketHandlers::HandleNewPlayer},
{SMSG_PLANT_BOMB, &PacketHandlers::HandlePlantBomb},
{SMSG_PLAYER_DIED, &PacketHandlers::HandlePlayerDied},
{SMSG_BOX_DESTROYED, &PacketHandlers::HandleBoxDestroyed}
};

#endif
2 changes: 2 additions & 0 deletions include/System/Stages.h
Expand Up @@ -216,6 +216,7 @@ class GameStage: public StageControl
GameStage()
{
m_type = STAGE_GAME;
m_lastBombPlant = 0;
}
void OnEnter();
void OnLeave();
Expand All @@ -227,6 +228,7 @@ class GameStage: public StageControl

protected:
uint8 m_consoleHistoryLine;
clock_t m_lastBombPlant;
};

/** \class CreditsStage
Expand Down
19 changes: 19 additions & 0 deletions include/System/Storage.h
Expand Up @@ -33,6 +33,9 @@ enum InterThreadRequest
REQUEST_PLAYER_ANIM = 7,
REQUEST_PLAYER_POS = 8,
REQUEST_PLAYER_ROTATION = 9,
REQUEST_PLANT_BOMB = 10,
REQUEST_PLAYER_DEATH = 11,
REQUEST_BOX_DESTROY = 12,
MAX_REQUEST
};

Expand Down Expand Up @@ -61,6 +64,22 @@ struct ThreadRequestPlayerRotation
uint32 id;
float rotation;
};
struct ThreadRequestPlantBomb
{
uint32 id;
uint32 x;
uint32 y;
uint32 reach;
};
struct ThreadRequestPlayerDeath
{
uint32 id;
float x, z;
};
struct ThreadRequestBoxDestroy
{
uint32 x, y;
};

// Definice jednotlivych ulozist

Expand Down
100 changes: 100 additions & 0 deletions src/Gameplay/GameTypes/ClassicMultiType.cpp
Expand Up @@ -34,3 +34,103 @@ void ClassicMultiGameType::OnGameLeave()
void ClassicMultiGameType::OnUpdate()
{
}

void ClassicMultiGameType::OnBombBoom(BombRecord* bomb)
{
if (!bomb)
return;

Map* pMap = (Map*)sMapManager->GetMap();
if (pMap)
{
// Nejdrive znicime bombu na mape
pMap->DestroyDynamicRecords(bomb->x, bomb->y, DYNAMIC_TYPE_BOMB);

// Nyni promenliva hodnota podle bonusu
// Bonus se ale zapocita jen pokud je bomba polozena az po vzeti bonusu, ne na vsechny
// Jednak je to realistictejsi a jednak to usnadni trochu pathfinding pro AI
uint32 bombreach = bomb->reach;

// Projdeme vsechny mozne zaznamy na mape az na maximalni definovany dosah
// pokud tam neco je, zamezime dalsimu prepsani a zapiseme
uint32 reach_x1 = bombreach+1, reach_x2 = bombreach+1, reach_y1 = bombreach+1, reach_y2 = bombreach+1;
// Promenna urcujici, zdali doslo ke kolizi kvuli objektu (true) nebo kvuli dosahu (false)
bool rx1_box = false, rx2_box = false, ry1_box = false, ry2_box = false;

for (uint32 i = 0; i < bombreach; i++)
{
// Pokud jeste nebylo zapsano
if (reach_x1 == bombreach+1)
{
// Overime, zdali na dane pozici neco neprostupneho je
if (pMap->IsDynamicRecordPresent(bomb->x + i + 1, bomb->y, DYNAMIC_TYPE_BOX))
{
// Pokud ano, zamezime zapsanim maximalni pozice dalsimu prepsani
reach_x1 = i+1;
rx1_box = true;
}
else if (pMap->GetStaticRecord(bomb->x + i + 1,bomb->y) == TYPE_SOLID_BOX)
reach_x1 = i+1;
}

if (reach_x2 == bombreach+1)
{
if (pMap->IsDynamicRecordPresent(bomb->x - i - 1, bomb->y, DYNAMIC_TYPE_BOX))
{
reach_x2 = i+1;
rx2_box = true;
}
else if (pMap->GetStaticRecord(bomb->x - i - 1,bomb->y) == TYPE_SOLID_BOX)
reach_x2 = i+1;
}

if (reach_y1 == bombreach+1)
{
if (pMap->IsDynamicRecordPresent(bomb->x, bomb->y + i + 1, DYNAMIC_TYPE_BOX))
{
reach_y1 = i+1;
ry1_box = true;
}
else if (pMap->GetStaticRecord(bomb->x,bomb->y + i + 1) == TYPE_SOLID_BOX)
reach_y1 = i+1;
}

if (reach_y2 == bombreach+1)
{
if (pMap->IsDynamicRecordPresent(bomb->x, bomb->y - i - 1, DYNAMIC_TYPE_BOX))
{
reach_y2 = i+1;
ry2_box = true;
}
else if (pMap->GetStaticRecord(bomb->x,bomb->y - i - 1) == TYPE_SOLID_BOX)
reach_y2 = i+1;
}
}
// Pak vsechno dekrementujeme - zapise se vzdy pozice uz nepristupneho pole
--reach_x1;
--reach_x2;
--reach_y1;
--reach_y2;

// Exploze - particle emittery
BillboardDisplayListRecord* templ = BillboardDisplayListRecord::Create(31, 0, 0, 0, 0.8f, 0.8f, true, true);
sParticleEmitterMgr->AddEmitter(templ, bomb->x-0.5f, 0.1f, bomb->y-0.5f, 0.15f, 0.4f, 0, 0.0f, 0, 0, reach_y1*100 + (ry1_box?100:0), 20, 10.0f, 0.1f, 50, 10, 1, 0, ANIM_FLAG_NOT_REPEAT, DEFAULT_BOMB_FLAME_DURATION);

templ = BillboardDisplayListRecord::Create(31, 0, 0, 0, 0.8f, 0.8f, true, true);
sParticleEmitterMgr->AddEmitter(templ, bomb->x-0.5f, 0.1f, bomb->y-0.5f, 0.15f, 0.4f, 0, 90.0f, 0, 0, reach_x2*100 + (rx2_box?100:0), 20, 10.0f, 0.1f, 50, 10, 1, 0, ANIM_FLAG_NOT_REPEAT, DEFAULT_BOMB_FLAME_DURATION);

templ = BillboardDisplayListRecord::Create(31, 0, 0, 0, 0.8f, 0.8f, true, true);
sParticleEmitterMgr->AddEmitter(templ, bomb->x-0.5f, 0.1f, bomb->y-0.5f, 0.15f, 0.4f, 0, 180.0f, 0, 0, reach_y2*100 + (ry2_box?100:0), 20, 10.0f, 0.1f, 50, 10, 1, 0, ANIM_FLAG_NOT_REPEAT, DEFAULT_BOMB_FLAME_DURATION);

templ = BillboardDisplayListRecord::Create(31, 0, 0, 0, 0.8f, 0.8f, true, true);
sParticleEmitterMgr->AddEmitter(templ, bomb->x-0.5f, 0.1f, bomb->y-0.5f, 0.15f, 0.4f, 0, 270.0f, 0, 0, reach_x1*100 + (rx1_box?100:0), 20, 10.0f, 0.1f, 50, 10, 1, 0, ANIM_FLAG_NOT_REPEAT, DEFAULT_BOMB_FLAME_DURATION);

// Casovani vybuchu je implementovano pri polozeni bomby
}
}

void ClassicMultiGameType::OnBoxDestroy(uint32 x, uint32 y, bool by_bomb)
{
BillboardDisplayListRecord* templ = BillboardDisplayListRecord::Create(31, 0, 0, 0, 0.8f, 0.8f, true, true);
sParticleEmitterMgr->AddEmitter(templ, x-0.5f, 0.0f, y-0.5f, 0.6f, 0.6f, 90.0f, 0.0f, 0, 0, 150, 30, 5.0f, 0.1f, 10, 5, 0, 0, 0, DEFAULT_BOMB_FLAME_DURATION);
}
29 changes: 24 additions & 5 deletions src/Gameplay/Gameplay.cpp
Expand Up @@ -94,7 +94,8 @@ void GameplayMgr::Update()
}

m_game->OnBombBoom(*itr);
m_plActiveBombs--;
if (IsSingleGameType())
m_plActiveBombs--;
itr = BombMap.erase(itr);
continue;
}
Expand Down Expand Up @@ -291,26 +292,44 @@ GameType GameplayMgr::GetGameType()
return m_game->GetType();
}

/** \brief Funkce starajici se o pridani bomby v multiplayer modu
*
* Posle oznameni o pridani bomby (kteremu nemusi byt vyhoveno serverem)
*/
void GameplayMgr::SendAddBomb(uint32 x, uint32 y)
{
// Jako prvni zkontrolujeme a popripade ohandlujeme multiplayer pripad - je to rychle
if (IsSingleGameType())
return;

SmartPacket bomb(CMSG_PLANT_BOMB);
bomb << uint32(x);
bomb << uint32(y);
sNetwork->SendPacket(&bomb);
}

/** \brief Funkce starajici se o pridani bomby
*
* Prida bombu na zadane souradnice ve 2D mape. Vypocita dosah, oznaci budouci nebezpecna pole a vlozi zaznam bomby do mapy
*/
bool GameplayMgr::AddBomb(uint32 x, uint32 y)
bool GameplayMgr::AddBomb(uint32 x, uint32 y, uint32 owner, uint32 reach)
{
if (m_plActiveBombs >= m_plMaxBombs && !IsCheatOn(CHEAT_UNLIMITED_BOMBS))
return false;

BombRecord* bomb = new BombRecord;
bomb->x = x;
bomb->y = y;
bomb->ownerId = owner;
bomb->boomTime = clock() + 2500;
bomb->reach = IsCheatOn(CHEAT_MAX_FLAME)?10:GetFlameReach();
bomb->reach = (owner>0)?(reach):(IsCheatOn(CHEAT_MAX_FLAME)?10:GetFlameReach());
bomb->sizzleSound = sSoundMgr->PlayEffect(2, true, true);
BombMap.push_back(bomb);

sSoundMgr->PlayEffect(25);

m_plActiveBombs++;
if (IsSingleGameType())
m_plActiveBombs++;

if (sGameplayMgr->GetGameType() == GAME_TYPE_SP_CLASSIC)
localPlayerStats.ClassicSingleStats.bombsPlanted += 1;
Expand Down Expand Up @@ -751,7 +770,7 @@ void GameplayMgr::UpdatePlayerMoveAngle()
}

// Update uhlu pohybu pokud se lisi od posledniho updatu o vice jak 30 stupnu
if (fabs((180.0f * (PI/2-m_moveAngle) / PI) - m_lastUpdatedMoveAngle) > 30.0f)
if (fabs(GetPlayerRec()->rotate - m_lastUpdatedMoveAngle) > 30.0f)
SendMoveHeartbeat();
}

Expand Down
47 changes: 47 additions & 0 deletions src/Network/PacketHandlers.cpp
Expand Up @@ -261,3 +261,50 @@ void PacketHandlers::HandleMoveHeartbeat(SmartPacket* data)
req2->rotation = rot;
sStorage->MakeInterThreadObjectRequest(THREAD_NETWORK, REQUEST_PLAYER_ROTATION, req2);
}

void PacketHandlers::HandlePlantBomb(SmartPacket* data)
{
uint32 owner;
uint32 x, y, reach;

*data >> owner;
*data >> x;
*data >> y;
*data >> reach;

ThreadRequestPlantBomb* req = new ThreadRequestPlantBomb;
req->id = owner;
req->x = x;
req->y = y;
req->reach = reach;
sStorage->MakeInterThreadObjectRequest(THREAD_NETWORK, REQUEST_PLANT_BOMB, req);
}

void PacketHandlers::HandlePlayerDied(SmartPacket* data)
{
uint32 id;
float x, z;

*data >> id;
*data >> x;
*data >> z;

ThreadRequestPlayerDeath* req = new ThreadRequestPlayerDeath;
req->id = id;
req->x = x;
req->z = z;
sStorage->MakeInterThreadObjectRequest(THREAD_NETWORK, REQUEST_PLAYER_DEATH, req);
}

void PacketHandlers::HandleBoxDestroyed(SmartPacket* data)
{
uint32 x, y;

*data >> x;
*data >> y;

ThreadRequestBoxDestroy* req = new ThreadRequestBoxDestroy;
req->x = x;
req->y = y;
sStorage->MakeInterThreadObjectRequest(THREAD_NETWORK, REQUEST_BOX_DESTROY, req);
}
10 changes: 8 additions & 2 deletions src/Stages/GameStage.cpp
Expand Up @@ -413,12 +413,17 @@ void GameStage::OnMouseButtonPress(uint32 x, uint32 y, bool left)
// bloky if .. else if .. pouzity kvuli prehlednosti

// Pokladame bomby pouze kdyz hrajeme (ne v menu nebo kdyz jsme mrtvi)
if(m_subStage == 0)
if (m_subStage == 0)
{
Map* pMap = (Map*)sMapManager->GetMap();
if (!pMap)
return;

if (m_lastBombPlant + 300 > clock())
return;

m_lastBombPlant = clock();

uint32 bx = floor(sGameplayMgr->GetPlayerRec()->x)+1;
uint32 by = floor(sGameplayMgr->GetPlayerRec()->z)+1;

Expand All @@ -433,7 +438,8 @@ void GameStage::OnMouseButtonPress(uint32 x, uint32 y, bool left)
}
else
{
// TODO: multiplayer
// jen pozadat server o vlozeni bomby
sGameplayMgr->SendAddBomb(bx, by);
}
}
// jsme zapauzovani
Expand Down

0 comments on commit c5241be

Please sign in to comment.