Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Battle Royale - 90% finished

Experienced Elementalist
Joined
May 28, 2017
Messages
225
Reaction score
127
Dear ragezone fans,

Today Im going to release my whole work of my Battle Royale mode.

I hope you like it and it should be a great start for you if you like to make your own battle royale mode.

IT COULD HAPPEN THAT I FORGOT SOME CODE, so if I forgot something than tell me what I have forget!

THIS RELEASE DOES NOT INCLUDE MY UI PART!

IM SURE THAT I FORGOT SOME poop BUT WELL FIRST OF ALL TRY OUT TO USE THIS:
OBJ_TOXICCIRCLE FILES ARE IN THE ATTACHMENTS!!!!!

Sorry about that bad structure I have made here its hard to get an overview I know, but that code is not about copy pastarino its more about you can use that or maybe its something you were looking for.

Sorry that I dont take that much time to make a nice release of that Im just 17 years old and to lazy to waste all my time into every single release!

I hope you guys understand me :)


So we are going to start with the server:

/ @Tobi battle royale packages
PKT_S2C_SendExitMessage,
PKT_S2C_SendToxicTimer,
PKT_S2C_ResetPlayerLoadoutBR,
PKT_S2C_UpdateBRStats,
PKT_S2C_CreateToxicZone,
PKT_S2C_SetToxicZoneRadius,
PKT_S2C_SetSafeZoneOnMap,

// Battle Royale Packages
struct PKT_S2C_SendExitMessage_s : public DefaultPacketMixin<PKT_S2C_SendExitMessage>
{
bool ShowExitHud;
int Kills;
int GameDollars;
};

struct PKT_S2C_SendToxicTimer_s : public DefaultPacketMixin<PKT_S2C_SendToxicTimer>
{
float Timer;
int status;
int isvisible;
};

struct PKT_S2C_ResetPlayerLoadoutBR_s : public DefaultPacketMixin<PKT_S2C_ResetPlayerLoadoutBR>
{
DWORD peerID;
gp2pnetid_t PlayerID;
float spawnProtection;
};

struct PKT_S2C_UpdateBRStats_s : public DefaultPacketMixin<PKT_S2C_UpdateBRStats>
{
WORD playerIdx;
int alive;
};

struct PKT_S2C_CreateToxicZone_s : public DefaultPacketMixin<PKT_S2C_CreateToxicZone>
{
gp2pnetid_t spawnID;
r3dPoint3D pos;
float radius;

wiInventoryItem Item;
};

struct PKT_S2C_SetToxicZoneRadius_s : public DefaultPacketMixin<PKT_S2C_SetToxicZoneRadius>
{
float useRadius;
int Index;
};

struct PKT_S2C_SetSafeZoneOnMap_s : public DefaultPacketMixin<PKT_S2C_SetSafeZoneOnMap>
{
float useRadius;
};

If you want to disable XP in br mode than go to:
void CGameRewards::InitDefaultRewards()

and add this:

// if its battle royale dont add xp
if(gServerLogic.ginfo_.isBattleRoyale())
return;

find this:

void CGameRewards::ExportDefaultRewards()

add this:

#ifdef WO_SERVER
// if its battle royale dont add xp
if(gServerLogic.ginfo_.isBattleRoyale())
return;
#endif

NOW SOMETHING IMPORTANT!

In my version I have removed the BasePlayerSpawn Type, because it had no useage.

Add lobby spawn points
GO to:

class BasePlayerSpawnPoint : public MeshGameObject

And change:

enum type_e {

it should looks like this:

enum type_e {
SPAWN_LOBBY, // Used for battle royale
SPAWN_NEUTRAL, // when player dies and respawns, he spawns to the closes of those points
};

GO TO:
BOOL obj_ServerPlayer::OnCreate()

add:

isBattleRoyale = gServerLogic.ginfo_.isBattleRoyale(); //Battle Royale

go to:

void obj_ServerPlayer::OnNetPacket(const PKT_C2C_TradeRequest_s& n)

add:

// dont allow trading if gamemode is battle royale
if(gServerLogic.ginfo_.isBattleRoyale())
return;

IF YOU HAVE A RESPAWN SYSTEM:

Add this as a new respawn logic for the lobby:

if(gServerLogic.ginfo_.isBattleRoyale() && !gServerLogic.ginfo_.GameHasbeenStarted)
{
ReviveFast();

//SetLatePacketsBarrier("teleport");
PKT_C2S_ReviveFast_s Revive;
Revive.PlayerID = toP2pNetId(GetNetworkID());
gServerLogic.p2pBroadcastToAll(&Revive, sizeof(Revive), true);


wiCharDataFull& loadout = profile_.ProfileData.ArmorySlots[0];

packetBarrierReason = "";

GiveBRloadout();
}

GO TO:

void UpdateGameWorldFlags();

Add:

/ @Tobi for battle royale
void CheckIfOutSideOfToxicZone(DWORD index);

GO TO:

gServerLogic.PreloadDevEventLoadout();

Add UNDER THE #ENDIF:

// load server configs for battle royale
if(gServerLogic.ginfo_.isBattleRoyale())
gServerLogic.LoadBattleRoyaleServerConfigs();

GO TO:

ServerGameLogic::ServerGameLogic()

Add:

///////////BATTLE ROYALE////////////////////
m_StartGameTime = 0; //gamehardcore
m_StartGameTimeR = -1; //gamehardcore
countTimeFinish = 0; //gamehardcore
MaxAirdrop = 0;
m_spreadToxic = -1; / @Tobi spread toxic gas
m_preparingToxicZone = -1;
m_startspreadingGas = 0;
m_toxicLevel = 0;
ginfo_.isGameGoingToStart = 0;//gamehardcore
isBlocked = false;

m_resetGameTime = -1;
m_spawnAirdrop = -1;
////////////////////////////////////////////

GO TO:

bool ServerGameLogic::ApplyDamageToPlayer(GameObject* fromObj, obj_ServerPlayer* targetPlr, const r3dPoint3D& dmgPos, float damage, int bodyBone, int bodyPart, bool force_damage, STORE_CATEGORIES damageSource, uint32_t dmgItemID, int reputation, int airState, bool canApplyBleeding)
{

Add:

if (ginfo_.isBattleRoyale() && ginfo_.isGameGoingToStart == 0 && fromObj->Class->Name == "obj_Zombie") //Battle Royale
return false;

GO TO:

void ServerGameLogic::Tick()

AND ADD AT THE END OF THE FUNCTION THIS:

/////////////////////BATTLE ROYALE LOGIC///////////////////////////////////////////////////////////
if (ginfo_.isBattleRoyale())
{
// get all players on the server who are currently alive!
char msg[512]="";
int LivePlayers = 0;
int LiveID = 0;
bool DarSpawnProtection = false;
for( GameObject* obj = GameWorld().GetFirstObject(); obj; obj = GameWorld().GetNextObject(obj) )
{
if(obj->isObjType(OBJTYPE_Human))
{
obj_ServerPlayer* Player = (obj_ServerPlayer*)obj;
if (Player->loadout_->Alive > 0)
{
LivePlayers++;
LiveID = Player->GetNetworkID();
}
}
}

// reset only if our game is started otherwise we could get problems with server crashes I guess
if ( curPlayers_<1 && !ginfo_.GameHasbeenStarted && ginfo_.isGameGoingToStart > 0)
{
ginfo_.isGameGoingToStart = 0;
countTimeFinish = 0;
m_StartGameTime = 0;
m_StartGameTimeR = -1;
}
else if ( curPlayers_<1 && ginfo_.GameHasbeenStarted && ginfo_.isGameGoingToStart > 0)
{
// if game is on and our server us empty how ever this happens
EndMatch();
}

// LOBBY SYSTEM - START

// Check for players
if ( curPlayers_ >= MinimumConnectedPlayers && !ginfo_.GameHasbeenStarted ) // 5 players are enough to start with our logic
{
if (ginfo_.isGameGoingToStart == 0)
{
char msg[512]="";
sprintf(msg,"The Game is going to start soon!");

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);

m_StartGameTime = r3dGetTime()+StartCountDownTimer;

{
PKT_S2C_SendGameMessage_s n;
r3dscpy(n.msg, msg);
p2pBroadcastToAll(&n, sizeof(n), true);
}

ginfo_.isGameGoingToStart = 1;
}
}
else if(curPlayers_ <= MinimumConnectedPlayers && !ginfo_.GameHasbeenStarted && ginfo_.isGameGoingToStart > 0 && ginfo_.isGameGoingToStart < 3) { // we dont start under 5 players its not enough!
// if game is going to start but we dont have enough players, stop cuntdown!
ginfo_.isGameGoingToStart = 0;
countTimeFinish = 0;
m_StartGameTime = 0;
m_StartGameTimeR = -1;

char msg[512]="";
sprintf(msg,"The start countdown got stopped, because we don't have enough players!");

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);
}

// start faster logic
if(ginfo_.isGameGoingToStart == 1 && curPlayers_ >= EnoughConnectedPlayersToStartBRFaster1)
{
if(m_StartGameTime > 0) {
m_StartGameTime = r3dGetTime()+CountdownTime1;
ginfo_.isGameGoingToStart = 2;
}
}
else if(ginfo_.isGameGoingToStart == 1 && curPlayers_ >= EnoughConnectedPlayersToStartBRFaster2)
{
if(m_StartGameTime > 0) {
m_StartGameTime = r3dGetTime()+CountdownTime2;
ginfo_.isGameGoingToStart = 2;
}
}


// start Match - logic
if (ginfo_.isGameGoingToStart > 0)
{
if (m_StartGameTime > 0 && r3dGetTime() > m_StartGameTime)
{
m_StartGameTimeR = r3dGetTime()+30;
m_StartGameTime = -1;

sprintf(msg,"Game starts in 2 minutes!");

PKT_S2C_SendGameMessage_s n;
r3dscpy(n.msg, msg);
p2pBroadcastToAll(&n, sizeof(n), true);

{
ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);
}
}

// Start Match Cooldown - takes 2 minutes!
if (m_StartGameTimeR > 0 && r3dGetTime() > m_StartGameTimeR)
{
switch (countTimeFinish)
{
case 0:
{
sprintf(msg,"Game starts in 1 minute and 30 seconds");

PKT_S2C_SendGameMessage_s n;
r3dscpy(n.msg, msg);
p2pBroadcastToAll(&n, sizeof(n), true);

break;
}
case 1:
{
sprintf(msg,"Game starts in 1 minute");

PKT_S2C_SendGameMessage_s n;
r3dscpy(n.msg, msg);
p2pBroadcastToAll(&n, sizeof(n), true);

break;
}
case 2:
{
sprintf(msg,"Game starts in 30 seconds");

PKT_S2C_SendGameMessage_s n;
r3dscpy(n.msg, msg);
p2pBroadcastToAll(&n, sizeof(n), true);

break;
}
case 3:
{
sprintf(msg,"Game starts in 10 seconds");

PKT_S2C_SendGameMessage_s n;
r3dscpy(n.msg, msg);
p2pBroadcastToAll(&n, sizeof(n), true);

break;
}
case 4:
{
sprintf(msg,"Game starts in 5 seconds");

isBlocked = true;


for (int i = 0; i < curPlayers_; ++i)
{
obj_ServerPlayer* pl = plrList_;

if(pl->loadout_->Alive == 0) {
pl->ReviveFast();
PKT_C2S_ReviveFast_s Revive;
Revive.PlayerID = toP2pNetId(pl->GetNetworkID());
p2pBroadcastToAll(&Revive, sizeof(Revive), true);
}
}

PKT_S2C_SendGameMessage_s n;
r3dscpy(n.msg, msg);
p2pBroadcastToAll(&n, sizeof(n), true);

break;
}
}
ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);


// countTimeFinish Logic
if(countTimeFinish == 2)
m_StartGameTimeR = r3dGetTime()+20;
else if(countTimeFinish == 3 || countTimeFinish == 4)
m_StartGameTimeR = r3dGetTime()+5;
else
m_StartGameTimeR = r3dGetTime()+30;

countTimeFinish++;
}

