// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stdpch.h" #include "harvest_phrase.h" #include "game_share/brick_families.h" #include "s_phrase_factory.h" #include "entity_manager.h" #include "phrase_manager.h" #include "creature_manager.h" #include "player_manager.h" #include "character.h" #include "phrase_utilities_functions.h" extern CPlayerManager PlayerManager; extern CCreatureManager CreatureManager; DEFAULT_SPHRASE_FACTORY( CHarvestPhrase, BRICK_TYPE::HARVEST ); using namespace std; using namespace NLMISC; using namespace NLNET; //----------------------------------------------- // ctor //----------------------------------------------- CHarvestPhrase::CHarvestPhrase() { _SabrinaCost = 0; _SabrinaCredit = 0; _StaminaCost = 0; _HPCost = 0; _HarvestTime = 25; // 2.5s for DEBUG ONLY // _HarvestTime = 0; // 0s for DEBUG ONLY _IsStatic = true; } //----------------------------------------------- // CHarvestPhrase build //----------------------------------------------- bool CHarvestPhrase::build( const TDataSetRow & actorRowId, const std::vector< const CStaticBrick* >& bricks ) { // we are sure there is at least one brick and that there are non NULL; nlassert( !bricks.empty() ); _ActorRowId = actorRowId; // compute cost and credit and parse other params for ( uint i = 0; i < bricks.size(); ++i ) { const CStaticBrick & brick = *bricks[i]; if ( i == 0) _RootSheetId = brick.SheetId; if ( brick.SabrinaValue < 0 ) _SabrinaCredit -= brick.SabrinaValue; else _SabrinaCost += brick.SabrinaValue; switch( brick.Family ) { /* TempYoyo: case BRICK_FAMILIES::RootHarvest: break;*/ default: for ( uint i=0 ; iid()) { case TBrickParam::SAP: return false; case TBrickParam::HP: INFOLOG("HP: %i",((CSBrickParamHp *)brick.Params[i])->Hp); _HPCost += ((CSBrickParamHp *)brick.Params[i])->Hp; break; case TBrickParam::STA: INFOLOG("STA: %i",((CSBrickParamSta *)brick.Params[i])->Sta); _StaminaCost += ((CSBrickParamSta *)brick.Params[i])->Sta; break; default: // unused param ? break; } } break; } } return true; }// CHarvestPhrase build //----------------------------------------------- // CHarvestPhrase evaluate //----------------------------------------------- bool CHarvestPhrase::evaluate(CEvalReturnInfos *msg) { // update state _State = CSPhrase::Evaluated; return true; }// CHarvestPhrase evaluate //----------------------------------------------- // CHarvestPhrase validate //----------------------------------------------- bool CHarvestPhrase::validate() { // entities cant harvest if in combat TDataSetRow entityRowId = CPhraseManager::getInstance()->getEntityEngagedMeleeBy( _ActorRowId ); if (entityRowId.isValid()) { ///\todo david : send message return false; } CEntityBase * entity = CEntityBaseManager::getEntityBasePtr( _ActorRowId ); const sint32 hp = entity->getScores()._PhysicalScores[ SCORES::hit_points ].Current; if ( hp < _HPCost ) { ///\todo david : send message return false; } const sint32 sta = entity->getScores()._PhysicalScores[ SCORES::stamina ].Current; if ( sta < _StaminaCost ) { ///\todo david : send message return false; } if (hp <= 0 || entity->getMode()==MBEHAV::DEATH) { ///\todo david : send message return false; } /// todo david : test if on mount // update state if (_State == Evaluated) _State = Validated; else if (_State == ExecutionInProgress) _State = SecondValidated; return true; }// CHarvestPhrase validate //----------------------------------------------- // CHarvestPhrase update //----------------------------------------------- bool CHarvestPhrase::update() { const NLMISC::TGameCycle time = CTickEventHandler::getGameCycle(); // if the sentence execution delay time has ended, apply sentence effects if ( _State == SecondValidated && _ExecutionEndDate <= time && _NbWaitingRequests == 0) { apply(); } else if ( _State == Latent /*&& _LatencyEndDate <= time*/ ) { end(); } return true; }// CHarvestPhrase update //----------------------------------------------- // CHarvestPhrase execute //----------------------------------------------- void CHarvestPhrase::execute() { if( _NbWaitingRequests != 0) return; const NLMISC::TGameCycle time = CTickEventHandler::getGameCycle(); _State = CSPhrase::ExecutionInProgress; _ExecutionEndDate = time + _HarvestTime ; CCharacter* player = PlayerManager.getChar(_ActorRowId); if (player) { player->setCurrentAction(CLIENT_ACTION_TYPE::Harvest,_ExecutionEndDate); const CStaticItem *item = CSheets::getForm(_RawMaterialId); if (item != 0) { /* string msgName = "BS_HARVEST_BEGIN_S"; CMessage msg("STATIC_STRING"); msg.serial( const_cast (player->getId()) ); set excluded; msg.serialCont( excluded ); msg.serial( msgName ); msg.serial( const_cast (item->Name)); sendMessageViaMirror ("IOS", msg); */ string msgName = "WOS_HARVEST_SEARCHING"; CMessage msg("STATIC_STRING"); msg.serial( const_cast (player->getId()) ); set excluded; msg.serialCont( excluded ); msg.serial( msgName ); sendMessageViaMirror ("IOS", msg); } player->_PropertyDatabase.setProp( "EXECUTE_PHRASE:SHEET", _RootSheetId.asInt() ); } // set behaviour PHRASE_UTILITIES::sendUpdateBehaviour( _ActorRowId, MBEHAV::HARVESTING ); }// CHarvestPhrase execute //----------------------------------------------- // CHarvestPhrase apply //----------------------------------------------- void CHarvestPhrase::apply() { _State = CSPhrase::Latent; ///\todo behaviour // spend energies CEntityBase* entity = PHRASE_UTILITIES::entityPtrFromId( _ActorRowId ); if (entity == NULL) { nlwarning(" Invalid entity Id %s", TheDataset.getEntityId(_ActorRowId).toString().c_str() ); return; } RY_GAME_SHARE::SCharacteristicsAndScores &sta = entity->getScores()._PhysicalScores[SCORES::stamina]; if ( sta.Current != 0) { sta.Current = sta.Current - _StaminaCost; if (sta.Current < 0) sta.Current = 0; } RY_GAME_SHARE::SCharacteristicsAndScores &hp = entity->getScores()._PhysicalScores[SCORES::hit_points]; if ( hp.Current != 0) { hp.Current = hp.Current - _HPCost; if (hp.Current < 0) hp.Current = 0; } // Harvest the raw materials }//CHarvestPhrase apply //----------------------------------------------- // CHarvestPhrase end //----------------------------------------------- void CHarvestPhrase::end() { _State = CSPhrase::LatencyEnded; CCharacter* player = PlayerManager.getChar(_ActorRowId); if (player) { player->clearCurrentAction(); } vector qualities; // set behaviour PHRASE_UTILITIES::sendUpdateBehaviour( _ActorRowId, MBEHAV::HARVESTING_END ); if (_Deposit) //player->harvestResultDeposit( _MinQuality, false); player->harvestDepositResult( _MinQuality ); else //harvestCorpseResult(); player->harvestCorpseResult( qualities ); } // end // //----------------------------------------------- // CHarvestPhrase stop //----------------------------------------------- void CHarvestPhrase::stop() { CCharacter* player = PlayerManager.getChar(_ActorRowId); if (player) { player->clearCurrentAction(); // if (_Deposit) // PHRASE_UTILITIES::sendSimpleMessage( _ActorRowId, "EGS_FORAGE_INTERRUPTED"); // else // PHRASE_UTILITIES::sendSimpleMessage( _ActorRowId, "EGS_QUARTER_INTERRUPTED"); } _State = CSPhrase::LatencyEnded; // set behaviour PHRASE_UTILITIES::sendUpdateBehaviour( _ActorRowId, MBEHAV::HARVESTING_END ); } // stop // //----------------------------------------------- // CHarvestPhrase harvestCorpseResult //----------------------------------------------- void CHarvestPhrase::harvestCorpseResult() { // get harvester character CCharacter *character = PlayerManager.getChar( _ActorRowId ); if (character == NULL) { //nlwarning(" Invalid player Id %s", playerId.toString().c_str() ); return; } // get harvested corpse const CEntityId &harvestedEntity = character->harvestedEntity(); CCreature *creature = CreatureManager.getCreature( harvestedEntity ); if (creature == NULL) { nlwarning(" Invalid creature Id %s", harvestedEntity.toString().c_str() ); // reset harvest info character->resetHarvestInfos(); character->endHarvest(); return; } const vector< CCreatureRawMaterial> &mps = creature->getMps(); if ( character->harvestedMpIndex() >= mps.size() || character->harvestedMpQuantity() > mps[character->harvestedMpIndex()].Quantity ) { // reset harvest info character->resetHarvestInfos(); return; } uint16 quality = _MaxQuality; // create the mp items if any if (quality > 0) { if ( character->createItemInBag( (uint8) quality, character->harvestedMpQuantity(), _RawMaterialId) == false) { // CMissionEventItem event(CMissionEvent::Harvest,playerId,harvestedEntity,_RawMaterialId,quality,character->harvestedMpQuantity()); // character->processMissionEvent(event); // error creating the object, hand probably not empty // character->resetHarvestInfos(); // return; } else { const CStaticItem *item = CSheets::getForm(_RawMaterialId); if (item) { CMissionEventHarvest event(_RawMaterialId ,character->harvestedMpQuantity(),quality); character->processMissionEvent( event ); string msgName = "OPS_HARVEST_SUCESS_ISI"; CMessage msg("STATIC_STRING"); msg.serial( const_cast(character->getId()) ); set excluded; msg.serialCont( excluded ); msg.serial( msgName ); uint32 value = uint32(character->harvestedMpQuantity()); msg.serial( value );//qty msg.serial( const_cast (item->Name) );//mp name value = uint32(quality); msg.serial( value );//quality sendMessageViaMirror ("IOS", msg); } } } // the mp have been destroyed -> do nothing else { } // remove the quantity of mp harvested from the ressource creature->removeMp( character->harvestedMpIndex(), character->harvestedMpQuantity() ); // reset harvest info character->resetHarvestInfos(); } // harvestCorpseResult //