Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ryzom/server/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
IF(WITH_RYZOM_TOOLS OR WITH_RYZOM_SERVER)
ADD_SUBDIRECTORY(server_share)
ADD_SUBDIRECTORY(ai_share)
ADD_SUBDIRECTORY(egs_sheets)
ENDIF()

IF(WITH_RYZOM_SERVER)
Expand Down
26 changes: 1 addition & 25 deletions ryzom/server/src/ai_service/ai_script_comp.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,7 @@
#ifndef _SCRIPT_COMP_H_
#define _SCRIPT_COMP_H_


struct ReadFightActionException :public NLMISC::Exception
{
ReadFightActionException(const std::string &reason):NLMISC::Exception(reason){}
};

class CSpawnBot;

class CFightScriptComp
:public NLMISC::CRefCount
{
public:
CFightScriptComp()
{}
virtual ~CFightScriptComp()
{}
virtual std::string toString() const = 0;

virtual bool update(CSpawnBot &bot) const = 0; // returns true if it behaves normally, false if there a problem and callers may not consider it behaves normally.
// for instance ONCE may not consider that this call happened.
virtual void remove(CFightScriptComp *child)
{}
protected:
private:
};
#include "ai_script_comp_base.h"

class CFightScriptCompReader
:public NLMISC::CRefCount
Expand Down
47 changes: 47 additions & 0 deletions ryzom/server/src/ai_service/ai_script_comp_base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// 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 <http://www.gnu.org/licenses/>.

#ifndef _SCRIPT_COMP_BASE_H_
#define _SCRIPT_COMP_BASE_H_

#include "nel/misc/smart_ptr.h"

struct ReadFightActionException :public NLMISC::Exception
{
ReadFightActionException(const std::string &reason):NLMISC::Exception(reason){}
};

class CSpawnBot;

class CFightScriptComp
:public NLMISC::CRefCount
{
public:
CFightScriptComp()
{}
virtual ~CFightScriptComp()
{}
virtual std::string toString() const = 0;

virtual bool update(CSpawnBot &bot) const = 0; // returns true if it behaves normally, false if there a problem and callers may not consider it behaves normally.
// for instance ONCE may not consider that this call happened.
virtual void remove(CFightScriptComp *child)
{}
protected:
private:
};

#endif
151 changes: 151 additions & 0 deletions ryzom/server/src/ai_service/ai_sheets_creature.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This source file has been modified by the following contributors:
// Copyright (C) 2014 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
//
// 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 <http://www.gnu.org/licenses/>.

// AI-service-specific sheets overrides.
// These depend on ai_script_comp.cpp (CFightScriptCompReader,
// CFightSelectFilter) and are kept separate from the base CCreature
// so the base class can be used independently (e.g. by sheets_packer_shard).

#include "stdpch.h"

#include "ai_sheets_creature.h"
#include "ai_script_comp.h"

#include "nel/net/service.h"
#include "nel/georges/load_form.h"

using namespace std;
using namespace NLMISC;
using namespace NLNET;

extern char const* AISPackedSheetsFilename;
extern char const* AISPackedFightConfigSheetsFilename;
extern char const* AISPackedActionSheetsFilename;
extern char const* AISPackedRaceStatsSheetsFilename;

void AISHEETS::CCreatureAI::onScriptComp(const std::string &scriptCompStr)
{
CFightScriptComp* scriptComp;
try
{
scriptComp = CFightScriptCompReader::createScriptComp(scriptCompStr);
registerScriptComp(scriptComp);
}
catch (const ReadFightActionException& ex)
{
nlwarning("script read error (ignored): %s", ex.what());
}
}

void AISHEETS::CCreatureAI::registerScriptComp(CFightScriptComp* scriptComp)
{
_ScriptCompList.push_back(scriptComp);

CFightSelectFilter* filter = dynamic_cast<CFightSelectFilter*>(scriptComp);
if (!filter)
return;

std::string const& param = filter->getParam();
if (param == "ON_UPDATE")
_UpdateScriptList.push_back(scriptComp);
if (param == "ON_DEATH")
_DeathScriptList.push_back(scriptComp);
if (param == "ON_BIRTH")
_BirthScriptList.push_back(scriptComp);
}