// countTimeFinish == 6 - our countdown is over, now start the main game!
if (countTimeFinish == 6)
{
// revive all our dead players
for (int i = 0; i < curPlayers_; ++i)
{
obj_ServerPlayer* pl = plrList_;

if(pl->loadout_->Alive == 0) {
pl->ReviveFast();
PKT_C2S_ReviveFast_s Revive;
Revive.PlayerID = toP2pNetId(pl->GetNetworkID());
p2pBroadcastToAll(&Revive, sizeof(Revive), true);
}
else {
pl->ResetLoadout();
}
}

/ @Tobi start game
StartMatch();

// set timer -1
m_StartGameTimeR = -1;
}

// OutSide Of ToxicZone Logic - check if a players is outside the toxic zone and if yes, than damage the player!
if(LiveID >= 1 && ginfo_.GameHasbeenStarted) {

UpdateToxicCircle(m_ToxicIndex);

for (int i = 0; i < curPlayers_; ++i)
{
obj_ServerPlayer* pl = plrList_;

pl->CheckIfOutSideOfToxicZone(m_ToxicIndex);
}
}

// Toxic Logic - spreading
if(m_spreadToxic > 0 && r3dGetTime() > m_spreadToxic)
{
m_startspreadingGas = 1;

EnableToxicGas = 1;

{
PKT_S2C_SendToxicTimer_s n;
n.Timer = 0;
n.status = 3;
n.isvisible = 1;
p2pBroadcastToAll(&n, sizeof(n), true);
}
}

// Toxic Logic - Preparing
if(m_preparingToxicZone > 0 && r3dGetTime() > m_preparingToxicZone)
{
SpawnToxicZone();

// first safezone has a radius of m_toxicLevel0StopRadius
PKT_S2C_SetSafeZoneOnMap_s n;
n.useRadius = m_toxicLevel0StopRadius;
p2pBroadcastToAll(&n, sizeof(n), true);

m_preparingToxicZone = -1;
m_spreadToxic = r3dGetTime()+m_toxicLevel0NextLevelTimer;
}

// Airdrop Logic
if (m_spawnAirdrop > 0 && r3dGetTime() > m_spawnAirdrop)
{
obj_ServerPlayer* pl = (obj_ServerPlayer*)GameWorld().GetNetworkObject(LiveID);
SpawnAirdrop(pl);
m_spawnAirdrop = r3dGetTime()+u_GetRandom(m_SpawnAirdropTimeMinimum,m_SpawnAirdropTimeMaximum);
}

//End Battle Royale Match
if ( LivePlayers == 1 && ginfo_.GameHasbeenStarted)
{
int GameDollar = (int)u_GetRandom((float)RewardMoneyMinimum, (float)RewardMoneyMaximum);
obj_ServerPlayer* plr = (obj_ServerPlayer*)GameWorld().GetNetworkObject(LiveID);
if (plr)
{
plr->profile_.ProfileData.GameDollars += GameDollar;
//plr->loadout_->Stats.VictorysHardGames++;

char msg[512]="";
sprintf(msg,"Congratulations to %s! %s won %i GameDollar",plr->loadout_->Gamertag,plr->loadout_->Gamertag,GameDollar);

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);

{
/ @Tobi send package to the winner.
PKT_S2C_SendExitMessage_s n;
n.ShowExitHud = true;
n.Kills = plr->loadout_->Stats.Killstreak;
n.GameDollars = GameDollar;
p2pSendRawToPeer(plr->peerId_, &n, sizeof(n), true);
}

AddPlayerRewardBattleroyale(plr, RewardID);
ApiPlayerUpdateChar(plr);
}

EndMatch();
}
}

