khanat-opennel-code/code/ryzom/server/src/ags_test/position_generator.cpp

206 lines
5.1 KiB
C++

// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "position_generator.h"
#include <nel/misc/debug.h>
namespace AGS_TEST
{
// instantiating static class variables
int CPositionGenerator::_x=0;
int CPositionGenerator::_y=0;
int CPositionGenerator::_dx=0;
int CPositionGenerator::_dy=0;
int CPositionGenerator::_spacing=0;
std::string CPositionGenerator::_pattern("grid");
int CPositionGenerator::_linelen=0;
int CPositionGenerator::_leftonline=0;
std::string CPositionGenerator::_spawnZoneName="";
CPositionGenerator::TSpawnZoneMap CPositionGenerator::_spawnZones;
CPositionGenerator::TSpawnPointMap CPositionGenerator::_spawnPoints;
void CPositionGenerator::setPositionInMM(int x, int y)
{
_x=x;
_y=y;
_linelen=0;
_leftonline=0;
init();
nlinfo("Set spawn position to: %d, %d", (_x+500)/1000, (_y+500)/1000);
}
void CPositionGenerator::setPosition(int x, int y)
{
setPositionInMM(1000*x,1000*y);
}
void CPositionGenerator::setPosition(std::string spawnName) // name of a spawn point or spawn zone
{
if (_spawnPoints.find(spawnName)!=_spawnPoints.end())
{
setPositionInMM( (int)(_spawnPoints[spawnName].Point.x*1000.0f), (int)(_spawnPoints[spawnName].Point.y*1000.0f) );
}
else if (_spawnZones.find(spawnName)!=_spawnZones.end())
{
_spawnZoneName=spawnName;
setPattern("spawnZone");
NLMISC::CVector v=_spawnZones[_spawnZoneName].getNext();
setPositionInMM((int)(v.x*1000.0f),(int)(v.y*1000.0f));
nlinfo("Set spawn Zone to: %s",_spawnZoneName.c_str());
}
else
{
nlinfo("Unknown spawn zone/point: %s",spawnName.c_str());
}
}
void CPositionGenerator::setSpacing(int spacing)
{
_spacing=1000*spacing;
init();
}
void CPositionGenerator::setPattern(const std::string &pattern)
{
_pattern=pattern;
init();
}
void CPositionGenerator::init()
{
_dx=_spacing;
_dy=0;
_linelen=0;
_leftonline=0;
}
void CPositionGenerator::next(int &x, int &y)
{
x=_x;
y=_y;
// nlinfo("Pattern: %s: dx: %d dy: %d spacing: %d",_pattern.c_str(),_dx,_dy,_spacing);
if (_pattern==std::string("grid"))
{
if (_leftonline)
_leftonline--;
else
{
if (_dx)
_linelen++;
_leftonline=_linelen;
_dx+=_dy;
_dy-=_dx;
_dx+=_dy;
}
_x+=_dx;
_y+=_dy;
}
else if (_pattern==std::string("line"))
{
_x+=_dx;
_y+=_dy;
}
else if (_pattern==std::string("spawnZone"))
{
NLMISC::CVector v=_spawnZones[_spawnZoneName].getNext();
_x=(int)(v.x*1000.0f);
_y=(int)(v.y*1000.0f);
}
else
nlwarning("Unknown pattern: %s",_pattern.c_str());
}
void CPositionGenerator::addSpawnZone(const NLLIGO::CPrimZone &zone)
{
if (_spawnZones[zone.getName()].Points.size()!=0)
{
nlinfo("Spawn zone already exists: %s",zone.getName().c_str());
return;
}
// determine the extents of the zone
float minx=(float)(((uint)~0)>>1);
float maxx=-minx-1.0f;
float miny=minx;
float maxy=maxx;
for (uint i=0;i<zone.VPoints.size();i++)
{
if (zone.VPoints[i].x<minx) minx=zone.VPoints[i].x;
if (zone.VPoints[i].x>maxx) maxx=zone.VPoints[i].x;
if (zone.VPoints[i].y<miny) miny=zone.VPoints[i].y;
if (zone.VPoints[i].y>maxy) maxy=zone.VPoints[i].y;
}
// round off the zone extents to centre the bounding box about the zone centre
const float SPACING=4.0f;
float xbase= ((maxx-minx)/2.0f+minx);
float ybase= ((maxx-minx)/2.0f+miny);
int xcount=(int)((maxx-xbase)/SPACING);
int ycount=(int)((maxy-ybase)/SPACING);
// loop through the points in the bounding box seeing whether or not they're in the zone
for (int xi=-xcount;xi<xcount+1; xi++)
for (int yi=-ycount;yi<ycount+1; yi++)
{
NLMISC::CVector v( xbase+SPACING*(float)xi, ybase+SPACING*(float)yi, 0);
if (zone.contains(v))
{
// we've got a point that is in the zone so add it to the spawn zone point array
_spawnZones[zone.getName()].Points.push_back(v);
}
}
// add code here to shuffle the points in the zone
// check that the zone's not empty
if (_spawnZones[zone.getName()].Points.size()!=0)
{
nlinfo("Spawn zone '%s' contains %d spawn points",zone.getName().c_str(), _spawnZones[zone.getName()].Points.size());
}
else
{
nlwarning("FAILED to generate any points for spawn zone: %s", zone.getName().c_str());
_spawnZones.erase(zone.getName());
}
}
std::string CPositionGenerator::getSpawnName()
{
if (_pattern==std::string("spawnZone"))
return _spawnZoneName;
else
{
char buf[100];
sprintf(buf,"%f %f %f",double(_x)*0.001,double(_y)*0.001,0);
return std::string(buf);
}
}
} // end of namespace AGS_TEST