Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / server / src / ai_service / ai_place.cpp
blobe000fc4d551ba42f62be3b49f9982fa4446b105a
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
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.
8 //
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/>.
18 #include "stdpch.h"
19 #include "ai_place.h"
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 //////////////////////////////////////////////////////////////////////////////
26 // CAIPlace //
27 //////////////////////////////////////////////////////////////////////////////
29 std::string CAIPlace::getIndexString() const
31 return getOwner()->getIndexString()+NLMISC::toString(":%u", getChildIndex());
34 //////////////////////////////////////////////////////////////////////////////
35 // CAIPlaceXYR //
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());
53 return result;
56 //////////////////////////////////////////////////////////////////////////////
57 // CAIPlaceFastXYR //
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()
68 +" "
69 +_Pos.y().toString()
70 +" "+NLMISC::toString(_Pos.h())
71 +") Radius "
72 +NLMISC::toString(_Radius)
73 +" "
74 +getName());
77 uint CFaunaGenericPlace::setupFromOldName(const std::string &name)
79 uint32 stayTime;
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;
85 setIndex(0);
86 setReachNext(true);
87 setFlag(FLAG_SPAWN, true);
88 stayTime = CGrpFauna::refTimer(CGrpFauna::CORPSE_TIME);
90 else
91 if (NLMISC::nlstricmp(name,"food")==0)
93 placeIndex = CGrpFauna::EAT_PLACE;
94 setIndex(1);
95 setReachNext(true);
96 setFlag(FLAG_EAT, true);
97 stayTime = CGrpFauna::refTimer(CGrpFauna::EAT_TIME);
99 else
100 if (NLMISC::nlstricmp(name,"rest")==0)
102 placeIndex = CGrpFauna::REST_PLACE;
103 setIndex(2);
104 std::vector<sint32> arcs(1);
105 arcs[0] = 1; // can reach place 1 from place 2
106 setArcs(arcs);
107 setFlag(FLAG_REST, true);
108 stayTime = CGrpFauna::refTimer(CGrpFauna::REST_TIME);
110 else
112 nlwarning("Unknown fauna place type");
113 nlassert(0);
115 stayTime *= FAUNA_BEHAVIOR_GLOBAL_SCALE;
116 setMinStayTime(stayTime);
117 setMaxStayTime(stayTime);
118 return placeIndex;
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());
132 bool found = false;
133 for (uint k = 0; k < dayIntervals.size(); ++k)
135 bool goodToken = false;
136 if (NLMISC::nlstricmp(dayIntervals[k], "always") == 0)
138 found = true;
139 break;
141 if (NLMISC::nlstricmp(dayIntervals[k], season) == 0)
143 found = true;
144 break;
146 if (EGSPD::CSeason::fromString(season) != EGSPD::CSeason::Unknown)
148 goodToken = true;
150 if (NLMISC::nlstricmp(dayIntervals[k], month) == 0)
152 found = true;
153 break;
155 if (MONTH::toMonth(dayIntervals[k]) != MONTH::UNKNOWN)
157 goodToken = true;
159 if (NLMISC::nlstricmp(dayIntervals[k], weekday) == 0)
161 found = true;
162 break;
164 if (WEEKDAY::toWeekDay(dayIntervals[k]) != WEEKDAY::UNKNOWN)
166 goodToken = true;
168 // see if this is a n interval
169 int startDay, endDay;
170 if (sscanf(dayIntervals[k].c_str(), "%d-%d", &startDay, &endDay) == 2)
172 goodToken = true;
173 if ((int) (rt.getRyzomDay() + 1) >= startDay && (int) (rt.getRyzomDay() + 1) <= endDay)
175 found = true;
176 break;
179 // see if this is a single day
180 int day;
181 if (sscanf(dayIntervals[k].c_str(), "%d", &day) == 1)
183 goodToken = true;
184 if ((int) (rt.getRyzomDay() + 1) == day)
186 found = true;
187 break;
190 if (!goodToken)
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)
208 // reversed interval
209 if (rt.getRyzomTime() >= startHour || rt.getRyzomTime() <= endHour)
211 return true;
214 else
216 if (rt.getRyzomTime() >= startHour && rt.getRyzomTime() <= endHour)
218 return true;
222 else
224 nlwarning("Unknwon time interval token : %s", timeIntervals[k].c_str());
227 return false;
230 //////////////////////////////////////////////////////////////////////////////
231 // CAIPlaceShape //
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
259 return _MidPos;
262 RYAI_MAP_CRUNCH::CWorldPosition const& CAIPlaceShape::worldValidPos() const
264 return _WorldValidPos;
267 float CAIPlaceShape::getRadius() const
269 // :TODO: Compute a real radius here.
270 return 20.f;
273 AITYPES::TVerticalPos CAIPlaceShape::getVerticalPos() const
275 return _Shape.getVerticalPos();
278 void CAIPlaceShape::getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition& pos) const
280 CAIPos aiPos;
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);
308 if (_Place1)
309 return _Place1->atPlace(pos);
310 if (_Place2)
311 return _Place2->atPlace(pos);
312 return false;
315 bool CAIPlaceIntersect::atPlace(const CAIVectorMirror &pos) const
317 if (_Place1 && _Place2)
318 return _Place1->atPlace(pos) && _Place2->atPlace(pos);
319 if (_Place1)
320 return _Place1->atPlace(pos);
321 if (_Place2)
322 return _Place2->atPlace(pos);
323 return true;
326 bool CAIPlaceIntersect::atPlace(CAIEntityPhysical const* pos) const
328 if (_Place1 && _Place2)
329 return _Place1->atPlace(pos) && _Place2->atPlace(pos);
330 if (_Place1)
331 return _Place1->atPlace(pos);
332 if (_Place2)
333 return _Place2->atPlace(pos);
334 return true;
337 CAIPos const& CAIPlaceIntersect::midPos() const
339 nlassert(_Place1 || _Place2);
340 if (_Place1)
341 return _Place1->midPos();
342 if (_Place2)
343 return _Place2->midPos();
344 return _DummyMidPos;
347 RYAI_MAP_CRUNCH::CWorldPosition const& CAIPlaceIntersect::worldValidPos() const
349 nlassert(_Place1 || _Place2);
350 if (_Place1)
351 return _Place1->worldValidPos();
352 if (_Place2)
353 return _Place2->worldValidPos();
354 return _DummyValidPos;
357 float CAIPlaceIntersect::getRadius() const
359 nlassert(_Place1 || _Place2);
360 if (_Place1)
361 return _Place1->getRadius();
362 if (_Place2)
363 return _Place2->getRadius();
364 return 0.f;
367 AITYPES::TVerticalPos CAIPlaceIntersect::getVerticalPos() const
369 nlassert(_Place1 || _Place2);
370 if (_Place1)
371 return _Place1->getVerticalPos();
372 if (_Place2)
373 return _Place2->getVerticalPos();
374 return AITYPES::vp_auto;
377 void CAIPlaceIntersect::getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition& pos) const
379 nlassert(_Place1 || _Place2);
380 if (_Place1)
381 _Place1->getRandomPos(pos);
382 if (_Place2)
383 _Place2->getRandomPos(pos);
386 bool CAIPlaceIntersect::calcRandomPos(CAIPos& pos) const
388 // if (_Place1 && _Place1->calcRandomPos(pos))
389 // return true;
390 // if (_Place2 && _Place2->calcRandomPos(pos))
391 // return true;
392 return false;
395 void CAIPlaceIntersect::setPlace1(NLMISC::CSmartPtr<CAIPlace const> const& place)
397 _Place1 = place;
400 void CAIPlaceIntersect::setPlace2(NLMISC::CSmartPtr<CAIPlace const> const& place)
402 _Place2 = place;
405 //////////////////////////////////////////////////////////////////////////////
406 // CAIPlaceOutpost //
407 //////////////////////////////////////////////////////////////////////////////
409 CAIPlaceOutpost::CAIPlaceOutpost(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription)
410 : CAIPlaceShape(owner, aliasDescription,false)
411 , _OutpostAlias(0)
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;