// Close Server, becuase our game ended + winner celebration ended! | If noone is on the server and the countdown is bigger than one than instant close it useless to wait!
if (m_resetGameTime > 0 && r3dGetTime() > m_resetGameTime || m_resetGameTime > 0 && curPlayers_ == 0)
{
for (int i = 0; i < curPlayers_; ++i)
{
obj_ServerPlayer* pl = plrList_;
DisconnectPeer(pl->peerId_, false, "The Match has been ended");
return;
}

m_resetGameTime = -1;
ginfo_.GameHasbeenStarted = false;
gMasterServerLogic.SetGameStatusBR(ginfo_.GameHasbeenStarted);

gMasterServerLogic.CloseBRMatch();
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


GO TO:

void SetPVEinfo(DWORD isPVE); // for PVE maps

ADD:

////////Battle Royale Functions////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void SpawnAirdrop(obj_ServerPlayer* plr);
void StartMatch();
void EndMatch();
void StopMatch();
void PrepareToxicZone();

///////////Start/END Timers///////////////
float m_StartGameTime;
float m_StartGameTimeR;
float m_resetmatch;
float m_resetGameTime;
/////////////////////////////////////////

////////TOXIC ZONE////////////////
bool StartSpreadingToxic;
float m_spreadToxic; / @Tobi spread toxic gas
float m_preparingToxicZone;
float m_startspreadingGas; / @Tobi stop spread toxic gas
void UpdateToxicCircle(DWORD index);
void SpawnToxicZone();
int m_toxicLevel;
DWORD m_ToxicIndex;
int EnableToxicGas;
//////////////////////////////////

float m_spawnAirdrop;
int lastNumber;
int countTimeFinish; //gamehardcore
int MaxAirdrop;
bool isBlocked; // used to block player damage and use consumable items in br mode
//////////////////////////////////


// BATTLE ROYALE FUNCTIONS END
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

GO TO:

void ServerGameLogic::DumpPacketStatistics()

ADD UNDER THE FUNCTION:

void ServerGameLogic::StartMatch()
{
for (int i = 0; i < curPlayers_; ++i)
{
obj_ServerPlayer* pl = plrList_;

if(pl->loadout_->Alive == 0) {
pl->ReviveFast();
PKT_C2S_ReviveFast_s Revive;
Revive.PlayerID = toP2pNetId(pl->GetNetworkID());
p2pBroadcastToAll(&Revive, sizeof(Revive), true);
}
}

// Teleport players to their start positions
for (int i = 0; i < curPlayers_; ++i)
{
obj_ServerPlayer* pl = plrList_;
GetStartPositionBattleRoyale(pl);
//Cmd_GiveItem(pl, "/gi 500054"); // we disabled parachute first!

//peerInfo_s& peer = GetPeer(pl->peerId_);
}

ginfo_.GameHasbeenStarted = true;
isBlocked = false;

char msg[512]="";
sprintf(msg,"The game has started.");

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);

countTimeFinish = 0;

{
PKT_S2C_SendGameMessage_s n;
r3dscpy(n.msg, msg);
p2pBroadcastToAll(&n, sizeof(n), true);
}

r3dOutToLog("[Battle Royale] -- Teleported %i players\n", curPlayers_);

gMasterServerLogic.SetGameStatusBR(ginfo_.GameHasbeenStarted);

// Prepare our ToxicZone!
PrepareToxicZone();

// spawn Airdrop tick
m_spawnAirdrop = r3dGetTime()+u_GetRandom(m_SpawnAirdropTimeMinimum,m_SpawnAirdropTimeMaximum);
}

void ServerGameLogic::EndMatch()
{
// reset everything...
{
char msg[512]="";
sprintf(msg,"The Server is going to get restarted in %.f seconds!", m_restartFinishedGameTimer);

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);
}

ginfo_.isGameGoingToStart = 0;
//ginfo_.GameHasbeenStarted = false;
StartSpreadingToxic = false;
m_StartGameTime = 0;//gamehardcore
m_StartGameTimeR = -1;//gamehardcore
countTimeFinish = 0;//gamehardcore
MaxAirdrop = 0;

////////TOXIC ZONE////////////////
m_spreadToxic = -1; / @Tobi spread toxic gas
m_preparingToxicZone = -1;
m_startspreadingGas = 0;
m_toxicLevel = 0;
// m_ToxicIndex = NULL;
/////////////////////////////////

m_resetGameTime = -1;
m_spawnAirdrop = -1;
EnableToxicGas = 0;
isBlocked = false;
m_resetGameTime = r3dGetTime()+m_restartFinishedGameTimer;

{
PKT_S2C_SendToxicTimer_s n;
n.Timer = 0;
n.status = 0;
n.isvisible = 0;
p2pBroadcastToAll(&n, sizeof(n), true);
}
}

void ServerGameLogic::StopMatch()
{
// reset everything...
{
char msg[512]="";
sprintf(msg,"The Game got stopped by an admin!");

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);
}

ginfo_.GameHasbeenStarted = false;
StartSpreadingToxic = false;
ginfo_.isGameGoingToStart = 0;//gamehardcore
m_StartGameTime = 0;//gamehardcore
m_StartGameTimeR = -1;//gamehardcore
countTimeFinish = 0;//gamehardcore
MaxAirdrop = 0;

////////TOXIC ZONE////////////////
m_spreadToxic = -1; / @Tobi spread toxic gas
m_preparingToxicZone = -1;
m_startspreadingGas = 0;
m_toxicLevel = 0;
// m_ToxicIndex = NULL;
//////////////////////////////////

m_resetGameTime = -1;
m_spawnAirdrop = -1;
EnableToxicGas = 0;
isBlocked = false;

{
PKT_S2C_SendToxicTimer_s n;
n.Timer = 0;
n.status = 0;
n.isvisible = 0;
p2pBroadcastToAll(&n, sizeof(n), true);
}

gMasterServerLogic.SetGameStatusBR(ginfo_.GameHasbeenStarted);
}

void ServerGameLogic::prepareToxicZone()
{
{
PKT_S2C_SendToxicTimer_s n;
n.Timer = 30;
n.status = 1;
n.isvisible = 1;
p2pBroadcastToAll(&n, sizeof(n), true);
}

{
char msg[512]="";
sprintf(msg,"Preparing safe zone in 30 seconds!");

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);
}

m_preparingToxicZone = r3dGetTime()+SpawnToxicZoneTimer;
}

void ServerGameLogic::SpawnToxicZone()
{

r3dPoint3D ToxicZoneSpawn(0,0,0);

if (Terrain3)
ToxicZoneSpawn.y = Terrain3->GetHeight(ToxicZoneSpawn);

if (Terrain2)
ToxicZoneSpawn.y = Terrain2->GetHeight(ToxicZoneSpawn);

uint32_t AirDropRand = 1;

if (AirDropsPos.size()>1)
{
AirDropRand = rand() % AirDropsPos.size()+1;
}

ToxicZoneSpawn.x = AirDropsPos[AirDropRand].m_location.x + u_GetRandom(-AirDropsPos[AirDropRand].m_radius,AirDropsPos[AirDropRand].m_radius);
ToxicZoneSpawn.z = AirDropsPos[AirDropRand].m_location.z+ + u_GetRandom(-AirDropsPos[AirDropRand].m_radius,AirDropsPos[AirDropRand].m_radius);

obj_ToxicCircle* toxic = (obj_ToxicCircle*)srv_CreateGameObject("obj_ToxicCircle", "toxic", ToxicZoneSpawn);
toxic->SetNetworkID(GetFreeNetId());
toxic->NetworkLocal = true;
toxic->useRadius = SpawnToxicZoneRadius;
toxic->OnCreate();

gServerLogic.m_ToxicIndex = toxic->GetNetworkID();

{
PKT_S2C_SendToxicTimer_s n;
n.Timer = m_toxicLevel0NextLevelTimer;
n.status = 2;
n.isvisible = 1;
p2pBroadcastToAll(&n, sizeof(n), true);
}

{
char msg[512]="";
sprintf(msg,"Gas will be released in %.f seconds!", m_toxicLevel0NextLevelTimer);

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);
}

return;
}

