Allow random items number and type for arena with navmesh.
Number and types are hard-coded for now.
This commit is contained in:
parent
6f5d36f479
commit
d2509baf5c
@ -32,6 +32,7 @@
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/race_event_manager.hpp"
|
||||
#include "tracks/quad_graph.hpp"
|
||||
#include "tracks/battle_graph.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
@ -473,3 +474,96 @@ void ItemManager::switchItems()
|
||||
m_switch_time = m_switch_time < 0 ? stk_config->m_item_switch_time : -1;
|
||||
|
||||
} // switchItems
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos,
|
||||
unsigned int bonus, unsigned int big_nitro,
|
||||
unsigned int small_nitro, unsigned int banana)
|
||||
{
|
||||
if (!BattleGraph::get()) return false;
|
||||
|
||||
if (bonus == 0 && big_nitro == 0 && small_nitro == 0 && banana == 0)
|
||||
return false;
|
||||
|
||||
std::vector<int> used_location;
|
||||
std::vector<int> invalid_location;
|
||||
std::vector<int> final_location;
|
||||
for (unsigned int i = 0; i < pos.size(); i++)
|
||||
{
|
||||
// Load all starting positions of arena, so no items will be near them
|
||||
int node = BattleGraph::get()->pointToNode(/*cur_node*/-1,
|
||||
Vec3(pos[i].getOrigin()), /*ignore_vertical*/true);
|
||||
assert(node != -1);
|
||||
used_location.push_back(node);
|
||||
invalid_location.push_back(node);
|
||||
}
|
||||
|
||||
const unsigned int total_item = bonus + big_nitro + small_nitro + banana;
|
||||
for (unsigned int i = 0; i < total_item; i++)
|
||||
{
|
||||
int chosen_node = -1;
|
||||
const unsigned int total_node = BattleGraph::get()->getNumNodes();
|
||||
while(true)
|
||||
{
|
||||
if (final_location.size() + invalid_location.size() == total_node)
|
||||
{
|
||||
Log::warn("[ItemManager]","Can't place more random items! "
|
||||
"Use default item location.");
|
||||
return false;
|
||||
}
|
||||
|
||||
RandomGenerator random;
|
||||
const int node = random.get(total_node);
|
||||
|
||||
// Check if tried
|
||||
std::vector<int>::iterator it = std::find(invalid_location.begin(),
|
||||
invalid_location.end(), node);
|
||||
if (it != invalid_location.end())
|
||||
continue;
|
||||
|
||||
// Check if near edge
|
||||
if (BattleGraph::get()->isNearEdge(node))
|
||||
{
|
||||
invalid_location.push_back(node);
|
||||
continue;
|
||||
}
|
||||
// Check if too close
|
||||
bool found = true;
|
||||
for (unsigned int j = 0; j < used_location.size(); j++)
|
||||
{
|
||||
if (!found) continue;
|
||||
Vec3 d = BattleGraph::get()
|
||||
->getPolyOfNode(used_location[j]).getCenter() -
|
||||
BattleGraph::get()->getPolyOfNode(node).getCenter();
|
||||
found = d.length_2d() > 20.0f;
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
chosen_node = node;
|
||||
invalid_location.push_back(node);
|
||||
break;
|
||||
}
|
||||
else
|
||||
invalid_location.push_back(node);
|
||||
}
|
||||
|
||||
assert(chosen_node != -1);
|
||||
used_location.push_back(chosen_node);
|
||||
final_location.push_back(chosen_node);
|
||||
}
|
||||
|
||||
assert (final_location.size() == total_item);
|
||||
for (unsigned int i = 0; i < total_item; i++)
|
||||
{
|
||||
Item::ItemType type = (i < bonus ? Item::ITEM_BONUS_BOX :
|
||||
i < bonus + big_nitro ? Item::ITEM_NITRO_BIG :
|
||||
i < bonus + big_nitro + small_nitro ? Item::ITEM_NITRO_SMALL :
|
||||
Item::ITEM_BANANA);
|
||||
Vec3 loc = BattleGraph::get()
|
||||
->getPolyOfNode(final_location[i]).getCenter();
|
||||
Item* item = newItem(type, loc, Vec3(0, 1, 0));
|
||||
BattleGraph::get()->insertItems(item, final_location[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
} // randomItemsForArena
|
||||
|
@ -19,7 +19,10 @@
|
||||
#ifndef HEADER_ITEMMANAGER_HPP
|
||||
#define HEADER_ITEMMANAGER_HPP
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
|
||||
#include "items/item.hpp"
|
||||
#include "utils/aligned_array.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
#include <SColor.h>
|
||||
@ -110,6 +113,10 @@ public:
|
||||
int add_info=-1);
|
||||
void switchItems ();
|
||||
// ------------------------------------------------------------------------
|
||||
bool randomItemsForArena(const AlignedArray<btTransform>& pos,
|
||||
unsigned int bonus, unsigned int big_nitro,
|
||||
unsigned int small_nitro, unsigned int banana);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the number of items. */
|
||||
unsigned int getNumberOfItems() const { return (unsigned int) m_all_items.size(); }
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -116,7 +116,11 @@ public:
|
||||
const NavPoly& getPolyOfNode(int i) const
|
||||
{ return NavMesh::get()->getNavPoly(i); }
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if the NavPoly lies near the edge. */
|
||||
bool isNearEdge(int i) const
|
||||
{ return NavMesh::get()->getNavPoly(i).isPolyNearEdge(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the next polygon on the shortest path from i to j.
|
||||
* Note: m_parent_poly[j][i] contains the parent of i on path from j to i,
|
||||
* which is the next node on the path from i to j (undirected graph) */
|
||||
@ -124,9 +128,12 @@ public:
|
||||
|
||||
const std::vector < std::pair<const Item*, int> >& getItemList()
|
||||
{ return m_items_on_graph; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void insertItems(Item* item, int polygon)
|
||||
{ m_items_on_graph.push_back(std::make_pair(item, polygon)); }
|
||||
// ------------------------------------------------------------------------
|
||||
void findItemsOnGraphNodes();
|
||||
// ----------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
int pointToNode(const int cur_node,
|
||||
const Vec3& cur_point,
|
||||
bool ignore_vertical) const;
|
||||
|
@ -45,11 +45,11 @@ public:
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the center point of a polygon. */
|
||||
const Vec3& getCenter() const {return m_center;}
|
||||
const Vec3& getCenter() const { return m_center; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the adjacent polygons of a polygon. */
|
||||
const std::vector<int>& getAdjacents() const {return m_adjacents;}
|
||||
const std::vector<int>& getAdjacents() const { return m_adjacents; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the vertices(Vec3) of this polygon. */
|
||||
@ -57,13 +57,17 @@ public:
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the indices of the vertices of this polygon */
|
||||
const std::vector<int> getVerticesIndex() const {return m_vertices;}
|
||||
|
||||
const std::vector<int> getVerticesIndex() const
|
||||
{ return m_vertices; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if a given point lies in this polygon. */
|
||||
bool pointInPoly(const Vec3& p,
|
||||
bool ignore_vertical) const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if this polygon lies near the edge. */
|
||||
bool isPolyNearEdge() const
|
||||
{ return m_adjacents.size() < 4; }
|
||||
// ------------------------------------------------------------------------
|
||||
const Vec3& operator[](int i) const ;
|
||||
|
||||
}; // class NavPoly
|
||||
|
@ -1862,22 +1862,27 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
|
||||
createPhysicsModel(main_track_count);
|
||||
|
||||
const bool arena_random_item = (m_has_navmesh && ItemManager::get()
|
||||
->randomItemsForArena(m_start_transforms,5,2,2,1));
|
||||
|
||||
for (unsigned int i=0; i<root->getNumNodes(); i++)
|
||||
if (!arena_random_item)
|
||||
{
|
||||
const XMLNode *node = root->getNode(i);
|
||||
const std::string &name = node->getName();
|
||||
if (name=="banana" || name=="item" ||
|
||||
name=="small-nitro" || name=="big-nitro" ||
|
||||
name=="easter-egg" )
|
||||
for (unsigned int i=0; i<root->getNumNodes(); i++)
|
||||
{
|
||||
itemCommand(node);
|
||||
}
|
||||
} // for i<root->getNumNodes()
|
||||
const XMLNode *node = root->getNode(i);
|
||||
const std::string &name = node->getName();
|
||||
if (name=="banana" || name=="item" ||
|
||||
name=="small-nitro" || name=="big-nitro" ||
|
||||
name=="easter-egg" )
|
||||
{
|
||||
itemCommand(node);
|
||||
}
|
||||
} // for i<root->getNumNodes()
|
||||
}
|
||||
|
||||
delete root;
|
||||
|
||||
if ((m_is_arena || m_is_soccer) && !m_is_cutscene && m_has_navmesh)
|
||||
if ((m_is_arena || m_is_soccer) && !m_is_cutscene && m_has_navmesh && !arena_random_item)
|
||||
BattleGraph::get()->findItemsOnGraphNodes();
|
||||
|
||||
if (UserConfigParams::m_track_debug &&
|
||||
|
Loading…
Reference in New Issue
Block a user