void AISHEETS::CSheetsAI::initInstance()
{
setInstance(new CSheetsAI);
}

void AISHEETS::CSheetsAI::packSheets(const std::string &writeFilesDirectoryName)
{
CConfigFile::CVar *varPtr = IService::isServiceInitialized() ? IService::getInstance()->ConfigFile.getVarPtr(std::string("GeorgePaths")) : NULL;

// Use CCreatureAI map so script comps are processed during loading
std::map<CSheetId, CCreatureAIPtr> sheetsAI;

// if config file variable 'GeorgePaths' exists then only do a minimal loadForms otherwise do the full works
if (varPtr != NULL)
{
bool addSearchPath = false;

loadForm2("aiaction", writeFilesDirectoryName + AISPackedActionSheetsFilename, _ActionSheets, false, false);
if (_ActionSheets.empty())
{
if (!addSearchPath)
{
addSearchPath = true;
for (uint32 i = 0; i < varPtr->size(); ++i)
CPath::addSearchPath(NLMISC::expandEnvironmentVariables(varPtr->asString(i)), true, false);
}
loadForm2("aiaction", writeFilesDirectoryName + AISPackedActionSheetsFilename, _ActionSheets, true);
}

loadForm("actionlist", writeFilesDirectoryName + AISPackedFightConfigSheetsFilename, _ActionListSheets, false, false);
if (_ActionListSheets.empty())
{
if (!addSearchPath)
{
addSearchPath = true;
for (uint32 i = 0; i < varPtr->size(); ++i)
CPath::addSearchPath(NLMISC::expandEnvironmentVariables(varPtr->asString(i)), true, false);
}
loadForm("actionlist", writeFilesDirectoryName + AISPackedFightConfigSheetsFilename, _ActionListSheets, true);
}

loadForm2("creature", writeFilesDirectoryName + AISPackedSheetsFilename, sheetsAI, false, false);
if (sheetsAI.empty())
{
if (!addSearchPath)
{
addSearchPath = true;
for (uint32 i = 0; i < varPtr->size(); ++i)
CPath::addSearchPath(NLMISC::expandEnvironmentVariables(varPtr->asString(i)), true, false);
}
loadForm2("creature", writeFilesDirectoryName + AISPackedSheetsFilename, sheetsAI, true);
}

loadForm2("race_stats", writeFilesDirectoryName + AISPackedRaceStatsSheetsFilename, _RaceStatsSheets, false, false);
if (_RaceStatsSheets.empty())
{
if (!addSearchPath)
{
addSearchPath = true;
for (uint32 i = 0; i < varPtr->size(); ++i)
CPath::addSearchPath(NLMISC::expandEnvironmentVariables(varPtr->asString(i)), true, false);
}
loadForm2("race_stats", writeFilesDirectoryName + AISPackedRaceStatsSheetsFilename, _RaceStatsSheets, true);
}
}
else
{
loadForm2("aiaction", writeFilesDirectoryName + AISPackedActionSheetsFilename, _ActionSheets, true);
loadForm("actionlist", writeFilesDirectoryName + AISPackedFightConfigSheetsFilename, _ActionListSheets, true);
loadForm2("creature", writeFilesDirectoryName + AISPackedSheetsFilename, sheetsAI, true);
loadForm2("race_stats", writeFilesDirectoryName + AISPackedRaceStatsSheetsFilename, _RaceStatsSheets, true);
}

// Transfer CCreatureAI pointers into the base _Sheets map
for (std::map<CSheetId, CCreatureAIPtr>::iterator it = sheetsAI.begin(); it != sheetsAI.end(); ++it)
{
_Sheets.insert(std::make_pair(it->first, CCreaturePtr(it->second)));
}
}
60 changes: 60 additions & 0 deletions ryzom/server/src/ai_service/ai_sheets_creature.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This source file has been modified by the following contributors:
// Copyright (C) 2014 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
//
// 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 <http://www.gnu.org/licenses/>.

#ifndef RYAI_SHEETS_CREATURE_H
#define RYAI_SHEETS_CREATURE_H

