#include "stdafx.h" #include "v8tree/instance.h" #include "v8tree/service.h" #include "v8datamodel/teams.h" #include "V8Datamodel/DataModel.h" #include "network/player.h" #include "network/players.h" #include "v8DataModel/workspace.h" #include "Humanoid/Humanoid.h" namespace RBX { const char *const sTeams = "Teams"; REFLECTION_BEGIN(); static Reflection::BoundFuncDesc teams_rebalanceTeamsFunction(&Teams::rebalanceTeams, "RebalanceTeams", Security::None, Reflection::Descriptor::Attributes::deprecated()); static Reflection::BoundFuncDesc()> func_teams(&Teams::getTeams, "GetTeams", Security::None); REFLECTION_END(); Teams::Teams() : teams(Instances()) // Initialize to a non-NULL value { setName(sTeams); } Teams::~Teams() { } bool Teams::isTeamGame() { /* returns true if any player is non-neutral */ if(Network::Players *players = ServiceProvider::find(this)){ for(unsigned int n = 0; n < players->numChildren(); n++) { Network::Player* p = Instance::fastDynamicCast(players->getChild(n)); if (p == NULL) continue; // only care about player objects if (p->getNeutral() == false) return true; } } return false; } void Teams::rebalanceTeams() { // Do the elegant but slow thing - O(n^2) /* Network::Players *players = ServiceProvider::find(this); RBXASSERT(players); for(unsigned int n = 0; n < players->numChildren(); n++) { Network::Player* p = Instance::fastDynamicCast(players->getChild(n)); p->setTeam(NULL); assignNewPlayerToTeam(p); } */ } void Teams::assignNewPlayerToTeam(Network::Player *p) { // find all team children of this service with the assignable property == true // put the player on the team that has the least people. BrickColor best = BrickColor::brickGreen(); int best_count = 10000; bool found = false; // found one for(unsigned int i = 0; i < this->numChildren(); i++) { Team* child = Instance::fastDynamicCast(this->getChild(i)); if(child != NULL) { if(child->getAutoAssignable() == true) { int count = getNumPlayersInTeam(child->getTeamColor()); if (count < best_count) { best = child->getTeamColor(); best_count = count; found = true; } } } } if (found) { p->setTeamColor(best); p->setNeutral(false); } } int Teams::getNumPlayersInTeam(BrickColor color) { int result = 0; Network::Players *players = ServiceProvider::find(this); RBXASSERT(players); for(unsigned int n = 0; n < players->numChildren(); n++) { Network::Player* p = Instance::fastDynamicCast(players->getChild(n)); if (p == NULL) continue; // only care about player objects if (p->getNeutral() == false && p->getTeamColor() == color) result++; } return result; } bool Teams::teamExists(BrickColor color) { return (getTeamFromTeamColor(color) != NULL); } Team *Teams::getTeamFromTeamColor(BrickColor c) { for(unsigned int i = 0; i < numChildren(); i ++) { Team *t = Instance::fastDynamicCast(getChild(i)); if (t && t->getTeamColor() == c) return t; } return NULL; } Team *Teams::getTeamFromPlayer(Network::Player *p) { if(p->getNeutral()) return NULL; return getTeamFromTeamColor(p->getTeamColor()); } BrickColor Teams::getUnusedTeamColor() { BrickColor::Colors vec(BrickColor::allColors()); BrickColor::Colors::iterator iter; for(iter = vec.begin(); iter != vec.end(); iter++) { BrickColor c = *iter; for(unsigned int i = 0; i < numChildren(); i ++) { if (Team *t = Instance::fastDynamicCast(getChild(i))) if (t->getTeamColor() == c) vec.erase(iter); } } RBXASSERT(vec.size() > 0); return vec[rand() % vec.size()]; } G3D::Color3 Teams::getTeamColorForHumanoid(Humanoid *h) { Network::Players *players = ServiceProvider::find(this); RBXASSERT(players); if (players) { for(unsigned int n = 0; n < players->numChildren(); n++) { if (Network::Player* p = Instance::fastDynamicCast(players->getChild(n))) if (p->getNeutral() == false) if (ModelInstance *m = p->getCharacter()) if (m->findFirstChildOfType() == h) return p->getTeamColor().color3(); } } return G3D::Color3::white(); } void Teams::onChildAdded(Instance* child) { if (Team* t = Instance::fastDynamicCast(child)) { boost::shared_ptr& c = teams.write(); c->push_back(shared_from(t)); } } void Teams::onChildRemoving(Instance* child) { if (Team* t = Instance::fastDynamicCast(child)) { boost::shared_ptr& c = teams.write(); c->erase(std::find(c->begin(), c->end(), shared_from(t))); } } } // namespace