Pre-spawn spare tire karts on random nodes in graph

Don't use the item location, as it can be remembered by players
This commit is contained in:
Benau 2016-10-09 11:17:36 +08:00
parent 357567ae8d
commit 6b8156c254
6 changed files with 48 additions and 30 deletions

View File

@ -43,10 +43,7 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
m_distance_2 = 1.2f;
initItem(type, xyz);
Vec3 axis = -normal.cross(Vec3(0, 1, 0));
if (axis.length() == 0)
axis = Vec3(0, 0, 1);
m_original_rotation = btQuaternion(axis, normal.angle(Vec3(0, 1, 0)));
m_original_rotation = Track::createRotationFromNormal(normal);
m_rotation_angle = 0.0f;
m_original_mesh = mesh;
m_original_lowmesh = lowres_mesh;

View File

@ -276,9 +276,6 @@ public:
{
return (scene::ISceneNode *) m_node;
}
// ------------------------------------------------------------------------
const btQuaternion& getRotation() const { return m_original_rotation; }
}; // class Item
#endif

View File

@ -23,7 +23,6 @@
#include "graphics/camera.hpp"
#include "graphics/irr_driver.hpp"
#include "io/file_manager.hpp"
#include "items/item_manager.hpp"
#include "karts/kart.hpp"
#include "karts/controller/spare_tire_ai.hpp"
#include "karts/kart_model.hpp"
@ -32,10 +31,12 @@
#include "physics/physics.hpp"
#include "states_screens/race_gui_base.hpp"
#include "tracks/arena_graph.hpp"
#include "tracks/arena_node.hpp"
#include "tracks/track.hpp"
#include "tracks/track_object_manager.hpp"
#include "utils/constants.hpp"
#include <algorithm>
#include <string>
#include <IMeshSceneNode.h>
@ -675,27 +676,44 @@ void ThreeStrikesBattle::spawnSpareTireKarts()
//-----------------------------------------------------------------------------
void ThreeStrikesBattle::loadCustomModels()
{
// Pre-add spare tire karts
if (ArenaGraph::get())
// Pre-add spare tire karts if there are more than certain number of karts
ArenaGraph* ag = ArenaGraph::get();
if (ag && m_karts.size() > 4)
{
// Spare tire karts only added with large arena
const int all_nodes = ArenaGraph::get()->getNumNodes();
if (all_nodes > 200)
const int all_nodes = ag->getNumNodes();
if (all_nodes > 500)
{
// Don't create too many spare tire karts
const unsigned int max_sta_num = unsigned(m_karts.size() * 0.8f);
unsigned int pos_created = 0;
std::vector<int> used;
std::vector<btTransform> pos;
for (int i = 0; i < all_nodes; i++)
// Fill all current starting position into used first
for (unsigned int i = 0; i < getNumberOfRescuePositions(); i++)
{
// Pre-spawn the spare tire karts on the item position,
// preven affecting current karts
Item* item = ItemManager::get()->getFirstItemInQuad(i);
if (item == NULL) continue;
int node = -1;
ag->findRoadSector(getRescueTransform(i).getOrigin(), &node,
NULL, true);
assert(node != -1);
used.push_back(node);
}
// Find random nodes to pre-spawn spare tire karts
RandomGenerator random;
while (true)
{
const int node = random.get(all_nodes);
if (std::find(used.begin(), used.end(), node) != used.end())
continue;
const ArenaNode* n = ag->getNode(node);
btTransform t;
t.setOrigin(item->getXYZ());
t.setRotation(item->getRotation());
t.setOrigin(n->getCenter());
t.setRotation(Track::createRotationFromNormal(n->getNormal()));
pos.push_back(t);
pos_created++;
used.push_back(node);
if (pos_created >= max_sta_num) break;
}
@ -715,16 +733,17 @@ void ThreeStrikesBattle::loadCustomModels()
sta->setController(new SpareTireAI(sta));
m_karts.push_back(sta);
race_manager->addSpareTireKartStatus(sta_list[i]);
race_manager->addSpareTireKart(sta_list[i]);
m_track->adjustForFog(sta->getNode());
// Copy STA pointer to m_spare_tire_karts array, allowing them
// to respawn easily
m_spare_tire_karts.push_back(sta);
}
race_manager->setNumKarts(m_karts.size());
assert(m_spare_tire_karts.size() ==
race_manager->getNumSpareTireKarts());
unsigned int sta_num = race_manager->getNumSpareTireKarts();
assert(m_spare_tire_karts.size() == sta_num);
Log::info("ThreeStrikesBattle","%d spare tire kart(s) created.",
sta_num);
}
}
} // loadCustomModels

View File

@ -754,12 +754,13 @@ public:
return m_watching_replay;
} // isWatchingReplay
// ------------------------------------------------------------------------
void addSpareTireKartStatus(const std::string& name)
void addSpareTireKart(const std::string& name)
{
m_kart_status.push_back(KartStatus(name, 0, -1, -1,
-1, KT_SPARE_TIRE, PLAYER_DIFFICULTY_NORMAL));
m_num_spare_tire_karts++;
} // addSpareTireKartStatus
m_num_karts++;
} // addSpareTireKart
// ------------------------------------------------------------------------
void setSpareTireKartNum(unsigned int i)
{

View File

@ -702,11 +702,7 @@ btQuaternion Track::getArenaStartRotation(const Vec3& xyz, float heading)
}
const Vec3& normal = Graph::get()->getQuad(node)->getNormal();
Vec3 axis = -normal.cross(Vec3(0, 1, 0));
if (axis.length() == 0)
axis = Vec3(0, 0, 1);
btQuaternion q(axis, normal.angle(Vec3(0, 1, 0)));
btQuaternion q = createRotationFromNormal(normal);
btMatrix3x3 m;
m.setRotation(q);
return btQuaternion(m.getColumn(1), heading * DEGREE_TO_RAD) * q;

View File

@ -397,6 +397,14 @@ public:
static const float NOHIT;
static btQuaternion createRotationFromNormal(const Vec3& normal)
{
Vec3 axis = -normal.cross(Vec3(0, 1, 0));
if (axis.length() == 0)
axis = Vec3(0, 0, 1);
return btQuaternion(axis, normal.angle(Vec3(0, 1, 0)));
} // createRotationFromNormal
Track (const std::string &filename);
~Track ();
void cleanup ();