#include "sheets.h"

namespace AISHEETS {

/**
* AI-service-specific creature sheet class.
* Extends CCreature with script comp processing that depends on
* ai_script_comp.cpp (CFightScriptCompReader, CFightSelectFilter).
*/
class CCreatureAI
: public CCreature
{
protected:
void onScriptComp(const std::string &scriptCompStr);

public:
void registerScriptComp(CFightScriptComp* scriptComp);
};
typedef NLMISC::CSmartPtr<CCreatureAI> CCreatureAIPtr;

/**
* AI-service-specific sheets singleton.
* Overrides packSheets to load CCreatureAI instead of CCreature,
* enabling script comp processing without preprocessor hacks.
*/
class CSheetsAI
: public CSheets
{
public:
void packSheets(const std::string &writeFilesDirectoryName);

/// Register CSheetsAI as the singleton. Call before getInstance().
static void initInstance();
};

}

#endif
2 changes: 2 additions & 0 deletions ryzom/server/src/ai_service/service_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "aids_interface.h"
#include "game_share/fame.h"
#include "visual_properties_interface.h"
#include "ai_sheets_creature.h"

#include "ais_user_models.h"

Expand Down Expand Up @@ -208,6 +209,7 @@ void CAIService::init (void)
CAIKeywords::init();
CMirrors::init(cbTick, NULL, cbTickRelease);
CMessages::init();
AISHEETS::CSheetsAI::initInstance();
AISHEETS::CSheets::getInstance()->init();

// initialise the AI_SHARE library
Expand Down
49 changes: 7 additions & 42 deletions ryzom/server/src/ai_service/sheets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -628,18 +628,7 @@ void AISHEETS::CCreature::readGeorges(NLMISC::CSmartPtr<NLGEORGES::UForm> const&
{
std::string scriptCompStr;
scriptCompNode->getArrayValue(scriptCompStr, arrayIndex);
#ifndef NO_AI_COMP
CFightScriptComp* scriptComp;
try
{
scriptComp = CFightScriptCompReader::createScriptComp(scriptCompStr);
registerScriptComp(scriptComp);
}
catch (const ReadFightActionException& ex)
{
nlwarning("script read error (ignored): %s", ex.what());
}
#endif
onScriptComp(scriptCompStr);
}
}
// Creature race
Expand All @@ -653,23 +642,6 @@ void AISHEETS::CCreature::readGeorges(NLMISC::CSmartPtr<NLGEORGES::UForm> const&
}
}

void AISHEETS::CCreature::registerScriptComp(CFightScriptComp* scriptComp)
{
_ScriptCompList.push_back(scriptComp);

CFightSelectFilter* filter = dynamic_cast<CFightSelectFilter*>(scriptComp);
if (!filter)
return;

std::string const& param = filter->getParam();
if (param=="ON_UPDATE")
_UpdateScriptList.push_back(scriptComp);
if (param=="ON_DEATH")
_DeathScriptList.push_back(scriptComp);
if (param=="ON_BIRTH")
_BirthScriptList.push_back(scriptComp);
}


uint AISHEETS::CCreature::getVersion()
{
Expand Down Expand Up @@ -766,19 +738,7 @@ void AISHEETS::CCreature::serial(NLMISC::IStream &s)
{
string scriptCompStr;
s.serial(scriptCompStr);

#ifndef NO_AI_COMP
CFightScriptComp* scriptComp;
try
{
scriptComp = CFightScriptCompReader::createScriptComp(scriptCompStr);
registerScriptComp(scriptComp);
}
catch (const ReadFightActionException& ex)
{
nlwarning("script read error (ignored): %s", ex.what());
}
#endif
onScriptComp(scriptCompStr);
}
}
else
Expand Down Expand Up @@ -872,6 +832,11 @@ void AISHEETS::CSheets::destroyInstance()
_Instance = NULL;
}

void AISHEETS::CSheets::setInstance(CSheets* instance)
{
_Instance = instance;
}

AISHEETS::CSheets::CSheets()
: _Initialised(false)
{
Expand Down
Loading
Loading