void ServerGameLogic::SpawnAirdrop(obj_ServerPlayer* plr)
{

wiInventoryItem wi;
wi.itemID = 'ARDR';
wi.quantity = 1;
// create network object
r3dPoint3D AirDropSpawn(0,0,0);

obj_ToxicCircle* tcircle = (obj_ToxicCircle*)GameWorld().GetNetworkObject(m_ToxicIndex);

if (Terrain3)
AirDropSpawn.y = Terrain3->GetHeight(AirDropSpawn)+300.0f;

if (Terrain2)
AirDropSpawn.y = Terrain2->GetHeight(AirDropSpawn)+300.0f;

uint32_t AirDropRand = 1;

if (gServerLogic.AirDropsPos.size()>1)
{
AirDropRand = rand() % AirDropsPos.size()+1;
}

if(tcircle->useRadius <= SpawnToxicZoneRadius) {
AirDropSpawn.x = AirDropsPos[AirDropRand].m_location.x + u_GetRandom(-AirDropsPos[AirDropRand].m_radius,AirDropsPos[AirDropRand].m_radius);
AirDropSpawn.z = AirDropsPos[AirDropRand].m_location.z+ + u_GetRandom(-AirDropsPos[AirDropRand].m_radius,AirDropsPos[AirDropRand].m_radius);
}
else if(tcircle->useRadius <= m_toxicLevel0StopRadius && tcircle->useRadius > m_toxicLevel1StopRadius) {
AirDropSpawn.x = tcircle->GetPosition().x + u_GetRandom(-m_toxicLevel1StopRadius,m_toxicLevel1StopRadius);
AirDropSpawn.z = tcircle->GetPosition().z + u_GetRandom(-m_toxicLevel1StopRadius,m_toxicLevel1StopRadius);
}
else if(tcircle->useRadius <= m_toxicLevel1StopRadius && tcircle->useRadius > m_toxicLevel2StopRadius) {
AirDropSpawn.x = tcircle->GetPosition().x + u_GetRandom(-m_toxicLevel2StopRadius,m_toxicLevel2StopRadius);
AirDropSpawn.z = tcircle->GetPosition().z + u_GetRandom(-m_toxicLevel2StopRadius,m_toxicLevel2StopRadius);
}
else if(tcircle->useRadius <= m_toxicLevel2StopRadius && tcircle->useRadius > m_toxicLevel3StopRadius) {
AirDropSpawn.x = tcircle->GetPosition().x + u_GetRandom(-m_toxicLevel3StopRadius,m_toxicLevel3StopRadius);
AirDropSpawn.z = tcircle->GetPosition().z + u_GetRandom(-m_toxicLevel3StopRadius,m_toxicLevel3StopRadius);
}
else if(tcircle->useRadius <= m_toxicLevel3StopRadius && tcircle->useRadius > m_toxicLevel4StopRadius) {
AirDropSpawn.x = tcircle->GetPosition().x + u_GetRandom(-m_toxicLevel4StopRadius,m_toxicLevel4StopRadius);
AirDropSpawn.z = tcircle->GetPosition().z + u_GetRandom(-m_toxicLevel4StopRadius,m_toxicLevel4StopRadius);
}
else {
AirDropSpawn.x = AirDropsPos[AirDropRand].m_location.x + u_GetRandom(-AirDropsPos[AirDropRand].m_radius,AirDropsPos[AirDropRand].m_radius);
AirDropSpawn.z = AirDropsPos[AirDropRand].m_location.z+ + u_GetRandom(-AirDropsPos[AirDropRand].m_radius,AirDropsPos[AirDropRand].m_radius);
}

obj_DroppedItem* obj = (obj_DroppedItem*)srv_CreateGameObject("obj_DroppedItem", "obj_DroppedItem", AirDropSpawn);
obj->AirDropPos = AirDropSpawn;
obj->UseAirdropConfig = true;
/ @Tobi next patch, let a random number generate between 5-10

/ @Tobi Checken ob das Random Airdrop ist wenn ja adde diesen Loot table 133714
obj->m_LootBoxID1 = 0;
obj->m_LootBoxID2 = 0;
obj->m_LootBoxID3 = 0;
obj->m_LootBoxID4 = 0;
obj->m_LootBoxID5 = 0;
obj->m_LootBoxID6 = 0;
obj->SetPosition(AirDropSpawn);
plr->SetupPlayerNetworkItem(obj);
//obj->NetworkLocal = false;
// vars
obj->m_Item = wi;
obj->m_Item.quantity = 1;

char msg[512]="";

sprintf(msg,"An Airdrop spawned!"); ///

ChatSystemMessageAll(msg, "<AIRDROP>", 1);

return;
}

void ServerGameLogic::UpdateToxicCircle(DWORD index)
{
if(ginfo_.isBattleRoyale() && curPlayers_ >= 1)
{
// @Tobi scan for toxi circles
//for(int i=0; i<gToxicCircleMngr.numToxicCircles_; i++)
//{
obj_ToxicCircle* tcircle = (obj_ToxicCircle*)GameWorld().GetNetworkObject(index); / @Tobi ersteze i gegen eine Zahl um die toxic zone zu setzten, benutze u_getrandom dafür

if(tcircle) {
// Set First Toxic Radius
if(m_toxicLevel == 0 && StartSpreadingToxic == false)
tcircle->useRadius = SpawnToxicZoneRadius;

// spreading radius
if(m_startspreadingGas == 1)
{
StartSpreadingToxic = true;
}

/////////////////////////////////TOXIC LOGIC//////////////////////////////////////////////////
if(tcircle->useRadius <= m_toxicLevel0StopRadius && m_toxicLevel == 0)
{
m_startspreadingGas = 0;
m_toxicLevel = 1;
StartSpreadingToxic = false;

{
PKT_S2C_SendToxicTimer_s n;
n.Timer = m_toxicLevel1NextLevelTimer;
n.status = 2;
n.isvisible = 1;
gServerLogic.p2pBroadcastToAll(&n, sizeof(n), true);
}

{
PKT_S2C_SetSafeZoneOnMap_s n;
n.useRadius = m_toxicLevel1StopRadius;
gServerLogic.p2pBroadcastToAll(&n, sizeof(n), true);
}

{
char msg[512]="";
sprintf(msg,"Next gas zone will be released in %.f seconds!", m_toxicLevel1NextLevelTimer);

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);
}

m_spreadToxic = r3dGetTime()+m_toxicLevel1NextLevelTimer;
}

if(tcircle->useRadius <= m_toxicLevel1StopRadius && m_toxicLevel == 1)
{
m_startspreadingGas = 0;
m_toxicLevel = 2;
StartSpreadingToxic = false;

{
PKT_S2C_SendToxicTimer_s n;
n.Timer = m_toxicLevel2NextLevelTimer;
n.status = 2;
n.isvisible = 1;
p2pBroadcastToAll(&n, sizeof(n), true);
}

{
PKT_S2C_SetSafeZoneOnMap_s n;
n.useRadius = m_toxicLevel2StopRadius;
p2pBroadcastToAll(&n, sizeof(n), true);
}

{
char msg[512]="";
sprintf(msg,"Next gas zone will be released in %.f seconds!", m_toxicLevel2NextLevelTimer);

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);
}

m_spreadToxic = r3dGetTime()+m_toxicLevel2NextLevelTimer;
}

if(tcircle->useRadius <= m_toxicLevel2StopRadius && gServerLogic.m_toxicLevel == 2)
{
m_startspreadingGas = 0;
m_toxicLevel = 3;
StartSpreadingToxic = false;

{
PKT_S2C_SendToxicTimer_s n;
n.Timer = m_toxicLevel3NextLevelTimer;
n.status = 2;
n.isvisible = 1;
p2pBroadcastToAll(&n, sizeof(n), true);
}

{
PKT_S2C_SetSafeZoneOnMap_s n;
n.useRadius = m_toxicLevel3StopRadius;
p2pBroadcastToAll(&n, sizeof(n), true);
}

{
char msg[512]="";
sprintf(msg,"Next gas zone will be released in %.f seconds!", m_toxicLevel3NextLevelTimer);

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);
}

m_spreadToxic = r3dGetTime()+m_toxicLevel3NextLevelTimer;
}

if(tcircle->useRadius <= m_toxicLevel3StopRadius && gServerLogic.m_toxicLevel == 3)
{
m_startspreadingGas = 0;
m_toxicLevel = 4;
StartSpreadingToxic = false;

{
PKT_S2C_SendToxicTimer_s n;
n.Timer = m_toxicLevel4NextLevelTimer;
n.status = 2;
n.isvisible = 1;
p2pBroadcastToAll(&n, sizeof(n), true);
}

{
PKT_S2C_SetSafeZoneOnMap_s n;
n.useRadius = m_toxicLevel4StopRadius;
p2pBroadcastToAll(&n, sizeof(n), true);
}

{
char msg[512]="";
sprintf(msg,"Next gas zone will be released in %.f seconds!", m_toxicLevel4NextLevelTimer);

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);
}

m_spreadToxic = r3dGetTime()+m_toxicLevel4NextLevelTimer;
}

