Make flag a rewinder
It remove the capturing delay and allow ctf in local splitscreen
This commit is contained in:
parent
14389925fe
commit
d6946198c5
@ -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/*")
|
||||
|
@ -23,9 +23,12 @@
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
#include "modes/ctf_flag.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/protocols/game_events_protocol.hpp"
|
||||
#include "network/rewind_info.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
#include "network/server_config.hpp"
|
||||
#include "network/stk_host.hpp"
|
||||
#include "physics/triangle_mesh.hpp"
|
||||
@ -35,8 +38,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
const Vec3 g_kart_flag_offset(0.0, 0.2f, -0.5f);
|
||||
const float g_capture_length = 3.0f;
|
||||
const float g_capture_length = 2.0f;
|
||||
const int g_captured_score = 10;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -80,8 +82,15 @@ CaptureTheFlag::~CaptureTheFlag()
|
||||
void CaptureTheFlag::init()
|
||||
{
|
||||
FreeForAll::init();
|
||||
m_orig_red_trans = Track::getCurrentTrack()->getRedFlag();
|
||||
m_orig_blue_trans = Track::getCurrentTrack()->getBlueFlag();
|
||||
const btTransform& orig_red = Track::getCurrentTrack()->getRedFlag();
|
||||
const btTransform& orig_blue = Track::getCurrentTrack()->getBlueFlag();
|
||||
m_red_flag = std::make_shared<CTFFlag>(FC_RED, orig_red);
|
||||
m_blue_flag = std::make_shared<CTFFlag>(FC_BLUE, orig_blue);
|
||||
if (NetworkConfig::get()->isNetworking())
|
||||
{
|
||||
m_red_flag->rewinderAdd();
|
||||
m_blue_flag->rewinderAdd();
|
||||
}
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
m_red_flag_node = irr_driver->addAnimatedMesh(m_red_flag_mesh, "red_flag");
|
||||
@ -96,13 +105,13 @@ void CaptureTheFlag::init()
|
||||
file_manager->getAsset(FileManager::GUI_ICON, "blue_arrow.png");
|
||||
|
||||
m_red_flag_indicator = irr_driver->addBillboard(
|
||||
core::dimension2df(1.5f, 1.5f), red_path, NULL);
|
||||
core::dimension2df(1.5f, 1.5f), red_path, NULL);
|
||||
m_red_flag_indicator->setPosition(Vec3(
|
||||
m_orig_red_trans(Vec3(0.0f, 2.5f, 0.0f))).toIrrVector());
|
||||
orig_red(Vec3(0.0f, 2.5f, 0.0f))).toIrrVector());
|
||||
m_blue_flag_indicator = irr_driver->addBillboard(
|
||||
core::dimension2df(1.5f, 1.5f), blue_path, NULL);
|
||||
core::dimension2df(1.5f, 1.5f), blue_path, NULL);
|
||||
m_blue_flag_indicator->setPosition(Vec3(
|
||||
m_orig_blue_trans(Vec3(0.0f, 2.5f, 0.0f))).toIrrVector());
|
||||
orig_blue(Vec3(0.0f, 2.5f, 0.0f))).toIrrVector());
|
||||
#endif
|
||||
} // init
|
||||
|
||||
@ -110,53 +119,85 @@ void CaptureTheFlag::init()
|
||||
void CaptureTheFlag::reset(bool restart)
|
||||
{
|
||||
FreeForAll::reset(restart);
|
||||
m_red_trans = m_orig_red_trans;
|
||||
m_blue_trans = m_orig_blue_trans;
|
||||
m_red_return_ticks = m_blue_return_ticks = m_red_scores =
|
||||
m_blue_scores = 0;
|
||||
m_red_holder = m_blue_holder = -1;
|
||||
updateFlagNodes();
|
||||
m_red_scores = m_blue_scores = 0;
|
||||
m_swatter_reset_kart_ticks.clear();
|
||||
m_last_captured_flag_ticks = 0;
|
||||
m_red_flag_status = m_blue_flag_status = CTFFlag::IN_BASE;
|
||||
m_red_flag->resetToBase();
|
||||
m_blue_flag->resetToBase();
|
||||
#ifndef SERVER_ONLY
|
||||
if (m_red_flag_node)
|
||||
m_red_flag->updateFlagGraphics(m_red_flag_node);
|
||||
if (m_blue_flag_node)
|
||||
m_blue_flag->updateFlagGraphics(m_blue_flag_node);
|
||||
#endif
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CaptureTheFlag::updateGraphics(float dt)
|
||||
{
|
||||
FreeForAll::updateGraphics(dt);
|
||||
if (!NetworkConfig::get()->isNetworking() ||
|
||||
NetworkConfig::get()->isClient())
|
||||
{
|
||||
if (m_red_holder != -1)
|
||||
{
|
||||
m_red_trans = getKart(m_red_holder)->getSmoothedTrans();
|
||||
m_red_trans.setOrigin(m_red_trans(g_kart_flag_offset));
|
||||
m_red_flag_node->setAnimationSpeed(fabsf(getKart(m_red_holder)
|
||||
->getSpeed()) * 3.0f + 25.0f);
|
||||
}
|
||||
else
|
||||
m_red_flag_node->setAnimationSpeed(25.0f);
|
||||
|
||||
if (m_blue_holder != -1)
|
||||
#ifndef SERVER_ONLY
|
||||
if (m_red_flag_node)
|
||||
m_red_flag->updateFlagGraphics(m_red_flag_node);
|
||||
if (m_blue_flag_node)
|
||||
m_blue_flag->updateFlagGraphics(m_blue_flag_node);
|
||||
if (m_red_flag_indicator)
|
||||
m_red_flag_indicator->setVisible(!m_red_flag->isInBase());
|
||||
if (m_blue_flag_indicator)
|
||||
m_blue_flag_indicator->setVisible(!m_blue_flag->isInBase());
|
||||
|
||||
core::stringw msg;
|
||||
// Don't show flag has been returned message if there was scored event
|
||||
// happening recently
|
||||
const bool scored_recently =
|
||||
getTicksSinceStart() > m_last_captured_flag_ticks &&
|
||||
getTicksSinceStart() - m_last_captured_flag_ticks < 200;
|
||||
if (m_red_flag_status != m_red_flag->getStatus())
|
||||
{
|
||||
if (m_red_flag->getHolder() != -1)
|
||||
{
|
||||
m_blue_trans = getKart(m_blue_holder)->getSmoothedTrans();
|
||||
m_blue_trans.setOrigin(m_blue_trans(g_kart_flag_offset));
|
||||
m_blue_flag_node->setAnimationSpeed(fabsf(getKart(m_blue_holder)
|
||||
->getSpeed()) * 3.0f + 25.0f);
|
||||
AbstractKart* kart = getKart(m_red_flag->getHolder());
|
||||
const core::stringw& name = kart->getController()->getName();
|
||||
// I18N: Show when a player gets the red flag in CTF
|
||||
msg = _("%s has the red flag!", name);
|
||||
if (kart->getController()->isLocalPlayerController())
|
||||
SFXManager::get()->quickSound("wee");
|
||||
}
|
||||
else
|
||||
m_blue_flag_node->setAnimationSpeed(25.0f);
|
||||
m_red_flag_indicator->setVisible(!isRedFlagInBase());
|
||||
m_blue_flag_indicator->setVisible(!isBlueFlagInBase());
|
||||
else if (m_red_flag->isInBase() && !scored_recently)
|
||||
{
|
||||
// I18N: Show when the red flag is returned to its base in CTF
|
||||
msg = _("The red flag has returned!");
|
||||
}
|
||||
m_red_flag_status = m_red_flag->getStatus();
|
||||
}
|
||||
else if (m_blue_flag_status != m_blue_flag->getStatus())
|
||||
{
|
||||
if (m_blue_flag->getHolder() != -1)
|
||||
{
|
||||
AbstractKart* kart = getKart(m_blue_flag->getHolder());
|
||||
const core::stringw& name = kart->getController()->getName();
|
||||
// I18N: Show when a player gets the blue flag in CTF
|
||||
msg = _("%s has the blue flag!", name);
|
||||
if (kart->getController()->isLocalPlayerController())
|
||||
SFXManager::get()->quickSound("wee");
|
||||
}
|
||||
else if (m_blue_flag->isInBase() && !scored_recently)
|
||||
{
|
||||
// I18N: Show when the blue flag is returned to its base in CTF
|
||||
msg = _("The blue flag has returned!");
|
||||
}
|
||||
m_blue_flag_status = m_blue_flag->getStatus();
|
||||
}
|
||||
if (!msg.empty())
|
||||
m_race_gui->addMessage(msg, NULL, 1.5f);
|
||||
#endif
|
||||
} // updateGraphics
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CaptureTheFlag::update(int ticks)
|
||||
{
|
||||
if (m_red_holder != -1 && m_blue_holder != -1 &&
|
||||
m_red_holder == m_blue_holder)
|
||||
Log::fatal("CaptureTheFlag", "Flag management messed up, abort.");
|
||||
|
||||
FreeForAll::update(ticks);
|
||||
|
||||
for (auto it = m_swatter_reset_kart_ticks.begin();
|
||||
@ -189,88 +230,61 @@ void CaptureTheFlag::update(int ticks)
|
||||
}
|
||||
}
|
||||
|
||||
if (!NetworkConfig::get()->isNetworking() ||
|
||||
NetworkConfig::get()->isClient())
|
||||
return;
|
||||
|
||||
// Update new flags position
|
||||
if (m_red_holder != -1)
|
||||
{
|
||||
m_red_trans = getKart(m_red_holder)->getTrans();
|
||||
m_red_trans.setOrigin(m_red_trans(g_kart_flag_offset));
|
||||
}
|
||||
if (m_blue_holder != -1)
|
||||
{
|
||||
m_blue_trans = getKart(m_blue_holder)->getTrans();
|
||||
m_blue_trans.setOrigin(m_blue_trans(g_kart_flag_offset));
|
||||
}
|
||||
m_red_flag->update(ticks);
|
||||
m_blue_flag->update(ticks);
|
||||
|
||||
const bool red_flag_in_base =
|
||||
m_red_trans.getOrigin() == m_orig_red_trans.getOrigin();
|
||||
const bool blue_flag_in_base =
|
||||
m_blue_trans.getOrigin() == m_orig_blue_trans.getOrigin();
|
||||
|
||||
// Check if not returning for too long
|
||||
if (m_red_holder != -1 || red_flag_in_base)
|
||||
m_red_return_ticks = 0;
|
||||
else
|
||||
m_red_return_ticks++;
|
||||
|
||||
if (m_blue_holder != -1 || blue_flag_in_base)
|
||||
m_blue_return_ticks = 0;
|
||||
else
|
||||
m_blue_return_ticks++;
|
||||
|
||||
const int max_flag_return_timeout = stk_config->time2Ticks(
|
||||
ServerConfig::m_flag_return_timemout);
|
||||
if (m_red_holder == -1 && m_red_return_ticks > max_flag_return_timeout)
|
||||
{
|
||||
resetRedFlagToOrigin();
|
||||
m_red_return_ticks = 0;
|
||||
return;
|
||||
}
|
||||
if (m_blue_holder == -1 && m_blue_return_ticks > max_flag_return_timeout)
|
||||
{
|
||||
resetBlueFlagToOrigin();
|
||||
m_blue_return_ticks = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_red_holder != -1 && m_blue_holder == -1 &&
|
||||
blue_flag_in_base &&
|
||||
(m_orig_blue_trans.getOrigin() - m_red_trans.getOrigin()).length() <
|
||||
if (m_red_flag->getHolder() != -1 && m_blue_flag->isInBase() &&
|
||||
(m_blue_flag->getBaseOrigin() - m_red_flag->getOrigin()).length() <
|
||||
g_capture_length)
|
||||
{
|
||||
// Blue team scored
|
||||
NetworkString p(PROTOCOL_GAME_EVENTS);
|
||||
p.setSynchronous(true);
|
||||
p.addUInt8(GameEventsProtocol::GE_CTF_RESET)
|
||||
.addUInt8(1 << 1 | 0) // Reset red flag
|
||||
.addUInt8((int8_t)m_red_holder);
|
||||
STKHost::get()->sendPacketToAllPeers(&p, true);
|
||||
m_scores.at(m_red_holder) += g_captured_score;
|
||||
m_red_holder = -1;
|
||||
m_red_trans = m_orig_red_trans;
|
||||
m_blue_scores++;
|
||||
return;
|
||||
if (!NetworkConfig::get()->isNetworking() ||
|
||||
NetworkConfig::get()->isServer())
|
||||
{
|
||||
int red_holder = m_red_flag->getHolder();
|
||||
int new_score = m_scores.at(red_holder) + g_captured_score;
|
||||
m_scores.at(red_holder) = new_score;
|
||||
if (NetworkConfig::get()->isServer())
|
||||
{
|
||||
NetworkString p(PROTOCOL_GAME_EVENTS);
|
||||
p.setSynchronous(true);
|
||||
p.addUInt8(GameEventsProtocol::GE_CTF_SCORED)
|
||||
.addUInt8((int8_t)red_holder)
|
||||
.addUInt8(0/*red_team_scored*/)
|
||||
.addUInt32(new_score);
|
||||
STKHost::get()->sendPacketToAllPeers(&p, true);
|
||||
}
|
||||
ctfScored(red_holder, false/*red_team_scored*/, new_score);
|
||||
}
|
||||
m_last_captured_flag_ticks = World::getWorld()->getTicksSinceStart();
|
||||
m_red_flag->resetToBase();
|
||||
}
|
||||
else if (m_blue_holder != -1 && m_red_holder == -1 &&
|
||||
red_flag_in_base &&
|
||||
(m_orig_red_trans.getOrigin() - m_blue_trans.getOrigin()).length() <
|
||||
else if (m_blue_flag->getHolder() != -1 && m_red_flag->isInBase() &&
|
||||
(m_red_flag->getBaseOrigin() - m_blue_flag->getOrigin()).length() <
|
||||
g_capture_length)
|
||||
{
|
||||
// Red team scored
|
||||
NetworkString p(PROTOCOL_GAME_EVENTS);
|
||||
p.setSynchronous(true);
|
||||
p.addUInt8(GameEventsProtocol::GE_CTF_RESET)
|
||||
.addUInt8(0 << 1 | 0) // Reset blue flag
|
||||
.addUInt8((int8_t)m_blue_holder);
|
||||
STKHost::get()->sendPacketToAllPeers(&p, true);
|
||||
m_scores.at(m_blue_holder) += g_captured_score;
|
||||
m_blue_holder = -1;
|
||||
m_blue_trans = m_orig_blue_trans;
|
||||
m_red_scores++;
|
||||
return;
|
||||
if (!NetworkConfig::get()->isNetworking() ||
|
||||
NetworkConfig::get()->isServer())
|
||||
{
|
||||
int blue_holder = m_blue_flag->getHolder();
|
||||
int new_score = m_scores.at(blue_holder) + g_captured_score;
|
||||
m_scores.at(blue_holder) = new_score;
|
||||
if (NetworkConfig::get()->isServer())
|
||||
{
|
||||
NetworkString p(PROTOCOL_GAME_EVENTS);
|
||||
p.setSynchronous(true);
|
||||
p.addUInt8(GameEventsProtocol::GE_CTF_SCORED)
|
||||
.addUInt8((int8_t)blue_holder)
|
||||
.addUInt8(1/*red_team_scored*/)
|
||||
.addUInt32(new_score);
|
||||
STKHost::get()->sendPacketToAllPeers(&p, true);
|
||||
}
|
||||
ctfScored(blue_holder, true/*red_team_scored*/, new_score);
|
||||
}
|
||||
m_last_captured_flag_ticks = World::getWorld()->getTicksSinceStart();
|
||||
m_blue_flag->resetToBase();
|
||||
}
|
||||
|
||||
// Test if red or blue flag is touched
|
||||
@ -279,220 +293,108 @@ void CaptureTheFlag::update(int ticks)
|
||||
if (k->isEliminated() || k->getKartAnimation() || k->isSquashed())
|
||||
continue;
|
||||
|
||||
if (m_red_holder == -1 &&
|
||||
(k->getXYZ() - m_red_trans.getOrigin()).length() <
|
||||
if (m_red_flag->canBeCaptured() &&
|
||||
(k->getXYZ() - m_red_flag->getOrigin()).length() <
|
||||
g_capture_length)
|
||||
{
|
||||
uint8_t kart_id = (uint8_t)k->getWorldKartId();
|
||||
if (getKartTeam(kart_id) == KART_TEAM_RED)
|
||||
{
|
||||
if (!red_flag_in_base)
|
||||
if (!m_red_flag->isInBase())
|
||||
{
|
||||
// Return the flag
|
||||
resetRedFlagToOrigin();
|
||||
m_red_flag->resetToBase();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the flag
|
||||
NetworkString p(PROTOCOL_GAME_EVENTS);
|
||||
p.setSynchronous(true);
|
||||
p.addUInt8(GameEventsProtocol::GE_CTF_ATTACH)
|
||||
.addUInt8(1) // Attach red flag
|
||||
.addUInt8(kart_id);
|
||||
STKHost::get()->sendPacketToAllPeers(&p, true);
|
||||
m_red_holder = kart_id;
|
||||
m_red_flag->setCapturedByKart(kart_id);
|
||||
}
|
||||
}
|
||||
if (m_blue_holder == -1 &&
|
||||
(k->getXYZ() - m_blue_trans.getOrigin()).length() <
|
||||
if (m_blue_flag->canBeCaptured() &&
|
||||
(k->getXYZ() - m_blue_flag->getOrigin()).length() <
|
||||
g_capture_length)
|
||||
{
|
||||
uint8_t kart_id = (uint8_t)k->getWorldKartId();
|
||||
if (getKartTeam(kart_id) == KART_TEAM_BLUE)
|
||||
{
|
||||
if (!blue_flag_in_base)
|
||||
if (!m_blue_flag->isInBase())
|
||||
{
|
||||
// Return the flag
|
||||
resetBlueFlagToOrigin();
|
||||
m_blue_flag->resetToBase();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the flag
|
||||
NetworkString p(PROTOCOL_GAME_EVENTS);
|
||||
p.setSynchronous(true);
|
||||
p.addUInt8(GameEventsProtocol::GE_CTF_ATTACH)
|
||||
.addUInt8(0) // Attach blue flag
|
||||
.addUInt8(kart_id);
|
||||
STKHost::get()->sendPacketToAllPeers(&p, true);
|
||||
m_blue_holder = kart_id;
|
||||
m_blue_flag->setCapturedByKart(kart_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CaptureTheFlag::resetRedFlagToOrigin()
|
||||
int CaptureTheFlag::getRedHolder() const
|
||||
{
|
||||
NetworkString p(PROTOCOL_GAME_EVENTS);
|
||||
p.setSynchronous(true);
|
||||
p.addUInt8(GameEventsProtocol::GE_CTF_RESET)
|
||||
.addUInt8(1 << 1 | 0) // Reset red flag to original
|
||||
.addUInt8(((int8_t)-1));
|
||||
STKHost::get()->sendPacketToAllPeers(&p, true);
|
||||
m_red_trans = m_orig_red_trans;
|
||||
} // resetRedFlagToOrigin
|
||||
return m_red_flag->getHolder();
|
||||
} // getRedHolder
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CaptureTheFlag::resetBlueFlagToOrigin()
|
||||
int CaptureTheFlag::getBlueHolder() const
|
||||
{
|
||||
NetworkString p(PROTOCOL_GAME_EVENTS);
|
||||
p.setSynchronous(true);
|
||||
p.addUInt8(GameEventsProtocol::GE_CTF_RESET)
|
||||
.addUInt8(0 << 1 | 0) // Reset blue flag to original
|
||||
.addUInt8(((int8_t)-1));
|
||||
STKHost::get()->sendPacketToAllPeers(&p, true);
|
||||
m_blue_trans = m_orig_blue_trans;
|
||||
} // resetBlueFlagToOrigin
|
||||
return m_blue_flag->getHolder();
|
||||
} // getBlueHolder
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CaptureTheFlag::updateFlagNodes()
|
||||
bool CaptureTheFlag::isRedFlagInBase() const
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
Vec3 hpr;
|
||||
if (m_red_holder == -1)
|
||||
{
|
||||
m_red_flag_node->setPosition(
|
||||
Vec3(m_red_trans.getOrigin()).toIrrVector());
|
||||
hpr.setHPR(m_red_trans.getRotation());
|
||||
m_red_flag_node->setRotation(hpr.toIrrHPR());
|
||||
}
|
||||
|
||||
if (m_blue_holder == -1)
|
||||
{
|
||||
m_blue_flag_node->setPosition(
|
||||
Vec3(m_blue_trans.getOrigin()).toIrrVector());
|
||||
hpr.setHPR(m_blue_trans.getRotation());
|
||||
m_blue_flag_node->setRotation(hpr.toIrrHPR());
|
||||
}
|
||||
#endif
|
||||
} // updateFlagNodes
|
||||
return m_red_flag->isInBase();
|
||||
} // isRedFlagInBase
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CaptureTheFlag::attachFlag(NetworkString& ns)
|
||||
bool CaptureTheFlag::isBlueFlagInBase() const
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
bool attach_red_flag = ns.getUInt8() == 1;
|
||||
unsigned kart_id = ns.getUInt8();
|
||||
core::stringw get_msg;
|
||||
const core::stringw& name = getKart(kart_id)->getController()
|
||||
->getName();
|
||||
if (attach_red_flag)
|
||||
return m_blue_flag->isInBase();
|
||||
} // isBlueFlagInBase
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
const Vec3& CaptureTheFlag::getRedFlag() const
|
||||
{
|
||||
return m_red_flag->getOrigin();
|
||||
} // getRedFlag
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
const Vec3& CaptureTheFlag::getBlueFlag() const
|
||||
{
|
||||
return m_blue_flag->getOrigin();
|
||||
} // getBlueFlag
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CaptureTheFlag::ctfScored(int kart_id, bool red_team_scored,
|
||||
int new_score)
|
||||
{
|
||||
m_scores.at(kart_id) = new_score;
|
||||
AbstractKart* kart = getKart(kart_id);
|
||||
core::stringw scored_msg;
|
||||
const core::stringw& name = kart->getController()->getName();
|
||||
if (red_team_scored)
|
||||
{
|
||||
m_red_holder = kart_id;
|
||||
m_red_flag_node->setParent(getKart(kart_id)->getNode());
|
||||
m_red_flag_node->setPosition(g_kart_flag_offset.toIrrVector());
|
||||
m_red_flag_node->setRotation(core::vector3df(0.0f, 180.0f, 0.0f));
|
||||
// I18N: Show when a player gets the flag in CTF
|
||||
get_msg = _("%s has the red flag!", name);
|
||||
scored_msg = _("%s captured the blue flag!", name);
|
||||
m_red_scores++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_blue_holder = kart_id;
|
||||
m_blue_flag_node->setParent(getKart(kart_id)->getNode());
|
||||
m_blue_flag_node->setPosition(g_kart_flag_offset.toIrrVector());
|
||||
m_blue_flag_node->setRotation(core::vector3df(0.0f, 180.0f, 0.0f));
|
||||
// I18N: Show when a player gets the flag in CTF
|
||||
get_msg = _("%s has the blue flag!", name);
|
||||
scored_msg = _("%s captured the red flag!", name);
|
||||
m_blue_scores++;
|
||||
}
|
||||
if (getKart(kart_id)->getController()->isLocalPlayerController())
|
||||
SFXManager::get()->quickSound("wee");
|
||||
m_race_gui->addMessage(get_msg, NULL, 1.5f);
|
||||
#endif
|
||||
} // attachFlag
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CaptureTheFlag::resetFlag(NetworkString& ns)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
uint8_t reset_info = ns.getUInt8();
|
||||
bool reset_red_flag = (reset_info >> 1 & 1) == 1;
|
||||
bool with_custom_transform = (reset_info & 1) == 1;
|
||||
int8_t kart_id = ns.getUInt8();
|
||||
if (kart_id != -1)
|
||||
{
|
||||
core::stringw scored_msg;
|
||||
AbstractKart* kart = getKart(kart_id);
|
||||
const core::stringw& name = kart->getController()->getName();
|
||||
if (reset_red_flag)
|
||||
{
|
||||
m_scores.at(kart_id) += g_captured_score;
|
||||
m_red_holder = -1;
|
||||
m_red_trans = m_orig_red_trans;
|
||||
// I18N: Show when a player captured the flag in CTF
|
||||
scored_msg = _("%s captured the red flag!", name);
|
||||
m_red_flag_node->setParent(
|
||||
irr_driver->getSceneManager()->getRootSceneNode());
|
||||
m_blue_scores++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scores.at(kart_id) += g_captured_score;
|
||||
m_blue_holder = -1;
|
||||
m_blue_trans = m_orig_blue_trans;
|
||||
// I18N: Show when a player captured the flag in CTF
|
||||
scored_msg = _("%s captured the blue flag!", name);
|
||||
m_blue_flag_node->setParent(
|
||||
irr_driver->getSceneManager()->getRootSceneNode());
|
||||
m_red_scores++;
|
||||
}
|
||||
m_race_gui->addMessage(scored_msg, NULL, 3.0f);
|
||||
kart->getKartModel()
|
||||
->setAnimation(KartModel::AF_WIN_START, true/* play_non_loop*/);
|
||||
m_scored_sound->play();
|
||||
}
|
||||
else
|
||||
{
|
||||
core::stringw returned_msg;
|
||||
if (reset_red_flag)
|
||||
{
|
||||
btTransform t = m_orig_red_trans;
|
||||
// I18N: Show when the red flag is returned to its base in CTF
|
||||
if (!with_custom_transform)
|
||||
returned_msg = _("The red flag has returned!");
|
||||
else
|
||||
{
|
||||
t.setOrigin(ns.getVec3());
|
||||
t.setRotation(ns.getQuat());
|
||||
}
|
||||
m_red_holder = -1;
|
||||
m_red_trans = t;
|
||||
m_red_flag_node->setParent(
|
||||
irr_driver->getSceneManager()->getRootSceneNode());
|
||||
}
|
||||
else
|
||||
{
|
||||
btTransform t = m_orig_blue_trans;
|
||||
// I18N: Show when the blue flag is returned to its base in CTF
|
||||
if (!with_custom_transform)
|
||||
returned_msg = _("The blue flag has returned!");
|
||||
else
|
||||
{
|
||||
t.setOrigin(ns.getVec3());
|
||||
t.setRotation(ns.getQuat());
|
||||
}
|
||||
m_blue_holder = -1;
|
||||
m_blue_trans = t;
|
||||
m_blue_flag_node->setParent(
|
||||
irr_driver->getSceneManager()->getRootSceneNode());
|
||||
}
|
||||
if (!returned_msg.empty())
|
||||
m_race_gui->addMessage(returned_msg, NULL, 1.5f);
|
||||
}
|
||||
updateFlagNodes();
|
||||
m_race_gui->addMessage(scored_msg, NULL, 3.0f);
|
||||
kart->getKartModel()
|
||||
->setAnimation(KartModel::AF_WIN_START, true/*play_non_loop*/);
|
||||
m_scored_sound->play();
|
||||
#endif
|
||||
} // resetFlag
|
||||
} // ctfScored
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool CaptureTheFlag::getDroppedFlagTrans(const btTransform& kt,
|
||||
@ -545,48 +447,66 @@ bool CaptureTheFlag::isRaceOver()
|
||||
// ----------------------------------------------------------------------------
|
||||
void CaptureTheFlag::loseFlagForKart(int kart_id)
|
||||
{
|
||||
if (!(m_red_holder == kart_id || m_blue_holder == kart_id))
|
||||
if (!(m_red_flag->getHolder() == kart_id ||
|
||||
m_blue_flag->getHolder() == kart_id))
|
||||
return;
|
||||
|
||||
bool reset_red_flag = m_red_holder == kart_id;
|
||||
btTransform dropped_trans = reset_red_flag ?
|
||||
m_orig_red_trans : m_orig_blue_trans;
|
||||
bool drop_red_flag = m_red_flag->getHolder() == kart_id;
|
||||
btTransform dropped_trans = drop_red_flag ?
|
||||
m_red_flag->getBaseTrans() :
|
||||
m_blue_flag->getBaseTrans();
|
||||
bool succeed = getDroppedFlagTrans(getKart(kart_id)->getTrans(),
|
||||
&dropped_trans);
|
||||
NetworkString p(PROTOCOL_GAME_EVENTS);
|
||||
p.setSynchronous(true);
|
||||
// If reset red flag
|
||||
uint8_t reset_info = reset_red_flag ? 1 : 0;
|
||||
reset_info <<= 1;
|
||||
// With custom transform
|
||||
if (succeed)
|
||||
reset_info |= 1;
|
||||
p.addUInt8(GameEventsProtocol::GE_CTF_RESET).addUInt8(reset_info)
|
||||
.addUInt8(((int8_t)-1));
|
||||
if (succeed)
|
||||
if (drop_red_flag)
|
||||
{
|
||||
p.add(Vec3(dropped_trans.getOrigin()))
|
||||
.add(dropped_trans.getRotation());
|
||||
}
|
||||
STKHost::get()->sendPacketToAllPeers(&p, true);
|
||||
if (reset_red_flag)
|
||||
{
|
||||
m_red_holder = -1;
|
||||
m_red_trans = dropped_trans;
|
||||
if (succeed)
|
||||
m_red_flag->dropFlagAt(dropped_trans);
|
||||
else
|
||||
m_red_flag->resetToBase();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_blue_holder = -1;
|
||||
m_blue_trans = dropped_trans;
|
||||
if (succeed)
|
||||
m_blue_flag->dropFlagAt(dropped_trans);
|
||||
else
|
||||
m_blue_flag->resetToBase();
|
||||
}
|
||||
if (NetworkConfig::get()->isNetworking() &&
|
||||
NetworkConfig::get()->isClient())
|
||||
{
|
||||
RewindManager::get()->addRewindInfoEventFunction(new
|
||||
RewindInfoEventFunction(World::getWorld()->getTicksSinceStart(),
|
||||
[](){},
|
||||
/*replay_function*/[dropped_trans, drop_red_flag, succeed, this]()
|
||||
{
|
||||
if (drop_red_flag)
|
||||
{
|
||||
if (succeed)
|
||||
m_red_flag->dropFlagAt(dropped_trans);
|
||||
else
|
||||
m_red_flag->resetToBase();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (succeed)
|
||||
m_blue_flag->dropFlagAt(dropped_trans);
|
||||
else
|
||||
m_blue_flag->resetToBase();
|
||||
}
|
||||
}));
|
||||
}
|
||||
} // loseFlagForKart
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool CaptureTheFlag::kartHit(int kart_id, int hitter)
|
||||
{
|
||||
if (!FreeForAll::kartHit(kart_id, hitter))
|
||||
if (isRaceOver())
|
||||
return false;
|
||||
|
||||
if (!NetworkConfig::get()->isNetworking() ||
|
||||
NetworkConfig::get()->isServer())
|
||||
handleScoreInServer(kart_id, hitter);
|
||||
|
||||
loseFlagForKart(kart_id);
|
||||
return true;
|
||||
} // kartHit
|
||||
|
@ -31,6 +31,8 @@ namespace irr
|
||||
}
|
||||
}
|
||||
|
||||
class CTFFlag;
|
||||
|
||||
class CaptureTheFlag : public FreeForAll
|
||||
{
|
||||
private:
|
||||
@ -48,16 +50,18 @@ private:
|
||||
|
||||
SFXBase* m_scored_sound;
|
||||
|
||||
int m_red_scores, m_blue_scores, m_red_holder, m_blue_holder;
|
||||
int m_red_scores, m_blue_scores;
|
||||
|
||||
btTransform m_red_trans, m_blue_trans, m_orig_red_trans, m_orig_blue_trans;
|
||||
/* Save the last captured flag ticks */
|
||||
int m_last_captured_flag_ticks;
|
||||
|
||||
int m_red_return_ticks, m_blue_return_ticks;
|
||||
/* Used in updateGraphics to add race gui message for flag */
|
||||
int m_red_flag_status, m_blue_flag_status;
|
||||
|
||||
std::map<int, int> m_swatter_reset_kart_ticks;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void updateFlagNodes();
|
||||
std::shared_ptr<CTFFlag> m_red_flag, m_blue_flag;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool getDroppedFlagTrans(const btTransform& kt, btTransform* out) const;
|
||||
// ------------------------------------------------------------------------
|
||||
@ -91,10 +95,6 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
virtual const std::string& getIdent() const OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
void attachFlag(NetworkString& ns);
|
||||
// ------------------------------------------------------------------------
|
||||
void resetFlag(NetworkString& ns);
|
||||
// ------------------------------------------------------------------------
|
||||
bool getKartCTFResult(unsigned int kart_id) const
|
||||
{
|
||||
if (m_red_scores == m_blue_scores)
|
||||
@ -114,25 +114,19 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
int getBlueScore() const { return m_blue_scores; }
|
||||
// ------------------------------------------------------------------------
|
||||
int getRedHolder() const { return m_red_holder; }
|
||||
int getRedHolder() const;
|
||||
// ------------------------------------------------------------------------
|
||||
int getBlueHolder() const { return m_blue_holder; }
|
||||
int getBlueHolder() const;
|
||||
// ------------------------------------------------------------------------
|
||||
bool isRedFlagInBase() const
|
||||
{
|
||||
return m_red_holder == -1 &&
|
||||
m_red_trans.getOrigin() == m_orig_red_trans.getOrigin();
|
||||
}
|
||||
bool isRedFlagInBase() const;
|
||||
// ------------------------------------------------------------------------
|
||||
bool isBlueFlagInBase() const
|
||||
{
|
||||
return m_blue_holder == -1 &&
|
||||
m_blue_trans.getOrigin() == m_orig_blue_trans.getOrigin();
|
||||
}
|
||||
bool isBlueFlagInBase() const;
|
||||
// ------------------------------------------------------------------------
|
||||
const Vec3& getRedFlag() const { return (Vec3&)m_red_trans.getOrigin(); }
|
||||
const Vec3& getRedFlag() const;
|
||||
// ------------------------------------------------------------------------
|
||||
const Vec3& getBlueFlag() const { return (Vec3&)m_blue_trans.getOrigin(); }
|
||||
const Vec3& getBlueFlag() const;
|
||||
// ------------------------------------------------------------------------
|
||||
void ctfScored(int kart_id, bool red_team_scored, int new_score);
|
||||
// ------------------------------------------------------------------------
|
||||
void loseFlagForKart(int kart_id);
|
||||
// ------------------------------------------------------------------------
|
||||
|
122
src/modes/ctf_flag.cpp
Normal file
122
src/modes/ctf_flag.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
// 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/ctf_flag.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "utils/mini_glm.hpp"
|
||||
|
||||
#include "LinearMath/btQuaternion.h"
|
||||
|
||||
// ============================================================================
|
||||
// Position offset to attach in kart model
|
||||
const Vec3 g_kart_flag_offset(0.0, 0.2f, -0.5f);
|
||||
// ============================================================================
|
||||
BareNetworkString* CTFFlag::saveState(std::vector<std::string>* ru)
|
||||
{
|
||||
using namespace MiniGLM;
|
||||
ru->push_back(getUniqueIdentity());
|
||||
BareNetworkString* buffer = new BareNetworkString();
|
||||
buffer->addUInt8(m_flag_status);
|
||||
if (m_flag_status == OFF_BASE)
|
||||
{
|
||||
Vec3 normal = quatRotate(m_flag_trans.getRotation(),
|
||||
Vec3(0.0f, 1.0f, 0.0f));
|
||||
buffer->add(m_flag_trans.getOrigin());
|
||||
buffer->addUInt32(
|
||||
compressVector3(Vec3(normal.normalize()).toIrrVector()));
|
||||
buffer->addUInt16(m_ticks_since_off_base);
|
||||
}
|
||||
return buffer;
|
||||
} // saveState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CTFFlag::restoreState(BareNetworkString* buffer, int count)
|
||||
{
|
||||
using namespace MiniGLM;
|
||||
m_flag_status = buffer->getUInt8();
|
||||
if (m_flag_status == OFF_BASE)
|
||||
{
|
||||
Vec3 origin = buffer->getVec3();
|
||||
uint32_t normal_packed = buffer->getUInt32();
|
||||
Vec3 normal = decompressVector3(normal_packed);
|
||||
m_flag_trans.setOrigin(origin);
|
||||
m_flag_trans.setRotation(
|
||||
shortestArcQuat(Vec3(0.0f, 1.0f, 0.0f), normal));
|
||||
m_ticks_since_off_base = buffer->getUInt16();
|
||||
}
|
||||
updateFlagTrans(m_flag_trans);
|
||||
} // restoreState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CTFFlag::updateFlagTrans(const btTransform& off_base_trans)
|
||||
{
|
||||
if (getHolder() != -1)
|
||||
{
|
||||
AbstractKart* k = World::getWorld()->getKart(getHolder());
|
||||
m_flag_trans = k->getTrans();
|
||||
m_flag_trans.setOrigin(m_flag_trans(g_kart_flag_offset));
|
||||
}
|
||||
else if (m_flag_status == OFF_BASE)
|
||||
{
|
||||
m_flag_trans = off_base_trans;
|
||||
}
|
||||
else
|
||||
m_flag_trans = m_flag_base_trans;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CTFFlag::update(int ticks)
|
||||
{
|
||||
updateFlagTrans(m_flag_trans);
|
||||
|
||||
// Check if not returning for too long
|
||||
if (m_flag_status != OFF_BASE)
|
||||
return;
|
||||
|
||||
m_ticks_since_off_base += ticks;
|
||||
if (m_ticks_since_off_base > race_manager->getFlagReturnTicks())
|
||||
{
|
||||
resetToBase();
|
||||
}
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CTFFlag::updateFlagGraphics(irr::scene::IAnimatedMeshSceneNode* flag_node)
|
||||
{
|
||||
if (getHolder() != -1)
|
||||
{
|
||||
AbstractKart* k = World::getWorld()->getKart(getHolder());
|
||||
flag_node->setParent(k->getNode());
|
||||
flag_node->setPosition(g_kart_flag_offset.toIrrVector());
|
||||
flag_node->setRotation(core::vector3df(0.0f, 180.0f, 0.0f));
|
||||
flag_node->setAnimationSpeed(fabsf(k->getSpeed()) * 3.0f + 25.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
flag_node->setParent(
|
||||
irr_driver->getSceneManager()->getRootSceneNode());
|
||||
Vec3 hpr;
|
||||
flag_node->setPosition(
|
||||
Vec3(m_flag_trans.getOrigin()).toIrrVector());
|
||||
hpr.setHPR(m_flag_trans.getRotation());
|
||||
flag_node->setRotation(hpr.toIrrHPR());
|
||||
flag_node->setAnimationSpeed(25.0f);
|
||||
}
|
||||
} // updateFlagPosition
|
137
src/modes/ctf_flag.hpp
Normal file
137
src/modes/ctf_flag.hpp
Normal file
@ -0,0 +1,137 @@
|
||||
// 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 HEADER_CTF_FLAG_HPP
|
||||
#define HEADER_CTF_FLAG_HPP
|
||||
|
||||
#include "network/rewinder.hpp"
|
||||
#include "utils/types.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
|
||||
enum FlagColor : unsigned int
|
||||
{
|
||||
FC_RED = 0,
|
||||
FC_BLUE = 1
|
||||
};
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
class IAnimatedMeshSceneNode;
|
||||
}
|
||||
}
|
||||
class CTFFlag : public Rewinder
|
||||
{
|
||||
public:
|
||||
static const int IN_BASE = -1;
|
||||
static const int OFF_BASE = -2;
|
||||
private:
|
||||
/* Either save the above 2 status, or kart id holder this flag. */
|
||||
int8_t m_flag_status;
|
||||
|
||||
/* Currnet flag transformation. */
|
||||
btTransform m_flag_trans;
|
||||
|
||||
/* Transformation of IN_BASE. */
|
||||
const btTransform m_flag_base_trans;
|
||||
|
||||
/* If OFF_BASE of m_flag_status, save the ticks since off base, use for
|
||||
* auto return base for a flag (see ServerConfig). */
|
||||
uint16_t m_ticks_since_off_base;
|
||||
|
||||
FlagColor m_flag_color;
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
CTFFlag(FlagColor fc, const btTransform& base_trans)
|
||||
: Rewinder(fc == FC_RED ? "TR" : "TB"), m_flag_base_trans(base_trans)
|
||||
{
|
||||
// UID rewinder with "T" which is after "Kx" for kart so
|
||||
// updateFlagTrans is called after kart is rewound
|
||||
m_flag_status = IN_BASE;
|
||||
m_flag_trans.setOrigin(Vec3(0.0f));
|
||||
m_flag_trans.setRotation(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
m_flag_color = fc;
|
||||
m_ticks_since_off_base = 0;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void saveTransform() {}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void computeError() {}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual BareNetworkString* saveState(std::vector<std::string>* ru);
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void undoEvent(BareNetworkString* buffer) {}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void rewindToEvent(BareNetworkString* buffer) {}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void restoreState(BareNetworkString* buffer, int count);
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void undoState(BareNetworkString* buffer) {}
|
||||
// ------------------------------------------------------------------------
|
||||
int getHolder() const
|
||||
{
|
||||
if (m_flag_status >= 0)
|
||||
return m_flag_status;
|
||||
return -1;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
int getStatus() const { return m_flag_status; }
|
||||
// ------------------------------------------------------------------------
|
||||
const Vec3& getOrigin() const { return (Vec3&)m_flag_trans.getOrigin(); }
|
||||
// ------------------------------------------------------------------------
|
||||
const Vec3& getBaseOrigin() const
|
||||
{ return (Vec3&)m_flag_base_trans.getOrigin(); }
|
||||
// ------------------------------------------------------------------------
|
||||
const btTransform& getBaseTrans() const { return m_flag_base_trans; }
|
||||
// ------------------------------------------------------------------------
|
||||
void resetToBase()
|
||||
{
|
||||
m_flag_status = IN_BASE;
|
||||
m_ticks_since_off_base = 0;
|
||||
updateFlagTrans();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void setCapturedByKart(int kart_id)
|
||||
{
|
||||
m_flag_status = (int8_t)kart_id;
|
||||
m_ticks_since_off_base = 0;
|
||||
updateFlagTrans();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void dropFlagAt(const btTransform& t)
|
||||
{
|
||||
m_flag_status = OFF_BASE;
|
||||
m_ticks_since_off_base = 0;
|
||||
m_flag_trans = t;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
bool isInBase() const { return m_flag_status == IN_BASE; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool canBeCaptured() const { return !(m_flag_status >= 0); }
|
||||
// ------------------------------------------------------------------------
|
||||
void update(int ticks);
|
||||
// ------------------------------------------------------------------------
|
||||
void updateFlagTrans(const btTransform& off_base_trans = btTransform());
|
||||
// ------------------------------------------------------------------------
|
||||
void updateFlagGraphics(irr::scene::IAnimatedMeshSceneNode* flag_node);
|
||||
}; // CTFFlag
|
||||
#endif
|
||||
|
@ -99,17 +99,37 @@ bool FreeForAll::kartHit(int kart_id, int hitter)
|
||||
if (isRaceOver())
|
||||
return false;
|
||||
|
||||
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);
|
||||
handleScoreInServer(kart_id, hitter);
|
||||
return true;
|
||||
} // kartHit
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called when the score of kart needs updated.
|
||||
* \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::handleScoreInServer(int kart_id, int hitter)
|
||||
{
|
||||
int new_score = 0;
|
||||
if (kart_id == hitter || hitter == -1)
|
||||
new_score = --m_scores[kart_id];
|
||||
else
|
||||
new_score = ++m_scores[hitter];
|
||||
|
||||
if (NetworkConfig::get()->isNetworking() &&
|
||||
NetworkConfig::get()->isServer())
|
||||
{
|
||||
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(new_score);
|
||||
else
|
||||
p.addUInt8((uint8_t)hitter).addUInt32(new_score);
|
||||
STKHost::get()->sendPacketToAllPeers(&p, true);
|
||||
}
|
||||
} // handleScoreInServer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void FreeForAll::setKartScoreFromServer(NetworkString& ns)
|
||||
{
|
||||
|
@ -31,6 +31,8 @@ protected:
|
||||
bool m_count_down_reached_zero;
|
||||
|
||||
std::vector<int> m_scores;
|
||||
// ------------------------------------------------------------------------
|
||||
void handleScoreInServer(int kart_id, int hitter);
|
||||
|
||||
private:
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -267,6 +267,8 @@ void ClientLobby::addAllPlayers(Event* event)
|
||||
int hit_capture_limit = data.getUInt32();
|
||||
float time_limit = data.getFloat();
|
||||
m_game_setup->setHitCaptureTime(hit_capture_limit, time_limit);
|
||||
uint16_t flag_return_timeout = data.getUInt16();
|
||||
race_manager->setFlagReturnTicks(flag_return_timeout);
|
||||
}
|
||||
configRemoteKart(players);
|
||||
loadWorld();
|
||||
|
@ -79,18 +79,14 @@ bool GameEventsProtocol::notifyEvent(Event* event)
|
||||
ffa->setKartScoreFromServer(data);
|
||||
break;
|
||||
}
|
||||
case GE_CTF_ATTACH:
|
||||
case GE_CTF_SCORED:
|
||||
{
|
||||
if (!ctf)
|
||||
throw std::invalid_argument("No CTF world");
|
||||
ctf->attachFlag(data);
|
||||
break;
|
||||
}
|
||||
case GE_CTF_RESET:
|
||||
{
|
||||
if (!ctf)
|
||||
throw std::invalid_argument("No CTF world");
|
||||
ctf->resetFlag(data);
|
||||
uint8_t kart_id = data.getUInt8();
|
||||
bool red_team_scored = data.getUInt8() == 1;
|
||||
int new_score = data.getUInt32();
|
||||
ctf->ctfScored(kart_id, red_team_scored, new_score);
|
||||
break;
|
||||
}
|
||||
case GE_STARTUP_BOOST:
|
||||
|
@ -16,9 +16,8 @@ public:
|
||||
GE_RESET_BALL = 3,
|
||||
GE_PLAYER_GOAL = 4,
|
||||
GE_BATTLE_KART_SCORE = 5,
|
||||
GE_CTF_ATTACH = 6,
|
||||
GE_CTF_RESET = 7,
|
||||
GE_STARTUP_BOOST = 8,
|
||||
GE_CTF_SCORED = 6,
|
||||
GE_STARTUP_BOOST = 7,
|
||||
}; // GameEventType
|
||||
private:
|
||||
int m_last_finished_position;
|
||||
|
@ -595,6 +595,10 @@ void ServerLobby::asynchronousUpdate()
|
||||
auto hcl = getHitCaptureLimit((float)players.size());
|
||||
load_world_message->addUInt32(hcl.first).addFloat(hcl.second);
|
||||
m_game_setup->setHitCaptureTime(hcl.first, hcl.second);
|
||||
uint16_t flag_return_time = (uint16_t)stk_config->time2Ticks(
|
||||
ServerConfig::m_flag_return_timemout);
|
||||
load_world_message->addUInt16(flag_return_time);
|
||||
race_manager->setFlagReturnTicks(flag_return_time);
|
||||
}
|
||||
configRemoteKart(players);
|
||||
|
||||
|
@ -261,6 +261,15 @@ void loadServerLobbyFromConfig()
|
||||
if (m_voting_timeout == 20.0f)
|
||||
m_voting_timeout = 30.0f;
|
||||
|
||||
if (stk_config->time2Ticks(m_flag_return_timemout) > 65535)
|
||||
{
|
||||
float timeout = m_flag_return_timemout;
|
||||
// in CTFFlag it uses 16bit unsigned integer for timeout
|
||||
Log::warn("ServerConfig", "Invalid %f m_flag_return_timemout which "
|
||||
"is too large, use default value.", timeout);
|
||||
m_flag_return_timemout.revertToDefaults();
|
||||
}
|
||||
|
||||
int frequency_in_config = m_state_frequency;
|
||||
if (frequency_in_config <= 0 ||
|
||||
frequency_in_config > stk_config->getPhysicsFPS())
|
||||
|
@ -81,6 +81,7 @@ RaceManager::RaceManager()
|
||||
m_have_kart_last_position_on_overworld = false;
|
||||
m_num_local_players = 0;
|
||||
m_hit_capture_limit = 0;
|
||||
m_flag_return_ticks = stk_config->time2Ticks(20.0f);
|
||||
setMaxGoal(0);
|
||||
setTimeTarget(0.0f);
|
||||
setReverseTrack(false);
|
||||
|
@ -356,6 +356,7 @@ private:
|
||||
unsigned int m_num_spare_tire_karts;
|
||||
unsigned int m_num_finished_karts;
|
||||
unsigned int m_num_finished_players;
|
||||
unsigned m_flag_return_ticks;
|
||||
int m_coin_target;
|
||||
float m_time_target;
|
||||
int m_goal_target;
|
||||
@ -896,7 +897,10 @@ public:
|
||||
return m_minor_mode == MINOR_MODE_SOCCER ||
|
||||
m_minor_mode == MINOR_MODE_CAPTURE_THE_FLAG;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void setFlagReturnTicks(unsigned ticks) { m_flag_return_ticks = ticks; }
|
||||
// ------------------------------------------------------------------------
|
||||
unsigned getFlagReturnTicks() const { return m_flag_return_ticks; }
|
||||
}; // RaceManager
|
||||
|
||||
extern RaceManager *race_manager;
|
||||
|
@ -532,8 +532,10 @@ void RaceGUI::drawGlobalMiniMap()
|
||||
lower_y -(int)(draw_at.getY()-(m_minimap_player_size/2.2f)));
|
||||
draw2DImage(m_red_flag, rp, rs, NULL, NULL, true, true);
|
||||
}
|
||||
Vec3 pos = ctf_world->getRedHolder() == -1 ? ctf_world->getRedFlag() :
|
||||
ctf_world->getKart(ctf_world->getRedHolder())->getSmoothedTrans().getOrigin();
|
||||
|
||||
track->mapPoint2MiniMap(ctf_world->getRedFlag(), &draw_at);
|
||||
track->mapPoint2MiniMap(pos, &draw_at);
|
||||
core::rect<s32> rs(core::position2di(0, 0), m_red_flag->getSize());
|
||||
core::rect<s32> rp(m_map_left+(int)(draw_at.getX()-(m_minimap_player_size/1.4f)),
|
||||
lower_y -(int)(draw_at.getY()+(m_minimap_player_size/2.2f)),
|
||||
@ -553,7 +555,10 @@ void RaceGUI::drawGlobalMiniMap()
|
||||
draw2DImage(m_blue_flag, rp, rs, NULL, NULL, true, true);
|
||||
}
|
||||
|
||||
track->mapPoint2MiniMap(ctf_world->getBlueFlag(), &draw_at);
|
||||
pos = ctf_world->getBlueHolder() == -1 ? ctf_world->getBlueFlag() :
|
||||
ctf_world->getKart(ctf_world->getBlueHolder())->getSmoothedTrans().getOrigin();
|
||||
|
||||
track->mapPoint2MiniMap(pos, &draw_at);
|
||||
core::rect<s32> bs(core::position2di(0, 0), m_blue_flag->getSize());
|
||||
core::rect<s32> bp(m_map_left+(int)(draw_at.getX()-(m_minimap_player_size/1.4f)),
|
||||
lower_y -(int)(draw_at.getY()+(m_minimap_player_size/2.2f)),
|
||||
|
Loading…
Reference in New Issue
Block a user