// 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 "sabrina_com.h"
using namespace NLMISC;
using namespace std;
// ***************************************************************************
CSabrinaCom::CSabrinaCom(IBrickContainer *bc)
{
nlassert(bc);
_BC= bc;
}
// ***************************************************************************
CSabrinaCom::~CSabrinaCom()
{
_BC= NULL;
}
// ***************************************************************************
void CSabrinaCom::getPhraseCost(const std::vector &bricks, uint32 &pos, uint32 &neg) const
{
pos= 0;
neg= 0;
float rpos= 1.0f;
float rneg= 1.0f;
// Yoyo: for now easy, sum pos or neg SabrinaCost
for(uint i=0;igetSabrinaCost(bricks[i]);
if(cost>0)
pos+= cost;
else
neg+= (-cost);
float rcost = _BC->getSabrinaRelativeCost(bricks[i]);
if( rcost>0.f)
rpos+= rcost;
else
rneg-= rcost;
}
pos = (uint32)(pos * rpos);
neg = (uint32)(neg * rneg);
}
// ***************************************************************************
uint32 CSabrinaCom::getPhraseMaxBrickCost(const std::vector &bricks) const
{
uint32 costMax= 0;
for(uint i=0;igetSabrinaCost(bricks[i]);
if(cost>0)
costMax= max(costMax, (uint32)cost);
}
return costMax;
}
// ***************************************************************************
sint32 CSabrinaCom::getPhraseBrickAndParamCost(const std::vector &bricks, uint brickIndex) const
{
if(brickIndex>=bricks.size())
return 0;
sint32 res= 0;
// Yoyo: for now easy, sum the brick and all params cost.
uint numParams= 0;
// Add the brick and its params cost.
for(uint i=brickIndex;igetSabrinaCost(bricks[i]);
// If this brick adds a parameter (main brick or base parameter)
numParams+= _BC->getNumParameters(bricks[i]);
}
return res;
}
// ***************************************************************************
float CSabrinaCom::getPhraseBrickAndParamRelativeCost(const std::vector &bricks, uint brickIndex) const
{
if(brickIndex>=bricks.size())
return 0.f;
float res= 0.f;
// Yoyo: for now easy, sum the brick and all params relative cost.
uint numParams= 0;
// Add the brick and its params cost.
for(uint i=brickIndex;igetSabrinaRelativeCost(bricks[i]);
// If this brick adds a parameter (main brick or base parameter)
numParams+= _BC->getNumParameters(bricks[i]);
}
return res;
}
// ***************************************************************************
void CSabrinaCom::filterMandatoryComposition(const std::vector &/* phraseBricks */, std::vector &/* mandatoryBricks */) const
{
// Yoyo: for now, no simple rule known => never exclude mandatories.
}
// ***************************************************************************
TOOL_TYPE::TCraftingToolType CSabrinaCom::getPhraseFaberPlanToolType(const std::vector &phraseBricks) const
{
// Valid only if not empty, and a faber one,
if( phraseBricks.size()>=1 && _BC->getBrickType(phraseBricks[0])== BRICK_TYPE::FABER )
{
return _BC->getFaberPlanToolType(phraseBricks[0]);
}
return TOOL_TYPE::Unknown;
}
// ***************************************************************************
NLMISC::CSheetId CSabrinaCom::getPhraseBestDisplayBrick(const std::vector &phraseBricks) const
{
if(phraseBricks.empty())
return CSheetId();
BRICK_TYPE::EBrickType bType= _BC->getBrickType(phraseBricks[0]);
// Magic? take the coster mandatory brick.
// Combat? take the coster optional brick
if( bType== BRICK_TYPE::MAGIC ||
bType== BRICK_TYPE::COMBAT )
{
// default still to root (error case)
uint best= 0;
uint bestCost= 0;
// The cost of the effect is its + all its params.
for(uint i=1;igetBrickFamily(brickId, indexInFamily);
if( (BRICK_FAMILIES::isMandatoryFamily(bf) && bType==BRICK_TYPE::MAGIC) ||
(BRICK_FAMILIES::isOptionFamily(bf) && bType==BRICK_TYPE::COMBAT) )
{
effectCost= _BC->getSabrinaCost(brickId);
// next brick
i++;
// add its params cost
uint numParams= _BC->getNumParameters(brickId);
for(;numParams>0 && igetSabrinaCost(brickId);
}
}
else
// next brick
i++;
// coster?
if(effectCost>bestCost)
{
bestCost= effectCost;
best= effectId;
}
}
return phraseBricks[best];
}
// SpecialPower? take the first mandatory brick.
else if(bType== BRICK_TYPE::SPECIAL_POWER)
{
if( phraseBricks.size()>=3 )
return phraseBricks[2];
if( phraseBricks.size()>=2 )
return phraseBricks[1];
}
// Prospection & extraction?
// Take the last most expensive brick (except the root and ecotype specializing)
else if ( (bType == BRICK_TYPE::FORAGE_PROSPECTION) || (bType == BRICK_TYPE::FORAGE_EXTRACTION) )
{
uint bestIndex = 0;
uint bestCost = 0;
uint maxIndexInExtractionFamily = 0;
for ( uint i=1; igetBrickFamily( brickId, indexInFamily );
if ( brickFamily == BRICK_FAMILIES::Unknown )
continue;
if ( BRICK_FAMILIES::isCreditFamily( brickFamily ) )
continue;
// Do not print ecosystem specialization if not alone in the phrase
if ( (brickFamily == BRICK_FAMILIES::BHFPMA) && (phraseBricks.size() > 4) )
continue;
if ( (brickFamily == BRICK_FAMILIES::BHFEMA) && ((maxIndexInExtractionFamily != 1) || (phraseBricks.size() != 7)) ) // works only for default phrase where eco. spec. is at the end
continue;
// Calc the last highest cost
uint brickCost = _BC->getSabrinaCost( brickId);
if ( brickCost >= bestCost )
{
bestCost = brickCost;
bestIndex = i;
}
if ( (brickFamily >= BRICK_FAMILIES::BHFEEA) && (brickFamily <= BRICK_FAMILIES::BHFEEC) && (indexInFamily > maxIndexInExtractionFamily) )
maxIndexInExtractionFamily = indexInFamily;
}
if ( (bType == BRICK_TYPE::FORAGE_EXTRACTION) && (maxIndexInExtractionFamily==1) && (phraseBricks.size()==5) )
bestIndex = 0; // "Basic Extraction": index of the root brick
return phraseBricks[bestIndex];
}
// Other cases: return the rootBrick.
return phraseBricks[0];
}
// ***************************************************************************
bool CSabrinaCom::isMainDisplayIconInOverSlot(const NLMISC::CSheetId &brickId, bool& iconOver2NotSuitableForActionDisplay) const
{
uint indexInFamily;
BRICK_FAMILIES::TBrickFamily brickFamily = _BC->getBrickFamily( brickId, indexInFamily );
iconOver2NotSuitableForActionDisplay = ((brickFamily >= BRICK_FAMILIES::BeginForageProspection) && (brickFamily <= BRICK_FAMILIES::EndForageExtraction));
// True only for the 3 extraction bricks
return ((brickFamily >= BRICK_FAMILIES::BHFEEA) && (brickFamily <= BRICK_FAMILIES::BHFEEC));
}