if(tcircle->useRadius <= m_toxicLevel4StopRadius && gServerLogic.m_toxicLevel == 4)
{
m_startspreadingGas = 0;
m_toxicLevel = 5;
StartSpreadingToxic = false;

{
PKT_S2C_SendToxicTimer_s n;
n.Timer = m_toxicLevel5NextLevelTimer;
n.status = 2;
n.isvisible = 1;
p2pBroadcastToAll(&n, sizeof(n), true);
}

{
PKT_S2C_SetSafeZoneOnMap_s n;
n.useRadius = m_toxicLevel5StopRadius;
p2pBroadcastToAll(&n, sizeof(n), true);
}

{
char msg[512]="";
sprintf(msg,"Next gas zone will be released in %.f seconds!", m_toxicLevel5NextLevelTimer);

ChatSystemMessageAll(msg, "<BATTLE ROYALE>", 1);
}

m_spreadToxic = r3dGetTime()+m_toxicLevel5NextLevelTimer;
}

if(tcircle->useRadius <= m_toxicLevel5StopRadius && gServerLogic.m_toxicLevel == 5)
{
m_startspreadingGas = 0;
// m_toxicLevel = 5;
StartSpreadingToxic = false;
}
/////////////////////////////////TOXIC LOGIC END//////////////////////////////////////////////////

if(StartSpreadingToxic) {

if(m_toxicLevel == 0) {
tcircle->useRadius -= m_toxicLevel0DecreaseRadius;
}
if(m_toxicLevel == 1) {
tcircle->useRadius -= m_toxicLevel1DecreaseRadius;
}
if(m_toxicLevel == 2) {
tcircle->useRadius -= m_toxicLevel2DecreaseRadius;
}
if(m_toxicLevel == 3) {
tcircle->useRadius -= m_toxicLevel3DecreaseRadius;
}
if(m_toxicLevel == 4) {
tcircle->useRadius -= m_toxicLevel4DecreaseRadius;
}
if(m_toxicLevel == 5) {
tcircle->useRadius -= m_toxicLevel5DecreaseRadius;
}

//tcircle->UpdateToxicZone(peerId_, tcircle->useRadius);

PKT_S2C_SetToxicZoneRadius_s n;
n.useRadius = tcircle->useRadius;
n.Index = index;
p2pBroadcastToActive(tcircle, &n, sizeof(n));
}
}
}

return;
}

GO TO:

void ServerGameLogic::cleanPlayerGroupInvites(obj_ServerPlayer* plr)

Add:

void ServerGameLogic::LoadBattleRoyaleServerConfigs()
{
MinimumConnectedPlayers = 0;
StartCountDownTimer = 0.0f;
m_restartFinishedGameTimer = 0.0f;
EnoughConnectedPlayersToStartBRFaster1 = 0;
EnoughConnectedPlayersToStartBRFaster2 = 0;
CountdownTime1 = 0.0f;
CountdownTime2 = 0.0f;
RewardID = 0;
RewardMoneyMinimum = 0;
RewardMoneyMaximum = 0;
SpawnToxicZoneTimer = 0.0f;
SpawnToxicZoneRadius = 0.0f;
m_toxicLevel0Damage = 0.0f;
m_toxicLevel1Damage = 0.0f;
m_toxicLevel2Damage = 0.0f;
m_toxicLevel3Damage = 0.0f;
m_toxicLevel4Damage = 0.0f;
m_toxicLevel5Damage = 0.0f;
m_toxicLevel0DecreaseRadius = 0.0f;
m_toxicLevel1DecreaseRadius = 0.0f;
m_toxicLevel2DecreaseRadius = 0.0f;
m_toxicLevel3DecreaseRadius = 0.0f;
m_toxicLevel4DecreaseRadius = 0.0f;
m_toxicLevel5DecreaseRadius = 0.0f;
m_toxicLevel0StopRadius = 0;
m_toxicLevel1StopRadius = 0;
m_toxicLevel2StopRadius = 0;
m_toxicLevel3StopRadius = 0;
m_toxicLevel4StopRadius = 0;
m_toxicLevel5StopRadius = 0;
m_toxicLevel0NextLevelTimer = 0.0f;
m_toxicLevel1NextLevelTimer = 0.0f;
m_toxicLevel2NextLevelTimer = 0.0f;
m_toxicLevel3NextLevelTimer = 0.0f;
m_toxicLevel4NextLevelTimer = 0.0f;
m_toxicLevel5NextLevelTimer = 0.0f;
m_SpawnAirdropTimeMinimum = 0.0f;
m_SpawnAirdropTimeMaximum = 0.0f;

const char* xmlPath = "Data\\ServerConfigs\\BattleRoyaleServerConfigs.xml";

r3dFile* file = r3d_open(xmlPath, "rb");
if (!file)
{
r3dOutToLog("Failed to open Battle Royale Server Configs file: %s\n", xmlPath);
return;
}

char* buffer = game_new char[file->size + 1];
fread(buffer, file->size, 1, file);
buffer[file->size] = 0;

pugi::xml_document xmlDoc;
pugi::xml_parse_result parseResult = xmlDoc.load_buffer_inplace(buffer, file->size);
fclose(file);

if (!parseResult)
r3dError("Failed to parse Battle Royale Server Configs XML file, error: %s", parseResult.description());

pugi::xml_node configs = xmlDoc.child("configs");
pugi::xml_node players = configs.child("MinPlayers");
pugi::xml_node lobby = configs.child("startCountDown");
pugi::xml_node faster1 = configs.child("ForwardStartCountdown1");
pugi::xml_node faster2 = configs.child("ForwardStartCountdown2");
pugi::xml_node preparetoxiczone = configs.child("PrepareToxicZone");
pugi::xml_node spawntoxiczone = configs.child("SpawnToxicZone");
pugi::xml_node airdrop = configs.child("Airdrop");
pugi::xml_node m_toxicLevel0 = configs.child("m_toxicLevel0");
pugi::xml_node m_toxicLevel1 = configs.child("m_toxicLevel1");
pugi::xml_node m_toxicLevel2 = configs.child("m_toxicLevel2");
pugi::xml_node m_toxicLevel3 = configs.child("m_toxicLevel3");
pugi::xml_node m_toxicLevel4 = configs.child("m_toxicLevel4");
pugi::xml_node m_toxicLevel5 = configs.child("m_toxicLevel5");
pugi::xml_node restart = configs.child("restart");
pugi::xml_node winnerReward = configs.child("winnerReward");

MinimumConnectedPlayers = players.attribute("players").as_int();
StartCountDownTimer = lobby.attribute("countdowntime").as_float();
m_restartFinishedGameTimer = restart.attribute("time").as_float();
EnoughConnectedPlayersToStartBRFaster1 = faster1.attribute("players").as_int();
EnoughConnectedPlayersToStartBRFaster2 = faster2.attribute("players").as_int();
CountdownTime1 = faster1.attribute("countdowntime").as_float();
CountdownTime2 = faster2.attribute("countdowntime").as_float();
RewardID = winnerReward.attribute("ID").as_int();
RewardMoneyMinimum = winnerReward.attribute("RandomMoneyMinimum").as_int();
RewardMoneyMaximum = winnerReward.attribute("RandomMoneyMaximum").as_int();

// toxic zone settings
SpawnToxicZoneTimer = spawntoxiczone.attribute("spawntimer").as_float();
SpawnToxicZoneRadius = spawntoxiczone.attribute("spawnradius").as_float();
m_toxicLevel0Damage = m_toxicLevel0.attribute("damage").as_float();
m_toxicLevel1Damage = m_toxicLevel1.attribute("damage").as_float();
m_toxicLevel2Damage = m_toxicLevel2.attribute("damage").as_float();
m_toxicLevel3Damage = m_toxicLevel3.attribute("damage").as_float();
m_toxicLevel4Damage = m_toxicLevel4.attribute("damage").as_float();
m_toxicLevel5Damage = m_toxicLevel5.attribute("damage").as_float();
m_toxicLevel0DecreaseRadius = m_toxicLevel0.attribute("decreaseradius").as_float();
m_toxicLevel1DecreaseRadius = m_toxicLevel1.attribute("decreaseradius").as_float();
m_toxicLevel2DecreaseRadius = m_toxicLevel2.attribute("decreaseradius").as_float();
m_toxicLevel3DecreaseRadius = m_toxicLevel3.attribute("decreaseradius").as_float();
m_toxicLevel4DecreaseRadius = m_toxicLevel4.attribute("decreaseradius").as_float();
m_toxicLevel5DecreaseRadius = m_toxicLevel5.attribute("decreaseradius").as_float();
m_toxicLevel0StopRadius = m_toxicLevel0.attribute("stopradius").as_float();
m_toxicLevel1StopRadius = m_toxicLevel1.attribute("stopradius").as_float();
m_toxicLevel2StopRadius = m_toxicLevel2.attribute("stopradius").as_float();
m_toxicLevel3StopRadius = m_toxicLevel3.attribute("stopradius").as_float();
m_toxicLevel4StopRadius = m_toxicLevel4.attribute("stopradius").as_float();
m_toxicLevel5StopRadius = m_toxicLevel5.attribute("stopradius").as_float();
m_toxicLevel0NextLevelTimer = m_toxicLevel0.attribute("nextleveltimer").as_float();
m_toxicLevel1NextLevelTimer = m_toxicLevel1.attribute("nextleveltimer").as_float();
m_toxicLevel2NextLevelTimer = m_toxicLevel2.attribute("nextleveltimer").as_float();
m_toxicLevel3NextLevelTimer = m_toxicLevel3.attribute("nextleveltimer").as_float();
m_toxicLevel4NextLevelTimer = m_toxicLevel4.attribute("nextleveltimer").as_float();
m_toxicLevel5NextLevelTimer = m_toxicLevel5.attribute("nextleveltimer").as_float();

// Airdrop Settings
m_SpawnAirdropTimeMinimum = airdrop.attribute("SpawnTimeMinimum").as_float();
m_SpawnAirdropTimeMaximum = airdrop.attribute("SpawnTimeMaximum").as_float();

delete [] buffer;

r3dOutToLog("Battle Royale Server Configs has been loaded with: %d minimum of players.\n", MinimumConnectedPlayers);
}

