Initial work on FFA in network
This commit is contained in:
parent
c8c0e599db
commit
64595a7b18
@ -1,6 +1,8 @@
|
||||
## SuperTuxKart 0.9.4
|
||||
* Networking game for normal race, time trial, free for all, capture the flag and soccer
|
||||
* Better random item distribution for various numbers of karts
|
||||
* Improved powerup handling in AI
|
||||
* New tracks Las Dunas Soccer by samuncle
|
||||
|
||||
## SuperTuxKart 0.9.3
|
||||
* Reduced RAM and VRAM usage, reducing load times by Auria and Benau
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
|
||||
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
|
@ -574,7 +574,8 @@ void Flyable::explode(AbstractKart *kart_hit, PhysicalObject *object,
|
||||
ExplosionAnimation::create(kart, getXYZ(), kart==kart_hit);
|
||||
if(kart==kart_hit && Track::getCurrentTrack()->isArena())
|
||||
{
|
||||
world->kartHit(kart->getWorldKartId());
|
||||
world->kartHit(kart->getWorldKartId(),
|
||||
m_owner->getWorldKartId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -377,7 +377,8 @@ void Swatter::squashThingsAround()
|
||||
if (m_closest_kart->isSquashed())
|
||||
{
|
||||
// The kart may not be squashed if it was protected by a bubblegum shield
|
||||
World::getWorld()->kartHit(m_closest_kart->getWorldKartId());
|
||||
World::getWorld()->kartHit(m_closest_kart->getWorldKartId(),
|
||||
m_kart->getWorldKartId());
|
||||
}
|
||||
|
||||
// TODO: squash items
|
||||
|
@ -61,13 +61,10 @@
|
||||
#include "karts/rescue_animation.hpp"
|
||||
#include "karts/skidding.hpp"
|
||||
#include "main_loop.hpp"
|
||||
#include "modes/overworld.hpp"
|
||||
#include "modes/soccer_world.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "modes/capture_the_flag.hpp"
|
||||
#include "modes/linear_world.hpp"
|
||||
#include "modes/overworld.hpp"
|
||||
#include "modes/soccer_world.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/race_event_manager.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
@ -1026,11 +1023,17 @@ void Kart::setRaceResult()
|
||||
}
|
||||
}
|
||||
else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_FOLLOW_LEADER ||
|
||||
race_manager->getMinorMode() == RaceManager::MINOR_MODE_BATTLE)
|
||||
race_manager->getMajorMode() == RaceManager::MAJOR_MODE_3_STRIKES)
|
||||
{
|
||||
// the kart wins if it isn't eliminated
|
||||
m_race_result = !this->isEliminated();
|
||||
}
|
||||
else if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_FREE_FOR_ALL)
|
||||
{
|
||||
// the top kart wins
|
||||
FreeForAll* ffa = dynamic_cast<FreeForAll*>(World::getWorld());
|
||||
m_race_result = ffa->getKartAtPosition(1) == this;
|
||||
}
|
||||
else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
|
||||
{
|
||||
SoccerWorld* sw = dynamic_cast<SoccerWorld*>(World::getWorld());
|
||||
|
34
src/modes/capture_the_flag.cpp
Normal file
34
src/modes/capture_the_flag.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2018 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "modes/capture_the_flag.hpp"
|
||||
|
||||
#include "network/network_config.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Constructor. Sets up the clock mode etc.
|
||||
*/
|
||||
CaptureTheFlag::CaptureTheFlag() : FreeForAll()
|
||||
{
|
||||
|
||||
} // CaptureTheFlag
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
CaptureTheFlag::~CaptureTheFlag()
|
||||
{
|
||||
} // ~CaptureTheFlag
|
36
src/modes/capture_the_flag.hpp
Normal file
36
src/modes/capture_the_flag.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2018 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef CAPTURE_THE_FLAG_HPP
|
||||
#define CAPTURE_THE_FLAG_HPP
|
||||
|
||||
#include "modes/free_for_all.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class CaptureTheFlag : public FreeForAll
|
||||
{
|
||||
private:
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
CaptureTheFlag();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual ~CaptureTheFlag();
|
||||
}; // CaptureTheFlag
|
||||
|
||||
#endif
|
189
src/modes/free_for_all.cpp
Normal file
189
src/modes/free_for_all.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2018 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "modes/free_for_all.hpp"
|
||||
#include "karts/kart.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/protocols/game_events_protocol.hpp"
|
||||
#include "network/stk_host.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Constructor. Sets up the clock mode etc.
|
||||
*/
|
||||
FreeForAll::FreeForAll() : WorldWithRank()
|
||||
{
|
||||
if (race_manager->hasTimeTarget())
|
||||
{
|
||||
WorldStatus::setClockMode(WorldStatus::CLOCK_COUNTDOWN,
|
||||
race_manager->getTimeTarget());
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldStatus::setClockMode(CLOCK_CHRONO);
|
||||
}
|
||||
} // FreeForAll
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
FreeForAll::~FreeForAll()
|
||||
{
|
||||
} // ~FreeForAll
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void FreeForAll::init()
|
||||
{
|
||||
WorldWithRank::init();
|
||||
m_display_rank = false;
|
||||
m_count_down_reached_zero = false;
|
||||
} // init
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called when a battle is restarted.
|
||||
*/
|
||||
void FreeForAll::reset()
|
||||
{
|
||||
WorldWithRank::reset();
|
||||
if (race_manager->hasTimeTarget())
|
||||
{
|
||||
WorldStatus::setClockMode(WorldStatus::CLOCK_COUNTDOWN,
|
||||
race_manager->getTimeTarget());
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldStatus::setClockMode(CLOCK_CHRONO);
|
||||
}
|
||||
m_scores.clear();
|
||||
m_scores.resize(m_karts.size(), 0);
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called when the match time ends.
|
||||
*/
|
||||
void FreeForAll::countdownReachedZero()
|
||||
{
|
||||
// Prevent negative time in network soccer when finishing
|
||||
m_time_ticks = 0;
|
||||
m_time = 0.0f;
|
||||
m_count_down_reached_zero = true;
|
||||
} // countdownReachedZero
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called when a kart is hit.
|
||||
* \param kart_id The world kart id of the kart that was hit.
|
||||
* \param hitter The world kart id of the kart who hit(-1 if none).
|
||||
*/
|
||||
void FreeForAll::kartHit(int kart_id, int hitter)
|
||||
{
|
||||
if (NetworkConfig::get()->isNetworking() &&
|
||||
NetworkConfig::get()->isClient())
|
||||
return;
|
||||
|
||||
if (isRaceOver()) return;
|
||||
|
||||
NetworkString p(PROTOCOL_GAME_EVENTS);
|
||||
p.setSynchronous(true);
|
||||
p.addUInt8(GameEventsProtocol::GE_BATTLE_KART_SCORE);
|
||||
if (kart_id == hitter || hitter == -1)
|
||||
p.addUInt8((uint8_t)kart_id).addUInt32(--m_scores[kart_id]);
|
||||
else
|
||||
p.addUInt8((uint8_t)hitter).addUInt32(++m_scores[hitter]);
|
||||
STKHost::get()->sendPacketToAllPeers(&p, true);
|
||||
} // kartHit
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void FreeForAll::setKartScoreFromServer(NetworkString& ns)
|
||||
{
|
||||
int kart_id = ns.getUInt8();
|
||||
int score = ns.getUInt32();
|
||||
m_scores.at(kart_id) = score;
|
||||
} // setKartScoreFromServer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the internal identifier for this race.
|
||||
*/
|
||||
const std::string& FreeForAll::getIdent() const
|
||||
{
|
||||
return IDENT_STRIKES;
|
||||
} // getIdent
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void FreeForAll::update(int ticks)
|
||||
{
|
||||
WorldWithRank::update(ticks);
|
||||
WorldWithRank::updateTrack(ticks);
|
||||
|
||||
std::vector<std::pair<int, int> > ranks;
|
||||
for (unsigned i = 0; i < m_scores.size(); i++)
|
||||
ranks.emplace_back(i, m_scores[i]);
|
||||
std::sort(ranks.begin(), ranks.end(),
|
||||
[](const std::pair<int, int>& a, const std::pair<int, int>& b)
|
||||
{
|
||||
return a.second > b.second;
|
||||
});
|
||||
beginSetKartPositions();
|
||||
for (unsigned i = 0; i < ranks.size(); i++)
|
||||
setKartPosition(ranks[i].first, i + 1);
|
||||
endSetKartPositions();
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** The battle is over if only one kart is left, or no player kart.
|
||||
*/
|
||||
bool FreeForAll::isRaceOver()
|
||||
{
|
||||
if (NetworkConfig::get()->isNetworking() &&
|
||||
NetworkConfig::get()->isClient())
|
||||
return false;
|
||||
|
||||
if (!getKartAtPosition(1))
|
||||
return false;
|
||||
int top_id = getKartAtPosition(1)->getWorldKartId();
|
||||
return (m_count_down_reached_zero && race_manager->hasTimeTarget()) ||
|
||||
m_scores[top_id] >= race_manager->getHitCaptureLimit();
|
||||
} // isRaceOver
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the data to display in the race gui.
|
||||
*/
|
||||
void FreeForAll::getKartsDisplayInfo(
|
||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info)
|
||||
{
|
||||
const unsigned int kart_amount = getNumKarts();
|
||||
for (unsigned int i = 0; i < kart_amount ; i++)
|
||||
{
|
||||
RaceGUIBase::KartIconDisplayInfo& rank_info = (*info)[i];
|
||||
rank_info.lap = -1;
|
||||
rank_info.m_outlined_font = true;
|
||||
rank_info.m_text = m_karts[i]->getController()->getName() + L" (" +
|
||||
StringUtils::toWString(m_scores[i]) + L")";
|
||||
}
|
||||
} // getKartsDisplayInfo
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void FreeForAll::terminateRace()
|
||||
{
|
||||
const unsigned int kart_amount = getNumKarts();
|
||||
for (unsigned int i = 0; i < kart_amount ; i++)
|
||||
{
|
||||
m_karts[i]->finishedRace(0.0f, true/*from_server*/);
|
||||
} // i<kart_amount
|
||||
WorldWithRank::terminateRace();
|
||||
} // terminateRace
|
68
src/modes/free_for_all.hpp
Normal file
68
src/modes/free_for_all.hpp
Normal file
@ -0,0 +1,68 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2018 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef FREE_FOR_ALL_HPP
|
||||
#define FREE_FOR_ALL_HPP
|
||||
|
||||
#include "modes/world_with_rank.hpp"
|
||||
#include "states_screens/race_gui_base.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class NetworkString;
|
||||
|
||||
class FreeForAll : public WorldWithRank
|
||||
{
|
||||
private:
|
||||
bool m_count_down_reached_zero;
|
||||
|
||||
std::vector<int> m_scores;
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
FreeForAll();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual ~FreeForAll();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void init() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool isRaceOver() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void reset() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void getKartsDisplayInfo(
|
||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool raceHasLaps() OVERRIDE { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual const std::string& getIdent() const OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void kartHit(int kart_id, int hitter = -1) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void update(int ticks) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void countdownReachedZero() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void terminateRace() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
void setKartScoreFromServer(NetworkString& ns);
|
||||
// ------------------------------------------------------------------------
|
||||
int getKartScore(int kart_id) const { return m_scores.at(kart_id); }
|
||||
|
||||
}; // FreeForAll
|
||||
|
||||
|
||||
#endif
|
@ -207,8 +207,9 @@ void ThreeStrikesBattle::kartAdded(AbstractKart* kart, scene::ISceneNode* node)
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called when a kart is hit.
|
||||
* \param kart_id The world kart id of the kart that was hit.
|
||||
* \param hitter The world kart id of the kart who hit(-1 if none).
|
||||
*/
|
||||
void ThreeStrikesBattle::kartHit(const unsigned int kart_id)
|
||||
void ThreeStrikesBattle::kartHit(int kart_id, int hitter)
|
||||
{
|
||||
if (isRaceOver()) return;
|
||||
|
||||
@ -221,7 +222,7 @@ void ThreeStrikesBattle::kartHit(const unsigned int kart_id)
|
||||
return;
|
||||
}
|
||||
|
||||
assert(kart_id < m_karts.size());
|
||||
assert(kart_id < (int)m_karts.size());
|
||||
// make kart lose a life, ignore if in profiling mode
|
||||
if (!UserConfigParams::m_arena_ai_stats)
|
||||
m_kart_info[kart_id].m_lives--;
|
||||
@ -256,7 +257,7 @@ void ThreeStrikesBattle::kartHit(const unsigned int kart_id)
|
||||
{
|
||||
AbstractKart * const kart = getKart(i);
|
||||
if(kart->isEliminated() || kart->hasFinishedRace() ||
|
||||
kart->getWorldKartId()==kart_id) continue;
|
||||
kart->getWorldKartId()==(unsigned)kart_id) continue;
|
||||
if(m_kart_info[i].m_lives > max_lives)
|
||||
{
|
||||
leader = kart;
|
||||
@ -270,7 +271,7 @@ void ThreeStrikesBattle::kartHit(const unsigned int kart_id)
|
||||
for(unsigned int i=0; i<Camera::getNumCameras(); i++)
|
||||
{
|
||||
Camera *camera = Camera::getCamera(i);
|
||||
if(camera->getKart()->getWorldKartId()==kart_id)
|
||||
if(camera->getKart()->getWorldKartId()==(unsigned)kart_id)
|
||||
{
|
||||
camera->setMode(Camera::CM_NORMAL);
|
||||
camera->setKart(leader);
|
||||
|
@ -111,7 +111,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
virtual const std::string& getIdent() const OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void kartHit(const unsigned int kart_id) OVERRIDE;
|
||||
virtual void kartHit(int kart_id, int hitter = -1) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void update(int ticks) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -268,7 +268,7 @@ public:
|
||||
virtual void newLap(unsigned int kart_index) {}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called when a kart was hit by a projectile. */
|
||||
virtual void kartHit(const unsigned int kart_id) {};
|
||||
virtual void kartHit(int kart_id, int hitter = -1) {};
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void onMouseClick(int x, int y) {};
|
||||
|
||||
|
@ -100,8 +100,14 @@ void GameSetup::loadWorld()
|
||||
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER ||
|
||||
race_manager->getMinorMode() == RaceManager::MINOR_MODE_BATTLE)
|
||||
{
|
||||
const bool is_ctf = race_manager->getMajorMode() ==
|
||||
RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG;
|
||||
bool prev_val = UserConfigParams::m_random_arena_item;
|
||||
UserConfigParams::m_random_arena_item = m_reverse;
|
||||
if (is_ctf)
|
||||
UserConfigParams::m_random_arena_item = false;
|
||||
else
|
||||
UserConfigParams::m_random_arena_item = m_reverse;
|
||||
|
||||
race_manager->setReverseTrack(false);
|
||||
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
|
||||
{
|
||||
@ -110,6 +116,11 @@ void GameSetup::loadWorld()
|
||||
else
|
||||
race_manager->setTimeTarget((float)m_laps * 60.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
race_manager->setHitCaptureTime(m_hit_capture_limit,
|
||||
m_battle_time_limit);
|
||||
}
|
||||
race_manager->startSingleRace(m_tracks.back(), -1,
|
||||
false/*from_overworld*/);
|
||||
UserConfigParams::m_random_arena_item = prev_val;
|
||||
|
@ -54,6 +54,10 @@ private:
|
||||
|
||||
int m_extra_server_info;
|
||||
|
||||
int m_hit_capture_limit;
|
||||
|
||||
float m_battle_time_limit;
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
GameSetup()
|
||||
@ -114,6 +118,8 @@ public:
|
||||
m_tracks.clear();
|
||||
m_laps = 0;
|
||||
m_reverse = false;
|
||||
m_hit_capture_limit = 0;
|
||||
m_battle_time_limit = 0.0f;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void setGrandPrixTrack(int tracks_no) { m_extra_server_info = tracks_no; }
|
||||
@ -159,6 +165,12 @@ public:
|
||||
void sortPlayersForGrandPrix();
|
||||
// ------------------------------------------------------------------------
|
||||
void sortPlayersForSoccer();
|
||||
// ------------------------------------------------------------------------
|
||||
void setHitCaptureTime(int hc, float time)
|
||||
{
|
||||
m_hit_capture_limit = hc;
|
||||
m_battle_time_limit = time;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
@ -239,6 +239,12 @@ void ClientLobby::addAllPlayers(Event* event)
|
||||
}
|
||||
uint32_t random_seed = data.getUInt32();
|
||||
ItemManager::updateRandomSeed(random_seed);
|
||||
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_BATTLE)
|
||||
{
|
||||
int hit_capture_limit = data.getUInt32();
|
||||
float time_limit = data.getFloat();
|
||||
m_game_setup->setHitCaptureTime(hit_capture_limit, time_limit);
|
||||
}
|
||||
configRemoteKart(players);
|
||||
loadWorld();
|
||||
// Switch to assign mode in case a player hasn't chosen any karts
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "network/protocols/game_events_protocol.hpp"
|
||||
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "modes/free_for_all.hpp"
|
||||
#include "modes/soccer_world.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/game_setup.hpp"
|
||||
@ -44,6 +45,7 @@ bool GameEventsProtocol::notifyEvent(Event* event)
|
||||
return true;
|
||||
}
|
||||
uint8_t type = data.getUInt8();
|
||||
FreeForAll* ffa = dynamic_cast<FreeForAll*>(World::getWorld());
|
||||
SoccerWorld* sw = dynamic_cast<SoccerWorld*>(World::getWorld());
|
||||
switch (type)
|
||||
{
|
||||
@ -65,6 +67,13 @@ bool GameEventsProtocol::notifyEvent(Event* event)
|
||||
sw->handlePlayerGoalFromServer(data);
|
||||
break;
|
||||
}
|
||||
case GE_BATTLE_KART_SCORE:
|
||||
{
|
||||
if (!ffa)
|
||||
throw std::invalid_argument("No free for all world");
|
||||
ffa->setKartScoreFromServer(data);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Log::warn("GameEventsProtocol", "Unkown message type.");
|
||||
break;
|
||||
|
@ -14,7 +14,8 @@ public:
|
||||
GE_KART_FINISHED_RACE = 1,
|
||||
GE_PLAYER_DISCONNECT = 2,
|
||||
GE_RESET_BALL = 3,
|
||||
GE_PLAYER_GOAL = 4
|
||||
GE_PLAYER_GOAL = 4,
|
||||
GE_BATTLE_KART_SCORE = 5
|
||||
}; // GameEventType
|
||||
private:
|
||||
void eliminatePlayer(const NetworkString &ns);
|
||||
|
@ -250,7 +250,8 @@ void ServerLobby::handleChat(Event* event)
|
||||
//-----------------------------------------------------------------------------
|
||||
void ServerLobby::changeTeam(Event* event)
|
||||
{
|
||||
if (!NetworkConfig::get()->hasTeamChoosing())
|
||||
if (!NetworkConfig::get()->hasTeamChoosing() ||
|
||||
!race_manager->teamEnabled())
|
||||
return;
|
||||
if (!checkDataSize(event, 1)) return;
|
||||
NetworkString& data = event->data();
|
||||
@ -508,6 +509,12 @@ void ServerLobby::asynchronousUpdate()
|
||||
uint32_t random_seed = (uint32_t)StkTime::getTimeSinceEpoch();
|
||||
ItemManager::updateRandomSeed(random_seed);
|
||||
load_world->addUInt32(random_seed);
|
||||
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_BATTLE)
|
||||
{
|
||||
auto hcl = getHitCaptureLimit((float)players.size());
|
||||
load_world->addUInt32(hcl.first).addFloat(hcl.second);
|
||||
m_game_setup->setHitCaptureTime(hcl.first, hcl.second);
|
||||
}
|
||||
configRemoteKart(players);
|
||||
|
||||
// Reset for next state usage
|
||||
@ -798,11 +805,12 @@ void ServerLobby::startSelection(const Event *event)
|
||||
}
|
||||
}
|
||||
|
||||
if (NetworkConfig::get()->hasTeamChoosing())
|
||||
auto players = m_game_setup->getConnectedPlayers();
|
||||
const unsigned player_count = players.size();
|
||||
if (NetworkConfig::get()->hasTeamChoosing() && race_manager->teamEnabled())
|
||||
{
|
||||
int red_count = 0;
|
||||
int blue_count = 0;
|
||||
auto players = m_game_setup->getConnectedPlayers();
|
||||
for (auto& player : players)
|
||||
{
|
||||
if (player->getTeam() == SOCCER_TEAM_RED)
|
||||
@ -812,7 +820,7 @@ void ServerLobby::startSelection(const Event *event)
|
||||
if (red_count != 0 && blue_count != 0)
|
||||
break;
|
||||
}
|
||||
if ((red_count == 0 || blue_count == 0) && players.size() != 1)
|
||||
if ((red_count == 0 || blue_count == 0) && player_count != 1)
|
||||
{
|
||||
Log::warn("ServerLobby", "Bad team choosing.");
|
||||
NetworkString* bt = getNetworkString();
|
||||
@ -856,6 +864,22 @@ void ServerLobby::startSelection(const Event *event)
|
||||
m_available_kts.second.erase(track_erase);
|
||||
}
|
||||
|
||||
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_BATTLE &&
|
||||
race_manager->getMajorMode() == RaceManager::MAJOR_MODE_FREE_FOR_ALL)
|
||||
{
|
||||
auto it = m_available_kts.second.begin();
|
||||
while (it != m_available_kts.second.end())
|
||||
{
|
||||
Track* t = track_manager->getTrack(*it);
|
||||
if (t->getMaxArenaPlayers() < player_count)
|
||||
{
|
||||
it = m_available_kts.second.erase(it);
|
||||
}
|
||||
else
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
const auto& all_k = m_available_kts.first;
|
||||
const auto& all_t = m_available_kts.second;
|
||||
ns->addUInt16((uint16_t)all_k.size()).addUInt16((uint16_t)all_t.size());
|
||||
@ -1508,7 +1532,8 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr<STKPeer> peer,
|
||||
(peer, i == 0 && !online_name.empty() ? online_name : name,
|
||||
peer->getHostId(), default_kart_color, i == 0 ? online_id : 0,
|
||||
per_player_difficulty, (uint8_t)i, SOCCER_TEAM_NONE);
|
||||
if (NetworkConfig::get()->hasTeamChoosing())
|
||||
if (NetworkConfig::get()->hasTeamChoosing() &&
|
||||
race_manager->teamEnabled())
|
||||
player->setTeam((SoccerTeam)(peer->getHostId() % 2));
|
||||
peer->addPlayer(player);
|
||||
}
|
||||
@ -1570,7 +1595,7 @@ void ServerLobby::updatePlayerList(bool force_update)
|
||||
pl->addUInt8(server_owner);
|
||||
pl->addUInt8(profile->getPerPlayerDifficulty());
|
||||
if (NetworkConfig::get()->hasTeamChoosing() &&
|
||||
race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
|
||||
race_manager->teamEnabled())
|
||||
pl->addUInt8(profile->getTeam());
|
||||
else
|
||||
pl->addUInt8(SOCCER_TEAM_NONE);
|
||||
@ -1807,6 +1832,47 @@ std::tuple<std::string, uint8_t, bool, bool> ServerLobby::handleVote()
|
||||
true : false);
|
||||
} // handleVote
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
std::pair<int, float> ServerLobby::getHitCaptureLimit(float num_karts)
|
||||
{
|
||||
// Read user_config.hpp for formula
|
||||
int hit_capture_limit = std::numeric_limits<int>::max();
|
||||
float time_limit = 0.0f;
|
||||
if (race_manager->getMajorMode() ==
|
||||
RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG)
|
||||
{
|
||||
if (UserConfigParams::m_capture_limit_threshold > 0.0f)
|
||||
{
|
||||
float val = fmaxf(2.0f, num_karts *
|
||||
UserConfigParams::m_capture_limit_threshold);
|
||||
hit_capture_limit = (int)val;
|
||||
}
|
||||
if (UserConfigParams::m_time_limit_threshold_ctf > 0.0f)
|
||||
{
|
||||
time_limit = fmaxf(2.0f, num_karts *
|
||||
(UserConfigParams::m_time_limit_threshold_ctf +
|
||||
UserConfigParams::m_flag_return_timemout / 60.f) * 60.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UserConfigParams::m_hit_limit_threshold > 0.0f)
|
||||
{
|
||||
float val = fminf(num_karts *
|
||||
UserConfigParams::m_hit_limit_threshold, 40.0f);
|
||||
hit_capture_limit = (int)val;
|
||||
if (hit_capture_limit == 0)
|
||||
hit_capture_limit = 1;
|
||||
}
|
||||
if (UserConfigParams::m_time_limit_threshold_ffa > 0.0f)
|
||||
{
|
||||
time_limit = fmaxf(num_karts *
|
||||
UserConfigParams::m_time_limit_threshold_ffa, 2.0f) * 60.0f;
|
||||
}
|
||||
}
|
||||
return std::make_pair(hit_capture_limit, time_limit);
|
||||
} // getHitCaptureLimit
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called from the RaceManager of the server when the world is loaded. Marks
|
||||
* the server to be ready to start the race.
|
||||
|
@ -219,7 +219,7 @@ private:
|
||||
double scalingValueForTime(double time);
|
||||
void checkRaceFinished();
|
||||
void sendBadConnectionMessageToPeer(std::shared_ptr<STKPeer> p);
|
||||
|
||||
std::pair<int, float> getHitCaptureLimit(float num_karts);
|
||||
public:
|
||||
ServerLobby();
|
||||
virtual ~ServerLobby();
|
||||
|
@ -32,10 +32,12 @@
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "modes/capture_the_flag.hpp"
|
||||
#include "modes/cutscene_world.hpp"
|
||||
#include "modes/demo_world.hpp"
|
||||
#include "modes/easter_egg_hunt.hpp"
|
||||
#include "modes/follow_the_leader.hpp"
|
||||
#include "modes/free_for_all.hpp"
|
||||
#include "modes/overworld.hpp"
|
||||
#include "modes/profile_world.hpp"
|
||||
#include "modes/standard_race.hpp"
|
||||
@ -523,7 +525,14 @@ void RaceManager::startNextRace()
|
||||
else if(m_minor_mode==MINOR_MODE_TUTORIAL)
|
||||
World::setWorld(new TutorialWorld());
|
||||
else if(m_minor_mode==MINOR_MODE_BATTLE)
|
||||
World::setWorld(new ThreeStrikesBattle());
|
||||
{
|
||||
if (m_major_mode == MAJOR_MODE_3_STRIKES)
|
||||
World::setWorld(new ThreeStrikesBattle());
|
||||
else if (m_major_mode == MAJOR_MODE_FREE_FOR_ALL)
|
||||
World::setWorld(new FreeForAll());
|
||||
else if (m_major_mode == MAJOR_MODE_CAPTURE_THE_FLAG)
|
||||
World::setWorld(new CaptureTheFlag());
|
||||
}
|
||||
else if(m_minor_mode==MINOR_MODE_SOCCER)
|
||||
World::setWorld(new SoccerWorld());
|
||||
else if(m_minor_mode==MINOR_MODE_OVERWORLD)
|
||||
@ -919,7 +928,8 @@ void RaceManager::startSingleRace(const std::string &track_ident,
|
||||
|
||||
if (num_laps != -1) setNumLaps( num_laps );
|
||||
|
||||
setMajorMode(RaceManager::MAJOR_MODE_SINGLE);
|
||||
if (m_minor_mode != MINOR_MODE_BATTLE)
|
||||
setMajorMode(RaceManager::MAJOR_MODE_SINGLE);
|
||||
|
||||
setCoinTarget( 0 ); // Might still be set from a previous challenge
|
||||
|
||||
|
@ -849,6 +849,12 @@ public:
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
int getHitCaptureLimit() const { return m_hit_capture_limit; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool teamEnabled() const
|
||||
{
|
||||
return m_minor_mode == MINOR_MODE_SOCCER ||
|
||||
m_major_mode == MAJOR_MODE_CAPTURE_THE_FLAG;
|
||||
}
|
||||
|
||||
}; // RaceManager
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
using namespace irr;
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
@ -381,8 +382,10 @@ void RaceGUI::drawGlobalTimer()
|
||||
bool use_digit_font = true;
|
||||
|
||||
float elapsed_time = World::getWorld()->getTime();
|
||||
if (!race_manager->hasTimeTarget() || race_manager
|
||||
->getMinorMode()==RaceManager::MINOR_MODE_SOCCER)
|
||||
if (!race_manager->hasTimeTarget() ||
|
||||
race_manager ->getMinorMode()==RaceManager::MINOR_MODE_SOCCER ||
|
||||
race_manager->getMajorMode() == RaceManager::MAJOR_MODE_FREE_FOR_ALL ||
|
||||
race_manager->getMajorMode() == RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG)
|
||||
{
|
||||
sw = core::stringw (
|
||||
StringUtils::timeToString(elapsed_time).c_str() );
|
||||
@ -710,6 +713,28 @@ void RaceGUI::drawRank(const AbstractKart *kart,
|
||||
float min_ratio, int meter_width,
|
||||
int meter_height, float dt)
|
||||
{
|
||||
static video::SColor color = video::SColor(255, 255, 255, 255);
|
||||
// Draw hit or capture limit in network game
|
||||
if ((race_manager->getMajorMode() == RaceManager::MAJOR_MODE_FREE_FOR_ALL ||
|
||||
race_manager->getMajorMode() == RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG) &&
|
||||
race_manager->getHitCaptureLimit() != std::numeric_limits<int>::max())
|
||||
{
|
||||
gui::ScalableFont* font = GUIEngine::getHighresDigitFont();
|
||||
font->setScale(min_ratio * 1.0f);
|
||||
font->setShadow(video::SColor(255, 128, 0, 0));
|
||||
std::ostringstream oss;
|
||||
oss << race_manager->getHitCaptureLimit();
|
||||
|
||||
core::recti pos;
|
||||
pos.LowerRightCorner = core::vector2di(int(offset.X + 0.64f*meter_width),
|
||||
int(offset.Y - 0.49f*meter_height));
|
||||
pos.UpperLeftCorner = core::vector2di(int(offset.X + 0.64f*meter_width),
|
||||
int(offset.Y - 0.49f*meter_height));
|
||||
|
||||
font->draw(oss.str().c_str(), pos, color, true, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw rank
|
||||
WorldWithRank *world = dynamic_cast<WorldWithRank*>(World::getWorld());
|
||||
if (!world || !world->displayRank())
|
||||
@ -775,7 +800,6 @@ void RaceGUI::drawRank(const AbstractKart *kart,
|
||||
pos.UpperLeftCorner = core::vector2di(int(offset.X + 0.64f*meter_width),
|
||||
int(offset.Y - 0.49f*meter_height));
|
||||
|
||||
static video::SColor color = video::SColor(255, 255, 255, 255);
|
||||
font->draw(oss.str().c_str(), pos, color, true, true);
|
||||
font->setScale(1.0f);
|
||||
} // drawRank
|
||||
|
@ -845,14 +845,21 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_kart_display_infos[kart_id].m_text.size() > 0)
|
||||
if (info.m_text.size() > 0)
|
||||
{
|
||||
core::rect<s32> pos(x+ICON_PLAYER_WIDTH, y+5,
|
||||
x+ICON_PLAYER_WIDTH, y+5);
|
||||
core::stringw s=info.m_text.c_str();
|
||||
|
||||
font->draw(s.c_str(), pos, info.m_color, false, false, NULL,
|
||||
true /* ignore RTL */);
|
||||
if (info.m_outlined_font)
|
||||
{
|
||||
GUIEngine::getOutlineFont()->draw(info.m_text, pos,
|
||||
GUIEngine::getSkin()->getColor("font::normal"), false,
|
||||
false, NULL, true/*ignore RTL*/);
|
||||
}
|
||||
else
|
||||
{
|
||||
font->draw(info.m_text, pos, info.m_color, false, false, NULL,
|
||||
true/*ignore RTL*/);
|
||||
}
|
||||
}
|
||||
|
||||
if (info.special_title.size() > 0)
|
||||
|
@ -66,6 +66,8 @@ public:
|
||||
|
||||
/** Current lap of this kart, or -1 if irrelevant. */
|
||||
int lap;
|
||||
|
||||
bool m_outlined_font = false;
|
||||
}; // KartIconDisplayInfo
|
||||
|
||||
private:
|
||||
|
@ -42,9 +42,9 @@
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "modes/cutscene_world.hpp"
|
||||
#include "modes/demo_world.hpp"
|
||||
#include "modes/free_for_all.hpp"
|
||||
#include "modes/overworld.hpp"
|
||||
#include "modes/soccer_world.hpp"
|
||||
#include "modes/world_with_rank.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/stk_host.hpp"
|
||||
#include "network/protocols/client_lobby.hpp"
|
||||
@ -523,6 +523,7 @@ void RaceResultGUI::backToLobby()
|
||||
m_width_kart_name = 0;
|
||||
float max_finish_time = 0;
|
||||
|
||||
FreeForAll* ffa = dynamic_cast<FreeForAll*>(World::getWorld());
|
||||
for (unsigned int position = first_position;
|
||||
position <= race_manager->getNumberOfKarts() - sta; position++)
|
||||
{
|
||||
@ -543,6 +544,13 @@ void RaceResultGUI::backToLobby()
|
||||
{
|
||||
ri->m_finish_time_string = core::stringw(_("Eliminated"));
|
||||
}
|
||||
else if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_FREE_FOR_ALL ||
|
||||
race_manager->getMajorMode() == RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG)
|
||||
{
|
||||
assert(ffa);
|
||||
ri->m_finish_time_string =
|
||||
StringUtils::toWString(ffa->getKartScore(kart->getWorldKartId()));
|
||||
}
|
||||
else
|
||||
{
|
||||
const float time = kart->getFinishTime();
|
||||
|
Loading…
x
Reference in New Issue
Block a user