New lua versions
[ryzomcore.git] / ryzom / server / src / ai_service / ai_profile_pet.cpp
blobb4d7efe76eed70db8ebd7599c5cbf332ba52fad7
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/>.
17 #include "stdpch.h"
18 #include "ai_profile_pet.h"
20 #include "ai_bot_pet.h" // for CSpawnBotPet
21 #include "ai_grp_pet.h" // for CSpawnGroupPet
22 #include "server_share/animal_hunger.h" // for CSpeedLimit
24 using namespace NLMISC;
25 using namespace NLNET;
26 using namespace RYAI_MAP_CRUNCH;
27 using namespace AITYPES;
29 /****************************************************************************/
30 /* Local classes */
31 /****************************************************************************/
33 //////////////////////////////////////////////////////////////////////////////
34 // CTopoPosValidator //
35 //////////////////////////////////////////////////////////////////////////////
37 class CTopoPosValidator
38 : public CWorldContainer::CPosValidator
40 public:
41 CTopoPosValidator(CWorldPosition const& startPos, TAStarFlag denyFlags);
42 bool check(CWorldPosition const& wpos) const;
44 private:
45 CWorldPosition _StartPos;
46 TAStarFlag _DenyFlags;
49 /****************************************************************************/
50 /* Methods definitions */
51 /****************************************************************************/
53 //////////////////////////////////////////////////////////////////////////////
54 // CAIPetProfileStand //
55 //////////////////////////////////////////////////////////////////////////////
57 CAIPetProfileStand::CAIPetProfileStand(CSpawnBotPet* bot)
58 : CAIBaseProfile()
59 , _Bot(bot)
61 #ifndef NL_DEBUG
62 nlassert(bot);
63 #endif
66 //////////////////////////////////////////////////////////////////////////////
67 // CAIPetProfileFollowPlayer //
68 //////////////////////////////////////////////////////////////////////////////
70 CAIPetProfileFollowPlayer::CAIPetProfileFollowPlayer(CSpawnBotPet* bot, TDataSetRow const& playerRow)
71 : CAIBaseProfile()
72 , _Bot(bot)
73 , _PlayerRow(playerRow)
77 void CAIPetProfileFollowPlayer::updateProfile(uint ticksSinceLastUpdate)
79 H_AUTO(PetFollowPlayer);
81 // Is the pet stucked by something?
82 if (!_Bot->canMove())
83 return;
85 // Need to wait for a correct position before moving?
86 CAIVector const& dest = _Bot->spawnGrp().getPathCont().getDestination();
87 if (dest.x()==0 || dest.y()==0)
88 return;
90 CPathCont& pathCont = _Bot->spawnGrp().getPathCont();
92 if (_Bot->getPersistent().getSheet()->Scale() <= .5f || (pathCont.getDestination()-_Bot->wpos().toAIVector()).quickNorm() > 6.f) // follow only if > 6 meters or it's a tiny creature.
94 // Handle the hunger of the animal
95 CSpeedLimit speedLimit( TheDataset, _Bot->dataSetRow() );
96 float speedToUse = speedLimit.getSpeedLimit( _Bot->walkSpeed(), _Bot->runSpeed() );
98 // Move
99 float const dist = speedToUse * ticksSinceLastUpdate;
100 CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath(
101 _Bot,
102 _Bot->pathPos(),
103 pathCont,
104 dist,
106 .5f);
107 if (status==CFollowPath::FOLLOW_NO_PATH)
109 nlwarning("problem with pet following behavior and ground properties like (Water, Nogo)");
114 //////////////////////////////////////////////////////////////////////////////
115 // CAIPetProfileGotoPoint //
116 //////////////////////////////////////////////////////////////////////////////
118 CAIPetProfileGotoPoint::CAIPetProfileGotoPoint(CSpawnBotPet* bot, CAIPos const& position, TAStarFlag denyFlags, bool despawn)
119 : CAIBaseProfile()
120 , _Bot(bot)
121 , _Pos(position)
122 , _Despawn(despawn)
123 , _Valid(false)
124 , _PathCont(denyFlags)
126 #ifndef NL_DEBUG
127 nlassert(bot);
128 #endif
129 CTopoPosValidator const posValidator(bot->wpos(), denyFlags);
131 CWorldPosition gotoPos;
132 if (!CWorldContainer::calcNearestWPosFromPosAnRadius(vp_auto, gotoPos, _Pos, 16, 300, posValidator))
134 #ifdef NL_DEBUG
135 nldebug("position problem CAIPetProfileGotoPoint");
136 #endif
137 return;
139 _Pos.setXY(gotoPos.toAIVector());
140 _PathCont.setDestination((TVerticalPos)position.h(), _Pos);
141 _Valid = true;
144 void CAIPetProfileGotoPoint::updateProfile(uint ticksSinceLastUpdate)
146 H_AUTO(PetGotoPoint);
147 if (!_Bot->canMove())
148 return;
150 CAIVector botPos = _Bot->wpos().toAIVector();
151 float dist = _Bot->runSpeed() * ticksSinceLastUpdate;
153 if ((_PathCont.getDestination()-botPos).quickNorm()>3.f) // follow only if > 6 meters.
155 CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath(
156 _Bot,
157 _Bot->pathPos(),
158 _PathCont,
159 dist,
160 0.f,
161 .5f);
162 if (status==CFollowPath::FOLLOW_NO_PATH)
164 nlwarning("PetGotoPoint problem with destination properties (Water, Nogo)");
167 botPos -= _Bot->wpos().toAIVector();
169 if (botPos.quickNorm()<(dist*0.1))
171 if (_Despawn)
173 _Bot->getPersistent().setDespawn();
174 return;
176 _Bot->setAIProfile(new CAIPetProfileStand(_Bot));
177 return;
181 TProfiles CAIPetProfileGotoPoint::getAIProfileType() const
183 if (_Despawn)
184 return PET_GOTO_AND_DESPAWN;
185 else
186 return PET_GOTO;
189 //////////////////////////////////////////////////////////////////////////////
190 // CTopoPosValidator //
191 //////////////////////////////////////////////////////////////////////////////
193 CTopoPosValidator::CTopoPosValidator(CWorldPosition const& startPos, TAStarFlag denyFlags)
194 : _StartPos(startPos)
195 , _DenyFlags(denyFlags)
199 bool CTopoPosValidator::check(CWorldPosition const& wpos) const
201 CCompatibleResult res;
202 areCompatiblesWithoutStartRestriction(_StartPos, wpos, _DenyFlags, res, true);
203 return res.isValid();