AND ADD:

void ServerGameLogic::GiveBattleRoyaleLobbyLoadout(obj_ServerPlayer* plr)
{
battleRoyaleLobbyItemsCount = 0;

const char* xmlPath = "Data\\ServerConfigs\\BattleRoyaleLobbyLoadout.xml";

r3dFile* file = r3d_open(xmlPath, "rb");
if (!file)
{
r3dOutToLog("Failed to open Battle Royale Lobby Loadout configuration file: %s\n", xmlPath);
return;
}

char* buffer = game_new char[file->size + 1];
fread(buffer, file->size, 1, file);
buffer[file->size] = 0;

pugi::xml_document xmlDoc;
pugi::xml_parse_result parseResult = xmlDoc.load_buffer_inplace(buffer, file->size);
fclose(file);

if (!parseResult)
r3dError("Failed to parse Battle Royale Lobby Loadout XML file, error: %s", parseResult.description());

pugi::xml_node Configs = xmlDoc.child("Configs");

char LoadLoadout[128];

sprintf(LoadLoadout, "loadout%.i", (int)u_GetRandom(1, Configs.attribute("Loadouts").as_float()));

pugi::xml_node loadout = Configs.child(LoadLoadout);

pugi::xml_node item = loadout.child("item");

battleRoyaleLobbyItemsCount = -1;
while (item)
{
wiInventoryItem tempItem;
tempItem.InventoryID = 0;
tempItem.itemID = item.attribute("id").as_uint();
tempItem.quantity = item.attribute("qty").as_int();

battleRoyaleLobbyItems[++battleRoyaleLobbyItemsCount] = tempItem;

item = item.next_sibling();
}

delete [] buffer;

r3dOutToLog("Battle Royale Lobby Loadout configuration has been loaded with: %d items.\n", battleRoyaleLobbyItemsCount+1);

int useIndex = 0;
for (int i = 0; i < battleRoyaleLobbyItemsCount+1; ++i)
{
wiInventoryItem tempItem;
tempItem.InventoryID = useIndex+1;
tempItem.itemID = battleRoyaleLobbyItems.itemID;
tempItem.quantity = battleRoyaleLobbyItems.quantity;
plr->BackpackAddItem(tempItem);
}
}


GO TO:

int devEventBackpackId;

ADD:

wiInventoryItem battleRoyaleLobbyItems[72];
int battleRoyaleLobbyItemsCount;

// Battle Royale Configs
int MinimumConnectedPlayers;
float StartCountDownTimer;
float m_restartFinishedGameTimer;
// used for lobby system
int EnoughConnectedPlayersToStartBRFaster1;
int EnoughConnectedPlayersToStartBRFaster2;
float CountdownTime1;
float CountdownTime2;

// winner reward ID
int RewardID;
int RewardMoneyMinimum;
int RewardMoneyMaximum;

// Airdrop Settings
float m_SpawnAirdropTimeMinimum;
float m_SpawnAirdropTimeMaximum;

public:
// Toxic Zone Settings
float SpawnToxicZoneTimer;
float SpawnToxicZoneRadius;
float m_toxicLevel0Damage;
float m_toxicLevel1Damage;
float m_toxicLevel2Damage;
float m_toxicLevel3Damage;
float m_toxicLevel4Damage;
float m_toxicLevel5Damage;
float m_toxicLevel0DecreaseRadius;
float m_toxicLevel1DecreaseRadius;
float m_toxicLevel2DecreaseRadius;
float m_toxicLevel3DecreaseRadius;
float m_toxicLevel4DecreaseRadius;
float m_toxicLevel5DecreaseRadius;
float m_toxicLevel0StopRadius;
float m_toxicLevel1StopRadius;
float m_toxicLevel2StopRadius;
float m_toxicLevel3StopRadius;
float m_toxicLevel4StopRadius;
float m_toxicLevel5StopRadius;
float m_toxicLevel0NextLevelTimer;
float m_toxicLevel1NextLevelTimer;
float m_toxicLevel2NextLevelTimer;
float m_toxicLevel3NextLevelTimer;
float m_toxicLevel4NextLevelTimer;
float m_toxicLevel5NextLevelTimer;

// Battle royale Configs
void LoadBattleRoyaleServerConfigs();

GO TO:

void DisconnectCheatPeer(DWORD peerId, const char* message);

ADD:

void DisconnectBRGamePeer(DWORD peerId);

AND THE FUNCTION:

void CSupervisorGameServer::DisconnectBRGamePeer(DWORD peerId)
{
r3dOutToLog("Battle Royale Match ended at peer %d\n", peerId);
net_->DisconnectPeer(peerId);

// fire up disconnect event manually, enet might skip if if other peer disconnect as well
OnNetPeerDisconnected(peerId);
}

DONT FORGET TO DECLARE THAT BOTH THINGS HERE:

// USED FOR BATTLE ROYALE
BYTE isGameGoingToStart;
bool GameHasbeenStarted;

AND IN:

