merge soccer branch
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@13450 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
commit
d3e6569a54
@ -4,5 +4,7 @@
|
|||||||
<material name="speedback.png" compositing="test" clampU="Y" clampV="Y" light="N" ignore="Y"/>
|
<material name="speedback.png" compositing="test" clampU="Y" clampV="Y" light="N" ignore="Y"/>
|
||||||
<material name="speedfore.png" compositing="test" clampU="Y" clampV="Y" light="N" ignore="Y"/>
|
<material name="speedfore.png" compositing="test" clampU="Y" clampV="Y" light="N" ignore="Y"/>
|
||||||
<material name="notes.png" compositing="test" light="N" ignore="Y"/>
|
<material name="notes.png" compositing="test" light="N" ignore="Y"/>
|
||||||
|
<material name="soccer_player_red.png" compositing="blend" light="N" ignore="Y"/>
|
||||||
|
<material name="soccer_player_blue.png" compositing="blend" light="N" ignore="Y"/>
|
||||||
|
|
||||||
</materials>
|
</materials>
|
@ -850,12 +850,14 @@ PerCameraNode *IrrDriver::addPerCameraMesh(scene::IMesh* mesh,
|
|||||||
*/
|
*/
|
||||||
scene::ISceneNode *IrrDriver::addBillboard(const core::dimension2d< f32 > size,
|
scene::ISceneNode *IrrDriver::addBillboard(const core::dimension2d< f32 > size,
|
||||||
video::ITexture *texture,
|
video::ITexture *texture,
|
||||||
scene::ISceneNode* parent)
|
scene::ISceneNode* parent, bool alphaTesting)
|
||||||
{
|
{
|
||||||
scene::IBillboardSceneNode* node =
|
scene::IBillboardSceneNode* node =
|
||||||
m_scene_manager->addBillboardSceneNode(parent, size);
|
m_scene_manager->addBillboardSceneNode(parent, size);
|
||||||
assert(node->getMaterialCount() > 0);
|
assert(node->getMaterialCount() > 0);
|
||||||
node->setMaterialTexture(0, texture);
|
node->setMaterialTexture(0, texture);
|
||||||
|
if(alphaTesting)
|
||||||
|
node->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
|
||||||
return node;
|
return node;
|
||||||
} // addMesh
|
} // addMesh
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ public:
|
|||||||
scene::ISceneNode *parent = NULL);
|
scene::ISceneNode *parent = NULL);
|
||||||
scene::ISceneNode *addBillboard(const core::dimension2d< f32 > size,
|
scene::ISceneNode *addBillboard(const core::dimension2d< f32 > size,
|
||||||
video::ITexture *texture,
|
video::ITexture *texture,
|
||||||
scene::ISceneNode* parent=NULL);
|
scene::ISceneNode* parent=NULL, bool alphaTesting = false);
|
||||||
|
|
||||||
scene::IParticleSystemSceneNode
|
scene::IParticleSystemSceneNode
|
||||||
*addParticleNode(bool default_emitter=true);
|
*addParticleNode(bool default_emitter=true);
|
||||||
|
@ -278,39 +278,7 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models)
|
|||||||
lod_node->add(500, static_model, true);
|
lod_node->add(500, static_model, true);
|
||||||
m_animated_node = static_cast<scene::IAnimatedMeshSceneNode*>(node);
|
m_animated_node = static_cast<scene::IAnimatedMeshSceneNode*>(node);
|
||||||
|
|
||||||
m_hat_node = NULL;
|
attachHat();
|
||||||
if(m_hat_name.size()>0)
|
|
||||||
{
|
|
||||||
scene::IBoneSceneNode *bone = m_animated_node->getJointNode("Head");
|
|
||||||
if(!bone)
|
|
||||||
bone = m_animated_node->getJointNode("head");
|
|
||||||
if(bone)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Till we have all models fixed, accept Head and head as bone naartme
|
|
||||||
scene::IMesh *hat_mesh =
|
|
||||||
irr_driver->getAnimatedMesh(
|
|
||||||
file_manager->getModelFile(m_hat_name));
|
|
||||||
m_hat_node = irr_driver->addMesh(hat_mesh);
|
|
||||||
bone->addChild(m_hat_node);
|
|
||||||
m_animated_node->setCurrentFrame((float)m_animation_frame[AF_STRAIGHT]);
|
|
||||||
m_animated_node->OnAnimate(0);
|
|
||||||
bone->updateAbsolutePosition();
|
|
||||||
|
|
||||||
// With the hat node attached to the head bone, we have to
|
|
||||||
// reverse the transformation of the bone, so that the hat
|
|
||||||
// is still properly placed. Esp. the hat offset needs
|
|
||||||
// to be rotated.
|
|
||||||
const core::matrix4 mat = bone->getAbsoluteTransformation();
|
|
||||||
core::matrix4 inv;
|
|
||||||
mat.getInverse(inv);
|
|
||||||
core::vector3df rotated_offset;
|
|
||||||
inv.rotateVect(rotated_offset, m_hat_offset);
|
|
||||||
m_hat_node->setPosition(rotated_offset);
|
|
||||||
m_hat_node->setScale(inv.getScale());
|
|
||||||
m_hat_node->setRotation(inv.getRotationDegrees());
|
|
||||||
} // if bone
|
|
||||||
} // if(m_hat_name)
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::string debug_name = m_model_filename+" (animated-kart-model)";
|
std::string debug_name = m_model_filename+" (animated-kart-model)";
|
||||||
@ -704,4 +672,40 @@ void KartModel::update(float rotation_dt, float steer, const float suspension[4]
|
|||||||
|
|
||||||
m_animated_node->setCurrentFrame(frame);
|
m_animated_node->setCurrentFrame(frame);
|
||||||
} // update
|
} // update
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void KartModel::attachHat(){
|
||||||
|
m_hat_node = NULL;
|
||||||
|
if(m_hat_name.size()>0)
|
||||||
|
{
|
||||||
|
scene::IBoneSceneNode *bone = m_animated_node->getJointNode("Head");
|
||||||
|
if(!bone)
|
||||||
|
bone = m_animated_node->getJointNode("head");
|
||||||
|
if(bone)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Till we have all models fixed, accept Head and head as bone naartme
|
||||||
|
scene::IMesh *hat_mesh =
|
||||||
|
irr_driver->getAnimatedMesh(
|
||||||
|
file_manager->getModelFile(m_hat_name));
|
||||||
|
m_hat_node = irr_driver->addMesh(hat_mesh);
|
||||||
|
bone->addChild(m_hat_node);
|
||||||
|
m_animated_node->setCurrentFrame((float)m_animation_frame[AF_STRAIGHT]);
|
||||||
|
m_animated_node->OnAnimate(0);
|
||||||
|
bone->updateAbsolutePosition();
|
||||||
|
|
||||||
|
// With the hat node attached to the head bone, we have to
|
||||||
|
// reverse the transformation of the bone, so that the hat
|
||||||
|
// is still properly placed. Esp. the hat offset needs
|
||||||
|
// to be rotated.
|
||||||
|
const core::matrix4 mat = bone->getAbsoluteTransformation();
|
||||||
|
core::matrix4 inv;
|
||||||
|
mat.getInverse(inv);
|
||||||
|
core::vector3df rotated_offset;
|
||||||
|
inv.rotateVect(rotated_offset, m_hat_offset);
|
||||||
|
m_hat_node->setPosition(rotated_offset);
|
||||||
|
m_hat_node->setScale(inv.getScale());
|
||||||
|
m_hat_node->setRotation(inv.getRotationDegrees());
|
||||||
|
} // if bone
|
||||||
|
} // if(m_hat_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -232,8 +232,14 @@ public:
|
|||||||
/** Name of the hat mesh to use. */
|
/** Name of the hat mesh to use. */
|
||||||
void setHatMeshName(const std::string &name) {m_hat_name = name; }
|
void setHatMeshName(const std::string &name) {m_hat_name = name; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
void attachHat();
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the array of wheel nodes. */
|
/** Returns the array of wheel nodes. */
|
||||||
scene::ISceneNode** getWheelNodes() { return m_wheel_node; }
|
scene::ISceneNode** getWheelNodes() { return m_wheel_node; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
scene::IAnimatedMeshSceneNode* getAnimatedNode(){ return m_animated_node; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
core::vector3df getHatOffset() { return m_hat_offset; }
|
||||||
|
|
||||||
}; // KartModel
|
}; // KartModel
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,9 +23,11 @@
|
|||||||
#include "audio/music_manager.hpp"
|
#include "audio/music_manager.hpp"
|
||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
|
#include "karts/kart.hpp"
|
||||||
#include "karts/kart_model.hpp"
|
#include "karts/kart_model.hpp"
|
||||||
#include "karts/kart_properties.hpp"
|
#include "karts/kart_properties.hpp"
|
||||||
#include "karts/rescue_animation.hpp"
|
#include "karts/rescue_animation.hpp"
|
||||||
|
#include "karts/controller/player_controller.hpp"
|
||||||
#include "physics/physics.hpp"
|
#include "physics/physics.hpp"
|
||||||
#include "states_screens/race_gui_base.hpp"
|
#include "states_screens/race_gui_base.hpp"
|
||||||
#include "tracks/track.hpp"
|
#include "tracks/track.hpp"
|
||||||
@ -56,6 +58,8 @@ void SoccerWorld::init()
|
|||||||
fprintf(stderr, "No AI exists for this game mode\n");
|
fprintf(stderr, "No AI exists for this game mode\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
m_goal_target = race_manager->getMaxGoal();
|
||||||
|
printf("Max Goal: %d\n", m_goal_target);
|
||||||
} // init
|
} // init
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -94,8 +98,11 @@ void SoccerWorld::update(float dt)
|
|||||||
void SoccerWorld::onCheckGoalTriggered(bool first_goal)
|
void SoccerWorld::onCheckGoalTriggered(bool first_goal)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
if(m_can_score_points)
|
if(m_can_score_points){
|
||||||
printf("*** GOOOOOOOOOAAAAAAALLLLLL!!!! (team: %d) ***\n", first_goal ? 0 : 1);
|
printf("*** GOOOOOOOOOAAAAAAALLLLLL!!!! (team: %d) ***\n", first_goal ? 0 : 1);
|
||||||
|
m_team_goals[first_goal]++;
|
||||||
|
printf("Score:\nTeam One %d : %d Team Two\n", m_team_goals[0], m_team_goals[1]);
|
||||||
|
}
|
||||||
|
|
||||||
//m_check_goals_enabled = false; // TODO: remove?
|
//m_check_goals_enabled = false; // TODO: remove?
|
||||||
|
|
||||||
@ -111,8 +118,13 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
obj->reset();
|
obj->reset();
|
||||||
|
obj->getPhysics()->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Resetting the ball triggers the goal check line one more time.
|
||||||
|
//This ensures that only one goal is counted, and the second is ignored.
|
||||||
|
m_can_score_points = !m_can_score_points;
|
||||||
|
|
||||||
//for(int i=0 ; i < getNumKarts() ; i++
|
//for(int i=0 ; i < getNumKarts() ; i++
|
||||||
|
|
||||||
/*if(World::getWorld()->getTrack()->isAutoRescueEnabled() &&
|
/*if(World::getWorld()->getTrack()->isAutoRescueEnabled() &&
|
||||||
@ -136,7 +148,11 @@ bool SoccerWorld::isRaceOver()
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// One team scored the target goals ...
|
||||||
|
else if(getScore(0) >= m_goal_target ||
|
||||||
|
getScore(1) >= m_goal_target){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// TODO
|
// TODO
|
||||||
return getCurrentNumKarts()==1 || getCurrentNumPlayers()==0;
|
return getCurrentNumKarts()==1 || getCurrentNumPlayers()==0;
|
||||||
} // isRaceOver
|
} // isRaceOver
|
||||||
@ -191,7 +207,88 @@ void SoccerWorld::getKartsDisplayInfo(
|
|||||||
*/
|
*/
|
||||||
} // getKartsDisplayInfo
|
} // getKartsDisplayInfo
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Moves a kart to its rescue position.
|
||||||
|
* \param kart The kart that was rescued.
|
||||||
|
*/
|
||||||
|
void SoccerWorld::moveKartAfterRescue(AbstractKart* kart)
|
||||||
|
{
|
||||||
|
// find closest point to drop kart on
|
||||||
|
World *world = World::getWorld();
|
||||||
|
const int start_spots_amount = world->getTrack()->getNumberOfStartPositions();
|
||||||
|
assert(start_spots_amount > 0);
|
||||||
|
|
||||||
|
float largest_accumulated_distance_found = -1;
|
||||||
|
int furthest_id_found = -1;
|
||||||
|
|
||||||
|
const float kart_x = kart->getXYZ().getX();
|
||||||
|
const float kart_z = kart->getXYZ().getZ();
|
||||||
|
|
||||||
|
for(int n=0; n<start_spots_amount; n++)
|
||||||
|
{
|
||||||
|
// no need for the overhead to compute exact distance with sqrt(),
|
||||||
|
// so using the 'manhattan' heuristic which will do fine enough.
|
||||||
|
const btTransform &s = world->getTrack()->getStartTransform(n);
|
||||||
|
const Vec3 &v=s.getOrigin();
|
||||||
|
float accumulatedDistance = .0f;
|
||||||
|
bool spawnPointClear = true;
|
||||||
|
|
||||||
|
for(unsigned int k=0; k<getCurrentNumKarts(); k++)
|
||||||
|
{
|
||||||
|
const AbstractKart *currentKart = World::getWorld()->getKart(k);
|
||||||
|
const float currentKart_x = currentKart->getXYZ().getX();
|
||||||
|
const float currentKartk_z = currentKart->getXYZ().getZ();
|
||||||
|
|
||||||
|
if(kart_x!=currentKart_x && kart_z !=currentKartk_z)
|
||||||
|
{
|
||||||
|
float absDistance = fabs(currentKart_x - v.getX()) +
|
||||||
|
fabs(currentKartk_z - v.getZ());
|
||||||
|
if(absDistance < CLEAR_SPAWN_RANGE)
|
||||||
|
{
|
||||||
|
spawnPointClear = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
accumulatedDistance += absDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(largest_accumulated_distance_found < accumulatedDistance && spawnPointClear)
|
||||||
|
{
|
||||||
|
furthest_id_found = n;
|
||||||
|
largest_accumulated_distance_found = accumulatedDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(furthest_id_found != -1);
|
||||||
|
const btTransform &s = world->getTrack()->getStartTransform(furthest_id_found);
|
||||||
|
const Vec3 &xyz = s.getOrigin();
|
||||||
|
kart->setXYZ(xyz);
|
||||||
|
kart->setRotation(s.getRotation());
|
||||||
|
|
||||||
|
//position kart from same height as in World::resetAllKarts
|
||||||
|
btTransform pos;
|
||||||
|
pos.setOrigin(kart->getXYZ()+btVector3(0, 0.5f*kart->getKartHeight(), 0.0f));
|
||||||
|
pos.setRotation( btQuaternion(btVector3(0.0f, 1.0f, 0.0f), 0 /* angle */) );
|
||||||
|
|
||||||
|
kart->getBody()->setCenterOfMassTransform(pos);
|
||||||
|
|
||||||
|
//project kart to surface of track
|
||||||
|
bool kart_over_ground = m_track->findGround(kart);
|
||||||
|
|
||||||
|
if (kart_over_ground)
|
||||||
|
{
|
||||||
|
//add vertical offset so that the kart starts off above the track
|
||||||
|
float vertical_offset = kart->getKartProperties()->getVertRescueOffset() *
|
||||||
|
kart->getKartHeight();
|
||||||
|
kart->getBody()->translate(btVector3(0, vertical_offset, 0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "WARNING: invalid position after rescue for kart %s on track %s.\n",
|
||||||
|
(kart->getIdent().c_str()), m_track->getIdent().c_str());
|
||||||
|
}
|
||||||
|
} // moveKartAfterRescue
|
||||||
|
|
||||||
/** Set position and team for the karts */
|
/** Set position and team for the karts */
|
||||||
void SoccerWorld::initKartList()
|
void SoccerWorld::initKartList()
|
||||||
{
|
{
|
||||||
@ -203,8 +300,6 @@ void SoccerWorld::initKartList()
|
|||||||
m_karts[n]->setPosition(-1);
|
m_karts[n]->setPosition(-1);
|
||||||
}
|
}
|
||||||
// TODO: remove
|
// TODO: remove
|
||||||
/*
|
|
||||||
const unsigned int kart_amount = m_karts.size();
|
|
||||||
|
|
||||||
int team_karts_amount[NB_SOCCER_TEAMS];
|
int team_karts_amount[NB_SOCCER_TEAMS];
|
||||||
memset(team_karts_amount, 0, sizeof(team_karts_amount));
|
memset(team_karts_amount, 0, sizeof(team_karts_amount));
|
||||||
@ -215,16 +310,34 @@ void SoccerWorld::initKartList()
|
|||||||
SoccerTeam round_robin_team = SOCCER_TEAM_RED;
|
SoccerTeam round_robin_team = SOCCER_TEAM_RED;
|
||||||
for(unsigned int n=0; n<kart_amount; n++)
|
for(unsigned int n=0; n<kart_amount; n++)
|
||||||
{
|
{
|
||||||
if(m_karts[n]->getSoccerTeam() == SOCCER_TEAM_NONE)
|
if(race_manager->getLocalKartInfo(n).getSoccerTeam() == SOCCER_TEAM_NONE)
|
||||||
m_karts[n]->setSoccerTeam(round_robin_team);
|
race_manager->setLocalKartSoccerTeam(
|
||||||
|
race_manager->getLocalKartInfo(n).getLocalPlayerId(),round_robin_team);
|
||||||
|
|
||||||
team_karts_amount[m_karts[n]->getSoccerTeam()]++;
|
team_karts_amount[race_manager->getLocalKartInfo(n).getSoccerTeam()]++;
|
||||||
|
|
||||||
round_robin_team = (round_robin_team==SOCCER_TEAM_RED ?
|
round_robin_team = (round_robin_team==SOCCER_TEAM_RED ?
|
||||||
SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
|
SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
|
||||||
}// next kart
|
}// next kart
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Loading the indicator textures
|
||||||
|
irr::video::ITexture *redTeamTexture = irr_driver->getTexture(
|
||||||
|
file_manager->getTextureFile("soccer_player_red.png"));
|
||||||
|
irr::video::ITexture *blueTeamTexture = irr_driver->getTexture(
|
||||||
|
file_manager->getTextureFile("soccer_player_blue.png"));
|
||||||
|
//Assigning indicators
|
||||||
|
for(int i=0; i<kart_amount; i++){
|
||||||
|
scene::ISceneNode *hatNode;
|
||||||
|
if(race_manager->getLocalKartInfo(i).getSoccerTeam() == SOCCER_TEAM_RED)
|
||||||
|
hatNode = irr_driver->addBillboard(core::dimension2d<irr::f32>(0.3,0.3)
|
||||||
|
,redTeamTexture,m_karts[i]->getNode(), true);
|
||||||
|
else
|
||||||
|
hatNode = irr_driver->addBillboard(core::dimension2d<irr::f32>(0.3,0.3)
|
||||||
|
,blueTeamTexture,m_karts[i]->getNode(),true);
|
||||||
|
hatNode->setPosition(m_karts[i]->getKartModel()->getHatOffset());
|
||||||
|
}
|
||||||
|
|
||||||
// Compute start positions for each team
|
// Compute start positions for each team
|
||||||
int team_cur_position[NB_SOCCER_TEAMS];
|
int team_cur_position[NB_SOCCER_TEAMS];
|
||||||
team_cur_position[0] = 1;
|
team_cur_position[0] = 1;
|
||||||
@ -234,9 +347,65 @@ void SoccerWorld::initKartList()
|
|||||||
// Set kart positions, ordering them by team
|
// Set kart positions, ordering them by team
|
||||||
for(unsigned int n=0; n<kart_amount; n++)
|
for(unsigned int n=0; n<kart_amount; n++)
|
||||||
{
|
{
|
||||||
SoccerTeam team = m_karts[n]->getSoccerTeam();
|
|
||||||
|
SoccerTeam team = race_manager->getLocalKartInfo(n).getSoccerTeam();
|
||||||
m_karts[n]->setPosition(team_cur_position[team]);
|
m_karts[n]->setPosition(team_cur_position[team]);
|
||||||
team_cur_position[team]++;
|
team_cur_position[team]++;
|
||||||
}// next kart
|
}// next kart
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int SoccerWorld::getScore(unsigned int i){
|
||||||
|
return m_team_goals[i];
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int SoccerWorld::getTeamLeader(unsigned int team){
|
||||||
|
for(int i = 0; i< m_karts.size(); i++){
|
||||||
|
if(race_manager->getLocalKartInfo(i).getSoccerTeam() == (SoccerTeam) team)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index,
|
||||||
|
int local_player_id, int global_player_id,
|
||||||
|
RaceManager::KartType kart_type)
|
||||||
|
{
|
||||||
|
int posIndex = index;
|
||||||
|
if(race_manager->getLocalKartInfo(index).getSoccerTeam() == SOCCER_TEAM_RED){
|
||||||
|
if(index % 2 != 0) posIndex += 1;
|
||||||
|
}
|
||||||
|
else if(race_manager->getLocalKartInfo(index).getSoccerTeam() == SOCCER_TEAM_BLUE){
|
||||||
|
if(index % 2 != 1) posIndex += 1;
|
||||||
|
}
|
||||||
|
int position = index+1;
|
||||||
|
btTransform init_pos = m_track->getStartTransform(posIndex);
|
||||||
|
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos);
|
||||||
|
new_kart->init(race_manager->getKartType(index));
|
||||||
|
Controller *controller = NULL;
|
||||||
|
switch(kart_type)
|
||||||
|
{
|
||||||
|
case RaceManager::KT_PLAYER:
|
||||||
|
controller = new PlayerController(new_kart,
|
||||||
|
StateManager::get()->getActivePlayer(local_player_id),
|
||||||
|
local_player_id);
|
||||||
|
m_num_players ++;
|
||||||
|
break;
|
||||||
|
case RaceManager::KT_NETWORK_PLAYER:
|
||||||
|
break; // Avoid compiler warning about enum not handled.
|
||||||
|
//controller = new NetworkController(kart_ident, position, init_pos,
|
||||||
|
// global_player_id);
|
||||||
|
//m_num_players++;
|
||||||
|
//break;
|
||||||
|
case RaceManager::KT_AI:
|
||||||
|
controller = loadAIController(new_kart);
|
||||||
|
break;
|
||||||
|
case RaceManager::KT_GHOST:
|
||||||
|
break;
|
||||||
|
case RaceManager::KT_LEADER:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_kart->setController(controller);
|
||||||
|
|
||||||
|
return new_kart;
|
||||||
|
} // createKart
|
@ -23,6 +23,7 @@
|
|||||||
#include "states_screens/race_gui_base.hpp"
|
#include "states_screens/race_gui_base.hpp"
|
||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
|
|
||||||
|
|
||||||
#include <IMesh.h>
|
#include <IMesh.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -30,6 +31,8 @@
|
|||||||
#define CLEAR_SPAWN_RANGE 5
|
#define CLEAR_SPAWN_RANGE 5
|
||||||
|
|
||||||
class PhysicalObject;
|
class PhysicalObject;
|
||||||
|
class AbstractKart;
|
||||||
|
class Controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief An implementation of World, to provide the soccer game mode
|
* \brief An implementation of World, to provide the soccer game mode
|
||||||
@ -41,11 +44,16 @@ private:
|
|||||||
/** Number of goals each team scored
|
/** Number of goals each team scored
|
||||||
*/
|
*/
|
||||||
int m_team_goals[NB_SOCCER_TEAMS];
|
int m_team_goals[NB_SOCCER_TEAMS];
|
||||||
|
/** Number of goals needed to win
|
||||||
|
*/
|
||||||
|
int m_goal_target;
|
||||||
/** Whether or not goals can be scored (they are disabled when a point is scored
|
/** Whether or not goals can be scored (they are disabled when a point is scored
|
||||||
and re-enabled when the next game can be played)*/
|
and re-enabled when the next game can be played)*/
|
||||||
bool m_can_score_points;
|
bool m_can_score_points;
|
||||||
|
|
||||||
|
/** Team karts */
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SoccerWorld();
|
SoccerWorld();
|
||||||
@ -63,16 +71,23 @@ public:
|
|||||||
virtual bool useFastMusicNearEnd() const { return false; }
|
virtual bool useFastMusicNearEnd() const { return false; }
|
||||||
virtual void getKartsDisplayInfo(
|
virtual void getKartsDisplayInfo(
|
||||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info);
|
std::vector<RaceGUIBase::KartIconDisplayInfo> *info);
|
||||||
|
int getScore(unsigned int i);
|
||||||
virtual bool raceHasLaps(){ return false; }
|
virtual bool raceHasLaps(){ return false; }
|
||||||
|
virtual void moveKartAfterRescue(AbstractKart* kart);
|
||||||
|
|
||||||
virtual const std::string& getIdent() const;
|
virtual const std::string& getIdent() const;
|
||||||
|
|
||||||
virtual void update(float dt);
|
virtual void update(float dt);
|
||||||
|
|
||||||
void onCheckGoalTriggered(bool first_goal);
|
void onCheckGoalTriggered(bool first_goal);
|
||||||
|
int getTeamLeader(unsigned int i);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initKartList();
|
void initKartList();
|
||||||
|
protected:
|
||||||
|
virtual AbstractKart *createKart(const std::string &kart_ident, int index,
|
||||||
|
int local_player_id, int global_player_id,
|
||||||
|
RaceManager::KartType type);
|
||||||
}; // SoccerWorld
|
}; // SoccerWorld
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ public:
|
|||||||
virtual btTransform getRescueTransform(unsigned int index) const OVERRIDE;
|
virtual btTransform getRescueTransform(unsigned int index) const OVERRIDE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}; // WorldWithRank
|
}; // WorldWithRank
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
void setHostId(int id) { m_host_id = id; }
|
void setHostId(int id) { m_host_id = id; }
|
||||||
void setLocalPlayerId(int id) { m_local_player_id = id; }
|
void setLocalPlayerId(int id) { m_local_player_id = id; }
|
||||||
void setGlobalPlayerId(int id) { m_global_player_id = id; }
|
void setGlobalPlayerId(int id) { m_global_player_id = id; }
|
||||||
void setSoccerTeam(SoccerTeam team) { m_soccer_team = team; }
|
const void setSoccerTeam(SoccerTeam team) { m_soccer_team = team; }
|
||||||
|
|
||||||
int getHostId() const { return m_host_id; }
|
int getHostId() const { return m_host_id; }
|
||||||
int getLocalPlayerId() const { return m_local_player_id; }
|
int getLocalPlayerId() const { return m_local_player_id; }
|
||||||
|
@ -331,6 +331,7 @@ private:
|
|||||||
int m_coin_target;
|
int m_coin_target;
|
||||||
bool m_has_time_target;
|
bool m_has_time_target;
|
||||||
float m_time_target;
|
float m_time_target;
|
||||||
|
int m_goal_target;
|
||||||
|
|
||||||
void startNextRace(); // start a next race
|
void startNextRace(); // start a next race
|
||||||
|
|
||||||
@ -390,6 +391,10 @@ public:
|
|||||||
|
|
||||||
bool hasTimeTarget() const { return m_has_time_target; }
|
bool hasTimeTarget() const { return m_has_time_target; }
|
||||||
|
|
||||||
|
void setMaxGoal(int maxGoal){ m_goal_target = maxGoal; }
|
||||||
|
|
||||||
|
int getMaxGoal(){ return m_goal_target; }
|
||||||
|
|
||||||
/** Sort karts and update the m_gp_rank KartStatus member, in preparation
|
/** Sort karts and update the m_gp_rank KartStatus member, in preparation
|
||||||
* for future calls to RaceManager::getKartGPRank or
|
* for future calls to RaceManager::getKartGPRank or
|
||||||
* RaceManager::getKartWithGPRank
|
* RaceManager::getKartWithGPRank
|
||||||
|
@ -44,6 +44,7 @@ using namespace irr;
|
|||||||
#include "modes/follow_the_leader.hpp"
|
#include "modes/follow_the_leader.hpp"
|
||||||
#include "modes/linear_world.hpp"
|
#include "modes/linear_world.hpp"
|
||||||
#include "modes/world.hpp"
|
#include "modes/world.hpp"
|
||||||
|
#include "modes/soccer_world.hpp"
|
||||||
#include "race/race_manager.hpp"
|
#include "race/race_manager.hpp"
|
||||||
#include "tracks/track.hpp"
|
#include "tracks/track.hpp"
|
||||||
#include "utils/constants.hpp"
|
#include "utils/constants.hpp"
|
||||||
@ -191,6 +192,8 @@ void RaceGUI::renderGlobal(float dt)
|
|||||||
{
|
{
|
||||||
drawGlobalPlayerIcons(m_map_height);
|
drawGlobalPlayerIcons(m_map_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(world->getTrack()->isSoccer()) drawScores();
|
||||||
} // renderGlobal
|
} // renderGlobal
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -226,6 +229,63 @@ void RaceGUI::renderPlayerView(const Camera *camera, float dt)
|
|||||||
RaceGUIBase::renderPlayerView(camera, dt);
|
RaceGUIBase::renderPlayerView(camera, dt);
|
||||||
} // renderPlayerView
|
} // renderPlayerView
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void RaceGUI::drawScores()
|
||||||
|
{
|
||||||
|
SoccerWorld* soccerWorld = (SoccerWorld*)World::getWorld();
|
||||||
|
int offsetY = 5;
|
||||||
|
int offsetX = 5;
|
||||||
|
gui::ScalableFont* font = GUIEngine::getFont();
|
||||||
|
static video::SColor color = video::SColor(255,255,255,255);
|
||||||
|
|
||||||
|
//Draw kart icons above score(denoting teams)
|
||||||
|
irr::video::ITexture *red_team = irr_driver->getTexture(
|
||||||
|
file_manager->getTextureFile("soccer_ball_red.png"));
|
||||||
|
irr::video::ITexture *blue_team = irr_driver->getTexture(
|
||||||
|
file_manager->getTextureFile("soccer_ball_blue.png"));
|
||||||
|
|
||||||
|
core::rect<s32> indicatorPos(offsetX-6, offsetY,
|
||||||
|
offsetX -6 + red_team->getSize().Width/8,
|
||||||
|
offsetY + red_team->getSize().Height/8);
|
||||||
|
core::rect<s32> sourceRect(core::position2d<s32>(0,0),
|
||||||
|
red_team->getOriginalSize());
|
||||||
|
irr_driver->getVideoDriver()->draw2DImage(red_team,indicatorPos,sourceRect,
|
||||||
|
NULL,NULL,true);
|
||||||
|
|
||||||
|
|
||||||
|
for(unsigned int i=0; i<soccerWorld->getNumKarts(); i++){
|
||||||
|
int j = soccerWorld->getTeamLeader(i);
|
||||||
|
if(j < 0) break;
|
||||||
|
|
||||||
|
core::rect<s32> source(j*m_marker_rendered_size, 0,
|
||||||
|
(j+1)*m_marker_rendered_size,m_marker_rendered_size);
|
||||||
|
core::recti position(offsetX, offsetY,
|
||||||
|
offsetX + 2*m_marker_player_size, offsetY + 2*m_marker_player_size);
|
||||||
|
irr_driver->getVideoDriver()->draw2DImage(m_marker, position, source,
|
||||||
|
NULL, NULL, true);
|
||||||
|
core::stringw score = StringUtils::toWString(soccerWorld->getScore(i));
|
||||||
|
int stringWidth =
|
||||||
|
GUIEngine::getFont()->getDimension(score.c_str()).Width;
|
||||||
|
int stringHeight =
|
||||||
|
GUIEngine::getFont()->getDimension(score.c_str()).Height;
|
||||||
|
core::recti pos(position.UpperLeftCorner.X + 5,
|
||||||
|
position.LowerRightCorner.Y + offsetY,
|
||||||
|
position.LowerRightCorner.X,
|
||||||
|
position.LowerRightCorner.Y + stringHeight);
|
||||||
|
|
||||||
|
font->draw(score.c_str(),pos,color);
|
||||||
|
offsetX += position.LowerRightCorner.X;
|
||||||
|
}
|
||||||
|
offsetX = 80;
|
||||||
|
offsetY = 5;
|
||||||
|
indicatorPos = core::rect<s32>(offsetX, offsetY,
|
||||||
|
offsetX + blue_team->getSize().Width/8,
|
||||||
|
offsetY + blue_team->getSize().Height/8);
|
||||||
|
sourceRect = core::rect<s32> (core::position2d<s32>(0,0),
|
||||||
|
blue_team->getOriginalSize());
|
||||||
|
irr_driver->getVideoDriver()->draw2DImage(blue_team,indicatorPos,sourceRect,
|
||||||
|
NULL,NULL,true);
|
||||||
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Displays the racing time on the screen.s
|
/** Displays the racing time on the screen.s
|
||||||
*/
|
*/
|
||||||
|
@ -105,6 +105,8 @@ private:
|
|||||||
/** Display items that are shown once only (for all karts). */
|
/** Display items that are shown once only (for all karts). */
|
||||||
void drawGlobalMiniMap ();
|
void drawGlobalMiniMap ();
|
||||||
void drawGlobalTimer ();
|
void drawGlobalTimer ();
|
||||||
|
void drawScores();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ void SoccerSetupScreen::eventCallback(Widget* widget, const std::string& name, c
|
|||||||
if(name == "continue")
|
if(name == "continue")
|
||||||
{
|
{
|
||||||
StateManager::get()->pushScreen( ArenasScreen::getInstance() );
|
StateManager::get()->pushScreen( ArenasScreen::getInstance() );
|
||||||
|
race_manager->setMaxGoal(getWidget<SpinnerWidget>("goalamount")->getValue());
|
||||||
}
|
}
|
||||||
else if (name == "back")
|
else if (name == "back")
|
||||||
{
|
{
|
||||||
@ -221,7 +222,7 @@ GUIEngine::EventPropagation SoccerSetupScreen::filterActions( PlayerAction acti
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(team_switch != SOCCER_TEAM_NONE) // A player wants to change its team?
|
if(team_switch != SOCCER_TEAM_NONE) // A player wants to change his team?
|
||||||
{
|
{
|
||||||
// Find the corresponding kart view, update its team and update the layout
|
// Find the corresponding kart view, update its team and update the layout
|
||||||
for(int i=0 ; i < nb_players ; i++)
|
for(int i=0 ; i < nb_players ; i++)
|
||||||
|
Loading…
Reference in New Issue
Block a user