1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "nel/misc/command.h"
22 #include "nel/misc/variable.h"
23 #include "nel/misc/config_file.h"
24 #include "nel/net/service.h"
25 #include "nel/ligo/primitive_utils.h"
27 #include "game_share/time_weather_season/time_and_season.h"
29 #include "zone_manager.h"
30 #include "mission_manager/mission_manager.h"
31 #include "primitives_parser.h"
32 #include "player_manager/player_manager.h"
33 #include "player_manager/player.h"
34 #include "player_manager/character.h"
35 #include "creature_manager/creature_manager.h"
37 #include "egs_globals.h"
38 #include "phrase_manager/phrase_utilities_functions.h"
39 #include "player_manager/character_respawn_points.h"
40 #include "stables/stable.h"
41 #include "chat_groups_ids.h"
42 #include "pvp_manager/pvp_manager.h"
43 #include "pvp_manager/pvp_manager_2.h"
44 #include "pvp_manager/pvp_safe_zone.h"
46 #include "backward_compatibility/spawn_zones_back_compat.h"
47 #include "backward_compatibility/places_back_compat.h"
49 #include "pvp_manager/pvp.h"
50 #include "pvp_manager/pvp_faction_reward_manager/pvp_faction_reward_manager.h"
52 #include "outpost_manager/outpost_manager.h"
53 #include "modules/shard_unifier_client.h"
56 using namespace NLMISC
;
57 using namespace NLLIGO
;
58 using namespace NLNET
;
61 CEcotypeZones
CZoneManager::_EcotypeZones
;
63 const std::string CContinent::ContNames [] =
72 arg0: is the zone name id
76 arg1 is interpreted as a boolean (0 - inactive, 1 - active)
78 arg1 is interpreted as
80 1 - active with faction point rewards
81 2 - active without faction point rewards
83 void cbSetZoneState( NLNET::CMessage
& msgin
, const std::string
&serviceName
, NLNET::TServiceId serviceId
)
88 msgin
.serial(sZoneName
);
91 CZoneManager
*pZM
= &CZoneManager::getInstance();
94 CPlace
*place
= pZM
->getPlaceFromName(sZoneName
);
96 if (place
->isGooPath())
97 place
->setGooActive(nState
!= 0);
101 // get the deposit zone (linear search)
102 const vector
<CDeposit
*> &rDeps
= pZM
->getDeposits();
103 for (uint32 i
= 0; i
< rDeps
.size(); ++i
)
105 CDeposit
*pd
= rDeps
[i
];
106 if (pd
->getName() == sZoneName
)
108 pd
->enable(nState
!=0);
114 CPVPManager
*pPVPM
= CPVPManager::getInstance();
115 IPVPZone
*pPVPZ
= pPVPM
->getPVPZone(sZoneName
);
118 pPVPZ
->setActive(nState
!=0);
120 CPVPVersusZone
*pPVPVZ
= dynamic_cast<CPVPVersusZone
*>(pPVPZ
);
122 pPVPVZ
->giveFactionPoints(nState
== 1);
127 // TODO : treat other zones !
131 //-----------------------------------------------
133 //-----------------------------------------------
134 /*bool CGooPath::build(const NLLIGO::CPrimPath * path,uint16 id )
137 *( (NLLIGO::CPrimPath*)this ) = *path;
139 if ( !zone->getPropertyByName("name",_Name) )
141 nlwarning("<CGooPath build> : no name in goo place %u", id);
145 if ( VPoints.empty() )
147 nlwarning("<CGooPath build> :no points in goo place %u/%s", id, _Name.c_str());
150 // get the bounding box
151 float minX = VPoints[0].x;
152 float minY = VPoints[0].y;
153 float maxX = VPoints[0].x;
154 float maxY = VPoints[0].y;
155 for ( uint i = 1; i < VPoints.size(); i++)
157 if ( VPoints[i].x < minX )minX = VPoints[i].x;
158 if ( VPoints[i].y < minY )minY = VPoints[i].y;
159 if ( VPoints[i].x > maxX )maxX = VPoints[i].x;
160 if ( VPoints[i].y > maxY )maxY = VPoints[i].y;
162 // get the center of the Box
163 _CenterX = sint32 ( ( minX + maxX ) *1000.0f / 2.0f );
164 _CenterY = sint32 ( ( minY + maxY ) *1000.0f / 2.0f );
169 //-----------------------------------------------
170 // Tp Dest zone build
171 //-----------------------------------------------
172 bool CTpSpawnZone::build(const NLLIGO::CPrimPoint
* point
)
174 *( (NLLIGO::CPrimPoint
*)this ) = *point
;
175 _Continent
= CONTINENT::UNKNOWN
;
177 if ( !point
->getPropertyByName("name",_Name
) )
179 nlwarning("<CTpSpawnZone build> : no name in CTpSpawnZone" );
182 if ( !point
->getPropertyByName("radius",value
) )
184 nlwarning("<CTpSpawnZone build> : no radius in CTpSpawnZone '%s'",_Name
.c_str() );
189 _Radius
= uint16( atof( value
.c_str() ) * 1000.0f
);
190 // get the z value if necessary
191 if ( !point
->getPropertyByName("use_z", value
) )
193 nlwarning("<CTpSpawnZone build> : no use_z in CTpSpawnZone '%s'",_Name
.c_str() );
197 if ( value
== "true" )
199 if ( !point
->getPropertyByName("z", value
) )
201 nlwarning("<CTpSpawnZone build> : no z in CTpSpawnZone '%s'",_Name
.c_str() );
204 NLMISC::fromString(value
, Point
.z
);
205 Point
.z
= float( sint32 (1000.0f
* Point
.z
) );
212 // convert coords in mm
213 Point
.x
= float( sint32 (1000.0f
* Point
.x
) );
214 Point
.y
= float( sint32 (1000.0f
* Point
.y
) );
217 if ( !point
->getPropertyByName("type", value
) )
219 nlwarning("<CTpSpawnZone build> : no type in CTpSpawnZone '%s'",_Name
.c_str() );
222 _Type
= RESPAWN_POINT::toRespawnPointType( value
);
223 if ( _Type
== RESPAWN_POINT::UNKNOWN
)
225 nlwarning("<CTpSpawnZone build> : invalid type '%s' in CTpSpawnZone '%s'",value
.c_str(), _Name
.c_str() );
231 //-----------------------------------------------
233 //-----------------------------------------------
234 bool CPlace::build(const NLLIGO::CPrimPath
* path
, uint16 id
, bool isPrim
)
237 if (!path
->VPoints
.empty())
240 *( (NLLIGO::CPrimZone
*)this ) = *(NLLIGO::CPrimZone
*) path
;
244 if ( isPrim
&& !path
->getPropertyByName("name",_Name
) )
246 nlwarning("<CPlace build> : no name for GooPath %u", id
);
250 if ( VPoints
.empty() )
252 nlwarning("<CPlace build> :no points in GooPath %u/%s", id
, _Name
.c_str());
257 if (path
->getPropertyByName("main place", val
))
258 _MainPlace
= val
== "true";
263 nlverify (CPrimitivesParser::getAlias(path
, _Alias
));
264 // _Alias = NLMISC::fromString( val.c_str() );
265 nlassert( _Alias
!= CAIAliasTranslator::Invalid
);
276 void CPlace::updateCenter()
278 // get the bounding box
279 float minX
= VPoints
[0].x
;
280 float minY
= VPoints
[0].y
;
281 float maxX
= VPoints
[0].x
;
282 float maxY
= VPoints
[0].y
;
283 for ( uint i
= 1; i
< VPoints
.size(); i
++)
285 if ( VPoints
[i
].x
< minX
)minX
= VPoints
[i
].x
;
286 if ( VPoints
[i
].y
< minY
)minY
= VPoints
[i
].y
;
287 if ( VPoints
[i
].x
> maxX
)maxX
= VPoints
[i
].x
;
288 if ( VPoints
[i
].y
> maxY
)maxY
= VPoints
[i
].y
;
290 // get the center of the Box
291 _CenterX
= sint32 ( ( minX
+ maxX
) *1000.0f
/ 2.0f
);
292 _CenterY
= sint32 ( ( minY
+ maxY
) *1000.0f
/ 2.0f
);
296 //-----------------------------------------------
298 //-----------------------------------------------
299 bool CPlace::build(const NLLIGO::CPrimZone
* zone
,uint16 id
, bool reportAutorised
)
302 if (!zone
->VPoints
.empty())
303 *( (NLLIGO::CPrimZone
*)this ) = *zone
;
305 if ( !zone
->getPropertyByName("name",_Name
) )
307 nlwarning("<CPlace build> : no name in place %u", id
);
312 if (zone
->getPropertyByName("reported", val
))
313 _Reported
= val
== "true";
315 _Reported
= true & reportAutorised
;
317 if (zone
->getPropertyByName("main place", val
))
318 _MainPlace
= val
== "true";
322 if (!CPrimitivesParser::getAlias(zone
, _Alias
))
324 nlwarning("Fatal Error, no alias in primitive '%s'",
325 buildPrimPath(zone
).c_str());
328 // _Alias = NLMISC::fromString( val.c_str() );
329 nlassert( _Alias
!= CAIAliasTranslator::Invalid
);
333 if ( VPoints
.empty() )
335 nlwarning("<CPlace build> :no points in place %u/%s", id
, _Name
.c_str());
344 if( zone
->getPropertyByName("place_type", val
) )
346 _PlaceType
= PLACE_TYPE::fromString(val
);
347 if( _PlaceType
== PLACE_TYPE::Undefined
)
348 _PlaceType
= PLACE_TYPE::Place
;
351 _PlaceType
= PLACE_TYPE::Place
;
353 // get children respawn points
355 for (uint i
=0; i
< getNumChildren();++i
)
357 const IPrimitive
*child
;
358 if ( getChild(child
,i
) && child
)
360 child
->getPropertyByName("name",val
);
361 uint16 idx
= CZoneManager::getInstance().getTpSpawnZoneIdByName(val
);
362 if ( idx
!= InvalidSpawnZoneId
)
364 const CTpSpawnZone
* spawn
= CZoneManager::getInstance().getTpSpawnZone( idx
);
367 nlwarning( "Invalid spawn zone '%s' in place '%s' : bad index %u",val
.c_str(), _Name
.c_str(), idx
);
370 // if the respawn point is validated when user enters the place, add it to the place.
371 // we dont add special respawn points ( outposts,... ) because they are validated separatly from the place where they are
372 else if ( spawn
->getType() == RESPAWN_POINT::KAMI
||
373 spawn
->getType() == RESPAWN_POINT::KARAVAN
||
374 spawn
->getType() == RESPAWN_POINT::RANGER
||
375 spawn
->getType() == RESPAWN_POINT::NEWBIELAND
||
376 spawn
->getType() == RESPAWN_POINT::RESPAWNABLE
)
378 (const_cast<CTpSpawnZone
*>(spawn
))->setPlaceType(_PlaceType
);
379 _RespawnPoints
.push_back( idx
);
387 //-----------------------------------------------
389 //-----------------------------------------------
390 bool CRegion::build(const NLLIGO::CPrimZone
* zone
,uint16 id
)
392 if ( CPlace::build(zone
,id
) )
395 if ( !zone
->getPropertyByName("newbie_region",value
) )
397 nlwarning("<CRegion build> : failed : no newbie_region property in primitive");
398 _NewbieRegion
= false;
402 _NewbieRegion
= (!nlstricmp( value
,"true"))?true:false;
408 nlwarning("<CRegion build> : failed in place build");
413 //-----------------------------------------------
415 //-----------------------------------------------
421 //-----------------------------------------------
422 // CRegion registerChatGroup
423 //-----------------------------------------------
424 void CRegion::registerChatGroup()
426 TGroupId idGroup
= CHAT_GROUPS_IDS::getRegionChatGroupId(_Id
);
427 CMessage
msgout("ADD_GROUP");
428 msgout
.serial( idGroup
);
429 CChatGroup::TGroupType type
= CChatGroup::region
;
430 msgout
.serialEnum( type
);
431 sendMessageViaMirror( "IOS", msgout
);
433 // add online members ( if IOS crashed... )
434 set
< CEntityId
>::iterator it
= _Players
.begin();
435 for (; it
!= _Players
.end(); ++it
)
437 TDataSetRow row
= TheDataset
.getDataSetRow( (*it
) );
438 // if we can get the user from this row, the user is ingame
439 CCharacter
* user
= PlayerManager
.getChar( row
);
442 CMessage
msgout("ADD_TO_GROUP");
443 msgout
.serial( idGroup
);
444 msgout
.serial( const_cast<NLMISC::CEntityId
&>(user
->getId()) );
445 sendMessageViaMirror( "IOS", msgout
);
450 //-----------------------------------------------
452 //-----------------------------------------------
453 void CRegion::addPlayer( const NLMISC::CEntityId
& id
)
456 TGroupId idGroup
= CHAT_GROUPS_IDS::getRegionChatGroupId(_Id
);
457 CMessage
msgout("ADD_TO_GROUP");
458 msgout
.serial( idGroup
);
459 msgout
.serial( const_cast<NLMISC::CEntityId
&>(id
) );
460 sendMessageViaMirror( "IOS", msgout
);
463 //-----------------------------------------------
464 // CRegion removePlayer
465 //-----------------------------------------------
466 void CRegion::removePlayer( const NLMISC::CEntityId
& id
)
469 TGroupId idGroup
= CHAT_GROUPS_IDS::getRegionChatGroupId(_Id
);
470 CMessage
msgout("REMOVE_FROM_GROUP");
471 msgout
.serial( idGroup
);
472 msgout
.serial( const_cast<NLMISC::CEntityId
&>(id
) );
473 sendMessageViaMirror( "IOS", msgout
);
476 //-----------------------------------------------
478 //-----------------------------------------------
479 bool CContinent::build(const NLLIGO::CPrimZone
* zone
)
482 if ( zone
->getPropertyByName("id",value
) )
484 _Id
= CONTINENT::toContinent( value
);
485 if ( _Id
!= CONTINENT::UNKNOWN
)
487 return CPlace::build( zone
,_Id
);
490 nlwarning("<CContinent build> : invalid continent id '%s'",value
.c_str());
493 nlwarning("<CContinent build> : no id in a continent");
497 //-----------------------------------------------
499 //-----------------------------------------------
500 CContinent::~CContinent()
506 //-----------------------------------------------
508 //-----------------------------------------------
509 void CZoneManager::init()
511 RandomGenerator
.srand( CTickEventHandler::getGameCycle() );
513 }// CZoneManager init
515 //-----------------------------------------------
516 // CZoneManager release
517 //-----------------------------------------------
518 void CZoneManager::release()
520 for (uint i
= 0; i
< _Deposits
.size(); i
++ )
522 for ( uint i
= 0; i
< _Places
.size(); i
++ )
525 }// CZoneManager release
527 //-----------------------------------------------
528 // CZoneManager initInstance
529 //-----------------------------------------------
530 void CZoneManager::initInstance()
532 _NextDepositIndexUpdated
= 0;
533 _SpreadUpdateLoopBeginTick
= CTickEventHandler::getGameCycle();
535 // get the loaded primitives
536 const CPrimitivesParser::TPrimitivesList
& primsList
= CPrimitivesParser::getInstance().getPrimitives();
538 _PlacesByAlias
.clear();
540 nlinfo("CZoneManager : parsing the zones");
541 CPrimitivesParser::TPrimitivesList::const_iterator first
, last
;
543 for (first
= primsList
.begin(), last
= primsList
.end(); first
!= last
; ++first
)
545 if (! parseContinents(first
->Primitive
.RootNode
) )
547 nlwarning("<CZoneManager constructor> Error while building the continents");
551 for (first
= primsList
.begin(), last
= primsList
.end(); first
!= last
; ++first
)
553 if (! parseRegions(first
->Primitive
.RootNode
) )
555 nlwarning("<CZoneManager constructor> Error while building the regions");
559 for (first
= primsList
.begin(), last
= primsList
.end(); first
!= last
; ++first
)
561 if (! parseTpSpawnZones(first
->Primitive
.RootNode
) )
563 nlwarning("<CZoneManager constructor> Error while building the tp spawn Zones");
567 for (first
= primsList
.begin(), last
= primsList
.end(); first
!= last
; ++first
)
569 if (! parseZones(first
->Primitive
.RootNode
) )
571 nlwarning("<CZoneManager constructor> Error while building the zones");
575 // Parse ecotypes, that will be used when building deposits
576 for (first
= primsList
.begin(), last
= primsList
.end(); first
!= last
; ++first
)
578 if (! parseEcotypes( first
->Primitive
.RootNode
) )
580 nlwarning("<CZoneManager constructor> Error while building the ecotypes");
584 // Parse (and build) deposits
585 for (first
= primsList
.begin(), last
= primsList
.end(); first
!= last
; ++first
)
587 if (! parseDeposits(first
->Primitive
.RootNode
) )
589 nlwarning("<CZoneManager constructor> Error while building the zones");
593 // Don't keep ecotypes in memory, the information is already in the deposits
594 CDeposit::clearEcotypes();
597 for (first
= primsList
.begin(), last
= primsList
.end(); first
!= last
; ++first
)
599 if (! parseStables(first
->Primitive
.RootNode
) )
601 nlwarning("<CZoneManager constructor> Error while building the stables");
605 // Parse the goo border
606 for (first
= primsList
.begin(), last
= primsList
.end(); first
!= last
; ++first
)
608 if (! parseGooBorder(first
->Primitive
.RootNode
) )
610 nlwarning("<CZoneManager constructor> Error while building the Goo Border");
614 // preallocate 5 start points per newbieland
615 _StartPoints
.reserve( 20 );
616 // Parse the start points
617 for (first
= primsList
.begin(), last
= primsList
.end(); first
!= last
; ++first
)
619 if (! parseStartPoints(first
->Primitive
.RootNode
) )
621 nlwarning("<CZoneManager constructor> Error while building the start points");
625 // parse the PVP zones, must be before parsing the PVP safe zones!
626 for (first
= primsList
.begin(), last
= primsList
.end(); first
!= last
; ++first
)
628 if ( !parsePVPZones(first
->Primitive
.RootNode
) )
630 nlwarning("<CZoneManager constructor> Error while building the PVP zones");
634 // parse the PVP safe zones (except for outpost zones)
635 for (first
= primsList
.begin(), last
= primsList
.end(); first
!= last
; ++first
)
637 if ( !parsePVPSafeZones(first
->Primitive
.RootNode
) )
639 nlwarning("<CZoneManager constructor> Error while building the PVP safe zones");
643 // apply config to PVP zones (must be done after loading primitives), except outpost ones
644 CPVPManager::getInstance()->applyConfigToPVPZones();
646 // for backward compatibility
647 //BACK_COMPAT::initSpawnZonesCompat();
648 BACK_COMPAT::initPlacesCompat();
651 // Initialize messages from other services
653 // array of callback items
654 NLNET::TUnifiedCallbackItem _cbArray
[] =
656 { "SET_ZONE_STATE", cbSetZoneState
},
658 // register call back for zone manager
659 CUnifiedNetwork::getInstance()->addCallbackArray( _cbArray
, sizeof(_cbArray
) / sizeof(_cbArray
[0]) );
661 }// CZoneManager ctor
663 //-----------------------------------------------
665 //-----------------------------------------------
666 CZoneManager::~CZoneManager()
669 for (uint i
= 0; i
< _Deposits
.size(); i
++ )
671 // all must have unregistered from the set of autospawn update
672 nlassert(_DepositNeedingAutoSpawnUpdate
.empty());
675 for ( uint i
= 0; i
< _Places
.size(); i
++ )
680 }// CZoneManager dtor
682 //-----------------------------------------------
683 // CZoneManager iosConnection
684 //-----------------------------------------------
685 void CZoneManager::iosConnection()
687 for ( uint i
= 0; i
< _Continents
.size(); i
++ )
689 for ( uint j
= 0; j
< _Continents
[i
].getRegions().size(); j
++ )
691 _Continents
[i
].getRegions()[j
]->registerChatGroup();
694 }// CZoneManager iosConnection
696 //-----------------------------------------------
697 // CZoneManager getTpSpawnZoneIdByName
698 //-----------------------------------------------
699 uint16
CZoneManager::getTpSpawnZoneIdByName( const std::string
& name
)
701 map
<string
,uint16
>::const_iterator it
= _TpSpawnZoneIdByName
.find( name
);
702 if ( it
== _TpSpawnZoneIdByName
.end() )
704 return InvalidSpawnZoneId
;
707 const uint16 id
= (*it
).second
;
708 BOMB_IF( (id
>= _TpSpawnZones
.size()), "<SPAWN_ZONE> invalid spawn zone id", return InvalidSpawnZoneId
);
709 BOMB_IF( (name
!= _TpSpawnZones
[id
].getName()), "<SPAWN_ZONE> spawn zone name does not match", return InvalidSpawnZoneId
);
712 }// CZoneManager getTpSpawnZoneIdByName
715 //-----------------------------------------------
716 // CZoneManager parseContinents
717 //-----------------------------------------------
718 bool CZoneManager::parseContinents( const NLLIGO::IPrimitive
* prim
)
721 const CPrimZone
* zone
= dynamic_cast<const CPrimZone
*>( prim
);
722 // if the primitive is a continent, parse it, build it and add it to this manager if it is correct
723 if ( zone
&& zone
->getPropertyByName("class",value
) && value
== "continent" )
725 CContinent continent
;
726 if ( continent
.build( zone
) )
729 for (; i
< _Continents
.size(); i
++ )
731 if ( _Continents
[i
].getId() == continent
.getId() )
734 if ( i
== _Continents
.size() )
736 _Continents
.push_back( continent
);
740 // Lookup recursively in the children
742 for (uint i
=0;i
<prim
->getNumChildren();++i
)
744 const IPrimitive
*child
;
745 if ( prim
->getChild(child
,i
) )
746 ok
= parseContinents(child
) && ok
;
749 }// CZoneManager parseContinents
751 //-----------------------------------------------
752 // CZoneManager parseRegions
753 //-----------------------------------------------
754 bool CZoneManager::parseRegions( const NLLIGO::IPrimitive
* prim
)
757 const CPrimZone
* zone
= dynamic_cast<const CPrimZone
*>(prim
);
758 // if the primitive is a continent, parse it, build it and add it to this manager if it is correct
759 if ( zone
&& prim
->getPropertyByName("class",value
) && value
== "region" )
761 CRegion
* region
= new CRegion();
762 if ( region
->build( zone
,(uint16
)_Places
.size() ) )
765 for (uint i
= 0; i
< _Continents
.size(); i
++ )
767 const std::vector
<CPrimVector
> & regionPoints
= zone
->VPoints
;
768 for (uint j
= 0; j
< regionPoints
.size(); j
++ )
770 if ( _Continents
[i
].contains( regionPoints
[j
] ) )
773 _Continents
[i
].addRegion( region
);
774 region
->setContinent( (CONTINENT::TContinent
) _Continents
[i
].getId() );
779 nlassertex(found
, (toString("No continent found that includes the region %s", prim
->getName().c_str()).c_str() ) );
780 _Places
.push_back( region
);
781 _PlacesByAlias
.insert( make_pair(region
->getAlias(), region
) );
786 // Lookup recursively in the children
788 for (uint i
=0;i
<prim
->getNumChildren();++i
)
790 const IPrimitive
*child
;
791 if ( prim
->getChild(child
,i
) )
792 ok
= parseRegions(child
) && ok
;
795 }// CZoneManager parseRegions
797 //-----------------------------------------------
798 // CZoneManager parseZones
799 //-----------------------------------------------
800 bool CZoneManager::parseZones( const NLLIGO::IPrimitive
* prim
)
803 const CPrimZone
* zone
= dynamic_cast<const CPrimZone
*>(prim
);
804 // if the primitive is a zone, parse it
807 // build the zone and add it to this manager if it is correct
808 if (prim
->getPropertyByName("class",value
) )
810 if ( value
== "place" )
812 CPlace
* place
= new CPlace();
813 if ( place
->build( zone
,(uint16
)_Places
.size() ) )
815 for (uint i
= 0; i
< _Continents
.size(); i
++ )
817 for (uint j
= 0; j
< _Continents
[i
].getRegions().size(); j
++ )
819 for ( uint k
= 0; k
< place
->VPoints
.size(); k
++ )
821 if ( _Continents
[i
].getRegions()[j
]->contains( place
->VPoints
[k
] ) )
823 _Continents
[i
].getRegions()[j
]->addPlace( place
);
829 _Places
.push_back( place
);
831 TAIAlias alias
= place
->getAlias();
832 if (alias
> maxGooBorderAlias
)
833 maxGooBorderAlias
= alias
;
835 _PlacesByAlias
.insert( make_pair(place
->getAlias(), place
) );
842 // Lookup recursively in the children
844 for (uint i
=0;i
<prim
->getNumChildren();++i
)
846 const IPrimitive
*child
;
847 if ( prim
->getChild(child
,i
) )
848 ok
= parseZones(child
) && ok
;
851 } // CZoneManager parseZones
853 //-----------------------------------------------
854 // CZoneManager parseEcotypes
855 //-----------------------------------------------
856 bool CZoneManager::parseEcotypes( const NLLIGO::IPrimitive
* prim
)
859 if (prim
->getPropertyByName("class",value
) )
861 if ( value
== "ecotypezone_list" )
863 std::string ecotypeZoneListName
;
864 prim
->getPropertyByName( "name", ecotypeZoneListName
);
866 // Parse the children ecotypes
867 for( uint i
= 0; i
< prim
->getNumChildren(); ++i
)
869 const IPrimitive
* childPrim
;
870 if ( prim
->getChild( childPrim
, i
) )
872 // If the primitive is a zone, parse it
873 const CPrimZone
* zone
= dynamic_cast<const CPrimZone
*>(childPrim
);
877 childPrim
->getPropertyByName( "class", primType
);
878 if( primType
== "ecotypezone" )
880 CEcotypeZone
*ecotype
= new CEcotypeZone();
881 if ( ecotype
->build( zone
) )
883 CDeposit::addEcotype( ecotype
);
884 CEcotypeZone
*ecotype2
= new CEcotypeZone();
885 if( ecotype2
->build( zone
) )
886 CZoneManager::addEcotype( ecotype2
);
899 // Lookup recursively in the children
901 for (uint i
=0;i
<prim
->getNumChildren();++i
)
903 const IPrimitive
*child
;
904 if ( prim
->getChild(child
,i
) )
905 ok
= parseEcotypes(child
) && ok
;
910 //-----------------------------------------------
911 // CZoneManager parseDeposits
912 // Assumes the ecotypes have been parsed before
913 //-----------------------------------------------
914 bool CZoneManager::parseDeposits( const NLLIGO::IPrimitive
* prim
)
917 if (prim
->getPropertyByName("class",value
) )
919 if ( value
== "depositzone_list" )
921 std::string depositZoneListName
;
922 prim
->getPropertyByName( "name", depositZoneListName
);
924 // Parse the children deposits
925 for( uint i
= 0; i
< prim
->getNumChildren(); ++i
)
927 const IPrimitive
* childPrim
;
928 if ( prim
->getChild( childPrim
, i
) )
930 // If the primitive is a zone, parse it
931 const CPrimZone
* zone
= dynamic_cast<const CPrimZone
*>(childPrim
);
935 childPrim
->getPropertyByName( "class", primType
);
936 if( primType
== "depositzone" )
939 CDeposit
* deposit
= new CDeposit
;
940 if ( deposit
->build( zone
) )
942 for (uint j
= 0; j
< _Continents
.size(); j
++ )
944 for (uint k
= 0; k
< _Continents
[j
].getRegions().size(); k
++ )
947 for ( ; l
< deposit
->VPoints
.size(); l
++ )
949 if ( _Continents
[j
].getRegions()[k
]->contains( deposit
->VPoints
[l
] ) )
951 _Continents
[j
].getRegions()[k
]->addDeposit( deposit
);
959 for ( uint k
= 0; k
< _Continents
[j
].getRegions().size(); k
++ )
961 for ( uint l
= 0 ; l
< _Continents
[j
].getRegions()[k
]->VPoints
.size(); l
++ )
963 if ( deposit
->contains( _Continents
[j
].getRegions()[k
]->VPoints
[l
] ) )
965 _Continents
[j
].getRegions()[k
]->addDeposit( deposit
);
974 nlwarning("<CZoneManager parseDeposits> a deposit of %s is not in a region", depositZoneListName
.c_str());
975 _Deposits
.push_back(deposit
);
986 // Lookup recursively in the children
988 for (uint i
=0;i
<prim
->getNumChildren();++i
)
990 const IPrimitive
*child
;
991 if ( prim
->getChild(child
,i
) )
992 ok
= parseDeposits(child
) && ok
;
995 } // CZoneManager parseDeposits
997 //-----------------------------------------------
998 // CZoneManager parseStables
999 //-----------------------------------------------
1000 bool CZoneManager::parseStables( const NLLIGO::IPrimitive
* prim
)
1002 // Primitives format:
1004 // <PRIMITIVE CLASS_NAME="stables" TYPE="node" AUTO_INIT="true" DELETABLE="true">
1005 // <DYNAMIC_CHILD CLASS_NAME="stable"/>
1009 // <PRIMITIVE CLASS_NAME="stable" TYPE="zone" R="0" G="255" B="255" A="128" AUTO_INIT="false" DELETABLE="true">>
1010 // <PARAMETER NAME="name" TYPE="string" VISIBLE="true"/>
1012 // <STATIC_CHILD CLASS_NAME="stable_entry" NAME ="stable entry"/>
1015 // <!-- stable entry point -->
1016 // <PRIMITIVE CLASS_NAME="stable_entry" TYPE="point" R="128" G="50" B="200" A="128" AUTO_INIT="true" DELETABLE="false">
1020 if (prim
->getPropertyByName("class",value
) )
1022 if ( value
== "stables" )
1024 string stableName
, continent
;
1026 prim
->getPropertyByName( "name", stableName
);
1028 for( uint c
= 0; c
< prim
->getNumChildren(); ++c
)
1030 const NLLIGO::IPrimitive
* child
;
1031 prim
->getChild(child
,c
);
1032 if (child
->getPropertyByName("class",value
) )
1034 if( value
== "stable" )
1036 //geometry of stable point (normally one dot with directional information)
1037 const NLLIGO::CPrimZone
* primZone
= dynamic_cast<const CPrimZone
*>(child
);
1042 CPlace
* place
= new CPlace();
1043 if ( place
->build( primZone
,(uint16
)_Places
.size(), true ) )
1045 for (uint i
= 0; i
< _Continents
.size(); i
++ )
1047 continent
= CONTINENT::toString( (CONTINENT::TContinent
)_Continents
[i
].getId() );
1048 for (uint j
= 0; j
< _Continents
[i
].getRegions().size(); ++j
)
1050 for ( uint k
= 0; k
< place
->VPoints
.size(); ++k
)
1052 if ( _Continents
[i
].getRegions()[j
]->contains( place
->VPoints
[k
] ) )
1054 _Continents
[i
].getRegions()[j
]->addPlace( place
);
1056 // Displaying the aliases of all the stables:
1057 //string branchPath = _Continents[i].getName() + "." + _Continents[i].getRegions()[j]->getName() + "." + place->getName();
1058 //InfoLog->displayRawNL( "STBL:%s: %u", branchPath.c_str(), place->getAlias() );
1066 if( place
->getId() == 0x35 )
1068 nlinfo("catch it!");
1071 if( found
== false )
1073 nlwarning("<CZoneManager::parseStables> Stable %s is not in a region", stableName
.c_str());
1078 _Places
.push_back( place
);
1079 _PlacesByAlias
.insert( make_pair(place
->getAlias(), place
) );
1081 for( uint c2
= 0; c2
< child
->getNumChildren(); ++c2
)
1083 const NLLIGO::IPrimitive
* child2
;
1084 child
->getChild(child2
,c2
);
1086 if (child2
->getPropertyByName("class",value
) )
1088 if( value
== "stable_entry" )
1090 const NLLIGO::CPrimPoint
*stableEntryPoint
= dynamic_cast< const CPrimPoint
* >(child2
);
1091 if( stableEntryPoint
== 0 )
1093 nlwarning("<CZoneManager::parseStables> Stable %s not contained stable entry point", stableName
.c_str());
1096 CStable::getInstance()->addStable( stableName
, place
->getId(), continent
, stableEntryPoint
->Point
.x
, stableEntryPoint
->Point
.y
, stableEntryPoint
->Point
.z
, stableEntryPoint
->Angle
);
1108 // Lookup recursively in the children
1110 for (uint i
=0;i
<prim
->getNumChildren();++i
)
1112 const IPrimitive
*child
;
1113 if ( prim
->getChild(child
,i
) )
1114 ok
= parseStables(child
) && ok
;
1119 //-----------------------------------------------
1120 // CZoneManager parseTpSpawnZones
1121 //-----------------------------------------------
1122 bool CZoneManager::parseTpSpawnZones( const NLLIGO::IPrimitive
* prim
)
1125 if (prim
->getPropertyByName("class",value
) )
1127 if ( value
== "teleport_spawn_zone" )
1129 const NLLIGO::CPrimPoint
* point
= dynamic_cast<const CPrimPoint
*>(prim
);
1132 nlwarning("CZoneManager::parseTpSpawnZones -> teleport_trigger should be prim points");
1136 if( !zone
.build( point
) )
1139 // if it is a respawn point get the continent where the zone is
1140 if ( zone
.getType() == RESPAWN_POINT::KAMI
||
1141 zone
.getType() == RESPAWN_POINT::KARAVAN
||
1142 zone
.getType() == RESPAWN_POINT::NEWBIELAND
||
1143 zone
.getType() == RESPAWN_POINT::RANGER
||
1144 zone
.getType() == RESPAWN_POINT::RESPAWNABLE
)
1148 for ( j
= 0; j
< _Continents
.size() && !found
; ++j
)
1150 if ( _Continents
[j
].contains( point
->Point
) )
1152 zone
.setContinent((CONTINENT::TContinent
) _Continents
[j
].getId());
1159 nlwarning("<CZoneManager::parseTpSpawnZones> Re-spawn point '%s' is not in a continent", zone
.getName().c_str());
1164 for ( uint k
= 0; k
< _Continents
[j
].getRegions().size(); k
++ )
1166 if( _Continents
[j
].getRegions()[k
]->contains( point
->Point
) )
1168 zone
.setRegion( _Continents
[j
].getRegions()[k
]->getId() );
1175 nlwarning("<CZoneManager::parseTpSpawnZones> Re-spawn point '%s' is not in a region", zone
.getName().c_str());
1180 nlassert( _TpSpawnZones
.size() < 0xffff );
1182 map
<string
,uint16
>::const_iterator it
= _TpSpawnZoneIdByName
.find( zone
.getName() );
1183 BOMB_IF( (it
!= _TpSpawnZoneIdByName
.end()),
1184 toString( "<SPAWN_ZONE> spawn zone name '%s' is already used!!!", zone
.getName().c_str() ),
1188 _TpSpawnZoneIdByName
[zone
.getName()] = (uint16
)_TpSpawnZones
.size();
1189 _TpSpawnZones
.push_back( zone
);
1194 // Lookup recursively in the children
1196 for (uint i
=0;i
<prim
->getNumChildren();++i
)
1198 const IPrimitive
*child
;
1199 if ( prim
->getChild(child
,i
) )
1200 ok
= parseTpSpawnZones(child
) && ok
;
1205 //-----------------------------------------------
1206 // CZoneManager parseGooBorder
1207 //-----------------------------------------------
1208 bool CZoneManager::parseGooBorder( const NLLIGO::IPrimitive
* prim
)
1211 if (prim
->getPropertyByName("class",value
) )
1213 if ( value
== "goo_border" )
1215 string gooBorderName
, continent
;
1216 prim
->getPropertyByName( "name", gooBorderName
);
1218 const CPrimPath
* path
= dynamic_cast<const CPrimPath
*>(prim
);
1221 CPlace
* place
= new CPlace();
1222 if ( place
->build( path
, (uint16
)_Places
.size()) ) //assume CPrimPath and CPrimZone has the same members, method needed are only in CPrimZone
1224 for (uint i
= 0; i
< _Continents
.size(); i
++ )
1226 for (uint j
= 0; j
< _Continents
[i
].getRegions().size(); j
++ )
1228 for ( uint k
= 0; k
< place
->VPoints
.size(); k
++ )
1230 if ( _Continents
[i
].getRegions()[j
]->contains( place
->VPoints
[k
] ) )
1232 _Continents
[i
].getRegions()[j
]->addPlace( place
);
1238 _Places
.push_back( place
);
1240 TAIAlias alias
= place
->getAlias();
1241 if (alias
> maxGooBorderAlias
)
1242 maxGooBorderAlias
= alias
;
1244 _PlacesByAlias
.insert( make_pair(place
->getAlias(), place
) );
1254 // Lookup recursively in the children
1256 for (uint i
=0;i
<prim
->getNumChildren();++i
)
1258 const IPrimitive
*child
;
1259 if ( prim
->getChild(child
,i
) )
1260 ok
= parseGooBorder(child
) && ok
;
1265 bool CZoneManager::parseGooBorder( const string
&name
, const string
¶ms
, const string
&damages
)
1267 CPlace
* havePlace
= getPlaceFromName(name
);
1269 if (havePlace
!= NULL
)
1273 havePlace
->setGooActive(false);
1277 havePlace
->setGooActive(true);
1278 havePlace
->setDamageName(damages
);
1283 CPlace
* place
= new CPlace();
1285 place
->setName(name
);
1288 place
->setDamageName(damages
);
1289 place
->setAlias(++maxGooBorderAlias
);
1290 CPrimPath
* path
= new CPrimPath();
1291 if (parsePath(params
, path
)) {
1292 if ( place
->build( path
, (uint16
)_Places
.size(), false ) ) //assume CPrimPath and CPrimZone has the same members, method needed are only in CPrimZone
1294 for (uint i
= 0; i
< _Continents
.size(); i
++ )
1296 for (uint j
= 0; j
< _Continents
[i
].getRegions().size(); j
++ )
1298 for ( uint k
= 0; k
< place
->VPoints
.size(); k
++ )
1300 if ( _Continents
[i
].getRegions()[j
]->contains( place
->VPoints
[k
] ) )
1302 _Continents
[i
].getRegions()[j
]->addPlace( place
);
1308 _Places
.push_back( place
);
1309 _PlacesByAlias
.insert( make_pair(place
->getAlias(), place
) );
1318 bool CZoneManager::parsePath( const string
¶ms
, CPrimPath
*path
)
1320 vector
< string
> points
;
1321 NLMISC::splitString(params
, "|", points
);
1322 for (uint i
=0; i
<points
.size(); i
++)
1325 vector
< string
> point_params
;
1326 NLMISC::splitString(points
[i
], ",", point_params
);
1328 if (point_params
.size() == 2)
1330 fromString(point_params
[0], x
);
1331 fromString(point_params
[1], y
);
1332 path
->VPoints
.push_back(CPrimVector(NLMISC::CVector(x
, y
, 0)));
1340 //-----------------------------------------------
1341 // CZoneManager parseStartPoints
1342 //-----------------------------------------------
1343 bool CZoneManager::parseStartPoints( const NLLIGO::IPrimitive
* prim
)
1346 if (prim
->getPropertyByName("class",value
) )
1348 if ( value
== "start_village" )
1351 prim
->getPropertyByName( "name", value
);
1352 RYZOM_STARTING_POINT::TStartPoint start
= RYZOM_STARTING_POINT::toStartPoint( value
);
1353 if ( start
== RYZOM_STARTING_POINT::NB_START_POINTS
)
1355 nlwarning("<parseStartPoints> invalid start point %s",value
.c_str() );
1358 uint16 startIdx
= (uint16
) start
;
1359 if ( startIdx
>= _StartPoints
.size() )
1360 _StartPoints
.resize( startIdx
+ 1);
1363 for (uint i
=0;i
<prim
->getNumChildren();++i
)
1365 const IPrimitive
*child
= NULL
;
1366 if ( prim
->getChild(child
,i
) && child
&& child
->getPropertyByName("class",value
) && value
== "start_point")
1369 child
->getPropertyByName( "mission", value
);
1370 point
.Mission
= CAIAliasTranslator::getInstance()->getMissionUniqueIdFromName( value
);
1371 if ( point
.Mission
== CAIAliasTranslator::Invalid
)
1373 nlwarning("<parseStartPoints> invalid mission %s",value
.c_str() );
1375 child
->getPropertyByName( "welcomer", value
);
1376 point
.Welcomer
= CAIAliasTranslator::Invalid
;
1377 vector
<TAIAlias
> aliases
;
1378 CAIAliasTranslator::getInstance()->getNPCAliasesFromName( value
, aliases
);
1379 if ( aliases
.empty() )
1381 nlwarning("<parseStartPoints> invalid welcomer %s",value
.c_str() );
1384 point
.Welcomer
= aliases
[0];
1385 if ( point
.Welcomer
== CAIAliasTranslator::Invalid
)
1387 nlwarning("<parseStartPoints> invalid welcomer %s",value
.c_str() );
1389 child
->getPropertyByName( "spawn_zone", value
);
1390 point
.SpawnZoneId
= getTpSpawnZoneIdByName( value
);
1391 if ( point
.SpawnZoneId
== InvalidSpawnZoneId
)
1393 nlwarning("<parseStartPoints> invalid spawn zone %s",value
.c_str() );
1398 _StartPoints
[startIdx
].push_back( point
);
1405 // Lookup recursively in the children
1407 for (uint i
=0;i
<prim
->getNumChildren();++i
)
1409 const IPrimitive
*child
;
1410 if ( prim
->getChild(child
,i
) )
1411 ok
= parseStartPoints(child
) && ok
;
1416 CVariable
<bool> LoadPVPFreeZones("egs", "LoadPVPFreeZones", "If true PVP free zones will be loaded", false, 0, true );
1417 CVariable
<bool> LoadPVPVersusZones("egs", "LoadPVPVersusZones", "If true PVP versus zones will be loaded", false, 0, true );
1418 CVariable
<bool> LoadPVPGuildZones("egs", "LoadPVPGuildZones", "If true PVP guild zones will be loaded", false, 0, true );
1420 //-----------------------------------------------
1421 // CZoneManager parsePVPZones
1422 //-----------------------------------------------
1423 bool CZoneManager::parsePVPZones( const NLLIGO::IPrimitive
* prim
)
1426 prim
->getPropertyByName("class",value
);
1427 const CPrimZone
* zone
= dynamic_cast<const CPrimZone
*>(prim
);
1429 // if the primitive is a zone, parse it
1430 if ( zone
&& (value
== "pvp_zone") )
1432 CSmartPtr
<IPVPZone
> pvpZone
= IPVPZone::build( zone
);
1435 switch (pvpZone
->getPVPZoneType())
1437 case PVP_ZONE_TYPE::FreeZone
:
1438 load
= LoadPVPFreeZones
;
1441 case PVP_ZONE_TYPE::VersusZone
:
1442 load
= LoadPVPVersusZones
;
1445 case PVP_ZONE_TYPE::GuildZone
:
1446 load
= LoadPVPGuildZones
;
1450 nlwarning( "Invalid %s zone in pvp_zone primitive %s", PVP_ZONE_TYPE::toString( pvpZone
->getPVPZoneType() ).c_str(), prim
->getName().c_str() );
1454 CPVPManager::getInstance()->addPVPZone( pvpZone
);
1458 // lookup recursively in the children
1460 for (uint i
= 0; i
< prim
->getNumChildren(); i
++)
1462 const IPrimitive
* child
;
1463 if ( prim
->getChild(child
, i
) )
1464 result
&= parsePVPZones(child
);
1468 } // CZoneManager parsePVPZones
1470 //-----------------------------------------------
1471 // CZoneManager parsePVPSafeZones
1472 //-----------------------------------------------
1473 bool CZoneManager::parsePVPSafeZones( const NLLIGO::IPrimitive
* prim
)
1476 const CPrimPoint
* point
= dynamic_cast<const CPrimPoint
*>(prim
);
1478 // if the primitive is a point, parse it
1479 if ( point
&& prim
->getPropertyByName("class",value
) && value
== "safe_zone" )
1482 prim
->getPropertyByName("safe_from_pvp", value
);
1483 if ( value
== "true" )
1485 CSmartPtr
<CPVPSafeZone
> safeZone
= CPVPSafeZone::build( point
);
1486 if ( !safeZone
.isNull() )
1488 CPVPManager::getInstance()->addPVPSafeZone( safeZone
);
1489 CPVPManager2::getInstance()->addPVPSafeZone( safeZone
);
1494 // lookup recursively in the children
1496 for (uint i
= 0; i
< prim
->getNumChildren(); i
++)
1498 const IPrimitive
* child
;
1499 if ( prim
->getChild(child
, i
) )
1500 result
&= parsePVPSafeZones(child
);
1504 } // CZoneManager parsePVPSafeZones
1506 //-----------------------------------------------
1507 // CZoneManager getContinent
1508 //-----------------------------------------------
1509 CContinent
* CZoneManager::getContinent( sint32 x
, sint32 y
)
1511 CVector
vect( x
* 0.001f
, y
* 0.001f
, 0.0f
);
1512 return getContinent(vect
);
1513 }// CZoneManager getContinent*
1516 //-----------------------------------------------
1518 //-----------------------------------------------
1519 CContinent
* CZoneManager::getContinent( const NLMISC::CVector
& pos
)
1521 for ( uint i
= 0; i
< _Continents
.size(); i
++ )
1523 if ( _Continents
[i
].contains(pos
) )
1524 return &_Continents
[i
];
1527 }// CZoneManager getContinent
1530 //-----------------------------------------------
1531 // CZoneManager getRegion
1532 //-----------------------------------------------
1533 bool CZoneManager::getRegion( sint32 x
, sint32 y
, const CRegion
** region
, const CContinent
** continent
)
1536 CVector
vect( x
* 0.001f
, y
* 0.001f
, 0.0f
);
1537 for ( uint i
= 0; i
< _Continents
.size(); i
++ )
1539 if ( _Continents
[i
].contains(vect
) )
1541 for (uint j
= 0; j
< _Continents
[i
].getRegions().size(); j
++ )
1543 if ( _Continents
[i
].getRegions()[j
]->contains( vect
) )
1546 *continent
= &_Continents
[i
];
1548 *region
= _Continents
[i
].getRegions()[j
];
1555 }// CZoneManager getRegion
1559 //-----------------------------------------------
1560 // CZoneManager getPlace
1561 //-----------------------------------------------
1562 bool CZoneManager::getPlace( sint32 x
, sint32 y
, float& gooDistance
, const CPlace
** stable
, std::vector
<const CPlace
*>& places
, const CRegion
** region
, const CContinent
** continent
, bool withGooActive
)
1566 if( continent
) *continent
= NULL
;
1567 if( region
) *region
= NULL
;
1570 float nearGooDistance
= numeric_limits
<float>::max();
1572 CVector
vect( x
* 0.001f
, y
* 0.001f
, 0.0f
);
1573 for ( uint i
= 0; i
< _Continents
.size(); i
++ )
1575 if ( _Continents
[i
].contains(vect
) )
1578 *continent
= &_Continents
[i
];
1579 for (uint j
= 0; j
< _Continents
[i
].getRegions().size(); j
++ )
1581 if ( _Continents
[i
].getRegions()[j
]->contains( vect
) )
1585 *region
= _Continents
[i
].getRegions()[j
];
1587 for (uint k
= 0; k
< _Continents
[i
].getRegions()[j
]->getPlaces().size(); k
++ )
1590 p
= _Continents
[i
].getRegions()[j
]->getPlaces()[k
];
1592 if (!p
->isGooActive())
1594 if ( p
->contains( vect
) )
1596 CStable::TStableData stableData
;
1597 if( CStable::getInstance()->getStableData( p
->getId(), stableData
) )
1601 places
.push_back( p
);
1606 CVector p1
, p2
, nearPos
;
1609 CPrimZone::contains (vect
, _Continents
[i
].getRegions()[j
]->getPlaces()[k
]->VPoints
, distance
, nearPos
, true);
1610 if( distance
< nearGooDistance
)
1612 nearGooDistance
= distance
;
1615 places
.push_back( p
);
1618 gooDistance
= nearGooDistance
;
1624 gooDistance
= nearGooDistance
;
1626 }// CZoneManager getPlace
1629 //-----------------------------------------------
1630 // CZoneManager getRegion
1631 //-----------------------------------------------
1632 CRegion
* CZoneManager::getRegion( const NLMISC::CVector
& pos
)
1634 const CRegion
*cregion
= 0;
1635 if ( (! getRegion( (sint32
)(pos
.x
*1000.0f
), (sint32
)(pos
.y
*1000.0f
), &cregion
)) || (! cregion
) )
1637 nlwarning( "Invalid region for pos %s", pos
.asString().c_str() );
1640 return (const_cast<CRegion
*>(cregion
));
1644 //-----------------------------------------------
1645 // CZoneManager getDepositsUnderUser
1646 //-----------------------------------------------
1647 void CZoneManager::getDepositsUnderPos( const CVector
& pos
, std::vector
<CDeposit
*>& deposits
, bool warnIfOutsideOfRegion
)
1649 const CRegion
*cregion
= 0;
1651 if ( (! getRegion( (sint32
)(pos
.x
*1000.0f
), (sint32
)(pos
.y
*1000.0f
), &cregion
)) || (! cregion
) )
1653 if ( warnIfOutsideOfRegion
)
1654 nlwarning( "<CZoneManager getDepositsUnderPos> invalid region for pos %s", pos
.asString().c_str() );
1657 region
= (const_cast<CRegion
*>(cregion
));
1659 for (uint i
=0; i
!=region
->getDeposits().size(); ++i
)
1661 if ( region
->getDeposits()[i
]->contains( pos
) )
1662 deposits
.push_back( region
->getDeposits()[i
] );
1664 }// CZoneManager getDepositsUnderPos
1668 // get the first deposit found under the position (faster than getDepositsUnderPos()), or NULL if not found
1670 CDeposit
* CZoneManager::getFirstFoundDepositUnderPos( const NLMISC::CVector
& pos
)
1672 const CRegion
*cregion
= 0;
1674 if ( (! getRegion( (sint32
)(pos
.x
*1000.0f
), (sint32
)(pos
.y
*1000.0f
), &cregion
)) || (! cregion
) )
1676 nlwarning( "<CZoneManager getFirstFoundDepositUnderPos> invalid region for pos %s", pos
.asString().c_str() );
1679 region
= (const_cast<CRegion
*>(cregion
));
1680 for (uint i
=0; i
!=region
->getDeposits().size(); ++i
)
1682 if ( region
->getDeposits()[i
]->contains( pos
) )
1683 return region
->getDeposits()[i
];
1688 //-----------------------------------------------
1689 // CZoneManager getContinentFromId
1690 //-----------------------------------------------
1691 CPlace
* CZoneManager::getPlaceFromAlias( TAIAlias alias
)
1693 std::map
< TAIAlias
, CPlace
* >::iterator it
= _PlacesByAlias
.find( alias
);
1694 if ( it
!= _PlacesByAlias
.end() )
1696 return ( (*it
).second
);
1701 //-----------------------------------------------
1702 // CZoneManager getPlaceFromName
1703 //-----------------------------------------------
1704 CPlace
* CZoneManager::getPlaceFromName( const std::string
& name
)
1706 for ( uint i
= 0; i
< _Places
.size(); i
++ )
1708 if ( _Places
[i
] && _Places
[i
]->getName() == name
)
1714 }// CZoneManager getPlaceFromName
1716 //-----------------------------------------------
1717 // CZoneManager getContinentFromId
1718 //-----------------------------------------------
1719 CContinent
* CZoneManager::getContinentFromId( CONTINENT::TContinent id
)
1721 if (id
== CONTINENT::UNKNOWN
)
1723 for ( uint i
= 0; i
< _Continents
.size(); i
++ )
1725 if ( _Continents
[i
].getId() == id
)
1726 return &_Continents
[i
];
1728 nlwarning("<CZoneManager getContinentFromId> continent id %u is out of bound",id
);
1730 }// CZoneManager getContinentFromId
1732 //-----------------------------------------------
1733 // CZoneManager updateCharacterPosition
1734 //-----------------------------------------------
1735 void CZoneManager::updateCharacterPosition( CCharacter
* user
, uint32 elapsedTime
)
1739 // if user is in an instance, do not update the places where he is
1740 CMirrorPropValueRO
<TYPE_CELL
> mirrorCell( TheDataset
, user
->getEntityRowId(), DSPropertyCELL
);
1741 sint32 cell
= mirrorCell
;
1744 if ( user
->getState().X
<= 0 || user
->getState().Y
>= 0 )
1747 SM_STATIC_PARAMS_1(params
, STRING_MANAGER::place
);
1748 SM_STATIC_PARAMS_2(params2
, STRING_MANAGER::place
, STRING_MANAGER::faction
);
1750 // get the current location of the character
1751 const CPlace
* stable
;
1752 std::vector
<const CPlace
*> places
;
1753 const CRegion
* region
;
1754 const CContinent
* continent
;
1756 getPlace( user
, gooDistance
, &stable
, places
, ®ion
, &continent
, true);
1758 // SOURCE: user->getCurrentContinent()
1759 // DESTINATION: continent->getId()
1761 // update the continent if necessary
1762 if ( continent
== NULL
)
1764 CPlace
* oldPlace
= getContinentFromId( user
->getCurrentContinent() ); // returns NULL for CONTINENT::UNKNOWN
1767 params
[0].Identifier
= oldPlace
->getName();
1768 PHRASE_UTILITIES::sendDynamicSystemMessage(user
->getEntityRowId(),"EGS_LEAVE_CONTINENT",params
);
1770 user
->setCurrentContinent( CONTINENT::UNKNOWN
);
1772 else if ( (CONTINENT::TContinent
)continent
->getId() != user
->getCurrentContinent() )
1774 // if current continent is NEWBIELAND, send an 'newbie' update to the SU
1775 bool updateSU
= false;
1776 if (user
->getCurrentContinent() == CONTINENT::NEWBIELAND
)
1779 const CONTINENT::TContinent oldContinent
= user
->getCurrentContinent();
1780 CPlace
* oldPlace
= getContinentFromId( oldContinent
); // returns NULL for CONTINENT::UNKNOWN
1783 params
[0].Identifier
= oldPlace
->getName();
1784 PHRASE_UTILITIES::sendDynamicSystemMessage(user
->getEntityRowId(),"EGS_LEAVE_CONTINENT",params
);
1786 params
[0].Identifier
= continent
->getName();
1787 PHRASE_UTILITIES::sendDynamicSystemMessage(user
->getEntityRowId(),"EGS_ENTER_CONTINENT",params
);
1788 user
->setCurrentContinent( (CONTINENT::TContinent
)continent
->getId() );
1789 // notify player respawn points system that continent changed
1790 user
->getRespawnPoints().cbContinentChanged(oldContinent
);
1791 // update newbieland flag (defailt to 1 if there's aproblem determining the true value)
1792 bool newbie
= user
->isNewbie();
1793 // user->_PropertyDatabase.setProp("USER:IS_NEWBIE", newbie);
1794 CBankAccessor_PLR::getUSER().setIS_NEWBIE(user
->_PropertyDatabase
, newbie
);
1796 bool trialPlayer
= false;
1797 CPlayer
*player
= PlayerManager
.getPlayer( PlayerManager
.getPlayerId(user
->getId()));
1800 nlwarning("Error %s was not found in player manager.",user
->getId().toString().c_str());
1801 trialPlayer
= player
->isTrialPlayer();
1803 // user->_PropertyDatabase.setProp("USER:IS_TRIAL", trialPlayer);
1804 CBankAccessor_PLR::getUSER().setIS_TRIAL(user
->_PropertyDatabase
, trialPlayer
);
1808 if (IShardUnifierEvent::getInstance() != NULL
)
1809 IShardUnifierEvent::getInstance()->onUpdateCharNewbieFlag(user
->getId(), newbie
);
1813 // do the same for region
1814 // first send message for leaving previous region
1815 CRegion
* oldRegion
= dynamic_cast<CRegion
*> ( getPlaceFromId( user
->getCurrentRegion() ) );
1816 if( user
->getCurrentRegion() != 0xFFFF )
1818 // previously in region
1819 if( region
== 0 || ( region
->getId() != user
->getCurrentRegion()) )
1821 // and not the same than actual region
1824 const CTotemBase
* pTotem
= CPVPFactionRewardManager::getInstance().getTotemBaseFromId( user
->getCurrentRegion() );
1827 PVP_CLAN::TPVPClan regionFaction
= pTotem
->getOwnerFaction();
1828 if( regionFaction
== PVP_CLAN::Neutral
)
1830 params
[0].Identifier
= oldRegion
->getName();
1831 PHRASE_UTILITIES::sendDynamicSystemMessage(user
->getEntityRowId(),"EGS_LEAVE_NEUTRAL_REGION",params
);
1835 params2
[0].Identifier
= oldRegion
->getName();
1836 params2
[1].Enum
= PVP_CLAN::getFactionIndex(regionFaction
);
1837 PHRASE_UTILITIES::sendDynamicSystemMessage(user
->getEntityRowId(),"EGS_LEAVE_FACTION_REGION",params2
);
1842 params
[0].Identifier
= oldRegion
->getName();
1843 PHRASE_UTILITIES::sendDynamicSystemMessage(user
->getEntityRowId(),"EGS_LEAVE_NEUTRAL_REGION",params
);
1846 oldRegion
->removePlayer( user
->getId() );
1851 user
->setCurrentRegion( 0xFFFF );
1852 // remove spire effects for Pvp-flagged players
1853 if ( user
->getPVPFlag() )
1854 CPVPFactionRewardManager::getInstance().removeTotemsEffects( user
);
1859 if ( region
!= 0 && (user
->getCurrentRegion() != region
->getId()) )
1861 const CTotemBase
* pTotem
= CPVPFactionRewardManager::getInstance().getTotemBaseFromId( region
->getId() );
1864 PVP_CLAN::TPVPClan regionFaction
= pTotem
->getOwnerFaction();
1865 if( regionFaction
== PVP_CLAN::Neutral
)
1867 params
[0].Identifier
= region
->getName();
1868 PHRASE_UTILITIES::sendDynamicSystemMessage(user
->getEntityRowId(),"EGS_ENTER_NEUTRAL_REGION",params
);
1872 params2
[0].Identifier
= region
->getName();
1873 params2
[1].Enum
= PVP_CLAN::getFactionIndex(regionFaction
);
1874 PHRASE_UTILITIES::sendDynamicSystemMessage(user
->getEntityRowId(),"EGS_ENTER_FACTION_REGION",params2
);
1879 params
[0].Identifier
= region
->getName();
1880 PHRASE_UTILITIES::sendDynamicSystemMessage(user
->getEntityRowId(),"EGS_ENTER_NEUTRAL_REGION",params
);
1883 // Check is region have a trigger to send an url
1884 string regionTrigger
= getRegionTrigger(region
->getName());
1885 if (!regionTrigger
.empty())
1886 user
->sendUrl(regionTrigger
);
1888 user
->setCurrentRegion( region
->getId() );
1890 ((CRegion
*)region
)->addPlayer( user
->getId() );
1892 // add new spire effects for Pvp-flagged players
1893 if ( user
->getPVPFlag() )
1894 CPVPFactionRewardManager::getInstance().giveTotemsEffects( user
);
1896 // Now the VisitPlace missions are checked in CMissionManager::checkVisitPlaceMissions()
1897 //CMissionEventVisitPlace event(region->getId() );
1898 //user->processMissionMultipleEvent(event);
1902 std::map
<TAIAlias
, uint8
>::const_iterator it
;
1903 for (it
= EntitiesDistanceTriggers
.begin(); it
!= EntitiesDistanceTriggers
.end(); it
++)
1905 nlinfo("Entity trigger : %s", NLMISC::toString(it
->first
).c_str());
1906 if (it
->second
== 0)
1908 std::map
<TAIAlias
, std::string
>::const_iterator it2
= EntitiesUrlTriggers
.find(it
->first
);
1909 if ( it2
!= EntitiesUrlTriggers
.end() )
1910 user
->sendRpPoints(it2
->second
);
1914 nlinfo("Distance = %d", it
->second
);
1915 const CEntityId
& botId
= CAIAliasTranslator::getInstance()->getEntityId(it
->first
);
1916 if ( botId
!= CEntityId::Unknown
)
1918 nlinfo("Botid found");
1919 CEntityBase
*entityBase
= CreatureManager
.getCreature (botId
);
1920 if (entityBase
!= NULL
)
1922 sint32 x
= entityBase
->getState().X
/1000.f
;
1923 sint32 y
= entityBase
->getState().Y
/1000.f
;
1924 sint32 px
= user
->getState().X
/1000.f
;
1925 sint32 py
= user
->getState().Y
/1000.f
;
1926 nlinfo("entityBase found, check pos %i, %i, %i, %i", x
, y
, px
, py
);
1927 if ((px
-x
)*(px
-x
)+(py
-y
)*(py
-y
) < it
->second
* it
->second
)
1928 user
->addRpPoints(elapsedTime
);
1938 const uint newPlacesSize
= (uint
)places
.size();
1939 //bool sendWarning = false;
1940 bool changed
= false;
1941 for ( uint i
= 0; i
< newPlacesSize
; i
++ )
1943 // Setup the damage name of the zone (place)
1944 if (!places
[i
]->getDamageName().empty())
1946 zoneDamage
= places
[i
]->getDamageName();
1949 if ( !user
->isInPlace( places
[i
]->getId() ) )
1951 if( places
[i
]->getReported() )
1953 params
[0].Identifier
= places
[i
]->getName();
1954 PHRASE_UTILITIES::sendDynamicSystemMessage(user
->getEntityRowId(),"EGS_ENTER_PLACE",params
);
1956 // Now the VisitPlace missions are checked in CMissionManager::checkVisitPlaceMissions()
1957 //CMissionEventVisitPlace event( places[i]->getId() );
1958 //user->processMissionMultipleEvent(event);
1960 // validate respawn points
1961 for ( uint j
= 0; j
< places
[i
]->getRespawnPoints().size(); j
++ )
1963 user
->getRespawnPoints().addRespawnPoint( places
[i
]->getRespawnPoints()[j
] );
1968 /// tells mission system that user enters a place
1969 for ( map
<TAIAlias
, CMission
*>::iterator it
= user
->getMissionsBegin(); it
!= user
->getMissionsEnd(); ++it
)
1971 CMissionManager::getInstance()->enterPlace( (*it
).second
,places
[i
]->getAlias(), places
[i
]->getId() );
1977 const uint oldPlacesSize
= (uint
)user
->getPlaces().size();
1978 for ( uint i
= 0; i
< oldPlacesSize
; i
++ )
1981 for (; j
< newPlacesSize
; j
++ )
1983 if ( places
[j
]->getId() == user
->getPlaces()[i
] )
1986 if ( j
== newPlacesSize
)
1988 CPlace
* place
= getPlaceFromId( user
->getPlaces()[i
] );
1991 if( place
->getReported() )
1993 params
[0].Identifier
= place
->getName();
1994 PHRASE_UTILITIES::sendDynamicSystemMessage(user
->getEntityRowId(),"EGS_LEAVE_PLACE",params
);
1997 /// tells mission system that user enters a place
1998 for ( map
<TAIAlias
, CMission
*>::iterator it
= user
->getMissionsBegin(); it
!= user
->getMissionsEnd(); ++it
)
2000 CMissionManager::getInstance()->leavePlace( (*it
).second
,place
->getAlias(), place
->getId() );
2008 // enter/leave PVP zones
2009 TAIAlias pvpZoneAlias
= CPVPManager::getInstance()->getPVPZoneFromUserPosition( user
);
2010 if ( pvpZoneAlias
!= user
->getCurrentPVPZone() && !user
->isDead() )
2012 if ( user
->getCurrentPVPZone() != CAIAliasTranslator::Invalid
)
2014 CPVPManager::getInstance()->leavePVPZone( user
);
2017 if ( pvpZoneAlias
!= CAIAliasTranslator::Invalid
)
2019 CPVPManager::getInstance()->enterPVPZone( user
, pvpZoneAlias
);
2022 user
->setCurrentPVPZone( pvpZoneAlias
);
2025 // enter/leave outpost zones
2026 TAIAlias outpostAlias
= COutpostManager::getInstance().getOutpostFromUserPosition( user
);
2027 if ( outpostAlias
!= user
->getCurrentOutpostZone() && !user
->isDead() )
2029 if ( user
->getCurrentOutpostZone() != CAIAliasTranslator::Invalid
)
2031 COutpostManager::getInstance().leaveOutpostZone( user
);
2034 user
->setCurrentOutpostZone( outpostAlias
);
2036 if ( outpostAlias
!= CAIAliasTranslator::Invalid
)
2038 COutpostManager::getInstance().enterOutpostZone( user
);
2041 else // Check if outpost have changed from peace state, if yes => player re-enter the pvpzone to ask to choose a side
2043 CSmartPtr
<COutpost
> outpost
= COutpostManager::getInstance().getOutpostFromAlias(outpostAlias
);
2046 OUTPOSTENUMS::TOutpostState savedState
= user
->getCurrentOutpostState();
2047 user
->setCurrentOutpostZone( outpostAlias
);
2048 if (savedState
!= outpost
->getState() && (savedState
== OUTPOSTENUMS::Peace
|| savedState
== OUTPOSTENUMS::WarDeclaration
|| savedState
== OUTPOSTENUMS::AttackAfter
))
2050 if ( pvpZoneAlias
!= CAIAliasTranslator::Invalid
&& !user
->isDead() )
2051 CPVPManager::getInstance()->enterPVPZone( user
, pvpZoneAlias
);
2057 user
->setPlaces( places
);
2060 // if the player is now in an unknown stable
2061 if( stable
== NULL
)
2063 // disable this message because stables are already treated as places
2064 /*CPlace * oldStable = getPlaceFromId( user->getCurrentStable() );
2067 if( oldStable->getReported() )
2069 params[0].Identifier = oldStable->getName();
2070 PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"EGS_LEAVE_PLACE",params);
2074 user
->setCurrentStable( 0xFFFF,0xFFFF);
2076 // check if player left old current stable for enter to another
2077 else if( user
->getCurrentStable() != stable
->getId() )
2079 // disable this message because stables are already treated as places
2080 /*CPlace * oldStable = getPlaceFromId( user->getCurrentStable() );
2083 if( oldStable->getReported() )
2085 params[0].Identifier = oldStable->getName();
2086 PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"EGS_LEAVE_PLACE",params);
2089 if( stable->getReported() )
2091 params[0].Identifier = stable->getName();
2092 PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"EGS_ENTER_PLACE",params);
2095 for ( uint i
= 0; i
< newPlacesSize
; i
++ )
2097 if ( places
[i
]->isMainPlace() )
2099 user
->setCurrentStable( stable
->getId(), places
[i
]->getId() );
2103 // Now the VisitPlace missions are checked in CMissionManager::checkVisitPlaceMissions()
2104 //CMissionEventVisitPlace event(stable->getId() );
2105 //user->processMissionMultipleEvent(event);
2108 // apply goo damage if needed
2109 user
->applyGooDamage( gooDistance
, zoneDamage
);
2111 }// CZoneManager updateCharacterPosition
2113 //-----------------------------------------------
2114 // CZoneManager tickUpdate
2115 //-----------------------------------------------
2116 void CZoneManager::tickUpdate()
2118 // *** Update deposits at low frequency (each deposit is updated once per DepositUpdateFrequency (which is a period in game cycles, actually))
2119 // CPU is smoothed if there are more deposits than cycles in the period.
2120 uint32 nbDeposit
= (uint32
)_Deposits
.size();
2121 if( ( (_NextDepositIndexUpdated
!= 0) || (CTickEventHandler::getGameCycle() - _SpreadUpdateLoopBeginTick
) >= DepositUpdateFrequency
.get()) )
2123 if ( _NextDepositIndexUpdated
== 0 )
2125 _SpreadUpdateLoopBeginTick
= CTickEventHandler::getGameCycle();
2127 uint32 i
, nbDepositUpdatedByTick
= (uint32
) ( nbDeposit
/ DepositUpdateFrequency
.get() ) + 1;
2128 for( i
= _NextDepositIndexUpdated
; i
< _NextDepositIndexUpdated
+ nbDepositUpdatedByTick
; ++i
)
2132 _Deposits
[ i
]->lowFreqUpdate();
2136 if( i
>= nbDeposit
)
2137 _NextDepositIndexUpdated
= 0;
2139 _NextDepositIndexUpdated
= i
;
2142 // *** Update the deposits that need an update for auto spawn
2143 std::set
< CDeposit
* >::iterator itDeposit
= _DepositNeedingAutoSpawnUpdate
.begin();
2144 while(itDeposit
!= _DepositNeedingAutoSpawnUpdate
.end())
2146 CDeposit
*deposit
= *itDeposit
;
2148 deposit
->autoSpawnUpdate();
2150 // remove the deposit from the set, and go next to update
2151 std::set
< CDeposit
* >::iterator itNext
= itDeposit
;
2153 _DepositNeedingAutoSpawnUpdate
.erase(itDeposit
);
2157 }// CZoneManager tickUpdate
2159 //-----------------------------------------------
2160 // CZoneManager dumpWorld
2161 //-----------------------------------------------
2162 void CZoneManager::dumpWorld(CLog
& log
)
2164 log
.displayNL("%u continents", _Continents
.size() );
2165 for (uint i
= 0; i
< _Continents
.size(); i
++ )
2167 log
.displayNL("CONTINENT %u : id=%u, name=%s", i
, _Continents
[i
].getId(),_Continents
[i
].getName().c_str() );
2168 const std::vector
< CRegion
* > & regions
= _Continents
[i
].getRegions();
2169 for (uint j
= 0; j
< regions
.size();j
++ )
2171 log
.displayNL(" region %u : id=%u, name=%s",j
, regions
[j
]->getId(),regions
[j
]->getName().c_str() );
2172 const std::vector
< CPlace
* > & places
= regions
[j
]->getPlaces();
2173 for (uint k
= 0; k
< places
.size();k
++ )
2175 log
.displayNL(" place %u : id=%u, name=%s", k
, places
[k
]->getId(),places
[k
]->getName().c_str() );
2178 const std::vector
< CDeposit
* > & deposits
= regions
[j
]->getDeposits();
2179 log
.displayNL("%u deposits", deposits
.size() );
2180 //for (uint k = 0; k < deposits.size();k++ )
2182 // log.displayNL(" deposits %u : id=%u", k, /*deposits[k]->getId()*/0, /*deposits[k]->getName().c_str()*/ );
2189 //-----------------------------------------------
2190 // CZoneManager dumpTpSpawnZones
2191 //-----------------------------------------------
2192 void CZoneManager::dumpTpSpawnZones(CLog
& log
)
2194 log
.displayNL("%u tp spawn zones", _TpSpawnZones
.size());
2195 for (uint i
= 0; i
< _TpSpawnZones
.size(); i
++)
2197 log
.displayNL("TP SPAWN ZONE %u : name=%s", i
, _TpSpawnZones
[i
].getName().c_str());
2201 //-----------------------------------------------
2202 // CZoneManager answerWhere
2203 //-----------------------------------------------
2204 void CZoneManager::answerWhere(const NLMISC::CEntityId
& eId
)
2206 ///\todo nico manage building
2207 CCharacter
* c
= PlayerManager
.getChar( eId
);
2210 c
->setAfkState(false);
2211 CContinent
* cont
= getContinentFromId(c
->getCurrentContinent());
2214 nlwarning("<CZoneManager answerWhere> invalid continent %u for entity %s",c
->getCurrentContinent(),eId
.toString().c_str());
2217 CPlace
* region
= getPlaceFromId( c
->getCurrentRegion() );
2220 nlwarning("<CZoneManager answerWhere> invalid region %u for entity %s",c
->getCurrentRegion(),eId
.toString().c_str());
2224 uint size
= (uint
)c
->getPlaces().size();
2225 CPlace
* place
= NULL
;
2226 for ( uint i
= 0; i
< size
; i
++ )
2228 CPlace
* placeTest
= getPlaceFromId( c
->getPlaces()[i
] );
2229 nlassert( placeTest
);
2230 if ( placeTest
->isMainPlace() )
2237 STRING_MANAGER::TParam param
;
2238 param
.Type
= STRING_MANAGER::place
;
2241 SM_STATIC_PARAMS_3(params
, STRING_MANAGER::place
, STRING_MANAGER::place
, STRING_MANAGER::place
);
2242 params
[0].Identifier
= cont
->getName();
2243 params
[1].Identifier
= region
->getName();
2244 params
[2].Identifier
= place
->getName();
2245 PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset
.getDataSetRow(eId
),"EGS_ANSWER_WHERE",params
);
2249 SM_STATIC_PARAMS_2(params
, STRING_MANAGER::place
, STRING_MANAGER::place
);
2250 params
[0].Identifier
= cont
->getName();
2251 params
[1].Identifier
= region
->getName();
2252 PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset
.getDataSetRow(eId
),"EGS_ANSWER_WHERE_NO_PLACE",params
);
2256 std::vector< NLMISC::CEntityId > bots;
2257 for ( uint i = 0; i < c->getPickedMissions().size(); i++ )
2259 if ( c->getPickedMissions()[i] )
2261 CStaticMission * mission = c->getPickedMissions()[i]->getTemplate();
2262 NLMISC::CEntityId bot;
2263 if ( CAIAliasTranslator::getInstance()->getEntityId(c->getPickedMissions()[i]->getRewardGiver(), bot ) )
2266 for (; j < bots.size(); j++ )
2268 if ( bots[j] == bot )
2271 if ( j == bots.size() )
2272 bots.push_back( bot );
2274 for (uint j = 0; j < mission->getSteps().size(); j++ )
2276 mission->getSteps()[j]->addImpliedBots( bots );
2280 if ( !bots.empty() )
2282 CCharacter::sendMessageToClient( eId,"EGS_MISSION_DIR_INTRO" );
2283 double xUser = (double)c->getState().X;
2284 double yUser = (double)c->getState().Y;
2285 for ( uint i = 0; i < bots.size(); i++ )
2287 CCreature * botPtr = CreatureManager.getCreature( bots[i] );
2291 if ( CAIAliasTranslator::getInstance()->getNPCNameFromAlias( botPtr->getAlias(), botName ) )
2293 double dx = (double)botPtr->getState().X/1000.0-(double)xUser/1000.0;
2294 double dy = (double)botPtr->getState().Y/1000.0-(double)yUser/1000.0;
2295 double dist = sqrt(dx*dx+dy*dy);
2296 uint32 distshort = (uint16)dist;
2298 double angle = atan2 (dy, dx) + NLMISC::Pi;
2299 sint direction =(sint) floor( 0.5 + 8.0 * angle /(NLMISC::Pi) );
2300 direction = direction %16;
2302 static string txts[]=
2321 static string msgBot = ("EGS_MISSION_DIR_BOT");
2323 CMessage msgout("STATIC_STRING");
2324 msgout.serial( const_cast<CEntityId&>(eId) );
2325 std::set<CEntityId> empty;
2326 msgout.serialCont( empty );
2327 msgout.serial( msgBot );
2328 msgout.serial( botName );
2329 msgout.serial( distshort );
2330 msgout.serial( txts[direction] );
2331 sendMessageViaMirror( "IOS", msgout );
2340 nlwarning( "<CZoneManager answerWhere>Invalid char %s",eId
.toString().c_str() );
2345 //-----------------------------------------------
2346 // CZoneManager harvestDeposit
2347 //-----------------------------------------------
2348 /*void CZoneManager::harvestDeposit(CCharacter * user)
2351 vector<CDeposit*> deposits;
2352 nlerror( "getDepositsUnderUser(user,deposits);" );
2353 if ( deposits.size() )
2356 for (uint i = 0; i < deposits.size(); i++ )
2357 nbMps+= deposits[i]->getContentSize();
2358 uint result = RandomGenerator.rand( nbMps - 1 );
2360 for (uint i = 0; i < deposits.size(); i++ )
2362 if ( result < nbMps + deposits[i]->getContentSize() )
2364 nlerror( "deposits[i]->harvestInfo(user->getId(),user->getHarvestInfos());" );
2367 nbMps += deposits[i]->getContentSize();
2370 if (user->getHarvestInfos().Sheet == CSheetId::Unknown)
2372 // no raw material found, return
2376 user->getHarvestInfos().EndCherchingTime = CTickEventHandler::getGameCycle() + DepositSearchTime;
2377 user->setCurrentAction( CLIENT_ACTION_TYPE::Harvest, user->getHarvestInfos().EndCherchingTime );
2379 }// CZoneManager harvestDeposit
2383 //-----------------------------------------------
2384 // CZoneManager displayAllDeposit
2385 //-----------------------------------------------
2386 void CZoneManager::dumpDeposits( NLMISC::CLog
& log
, const std::string
& depName
, bool extendedInfo
)
2388 bool displayAll
= (depName
== "ALL");
2389 for( uint i
= 0; i
< _Deposits
.size(); i
++ )
2393 if ( displayAll
|| (_Deposits
[i
]->name() == depName
) )
2394 _Deposits
[i
]->displayContent( &log
, extendedInfo
);
2397 log
.displayNL( "===== Deposit %d is NULL" );
2399 }// CZoneManager displayAllDeposit
2402 //-----------------------------------------------
2403 // CZoneManager getStartPointVector
2404 //-----------------------------------------------
2405 vector
<CZoneManager::CStartPoint
> CZoneManager::getStartPointVector( uint16 startPointIdx
) const
2407 if ( startPointIdx
>= _StartPoints
.size() )
2409 nlwarning("bad start point index %u ( count %u )",startPointIdx
, _StartPoints
.size() );
2410 return vector
<CStartPoint
>();
2413 return _StartPoints
[startPointIdx
];
2414 }// CZoneManager getStartPointVector
2417 //-----------------------------------------------
2418 // Get the ecotype zone under the position.
2419 // If not found, a NULL pointer is returned.
2420 //-----------------------------------------------
2421 ECOSYSTEM::EECosystem
CZoneManager::getEcotype( const NLMISC::CVector
& pos
)
2423 // The ecotypes must not be overlapped: only the first one found is returned
2424 for ( CEcotypeZones::iterator it
=_EcotypeZones
.begin(); it
!=_EcotypeZones
.end(); ++it
)
2426 CEcotypeZone
*ecotypeZone
= (*it
);
2427 if ( ecotypeZone
->contains( pos
) )
2429 return ecotypeZone
->ecotype();
2432 return ECOSYSTEM::unknown
;
2436 //-----------------------------------------------
2437 // Clear ecotype information
2438 //-----------------------------------------------
2439 void CZoneManager::clearEcotypes()
2441 for ( CEcotypeZones::iterator iez
=_EcotypeZones
.begin(); iez
!=_EcotypeZones
.end(); ++iez
)
2445 _EcotypeZones
.clear();
2449 //-----------------------------------------------
2450 // deposit auto spawn
2451 //-----------------------------------------------
2452 void CZoneManager::registerDepositToAutoSpawnUpdate(CDeposit
*deposit
)
2455 _DepositNeedingAutoSpawnUpdate
.insert(deposit
);
2457 void CZoneManager::unregisterDepositToAutoSpawnUpdate(CDeposit
*deposit
)
2460 _DepositNeedingAutoSpawnUpdate
.erase(deposit
);
2465 // dump the world organisation
2466 NLMISC_COMMAND(dumpWorld
," dump the world organisation","")
2468 if (args
.size() == 0)
2470 CZoneManager::getInstance().dumpWorld(log
);
2476 NLMISC_COMMAND(dumpTpSpawnZones
, "dump the tp spawn zones", "")
2478 if (args
.size() == 0)
2480 CZoneManager::getInstance().dumpTpSpawnZones(log
);
2487 addRegionTrigger uiR2_Jungle18 app_arcc action=mScript_Run&script=7624&command=reset_all
2489 NLMISC_COMMAND(addRegionTrigger
,"add region trigger","<region_name> <app> <params>")
2491 if (args
.size() == 3)
2493 CZoneManager::getInstance().addRegionTrigger(args
[0], args
[1]+" "+args
[2]);