GBGameInfo()
{

ADD:

// Battle Royale
isGameGoingToStart = 0;
GameHasbeenStarted = false;

IF SOMEONE WANTS THAT BOTH FUNCTIONS FOR THE CHAT:

void ServerGameLogic::ChatSystemMessageAll(const char* msg, const char* tag, int msgChannel, int userflag, int isServerMessage)
{
r3d_assert(msg);

PKT_C2C_ChatSystemMessage_s n;
n.userFlag = userflag;
n.msgChannel = msgChannel;
n.isServerMessage = isServerMessage;
r3dscpy(n.msg, msg);
r3dscpy(n.gamertag, tag);
p2pBroadcastToAll(&n, sizeof(n), true);
}

void ServerGameLogic::ChatSystemMessagePeer(const obj_ServerPlayer* plr, const char* msg, const char* tag, int msgChannel, int userflag, int isServerMessage)
{
r3d_assert(plr);
r3d_assert(msg);

PKT_C2C_ChatSystemMessage_s n;
n.FromID = toP2pNetId(plr->GetNetworkID());
n.userFlag = userflag;
n.msgChannel = msgChannel;
n.isServerMessage = isServerMessage;
r3dscpy(n.msg, msg);
r3dscpy(n.gamertag, tag);
p2pSendToPeer(plr->peerId_, plr, &n, sizeof(n), 1);
}

void ServerGameLogic::GetStartPositionBattleRoyale(obj_ServerPlayer* plr)
{
float posX, posY, posZ;

BasePlayerSpawnPoint* curSpawn;

// Get all spawnpoints
int numSpawns = 0;

for (int i = 0; i < gCPMgr.numControlPoints_; i++)
{
curSpawn = gCPMgr.controlPoints_;
for (int j = 0; j < curSpawn->m_NumSpawnPoints; j++)
{
numSpawns++;
}
}


for (int i = 0; i < gCPMgr.numControlPoints_; i++)
{
if(gCPMgr.controlPoints_->spawnType_ == 1)
curSpawn = gCPMgr.controlPoints_;


int j = rand() % curSpawn->m_NumSpawnPoints;
posX = curSpawn->m_SpawnPoints[j].pos.x;
//posY = 400.0f; Also we disabled spawn in the air for parachute!
posY = curSpawn->m_SpawnPoints[j].pos.y;
posZ = curSpawn->m_SpawnPoints[j].pos.z;
admin_TeleportPlayer(plr, posX, posY, posZ);
break;
}

return;
}

NOW MASTERSERVER poop:

GO TO:

case SBPKT_G2M_CloseGame:

ADD:

case SBPKT_G2M_ShutdownBRGame:
DisconnectBRGamePeer(peerId);
break;

GO TO:

void MasterServerLogic::AddPlayer(int playerIdx, DWORD CustomerID, const wiCharDataFull* loadout)

Add:


void MasterServerLogic::CloseBRMatch()
{
SBPKT_G2M_ShutdownBRGame_s n(gameId_);
net_->SendToHost(&n, sizeof(n), true);

return;
}

DECLARE IT, GO TO:

SBPKT_G2M_CloseGame, // close session

ADD:

SBPKT_G2M_ShutdownBRGame, // close session

GO TO:

struct SBPKT_G2M_CloseGame_s : public r3dNetPacketMixin<SBPKT_G2M_CloseGame>


ADD:

struct SBPKT_G2M_ShutdownBRGame_s : public r3dNetPacketMixin<SBPKT_G2M_ShutdownBRGame>
{
DEFINE_GAME_RELAYING_PACKET(SBPKT_G2M_ShutdownBRGame_s)
};


NOW THE CLIENT:

GO TO:

float obj_PlayerSpawnPoint::DrawPropertyEditor(float scrx, float scry, float scrw, float scrh, const AClass* startClass, const GameObjects& selected)
{

FIND:

if( !names.size() )
{

and change it to:

if( !names.size() )
{
names.push_back( "LOBBY (Used for Battle Royale)" );
names.push_back( "NEUTRAL" );
}

GO TO:
static bool SortGamesByModeDec(const GBPKT_M2C_GameData_s& g1, const GBPKT_M2C_GameData_s& g2) {

ADD:

// battle royale sort if game started or not
static bool SortGamesByGameStatus(const GBPKT_M2C_GameData_s& g1, const GBPKT_M2C_GameData_s& g2) {
return g1.info.GameHasbeenStarted==g2.info.GameHasbeenStarted; }

GO TO:

void ClientGameLogic::Reset()

ADD:

// Battle Royale Stuff //
isGameStarted = 0;
ToxicTimer = 0.0f;
isToxicVisible = 0;
ToxicZoneStatus = 0;
////////////////////////

GO TO:

IMPL_PACKET_FUNC(ClientGameLogic, PKT_S2C_PlayerNameJoined)

ADD ONLY IF YOU NEED THAT AND ITS NOT THE BEST ACTUALLY!:

//for battle royale
if(m_gameInfo.isBattleRoyale()) {
obj_Player* plr = gClientLogic().localPlayer_;
int Players = 0;
for(int i=0; i<R3D_ARRAYSIZE(playerNames); i++)
{
if(playerNames.Gamertag[0])
{
Players++;
}
}

int waitingForPlayers = plr->BRMaxPlayers-Players;
char text[512];
if(waitingForPlayers > 0) {
sprintf(text,"%s joined the Game! [%i/%i]", n.gamertag, Players, plr->BRMaxPlayers-Players);
}
else {
sprintf(text,"%s joined the Game! [%i/%i]", n.gamertag, Players, Players);
}
hudMain->showGameMessage(text);
}

THAT COULD HELP YOU:

int isvisible = gClientLogic().isToxicVisible;
if(isBattleRoyale && gClientLogic().ToxicZoneStatus > 0)
{
float Time = gClientLogic().ToxicTimer - r3dGetTime();
char toxicold[128];
char toxic[128];
char safezone[128];

if(gClientLogic().ToxicZoneStatus == 1) {
if(Time >= 60) {
float Minutes = Time / gClientLogic().ToxicTimer;
int Seconds = (int)Time % (int)gClientLogic().ToxicTimer;
if(Seconds < 10) {
sprintf(toxic, "Preparing Safe Zone in %.f:0%i", Minutes, Seconds);
sprintf(toxicold, toxic);
}
else {
sprintf(toxic, "Preparing Safe Zone in %.f:%i", Minutes, Seconds);
sprintf(toxicold, toxic);
}
}
else {
sprintf(toxic, "Preparing Safe Zone in %.f", Time);
sprintf(toxicold, toxic);
}
}
if(gClientLogic().ToxicZoneStatus == 2) {

//Play Sound Effect for Releasing Gas Zone
if(Time <= 5)
SoundSys.PlayAndForget(SoundSys.GetEventIDByPath("Sounds/WarZ/BR_Sounds/alarm"), gClientLogic().localPlayer_->GetPosition());

if(Time >= 60 && Time < 120) {
float Minutes = Time / 60;
int Seconds = (int)Time % 60;
if(Seconds < 10) {
sprintf(toxic, "Gas Advance in %.f:0%i", Minutes, Seconds);
sprintf(toxicold, toxic);
}
else {
sprintf(toxic, "Gas Advance in %.f:%i", Minutes, Seconds);
sprintf(toxicold, toxic);
}
}
else if(Time >= 120) {
float Minutes = Time / 120;
int Seconds = (int)Time % 120;
if(Seconds < 10) {
sprintf(toxic, "Gas Advance in %.f:0%i", Minutes, Seconds);
sprintf(toxicold, toxic);
}
else {
sprintf(toxic, "Gas Advance in %.f:%i", Minutes, Seconds);
sprintf(toxicold, toxic);
}
}
else {
sprintf(toxic, "Gas Advance in %.f", Time);
sprintf(toxicold, toxic);
}
}
if(gClientLogic().ToxicZoneStatus == 3) {
sprintf(toxic, "Gas is spreading!");
sprintf(toxicold, toxic);
}

if(toxicold != toxic)
hudMain->setToxicText(toxic, isvisible?1:0);

//Tobi Safezone stats for br mode
if(!ShowToxicZoneEffect)
sprintf(safezone, "SAFEZONE RADIUS: %.f | DISTANCE TO SAFEZONE: IN SAFEZONE", ToxicRadius);
else
sprintf(safezone, "SAFEZONE RADIUS: %.f | DISTANCE TO SAFEZONE: %.f meters", ToxicRadius, m_ToxicDistanceToPlayer);

//sprintf(safezone, "SAFEZONE RADIUS: %.f | DISTANCE TO SAFEZONE: %.f meters", ToxicRadius, m_ToxicDistanceToPlayer);

hudMain->setBRStats(safezone, gClientLogic().ToxicZoneStatus>1);
}
else {
if(isvisible == 1) {
hudMain->setToxicText("", false);
hudMain->setBRStats("", false);
}
}

PACKAGES:

IMPL_PACKET_FUNC(ClientGameLogic, PKT_S2C_SendExitMessage)
{
hudMain->showYouSurvived(n.Kills, n.GameDollars);
}

IMPL_PACKET_FUNC(ClientGameLogic, PKT_S2C_SendToxicTimer)
{
ToxicTimer = r3dGetTime() + n.Timer;
ToxicZoneStatus = n.status;
isToxicVisible = n.isvisible;
}

IMPL_PACKET_FUNC(ClientGameLogic, PKT_S2C_SetToxicZoneRadius)
{
obj_Player* plr = gClientLogic().localPlayer_;

plr->ToxicRadius = n.useRadius;
}

IMPL_PACKET_FUNC(ClientGameLogic, PKT_S2C_SetSafeZoneOnMap)
{
obj_Player* plr = gClientLogic().localPlayer_;

hudPause->setSafeZoneOnMap(n.useRadius);
}


IMPL_PACKET_FUNC(ClientGameLogic, PKT_S2C_CreateToxicZone)
{
//r3dOutToLog("obj_DroppedItem %d %d\n", n.spawnID, n.Item.itemID);
r3d_assert(GameWorld().GetNetworkObject(n.spawnID) == NULL);

obj_Player* plr = gClientLogic().localPlayer_;

obj_ToxicCircle* obj = (obj_ToxicCircle*)srv_CreateGameObject("obj_ToxicCircle", "obj_ToxicCircle", n.pos);
obj->SetNetworkID(n.spawnID);
plr->ToxicRadius = n.radius;
obj->OnCreate();

plr->m_ToxicNetID = obj->GetNetworkID();
}

IMPL_PACKET_FUNC(ClientGameLogic, PKT_S2C_ResetPlayerLoadoutBR)
{
GameObject* targetObj = GameWorld().GetNetworkObject(n.PlayerID);
if(!targetObj)
return;

obj_Player* targetPlr = (obj_Player*)targetObj;
if (!targetPlr)
return;

targetPlr->ResetLoadoutBR();
}

IMPL_PACKET_FUNC(ClientGameLogic, PKT_S2C_UpdateBRStats)
{
playerNames[n.playerIdx].Alive = n.alive;
}

DONT FORGET TO DECLARE:

bool isBattleRoyale; //gamehardcore
static const int BRMaxPlayers=5;//BattleRoyale
float ToxicRadius;
bool ShowToxicZoneEffect;
float m_ToxicDistanceToPlayer;

GO TO:

void obj_PlayerSpawnPoint::DoDrawComposite( const r3dCamera& Cam )

ADD:
if(spawnType_ == SPAWN_LOBBY) clr = r3dColor(0, 0, 255);

CHANGE RIGHT UNDER: D3DXVec3TransformNormal(&tempV, &tempV2, &tempM);

if(spawnType_ == SPAWN_LOBBY)
r3dDrawCircle3D(m_SpawnPoints.pos, 2.0f, Cam, 0.4f, ((i==m_SelectedSpawnPoint&&g_Manipulator3d.PickedObject() == this)?r3dColor24::red:r3dColor24::blue));
else
r3dDrawCircle3D(m_SpawnPoints.pos, 2.0f, Cam, 0.4f, ((i==m_SelectedSpawnPoint&&g_Manipulator3d.PickedObject() == this)?r3dColor24::red:r3dColor24::grey));



ADD SERVER CONFIG FILES:

BattleRoyaleAirdropLoadout:

<?xml version="1.0"?>
<!-- Configs Loadouts="N" is Important for our u_GetRandom(1, Configs.attribute("Loadouts").as_float()) -->
<Configs Loadouts="1">
<loadout1>
<item id="101172" />
<item id="20015" />
</loadout1>
</Configs>

BattleRoyaleLobbyLoadout:
<?xml version="1.0"?>
<!-- Configs Loadouts="N" is Important for our u_GetRandom(1, Configs.attribute("Loadouts").as_float()) -->
<Configs Loadouts="6">
<loadout1>
<item id="101172" qty="1" /> <!-- secondary weapon//Sig 226 Pistol -->
<item id="101262" qty="20" /> <!-- quickbar: item 2 // Bandage DX -->
<item id="101304" qty="1" /> <!-- quickbar: item 3 // MedKit -->
<item id="101318" qty="10" /> <!-- quickbar: item 4 // Riot Shield -->
<item id="101315" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="20015" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="20006" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="400016" qty="10" /> <!-- quickbar: item 1 // Binoculars -->
</loadout1>
<loadout2>
<item id="101173" qty="1" /> <!-- secondary weapon//Sig 226 Pistol -->
<item id="101262" qty="20" /> <!-- quickbar: item 2 // Bandage DX -->
<item id="101304" qty="1" /> <!-- quickbar: item 3 // MedKit -->
<item id="101318" qty="10" /> <!-- quickbar: item 4 // Riot Shield -->
<item id="101315" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="20015" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="20006" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="400016" qty="10" /> <!-- quickbar: item 1 // Binoculars -->
</loadout2>
<loadout3>
<item id="101084" qty="1" /> <!-- secondary weapon//Sig 226 Pistol -->
<item id="101262" qty="20" /> <!-- quickbar: item 2 // Bandage DX -->
<item id="101304" qty="1" /> <!-- quickbar: item 3 // MedKit -->
<item id="101318" qty="10" /> <!-- quickbar: item 4 // Riot Shield -->
<item id="101315" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="20015" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="20006" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="400016" qty="10" /> <!-- quickbar: item 1 // Binoculars -->
</loadout3>
<loadout4>
<item id="101088" qty="1" /> <!-- secondary weapon//Sig 226 Pistol -->
<item id="101262" qty="20" /> <!-- quickbar: item 2 // Bandage DX -->
<item id="101304" qty="1" /> <!-- quickbar: item 3 // MedKit -->
<item id="101318" qty="10" /> <!-- quickbar: item 4 // Riot Shield -->
<item id="101315" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="20015" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="20006" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="400016" qty="10" /> <!-- quickbar: item 1 // Binoculars -->
</loadout4>
<loadout5>
<item id="101210" qty="1" /> <!-- secondary weapon//Sig 226 Pistol -->
<item id="101262" qty="20" /> <!-- quickbar: item 2 // Bandage DX -->
<item id="101304" qty="1" /> <!-- quickbar: item 3 // MedKit -->
<item id="101318" qty="10" /> <!-- quickbar: item 4 // Riot Shield -->
<item id="101315" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="20015" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="20006" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="400016" qty="10" /> <!-- quickbar: item 1 // Binoculars -->
</loadout5>
<loadout6>
<item id="101210" qty="1" /> <!-- secondary weapon//Sig 226 Pistol -->
<item id="101262" qty="20" /> <!-- quickbar: item 2 // Bandage DX -->
<item id="101304" qty="1" /> <!-- quickbar: item 3 // MedKit -->
<item id="101318" qty="10" /> <!-- quickbar: item 4 // Riot Shield -->
<item id="101315" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="20015" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="20006" qty="1" /> <!-- quickbar: item 1 // Binoculars -->
<item id="400016" qty="10" /> <!-- quickbar: item 1 // Binoculars -->
</loadout6>
</Configs>

BattleRoyaleServerConfigs:
<?xml version="1.0"?>
<configs>
<!-- Timers are in seconds! -->
<!-- Minimun of Connected Players to start Battle Royale -->
<MinPlayers players="5" />
<!-- wait countdown is 5 minutes atm -->
<startCountDown countdowntime="300" />
<!-- Start faster lobby system logic if we have enough players -->
<ForwardStartCountdown1 players="10" countdowntime="120" />
<ForwardStartCountdown2 players="20" countdowntime="60" />
<!-- SpawnToxicZone - spawntimer means time how long need to wait for spawning toxic zone; spawnradius = spawn radius -->
<SpawnToxicZone spawntimer="30" spawnradius="1000" />
<!-- Airdrop - spawn airdrop works like this u_GetRandom(SpawnTimeMinimum, SpawnTimeMaximum) -->
<Airdrop SpawnTimeMinimum="120" SpawnTimeMaximum="200" />
<!-- we got 6 different types of toxiczones! -->
<!-- damage each server tick; decreaseradius each server tick; nextleveltimer to wait for next zone level; stopradius = stop spreading toxic at this radius -->
<m_toxicLevel0 damage="0.01" decreaseradius="0.1" stopradius="400" nextleveltimer="90" />
<m_toxicLevel1 damage="0.02" decreaseradius="0.05" stopradius="250" nextleveltimer="90" />
<m_toxicLevel2 damage="0.025" decreaseradius="0.03" stopradius="150" nextleveltimer="60" />
<m_toxicLevel3 damage="0.04" decreaseradius="0.02" stopradius="75" nextleveltimer="60" />
<m_toxicLevel4 damage="0.06" decreaseradius="0.01" stopradius="25" nextleveltimer="90" />
<m_toxicLevel5 damage="0.08" decreaseradius="0.01" stopradius="0" nextleveltimer="120" />
<!-- time of restart server after a game -->
<restart time="60" />
<!-- winner reward ItemID - 800139 = Battle Royale CASEID / Random money works like this u_GetRandom(RandomMoneyMinimum, RandomMoneyMaximum) -->
<winnerReward ID="101172" RandomMoneyMinimum="500000" RandomMoneyMaximum="1000000" />
</configs>
 

Attachments

You must be registered for see attachments list
Last edited:
Junior Spellweaver
Joined
Oct 25, 2017
Messages
158
Reaction score
17
Re: [Battle Royale] - 90% finished

Great work!
 
Newbie Spellweaver
Joined
Oct 6, 2016
Messages
60
Reaction score
76
Release swarm.. :D
Fred like this (Y) :sneaky2:
 
Back
Top