Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / server / src / sabrina / harvest_phrase.cpp
blob06944d7f64f48cd235100d1ce0bc9f9b2012ba7a
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/>.
19 #include "stdpch.h"
20 #include "harvest_phrase.h"
21 #include "game_share/brick_families.h"
22 #include "s_phrase_factory.h"
23 #include "entity_manager.h"
24 #include "phrase_manager.h"
25 #include "creature_manager.h"
26 #include "player_manager.h"
27 #include "character.h"
28 #include "phrase_utilities_functions.h"
30 extern CPlayerManager PlayerManager;
31 extern CCreatureManager CreatureManager;
33 DEFAULT_SPHRASE_FACTORY( CHarvestPhrase, BRICK_TYPE::HARVEST );
35 using namespace std;
36 using namespace NLMISC;
37 using namespace NLNET;
39 //-----------------------------------------------
40 // ctor
41 //-----------------------------------------------
42 CHarvestPhrase::CHarvestPhrase()
44 _SabrinaCost = 0;
45 _SabrinaCredit = 0;
46 _StaminaCost = 0;
47 _HPCost = 0;
48 _HarvestTime = 25; // 2.5s for DEBUG ONLY
49 // _HarvestTime = 0; // 0s for DEBUG ONLY
50 _IsStatic = true;
54 //-----------------------------------------------
55 // CHarvestPhrase build
56 //-----------------------------------------------
57 bool CHarvestPhrase::build( const TDataSetRow & actorRowId, const std::vector< const CStaticBrick* >& bricks )
59 // we are sure there is at least one brick and that there are non NULL;
60 nlassert( !bricks.empty() );
62 _ActorRowId = actorRowId;
64 // compute cost and credit and parse other params
65 for ( uint i = 0; i < bricks.size(); ++i )
67 const CStaticBrick & brick = *bricks[i];
69 if ( i == 0)
70 _RootSheetId = brick.SheetId;
72 if ( brick.SabrinaValue < 0 )
73 _SabrinaCredit -= brick.SabrinaValue;
74 else
75 _SabrinaCost += brick.SabrinaValue;
77 switch( brick.Family )
79 /* TempYoyo: case BRICK_FAMILIES::RootHarvest:
80 break;*/
81 default:
82 for ( uint i=0 ; i<brick.Params.size() ; ++i)
84 switch(brick.Params[i]->id())
86 case TBrickParam::SAP:
87 return false;
88 case TBrickParam::HP:
89 INFOLOG("HP: %i",((CSBrickParamHp *)brick.Params[i])->Hp);
90 _HPCost += ((CSBrickParamHp *)brick.Params[i])->Hp;
91 break;
92 case TBrickParam::STA:
93 INFOLOG("STA: %i",((CSBrickParamSta *)brick.Params[i])->Sta);
94 _StaminaCost += ((CSBrickParamSta *)brick.Params[i])->Sta;
95 break;
96 default:
97 // unused param ?
98 break;
101 break;
105 return true;
106 }// CHarvestPhrase build
109 //-----------------------------------------------
110 // CHarvestPhrase evaluate
111 //-----------------------------------------------
112 bool CHarvestPhrase::evaluate(CEvalReturnInfos *msg)
114 // update state
115 _State = CSPhrase::Evaluated;
116 return true;
117 }// CHarvestPhrase evaluate
120 //-----------------------------------------------
121 // CHarvestPhrase validate
122 //-----------------------------------------------
123 bool CHarvestPhrase::validate()
125 // entities cant harvest if in combat
126 TDataSetRow entityRowId = CPhraseManager::getInstance()->getEntityEngagedMeleeBy( _ActorRowId );
127 if (entityRowId.isValid())
129 ///\todo david : send message
130 return false;
132 CEntityBase * entity = CEntityBaseManager::getEntityBasePtr( _ActorRowId );
133 const sint32 hp = entity->getScores()._PhysicalScores[ SCORES::hit_points ].Current;
134 if ( hp < _HPCost )
136 ///\todo david : send message
137 return false;
139 const sint32 sta = entity->getScores()._PhysicalScores[ SCORES::stamina ].Current;
140 if ( sta < _StaminaCost )
142 ///\todo david : send message
143 return false;
145 if (hp <= 0 || entity->getMode()==MBEHAV::DEATH)
147 ///\todo david : send message
148 return false;
151 /// todo david : test if on mount
153 // update state
154 if (_State == Evaluated)
155 _State = Validated;
156 else if (_State == ExecutionInProgress)
157 _State = SecondValidated;
158 return true;
159 }// CHarvestPhrase validate
162 //-----------------------------------------------
163 // CHarvestPhrase update
164 //-----------------------------------------------
165 bool CHarvestPhrase::update()
167 const NLMISC::TGameCycle time = CTickEventHandler::getGameCycle();
169 // if the sentence execution delay time has ended, apply sentence effects
170 if ( _State == SecondValidated && _ExecutionEndDate <= time && _NbWaitingRequests == 0)
172 apply();
174 else if ( _State == Latent /*&& _LatencyEndDate <= time*/ )
176 end();
179 return true;
180 }// CHarvestPhrase update
183 //-----------------------------------------------
184 // CHarvestPhrase execute
185 //-----------------------------------------------
186 void CHarvestPhrase::execute()
188 if( _NbWaitingRequests != 0)
189 return;
191 const NLMISC::TGameCycle time = CTickEventHandler::getGameCycle();
192 _State = CSPhrase::ExecutionInProgress;
193 _ExecutionEndDate = time + _HarvestTime ;
195 CCharacter* player = PlayerManager.getChar(_ActorRowId);
196 if (player)
198 player->setCurrentAction(CLIENT_ACTION_TYPE::Harvest,_ExecutionEndDate);
200 const CStaticItem *item = CSheets::getForm(_RawMaterialId);
201 if (item != 0)
203 /* string msgName = "BS_HARVEST_BEGIN_S";
204 CMessage msg("STATIC_STRING");
205 msg.serial( const_cast<CEntityId&> (player->getId()) );
206 set<CEntityId> excluded;
207 msg.serialCont( excluded );
208 msg.serial( msgName );
209 msg.serial( const_cast<string&> (item->Name));
211 sendMessageViaMirror ("IOS", msg);
214 string msgName = "WOS_HARVEST_SEARCHING";
215 CMessage msg("STATIC_STRING");
216 msg.serial( const_cast<CEntityId&> (player->getId()) );
217 set<CEntityId> excluded;
218 msg.serialCont( excluded );
219 msg.serial( msgName );
220 sendMessageViaMirror ("IOS", msg);
223 player->_PropertyDatabase.setProp( "EXECUTE_PHRASE:SHEET", _RootSheetId.asInt() );
226 // set behaviour
227 PHRASE_UTILITIES::sendUpdateBehaviour( _ActorRowId, MBEHAV::HARVESTING );
228 }// CHarvestPhrase execute
231 //-----------------------------------------------
232 // CHarvestPhrase apply
233 //-----------------------------------------------
234 void CHarvestPhrase::apply()
236 _State = CSPhrase::Latent;
238 ///\todo behaviour
240 // spend energies
241 CEntityBase* entity = PHRASE_UTILITIES::entityPtrFromId( _ActorRowId );
242 if (entity == NULL)
244 nlwarning("<CHarvestPhrase::apply> Invalid entity Id %s", TheDataset.getEntityId(_ActorRowId).toString().c_str() );
245 return;
247 RY_GAME_SHARE::SCharacteristicsAndScores &sta = entity->getScores()._PhysicalScores[SCORES::stamina];
248 if ( sta.Current != 0)
250 sta.Current = sta.Current - _StaminaCost;
251 if (sta.Current < 0)
252 sta.Current = 0;
255 RY_GAME_SHARE::SCharacteristicsAndScores &hp = entity->getScores()._PhysicalScores[SCORES::hit_points];
256 if ( hp.Current != 0)
258 hp.Current = hp.Current - _HPCost;
259 if (hp.Current < 0)
260 hp.Current = 0;
263 // Harvest the raw materials
266 }//CHarvestPhrase apply
269 //-----------------------------------------------
270 // CHarvestPhrase end
271 //-----------------------------------------------
272 void CHarvestPhrase::end()
274 _State = CSPhrase::LatencyEnded;
276 CCharacter* player = PlayerManager.getChar(_ActorRowId);
277 if (player)
279 player->clearCurrentAction();
282 vector<uint16> qualities;
284 // set behaviour
285 PHRASE_UTILITIES::sendUpdateBehaviour( _ActorRowId, MBEHAV::HARVESTING_END );
287 if (_Deposit)
288 //player->harvestResultDeposit( _MinQuality, false);
289 player->harvestDepositResult( _MinQuality );
290 else
291 //harvestCorpseResult();
292 player->harvestCorpseResult( qualities );
294 } // end //
296 //-----------------------------------------------
297 // CHarvestPhrase stop
298 //-----------------------------------------------
299 void CHarvestPhrase::stop()
301 CCharacter* player = PlayerManager.getChar(_ActorRowId);
302 if (player)
304 player->clearCurrentAction();
305 // if (_Deposit)
306 // PHRASE_UTILITIES::sendSimpleMessage( _ActorRowId, "EGS_FORAGE_INTERRUPTED");
307 // else
308 // PHRASE_UTILITIES::sendSimpleMessage( _ActorRowId, "EGS_QUARTER_INTERRUPTED");
311 _State = CSPhrase::LatencyEnded;
313 // set behaviour
314 PHRASE_UTILITIES::sendUpdateBehaviour( _ActorRowId, MBEHAV::HARVESTING_END );
315 } // stop //
318 //-----------------------------------------------
319 // CHarvestPhrase harvestCorpseResult
320 //-----------------------------------------------
321 void CHarvestPhrase::harvestCorpseResult()
323 // get harvester character
324 CCharacter *character = PlayerManager.getChar( _ActorRowId );
325 if (character == NULL)
327 //nlwarning("<cbHarvestResult> Invalid player Id %s", playerId.toString().c_str() );
328 return;
331 // get harvested corpse
332 const CEntityId &harvestedEntity = character->harvestedEntity();
334 CCreature *creature = CreatureManager.getCreature( harvestedEntity );
335 if (creature == NULL)
337 nlwarning("<cbHarvestResult> Invalid creature Id %s", harvestedEntity.toString().c_str() );
338 // reset harvest info
339 character->resetHarvestInfos();
340 character->endHarvest();
341 return;
344 const vector< CCreatureRawMaterial> &mps = creature->getMps();
345 if ( character->harvestedMpIndex() >= mps.size() || character->harvestedMpQuantity() > mps[character->harvestedMpIndex()].Quantity )
347 // reset harvest info
348 character->resetHarvestInfos();
349 return;
352 uint16 quality = _MaxQuality;
354 // create the mp items if any
355 if (quality > 0)
357 if ( character->createItemInBag( (uint8) quality, character->harvestedMpQuantity(), _RawMaterialId) == false)
359 // CMissionEventItem event(CMissionEvent::Harvest,playerId,harvestedEntity,_RawMaterialId,quality,character->harvestedMpQuantity());
360 // character->processMissionEvent(event);
361 // error creating the object, hand probably not empty
362 // character->resetHarvestInfos();
363 // return;
365 else
367 const CStaticItem *item = CSheets::getForm(_RawMaterialId);
368 if (item)
370 CMissionEventHarvest event(_RawMaterialId ,character->harvestedMpQuantity(),quality);
371 character->processMissionEvent( event );
372 string msgName = "OPS_HARVEST_SUCESS_ISI";
374 CMessage msg("STATIC_STRING");
375 msg.serial( const_cast<CEntityId&>(character->getId()) );
376 set<CEntityId> excluded;
377 msg.serialCont( excluded );
378 msg.serial( msgName );
380 uint32 value = uint32(character->harvestedMpQuantity());
381 msg.serial( value );//qty
382 msg.serial( const_cast<string&> (item->Name) );//mp name
384 value = uint32(quality);
385 msg.serial( value );//quality
387 sendMessageViaMirror ("IOS", msg);
391 // the mp have been destroyed -> do nothing
392 else
396 // remove the quantity of mp harvested from the ressource
397 creature->removeMp( character->harvestedMpIndex(), character->harvestedMpQuantity() );
399 // reset harvest info
400 character->resetHarvestInfos();
401 } // harvestCorpseResult //