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/>.
20 #include "ai_place_xyr.h"
21 #include "ai_place_patat.h"
22 #include "ai_instance.h"
23 #include "ai_grp_fauna.h" // TODO nico : try to get rid of that dependency
25 //////////////////////////////////////////////////////////////////////////////
27 //////////////////////////////////////////////////////////////////////////////
29 std::string
CAIPlace::getIndexString() const
31 return getOwner()->getIndexString()+NLMISC::toString(":%u", getChildIndex());
34 //////////////////////////////////////////////////////////////////////////////
36 //////////////////////////////////////////////////////////////////////////////
38 bool CAIPlaceXYR::atPlace(CAIEntityPhysical
const* entity
) const
40 return atPlace(entity
->pos());
43 //////////////////////////////////////////////////////////////////////////////
44 // CAIPlaceXYRFauna //
45 //////////////////////////////////////////////////////////////////////////////
46 std::string
CAIPlaceXYRFauna::getOneLineInfoString() const
48 std::string result
= NLMISC::toString("Name = %s; Active : %s, index = %d ", getFullName().c_str(), getActive() ? "on" : "off", (int) getIndex());
49 if (getFlag(FLAG_SPAWN
)) result
+="spawn ";
50 if (getFlag(FLAG_EAT
)) result
+="food ";
51 if (getFlag(FLAG_REST
)) result
+="rest ";
52 if (getTimeDriven()) result
+= NLMISC::toString(" TIME_DRIVEN : days=%s; time=%s", getDayInterval().c_str(), getTimeInterval().c_str());
56 //////////////////////////////////////////////////////////////////////////////
58 //////////////////////////////////////////////////////////////////////////////
60 bool CAIPlaceFastXYR::atPlace(CAIEntityPhysical
const* entity
) const
62 return atPlace(entity
->pos());
65 void CAIPlaceFastXYR::display(CStringWriter
& stringWriter
) const
67 stringWriter
.append("XYR: ("+_Pos
.x().toString()
70 +" "+NLMISC::toString(_Pos
.h())
72 +NLMISC::toString(_Radius
)
77 uint
CFaunaGenericPlace::setupFromOldName(const std::string
&name
)
80 uint placeIndex
= std::numeric_limits
<uint
>::max();
81 // depending on place name setup eat/ rest/ sleep pointers
82 if (NLMISC::nlstricmp(name
,"spawn")==0)
84 placeIndex
= CGrpFauna::SPAWN_PLACE
;
87 setFlag(FLAG_SPAWN
, true);
88 stayTime
= CGrpFauna::refTimer(CGrpFauna::CORPSE_TIME
);
91 if (NLMISC::nlstricmp(name
,"food")==0)
93 placeIndex
= CGrpFauna::EAT_PLACE
;
96 setFlag(FLAG_EAT
, true);
97 stayTime
= CGrpFauna::refTimer(CGrpFauna::EAT_TIME
);
100 if (NLMISC::nlstricmp(name
,"rest")==0)
102 placeIndex
= CGrpFauna::REST_PLACE
;
104 std::vector
<sint32
> arcs(1);
105 arcs
[0] = 1; // can reach place 1 from place 2
107 setFlag(FLAG_REST
, true);
108 stayTime
= CGrpFauna::refTimer(CGrpFauna::REST_TIME
);
112 nlwarning("Unknown fauna place type");
115 stayTime
*= FAUNA_BEHAVIOR_GLOBAL_SCALE
;
116 setMinStayTime(stayTime
);
117 setMaxStayTime(stayTime
);
121 bool CFaunaGenericPlace::getActive() const
123 if (!_TimeDriven
) return _Active
;
124 // NB : INDICES FOR DAYS are expected to start at 1!!
125 extern bool FAUNA_GRAPH_USES_DEBUG_TIME
;
126 const CRyzomTime
&rt
= FAUNA_GRAPH_USES_DEBUG_TIME
? CTimeInterface::getRyzomDebugTime() : CTimeInterface::getRyzomTime();
127 std::vector
<std::string
> dayIntervals
;
128 NLMISC::explode(_DayInterval
, std::string(","), dayIntervals
, true);
129 std::string season
= EGSPD::CSeason::toString(rt
.getRyzomSeason());
130 std::string month
= MONTH::toString((MONTH::EMonth
) rt
.getRyzomMonth());
131 std::string weekday
= WEEKDAY::toString((WEEKDAY::EWeekDay
) rt
.getRyzomDay());
133 for (uint k
= 0; k
< dayIntervals
.size(); ++k
)
135 bool goodToken
= false;
136 if (NLMISC::nlstricmp(dayIntervals
[k
], "always") == 0)
141 if (NLMISC::nlstricmp(dayIntervals
[k
], season
) == 0)
146 if (EGSPD::CSeason::fromString(season
) != EGSPD::CSeason::Unknown
)
150 if (NLMISC::nlstricmp(dayIntervals
[k
], month
) == 0)
155 if (MONTH::toMonth(dayIntervals
[k
]) != MONTH::UNKNOWN
)
159 if (NLMISC::nlstricmp(dayIntervals
[k
], weekday
) == 0)
164 if (WEEKDAY::toWeekDay(dayIntervals
[k
]) != WEEKDAY::UNKNOWN
)
168 // see if this is a n interval
169 int startDay
, endDay
;
170 if (sscanf(dayIntervals
[k
].c_str(), "%d-%d", &startDay
, &endDay
) == 2)
173 if ((int) (rt
.getRyzomDay() + 1) >= startDay
&& (int) (rt
.getRyzomDay() + 1) <= endDay
)
179 // see if this is a single day
181 if (sscanf(dayIntervals
[k
].c_str(), "%d", &day
) == 1)
184 if ((int) (rt
.getRyzomDay() + 1) == day
)
192 nlwarning("Unknwon time interval token : %s", dayIntervals
[k
].c_str());
195 if (!found
) return false;
196 // test against time interval
197 // If no interval is given then assume whole day
198 if (_TimeInterval
.empty()) return true;
199 std::vector
<std::string
> timeIntervals
;
200 NLMISC::explode(_TimeInterval
, std::string(","), timeIntervals
, true);
201 for (uint k
= 0; k
< dayIntervals
.size(); ++k
)
203 uint startHour
, endHour
;
204 if (sscanf(timeIntervals
[k
].c_str(), "%d-%d", &startHour
, &endHour
) == 2)
206 if (startHour
> endHour
)
209 if (rt
.getRyzomTime() >= startHour
|| rt
.getRyzomTime() <= endHour
)
216 if (rt
.getRyzomTime() >= startHour
&& rt
.getRyzomTime() <= endHour
)
224 nlwarning("Unknwon time interval token : %s", timeIntervals
[k
].c_str());
230 //////////////////////////////////////////////////////////////////////////////
232 //////////////////////////////////////////////////////////////////////////////
234 CAIPlaceShape::CAIPlaceShape(CPlaceOwner
* owner
, CAIAliasDescriptionNode
* aliasDescription
, bool warnOnInvalidPosition
)
235 : CAIPlace(owner
, aliasDescription
), _Shape(!warnOnInvalidPosition
)
237 _Shape
.calcRandomPos(_MidPos
);
238 CWorldContainer::getWorldMap().setWorldPosition(AITYPES::vp_auto
, _WorldValidPos
, _MidPos
);
239 _Shape
.calcRandomPos(_MidPos
);
242 bool CAIPlaceShape::atPlace(CAIVector
const& pos
) const
244 return _Shape
.contains(pos
);
247 bool CAIPlaceShape::atPlace(const CAIVectorMirror
&pos
) const
249 return _Shape
.contains(pos
);
252 bool CAIPlaceShape::atPlace(CAIEntityPhysical
const* entity
) const
254 return atPlace(entity
->pos());
257 CAIPos
const& CAIPlaceShape::midPos() const
262 RYAI_MAP_CRUNCH::CWorldPosition
const& CAIPlaceShape::worldValidPos() const
264 return _WorldValidPos
;
267 float CAIPlaceShape::getRadius() const
269 // :TODO: Compute a real radius here.
273 AITYPES::TVerticalPos
CAIPlaceShape::getVerticalPos() const
275 return _Shape
.getVerticalPos();
278 void CAIPlaceShape::getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition
& pos
) const
281 _Shape
.calcRandomPos(aiPos
);
282 CWorldContainer::getWorldMap().setWorldPosition(AITYPES::vp_auto
, pos
, aiPos
);
285 bool CAIPlaceShape::calcRandomPos(CAIPos
& pos
) const
287 return _Shape
.calcRandomPos(pos
);
290 bool CAIPlaceShape::setPatat(AITYPES::TVerticalPos verticalPos
, std::vector
<CAIVector
> const& points
)
292 return _Shape
.setPatat(verticalPos
, points
);
295 //////////////////////////////////////////////////////////////////////////////
296 // CAIPlaceIntersect //
297 //////////////////////////////////////////////////////////////////////////////
299 CAIPlaceIntersect::CAIPlaceIntersect(CPlaceOwner
* owner
, CAIAliasDescriptionNode
* aliasDescription
)
300 : CAIPlace(owner
, aliasDescription
)
304 bool CAIPlaceIntersect::atPlace(CAIVector
const& pos
) const
306 if (_Place1
&& _Place2
)
307 return _Place1
->atPlace(pos
) && _Place2
->atPlace(pos
);
309 return _Place1
->atPlace(pos
);
311 return _Place2
->atPlace(pos
);
315 bool CAIPlaceIntersect::atPlace(const CAIVectorMirror
&pos
) const
317 if (_Place1
&& _Place2
)
318 return _Place1
->atPlace(pos
) && _Place2
->atPlace(pos
);
320 return _Place1
->atPlace(pos
);
322 return _Place2
->atPlace(pos
);
326 bool CAIPlaceIntersect::atPlace(CAIEntityPhysical
const* pos
) const
328 if (_Place1
&& _Place2
)
329 return _Place1
->atPlace(pos
) && _Place2
->atPlace(pos
);
331 return _Place1
->atPlace(pos
);
333 return _Place2
->atPlace(pos
);
337 CAIPos
const& CAIPlaceIntersect::midPos() const
339 nlassert(_Place1
|| _Place2
);
341 return _Place1
->midPos();
343 return _Place2
->midPos();
347 RYAI_MAP_CRUNCH::CWorldPosition
const& CAIPlaceIntersect::worldValidPos() const
349 nlassert(_Place1
|| _Place2
);
351 return _Place1
->worldValidPos();
353 return _Place2
->worldValidPos();
354 return _DummyValidPos
;
357 float CAIPlaceIntersect::getRadius() const
359 nlassert(_Place1
|| _Place2
);
361 return _Place1
->getRadius();
363 return _Place2
->getRadius();
367 AITYPES::TVerticalPos
CAIPlaceIntersect::getVerticalPos() const
369 nlassert(_Place1
|| _Place2
);
371 return _Place1
->getVerticalPos();
373 return _Place2
->getVerticalPos();
374 return AITYPES::vp_auto
;
377 void CAIPlaceIntersect::getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition
& pos
) const
379 nlassert(_Place1
|| _Place2
);
381 _Place1
->getRandomPos(pos
);
383 _Place2
->getRandomPos(pos
);
386 bool CAIPlaceIntersect::calcRandomPos(CAIPos
& pos
) const
388 // if (_Place1 && _Place1->calcRandomPos(pos))
390 // if (_Place2 && _Place2->calcRandomPos(pos))
395 void CAIPlaceIntersect::setPlace1(NLMISC::CSmartPtr
<CAIPlace
const> const& place
)
400 void CAIPlaceIntersect::setPlace2(NLMISC::CSmartPtr
<CAIPlace
const> const& place
)
405 //////////////////////////////////////////////////////////////////////////////
406 // CAIPlaceOutpost //
407 //////////////////////////////////////////////////////////////////////////////
409 CAIPlaceOutpost::CAIPlaceOutpost(CPlaceOwner
* owner
, CAIAliasDescriptionNode
* aliasDescription
)
410 : CAIPlaceShape(owner
, aliasDescription
,false)
415 bool CAIPlaceOutpost::atPlace(CAIEntityPhysical
const* entity
) const
417 if (_OutpostAlias
!=0)
419 CMirrorPropValueRO
<TYPE_IN_OUTPOST_ZONE_ALIAS
> entityInOutpostAlias(TheDataset
, entity
->dataSetRow(), DSPropertyIN_OUTPOST_ZONE_ALIAS
);
420 return (entityInOutpostAlias
== _OutpostAlias
);
422 return CAIPlaceShape::atPlace(entity
);
425 void CAIPlaceOutpost::setOutpostAlias(uint32 outpostAlias
)
427 _OutpostAlias
= outpostAlias
;