From d69429aff87b0fee843302f77a8b5ead4739b723 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Tue, 14 Jan 2014 11:08:15 -0700 Subject: [PATCH] Added the sharedSkillSystem library --- engine/shared/library/CMakeLists.txt | 1 + .../library/sharedSkillSystem/CMakeLists.txt | 11 + .../sharedSkillSystem/ExpertiseManager.h | 1 + .../FirstSharedSkillSystem.h | 1 + .../public/sharedSkillSystem/LevelManager.h | 1 + .../public/sharedSkillSystem/SkillManager.h | 1 + .../public/sharedSkillSystem/SkillObject.h | 1 + .../sharedSkillSystem/SkillObjectArchive.h | 1 + .../sharedSkillSystem/src/CMakeLists.txt | 40 ++ .../src/shared/ExpertiseManager.cpp | 640 ++++++++++++++++++ .../src/shared/ExpertiseManager.h | 69 ++ .../src/shared/FirstSharedSkillSystem.h | 16 + .../src/shared/LevelManager.cpp | 421 ++++++++++++ .../src/shared/LevelManager.h | 58 ++ .../src/shared/SkillManager.cpp | 212 ++++++ .../src/shared/SkillManager.h | 60 ++ .../src/shared/SkillObject.cpp | 561 +++++++++++++++ .../src/shared/SkillObject.h | 115 ++++ .../src/shared/SkillObjectArchive.cpp | 45 ++ .../src/shared/SkillObjectArchive.h | 29 + .../src/win32/FirstSharedSkillSystem.cpp | 8 + 21 files changed, 2292 insertions(+) create mode 100644 engine/shared/library/sharedSkillSystem/CMakeLists.txt create mode 100644 engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/ExpertiseManager.h create mode 100644 engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/FirstSharedSkillSystem.h create mode 100644 engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/LevelManager.h create mode 100644 engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/SkillManager.h create mode 100644 engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/SkillObject.h create mode 100644 engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/SkillObjectArchive.h create mode 100644 engine/shared/library/sharedSkillSystem/src/CMakeLists.txt create mode 100644 engine/shared/library/sharedSkillSystem/src/shared/ExpertiseManager.cpp create mode 100644 engine/shared/library/sharedSkillSystem/src/shared/ExpertiseManager.h create mode 100644 engine/shared/library/sharedSkillSystem/src/shared/FirstSharedSkillSystem.h create mode 100644 engine/shared/library/sharedSkillSystem/src/shared/LevelManager.cpp create mode 100644 engine/shared/library/sharedSkillSystem/src/shared/LevelManager.h create mode 100644 engine/shared/library/sharedSkillSystem/src/shared/SkillManager.cpp create mode 100644 engine/shared/library/sharedSkillSystem/src/shared/SkillManager.h create mode 100644 engine/shared/library/sharedSkillSystem/src/shared/SkillObject.cpp create mode 100644 engine/shared/library/sharedSkillSystem/src/shared/SkillObject.h create mode 100644 engine/shared/library/sharedSkillSystem/src/shared/SkillObjectArchive.cpp create mode 100644 engine/shared/library/sharedSkillSystem/src/shared/SkillObjectArchive.h create mode 100644 engine/shared/library/sharedSkillSystem/src/win32/FirstSharedSkillSystem.cpp diff --git a/engine/shared/library/CMakeLists.txt b/engine/shared/library/CMakeLists.txt index e80264ab..92f6867f 100644 --- a/engine/shared/library/CMakeLists.txt +++ b/engine/shared/library/CMakeLists.txt @@ -17,6 +17,7 @@ add_subdirectory(sharedNetwork) add_subdirectory(sharedNetworkMessages) add_subdirectory(sharedObject) add_subdirectory(sharedRandom) +add_subdirectory(sharedSkillSystem) add_subdirectory(sharedSynchronization) add_subdirectory(sharedTerrain) add_subdirectory(sharedThread) diff --git a/engine/shared/library/sharedSkillSystem/CMakeLists.txt b/engine/shared/library/sharedSkillSystem/CMakeLists.txt new file mode 100644 index 00000000..0ade0f09 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 2.8) + +project(sharedSkillSystem) + +if(WIN32) + add_definitions(/D_CRT_SECURE_NO_WARNINGS) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/public) + +add_subdirectory(src) diff --git a/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/ExpertiseManager.h b/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/ExpertiseManager.h new file mode 100644 index 00000000..f9878d9d --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/ExpertiseManager.h @@ -0,0 +1 @@ +#include "../../src/shared/ExpertiseManager.h" diff --git a/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/FirstSharedSkillSystem.h b/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/FirstSharedSkillSystem.h new file mode 100644 index 00000000..4c757993 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/FirstSharedSkillSystem.h @@ -0,0 +1 @@ +#include "../../src/shared/FirstSharedSkillSystem.h" diff --git a/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/LevelManager.h b/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/LevelManager.h new file mode 100644 index 00000000..191fb663 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/LevelManager.h @@ -0,0 +1 @@ +#include "../../src/shared/LevelManager.h" diff --git a/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/SkillManager.h b/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/SkillManager.h new file mode 100644 index 00000000..3e103b22 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/SkillManager.h @@ -0,0 +1 @@ +#include "../../src/shared/SkillManager.h" diff --git a/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/SkillObject.h b/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/SkillObject.h new file mode 100644 index 00000000..34992d9b --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/SkillObject.h @@ -0,0 +1 @@ +#include "../../src/shared/SkillObject.h" diff --git a/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/SkillObjectArchive.h b/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/SkillObjectArchive.h new file mode 100644 index 00000000..fa856c2b --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/include/public/sharedSkillSystem/SkillObjectArchive.h @@ -0,0 +1 @@ +#include "../../src/shared/SkillObjectArchive.h" diff --git a/engine/shared/library/sharedSkillSystem/src/CMakeLists.txt b/engine/shared/library/sharedSkillSystem/src/CMakeLists.txt new file mode 100644 index 00000000..76719fdc --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/CMakeLists.txt @@ -0,0 +1,40 @@ + +set(SHARED_SOURCES + shared/ExpertiseManager.cpp + shared/ExpertiseManager.h + shared/LevelManager.cpp + shared/LevelManager.h + shared/SkillManager.cpp + shared/SkillManager.h + shared/SkillObjectArchive.cpp + shared/SkillObjectArchive.h + shared/SkillObject.cpp + shared/SkillObject.h +) + +if(WIN32) + set(PLATFORM_SOURCES + win32/FirstSharedSkillSystem.cpp + ) + + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32) +else() + set(PLATFORM_SOURCES "") +endif() + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/shared + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include +) + +add_library(sharedSkillSystem STATIC + ${SHARED_SOURCES} + ${PLATFORM_SOURCES} +) diff --git a/engine/shared/library/sharedSkillSystem/src/shared/ExpertiseManager.cpp b/engine/shared/library/sharedSkillSystem/src/shared/ExpertiseManager.cpp new file mode 100644 index 00000000..a489ceed --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/shared/ExpertiseManager.cpp @@ -0,0 +1,640 @@ +//====================================================================== +// +// ExpertiseManager.cpp +// copyright (c) 2006 Sony Online Entertainment +// +//====================================================================== + +#include "sharedSkillSystem/FirstSharedSkillSystem.h" +#include "sharedSkillSystem/ExpertiseManager.h" + +#include "sharedFoundation/ExitChain.h" +#include "sharedSkillSystem/SkillObject.h" +#include "sharedUtility/DataTable.h" +#include "sharedUtility/DataTableManager.h" + +#include + +//====================================================================== + +namespace ExpertiseManagerNamespace +{ + bool s_installed = false; + + std::string const cs_expertiseSkillCategoryName("expertise"); + + int const cs_numExpertiseColumns = 7; + int const cs_numExpertiseTiers = 5; + + std::string const cs_emptyString; + ExpertiseManager::TreeIdList const cs_emptyTreeIdList; + DataTable const cs_unusedDataTable; + + // for direct access to expertise datatable + DataTable const * s_expertiseDatatable; + + // grid x,y,z -> expertise skill name + typedef std::map ExpertiseGrid; + ExpertiseGrid s_expertiseGrid; + std::string const cs_expertiseDatatableName("datatables/expertise/expertise.iff"); + void loadExpertiseTable(DataTable const & datatable); + + // character level --> expertise points awarded + typedef std::map LevelToPointsMap; + LevelToPointsMap s_expertisePointsForLevel; + std::string const cs_expertisePointsDatatableName("datatables/player/player_level.iff"); + void loadExpertisePointsTable(DataTable const & datatable); + + // expertise tree id --> string id + typedef std::map TreeToStringIdMap; + TreeToStringIdMap s_expertiseStringForTree; + TreeToStringIdMap s_uiBackgroundIdForTree; + std::string const cs_expertiseTreesDatatableName("datatables/expertise/expertise_trees.iff"); + void loadExpertiseTreesTable(DataTable const & datatable); + + // skill template --> expertise tree id list + typedef std::map ProfessionToTreeMap; + ProfessionToTreeMap s_expertiseTreesForProfession; + std::string const cs_skillTemplateDatatableName("datatables/skill_template/skill_template.iff"); + void loadSkillTemplateTable(DataTable const & datatable); + + void splitString(char delim, std::string const & source, std::vector & result); +}; + +using namespace ExpertiseManagerNamespace; + +//====================================================================== + +void ExpertiseManagerNamespace::loadExpertiseTable(DataTable const & datatable) +{ + UNREF(datatable); // required for callback, but unused + + s_expertiseGrid.clear(); + + s_expertiseDatatable = DataTableManager::getTable(cs_expertiseDatatableName, true); + + DEBUG_FATAL(!s_expertiseDatatable, ("ExpertiseManager: failed to load %s", cs_expertiseDatatableName.c_str())); + + int const numRows = s_expertiseDatatable->getNumRows(); + + int const nameColumn = s_expertiseDatatable->findColumnNumber("NAME"); + int const treeColumn = s_expertiseDatatable->findColumnNumber("TREE"); + int const tierColumn = s_expertiseDatatable->findColumnNumber("TIER"); + int const gridColumn = s_expertiseDatatable->findColumnNumber("GRID"); + int const rankColumn = s_expertiseDatatable->findColumnNumber("RANK"); + + for (int row = 0; row < numRows; ++row) + { + std::string const & name = s_expertiseDatatable->getStringValue(nameColumn, row); + + SkillObject const * skill = SkillManager::getInstance().getSkill(name); + DEBUG_FATAL(!skill, ("ExpertiseManager: %s row %d: skill does not exist for %s", cs_expertiseDatatableName.c_str(), row, name.c_str())); + + int tree = s_expertiseDatatable->getIntValue(treeColumn, row); + int tier = s_expertiseDatatable->getIntValue(tierColumn, row); + int grid = s_expertiseDatatable->getIntValue(gridColumn, row); + int rank = s_expertiseDatatable->getIntValue(rankColumn, row); + + DEBUG_WARNING(s_expertiseStringForTree.find(tree) == s_expertiseStringForTree.end(), + ("ExpertiseManager: %s row %d: expertise tree id %d for %s not defined in %s", + cs_expertiseDatatableName.c_str(), row, tree, name.c_str(), cs_expertiseTreesDatatableName.c_str())); + DEBUG_WARNING(tier > cs_numExpertiseTiers, ("ExpertiseManager: %s row %d: tier of %d for %s is greater than max of %d", + cs_expertiseDatatableName.c_str(), row, tier, name.c_str(), cs_numExpertiseTiers)); + DEBUG_WARNING(grid > cs_numExpertiseColumns, ("ExpertiseManager: %s row %d: grid of %d for %s is greater than max of %d", + cs_expertiseDatatableName.c_str(), row, grid, name.c_str(), cs_numExpertiseColumns)); + + ExpertiseManager::ExpertiseCoord expertiseCoord(tree, tier, grid, rank); + + std::string const & skillName = skill->getSkillName(); + std::pair result = s_expertiseGrid.insert(std::make_pair(expertiseCoord, skillName)); + + UNREF(result); + DEBUG_WARNING(!result.second, ("ExpertiseManager: %s row %d: duplicate expertise: %s", + cs_expertiseDatatableName.c_str(), row, name.c_str())); + } +} + +//---------------------------------------------------------------------- + +void ExpertiseManagerNamespace::loadExpertisePointsTable(DataTable const & datatable) +{ + UNREF(datatable); // required for callback, but unused + + s_expertisePointsForLevel.clear(); + + DataTable const * s_expertisePointsDatatable = DataTableManager::getTable(cs_expertisePointsDatatableName, true); + + DEBUG_FATAL(!s_expertisePointsDatatable, ("ExpertiseManager: failed to load %s", cs_expertisePointsDatatableName.c_str())); + + int const numRows = s_expertisePointsDatatable->getNumRows(); + + int const levelColumn = s_expertisePointsDatatable->findColumnNumber("level"); + int const pointsColumn = s_expertisePointsDatatable->findColumnNumber("expertise_points"); + + for (int row = 0; row < numRows; ++row) + { + int level = s_expertisePointsDatatable->getIntValue(levelColumn, row); + int points = s_expertisePointsDatatable->getIntValue(pointsColumn, row); + s_expertisePointsForLevel[level] = points; + } +} + +//---------------------------------------------------------------------- + +void ExpertiseManagerNamespace::loadExpertiseTreesTable(DataTable const & datatable) +{ + UNREF(datatable); // required for callback, but unused + + s_expertiseStringForTree.clear(); + + DataTable const * s_expertiseTreesDatatable = DataTableManager::getTable(cs_expertiseTreesDatatableName, true); + + DEBUG_FATAL(!s_expertiseTreesDatatable, ("ExpertiseManager: failed to load %s", cs_expertiseTreesDatatableName.c_str())); + + int const numRows = s_expertiseTreesDatatable->getNumRows(); + + int const treeIdColumn = s_expertiseTreesDatatable->findColumnNumber("expertise_tree_id"); + int const stringIdColumn = s_expertiseTreesDatatable->findColumnNumber("expertise_tree_string_id"); + int const uiBackgroundIdColumn = s_expertiseTreesDatatable->findColumnNumber("ui_background_id"); + + for (int row = 0; row < numRows; ++row) + { + int treeId = s_expertiseTreesDatatable->getIntValue(treeIdColumn, row); + std::string const & stringId = s_expertiseTreesDatatable->getStringValue(stringIdColumn, row); + s_expertiseStringForTree[treeId] = stringId; + std::string const & uiStringId = s_expertiseTreesDatatable->getStringValue(uiBackgroundIdColumn, row); + s_uiBackgroundIdForTree[treeId] = uiStringId; + } +} + +//---------------------------------------------------------------------- + +void ExpertiseManagerNamespace::loadSkillTemplateTable(DataTable const & datatable) +{ + UNREF(datatable); // required for callback, but unused + + s_expertiseTreesForProfession.clear(); + + DataTable const * s_skillTemplateDatatable = DataTableManager::getTable(cs_skillTemplateDatatableName, true); + + DEBUG_FATAL(!s_skillTemplateDatatable, ("ExpertiseManager: failed to load %s", cs_skillTemplateDatatableName.c_str())); + + int const numRows = s_skillTemplateDatatable->getNumRows(); + + int const templateNameColumn = s_skillTemplateDatatable->findColumnNumber("templateName"); + int const expertiseTreesColumn = s_skillTemplateDatatable->findColumnNumber("expertiseTrees"); + + for (int row = 0; row < numRows; ++row) + { + std::string const & templateName = s_skillTemplateDatatable->getStringValue(templateNameColumn, row); + std::string const & expertiseTrees = s_skillTemplateDatatable->getStringValue(expertiseTreesColumn, row); + + if (expertiseTrees.empty()) + { + continue; + } + + ExpertiseManager::TreeIdList treeIdList; + std::vector stringList; + splitString(',', expertiseTrees, stringList); + + for (std::vector::const_iterator i = stringList.begin(); i != stringList.end(); ++i) + { + int treeId = atoi((*i).c_str()); + DEBUG_FATAL(treeId < 1, ("ExpertiseManager: %s row %d: invalid tree id %d", cs_skillTemplateDatatableName.c_str(), row, treeId)); + treeIdList.push_back(treeId); + } + + s_expertiseTreesForProfession.insert(std::make_pair(templateName, treeIdList)); + } +} + +//---------------------------------------------------------------------- + +void ExpertiseManagerNamespace::splitString(char delim, std::string const & source, std::vector & result) +{ + std::string::size_type curPos = 0; + while(curPos != std::string::npos) + { + std::string::size_type nextPos = source.find(delim, curPos); + std::string element = source.substr(curPos, nextPos - curPos); + result.push_back(element); + curPos = nextPos; + if(curPos != std::string::npos) + curPos++; + } +} + +//====================================================================== + +void ExpertiseManager::install() +{ + DEBUG_FATAL(s_installed, ("ExpertiseManager already installed")); + s_installed = true; + + loadSkillTemplateTable(cs_unusedDataTable); + DataTableManager::addReloadCallback(cs_skillTemplateDatatableName, &loadSkillTemplateTable); + + loadExpertisePointsTable(cs_unusedDataTable); + DataTableManager::addReloadCallback(cs_expertisePointsDatatableName, &loadExpertisePointsTable); + + loadExpertiseTreesTable(cs_unusedDataTable); + DataTableManager::addReloadCallback(cs_expertiseTreesDatatableName, &loadExpertiseTreesTable); + + loadExpertiseTable(cs_unusedDataTable); + DataTableManager::addReloadCallback(cs_expertiseDatatableName, &loadExpertiseTable); + + ExitChain::add(ExpertiseManager::remove, "ExpertiseManager"); +} + +//---------------------------------------------------------------------- + +void ExpertiseManager::remove() +{ + DEBUG_FATAL(!s_installed, ("ExpertiseManager not installed")); + s_installed = false; +} + +//---------------------------------------------------------------------- + +/** + * @return the iff path of the expertise datatable + */ +std::string const & ExpertiseManager::getExpertiseDatatableName() +{ + return cs_expertiseDatatableName; +} + +//---------------------------------------------------------------------- + +/** + * @return int - the number of expertise columns in the grid + * (i.e. max x coordinate) + */ +int const ExpertiseManager::getNumExpertiseColumns() +{ + return cs_numExpertiseColumns; +} + +//---------------------------------------------------------------------- + +/** + * @return int - the number of expertise tiers in the grid + * (i.e. max y coordinate) + */ +int const ExpertiseManager::getNumExpertiseTiers() +{ + return cs_numExpertiseTiers; +} + +//---------------------------------------------------------------------- + +/** + * @param tree - tree id number + * @param tier - tier number (aka "y coordinate") + * @param grid - grid number (aka "x coordinate") + * @param rank - rank number (aka "z coordinate"). a rank + * of 1 is assumed when a particular rank is + * not needed, since rank 1 is guaranteed to + * exist. + * + * @return - skill object for expertise at grid location. + * returns NULL if none found + */ +SkillObject const * ExpertiseManager::getExpertiseSkillAt(int tree, int tier, int grid, int rank) +{ + SkillObject const * skill = 0; + + ExpertiseCoord expertiseCoord(tree, tier, grid, rank); + + ExpertiseGrid::const_iterator i = s_expertiseGrid.find(expertiseCoord); + if (i != s_expertiseGrid.end()) + { + std::string const & skillName = (*i).second; + skill = SkillManager::getInstance().getSkill(skillName); + } + + return skill; +} + +//---------------------------------------------------------------------- + +/** + * @param level - a character's combat level + * + * @return int - max Expertise Points available at that level + */ +int ExpertiseManager::getExpertisePointsForLevel(int level) +{ + int totalPoints = 0; + + for (LevelToPointsMap::const_iterator i = s_expertisePointsForLevel.begin(); i != s_expertisePointsForLevel.end(); ++i) + { + int const levelForRow = (*i).first; + int const pointsForRow = (*i).second; + if (levelForRow <= level) + { + totalPoints += pointsForRow; + } + } + + return totalPoints; +} + +//---------------------------------------------------------------------- + +/** + * @param empty list to populate with all existing tree ids + */ +void ExpertiseManager::getExpertiseTrees(ExpertiseManager::TreeIdList & treeIdList) +{ + treeIdList.clear(); + for (TreeToStringIdMap::const_iterator i = s_expertiseStringForTree.begin(); i != s_expertiseStringForTree.end(); ++i) + { + treeIdList.push_back((*i).first); + } +} + +//---------------------------------------------------------------------- + +/** + * @param skillTemplate - a profession template name from skill_template table + * + * @return list of tree id ints for profession + */ +ExpertiseManager::TreeIdList const & ExpertiseManager::getExpertiseTreesForProfession(std::string const & skillTemplate) +{ + ProfessionToTreeMap::const_iterator i = s_expertiseTreesForProfession.find(skillTemplate); + if (i != s_expertiseTreesForProfession.end()) + { + return (*i).second; + } + + return cs_emptyTreeIdList; +} + +//---------------------------------------------------------------------- + +/** + * @param treeId - int id of expertise tree + * + * @return string name of expertise tree, suitable for use in + * creating a StringId and localizing + */ +std::string const & ExpertiseManager::getExpertiseTreeNameFromId(int treeId) +{ + TreeToStringIdMap::const_iterator i = s_expertiseStringForTree.find(treeId); + if (i != s_expertiseStringForTree.end()) + { + return (*i).second; + } + + return cs_emptyString; +} + +//---------------------------------------------------------------------- + +std::string const & ExpertiseManager::getExpertiseTreeUiBackgroundIdFromId(int treeId) +{ + TreeToStringIdMap::const_iterator i = s_uiBackgroundIdForTree.find(treeId); + if (i != s_uiBackgroundIdForTree.end()) + { + return (*i).second; + } + + return cs_emptyString; +} + +//---------------------------------------------------------------------- + +/** + * @param skill - pointer to a skill + * + * @return bool - true if skill is an Expertise skill + */ +bool ExpertiseManager::isExpertise(SkillObject const * skill) +{ + bool result = false; + + if (skill) + { + SkillObject const * category = skill->findCategory(); + if (category) + { + std::string const & categoryName = category->getSkillName(); + if (categoryName == cs_expertiseSkillCategoryName) + { + result = true; + } + } + } + + return result; +} + +//---------------------------------------------------------------------- + +/** + * @param expertiseName - name of the expertise + * + * @return int - the id number of the expertise + */ +int ExpertiseManager::getExpertiseTree(std::string const & expertiseName) +{ + int result = 0; + + if (s_expertiseDatatable) + { + int rowNum = s_expertiseDatatable->searchColumnString(0, expertiseName); + if(rowNum == -1) + { + DEBUG_WARNING(true, ("while looking for tree that expertise %s belongs to, could not find expertise", expertiseName.c_str())); + return -1; + } + result = s_expertiseDatatable->getIntValue("TREE", rowNum); + } + + return result; +} + +//---------------------------------------------------------------------- + +/** + * @param expertiseName - name of the expertise + * + * @return int - the grid (aka "x coordinate") of the expertise + */ +int ExpertiseManager::getExpertiseGrid(std::string const & expertiseName) +{ + int result = 0; + + if (s_expertiseDatatable) + { + int rowNum = s_expertiseDatatable->searchColumnString(0, expertiseName); + result = s_expertiseDatatable->getIntValue("GRID", rowNum); + } + + return result; +} + +//---------------------------------------------------------------------- + +/** + * @param expertiseName - name of the expertise + * + * @return int - the tier (aka "y coordinate") of the expertise + */ +int ExpertiseManager::getExpertiseTier(std::string const & expertiseName) +{ + int result = 0; + + if (s_expertiseDatatable) + { + int rowNum = s_expertiseDatatable->searchColumnString(0, expertiseName); + result = s_expertiseDatatable->getIntValue("TIER", rowNum); + } + + return result; +} + +//---------------------------------------------------------------------- + +/** + * @param expertiseName - name of the expertise + * + * @return int - the rank (aka "z coordinate") of the expertise + */ +int ExpertiseManager::getExpertiseRank(std::string const & expertiseName) +{ + int result = 0; + + if (s_expertiseDatatable) + { + int rowNum = s_expertiseDatatable->searchColumnString(0, expertiseName); + result = s_expertiseDatatable->getIntValue("RANK", rowNum); + } + + return result; +} + +//---------------------------------------------------------------------- + +/** + * @param expertiseName - name of the expertise + * + * @return int - the highest existing rank (aka "z coordinate") of the expertise + */ +int ExpertiseManager::getExpertiseRankMax(std::string const & expertiseName) +{ + int result = 0; + + int tree = getExpertiseTree(expertiseName); + int tier = getExpertiseTier(expertiseName); + int grid = getExpertiseGrid(expertiseName); + int rank = getExpertiseRank(expertiseName); + + while (getExpertiseSkillAt(tree, tier, grid, rank) != 0) + { + result = rank; + ++rank; + } + + return result; +} + +//====================================================================== + +ExpertiseManager::ExpertiseCoord::ExpertiseCoord() : +tree(1), +tier(1), +grid(1), +rank(1) +{ +} + +// ---------------------------------------------------------------------- + +ExpertiseManager::ExpertiseCoord::ExpertiseCoord(ExpertiseCoord const & rhs) : +tree(rhs.tree), +tier(rhs.tier), +grid(rhs.grid), +rank(rhs.rank) +{ +} + +// ---------------------------------------------------------------------- + +ExpertiseManager::ExpertiseCoord::ExpertiseCoord(int const treeValue, int const tierValue, int const gridValue) : +tree(treeValue), +tier(tierValue), +grid(gridValue), +rank(1) +{ +} + +// ---------------------------------------------------------------------- + +ExpertiseManager::ExpertiseCoord::ExpertiseCoord(int const treeValue, int const tierValue, int const gridValue, int const rankValue) : +tree(treeValue), +tier(tierValue), +grid(gridValue), +rank(rankValue) +{ +} + +// ---------------------------------------------------------------------- + +ExpertiseManager::ExpertiseCoord const & ExpertiseManager::ExpertiseCoord::operator=(ExpertiseManager::ExpertiseCoord const & rhs) +{ + tree = rhs.tree; + tier = rhs.tier; + grid = rhs.grid; + rank = rhs.rank; + return *this; +} + +// ---------------------------------------------------------------------- + +bool ExpertiseManager::ExpertiseCoord::operator==(ExpertiseManager::ExpertiseCoord const & rhs) const +{ + return (tree == rhs.tree) && (tier == rhs.tier) && (grid == rhs.grid) && (rank == rhs.rank); +} + +// ---------------------------------------------------------------------- + +bool ExpertiseManager::ExpertiseCoord::operator!=(ExpertiseManager::ExpertiseCoord const & rhs) const +{ + return !((tree == rhs.tree) && (tier == rhs.tier) && (grid == rhs.grid) && (rank == rhs.rank)); +} + +// ---------------------------------------------------------------------- + +bool ExpertiseManager::ExpertiseCoord::operator<(ExpertiseManager::ExpertiseCoord const & rhs) const +{ + if (tree < rhs.tree) + { + return true; + } + if (tree == rhs.tree) + { + if (tier < rhs.tier) + { + return true; + } + if (tier == rhs.tier) + { + if (grid < rhs.grid) + { + return true; + } + if (grid == rhs.grid) + { + return (rank < rhs.rank); + } + } + } + return false; +} + +//====================================================================== + diff --git a/engine/shared/library/sharedSkillSystem/src/shared/ExpertiseManager.h b/engine/shared/library/sharedSkillSystem/src/shared/ExpertiseManager.h new file mode 100644 index 00000000..12dc20f3 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/shared/ExpertiseManager.h @@ -0,0 +1,69 @@ +//====================================================================== +// +// ExpertiseManager.h +// copyright (c) 2006 Sony Online Entertainment +// +//====================================================================== + +#ifndef INCLUDED_ExpertiseManager_H +#define INCLUDED_ExpertiseManager_H + +//====================================================================== + +class ExpertiseManager +{ +public: + + static void install(); + static void remove(); + + static std::string const & getExpertiseDatatableName(); + + // Expertise Points + static int getExpertisePointsForLevel(int level); + + // Expertise Trees + typedef std::vector TreeIdList; + static void getExpertiseTrees(TreeIdList & treeIdList); + static TreeIdList const & getExpertiseTreesForProfession(std::string const & skillTemplate); + static std::string const & getExpertiseTreeNameFromId(int treeId); + static std::string const & getExpertiseTreeUiBackgroundIdFromId(int treeId); + + // Individual Expertises + static bool isExpertise(SkillObject const * skill); + static int getExpertiseTree(std::string const & expertiseName); + static int getExpertiseGrid(std::string const & expertiseName); + static int getExpertiseTier(std::string const & expertiseName); + static int getExpertiseRank(std::string const & expertiseName); + static int getExpertiseRankMax(std::string const & expertiseName); + + // Expertise Grid + + static int const getNumExpertiseColumns(); + static int const getNumExpertiseTiers(); + + static SkillObject const * getExpertiseSkillAt(int tree, int tier, int grid, int rank = 1); + + struct ExpertiseCoord + { + int tree; + int tier; + int grid; + int rank; + + ExpertiseCoord(); + ExpertiseCoord(ExpertiseCoord const & rhs); + ExpertiseCoord(int const treeValue, int const tierValue, int const gridValue); + ExpertiseCoord(int const treeValue, int const tierValue, int const gridValue, int const rankValue); + + ExpertiseCoord const & operator=(ExpertiseCoord const & rhs); + bool operator==(ExpertiseCoord const & rhs) const; + bool operator!=(ExpertiseCoord const & rhs) const; + bool operator<(ExpertiseCoord const & rhs) const; + }; + +}; + +//====================================================================== + +#endif diff --git a/engine/shared/library/sharedSkillSystem/src/shared/FirstSharedSkillSystem.h b/engine/shared/library/sharedSkillSystem/src/shared/FirstSharedSkillSystem.h new file mode 100644 index 00000000..ed1e8b80 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/shared/FirstSharedSkillSystem.h @@ -0,0 +1,16 @@ +// FirstSharedSkillSystem.h +// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +#ifndef _INCLUDED_FirstSharedSkillSystem_H +#define _INCLUDED_FirstSharedSkillSystem_H + +//----------------------------------------------------------------------- + +#include "sharedFoundation/FirstSharedFoundation.h" +#include "sharedSkillSystem/SkillManager.h" +#include "sharedSkillSystem/SkillObject.h" + +//----------------------------------------------------------------------- + +#endif // _INCLUDED_FirstSharedSkillSystem_H diff --git a/engine/shared/library/sharedSkillSystem/src/shared/LevelManager.cpp b/engine/shared/library/sharedSkillSystem/src/shared/LevelManager.cpp new file mode 100644 index 00000000..12195492 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/shared/LevelManager.cpp @@ -0,0 +1,421 @@ +//====================================================================== +// +// LevelManager.cpp +// copyright (c) 2005 Sony Online Entertainment +// +//====================================================================== + +#include "sharedSkillSystem/FirstSharedSkillSystem.h" +#include "sharedSkillSystem/LevelManager.h" + +#include "sharedFile/Iff.h" +#include "sharedFoundation/Crc.h" +#include "sharedFoundation/CrcLowerString.h" +#include "sharedFoundation/ExitChain.h" +#include "sharedFoundation/PointerDeleter.h" + +#include "sharedSkillSystem/SkillObject.h" + +#include "sharedUtility/DataTable.h" +#include "sharedUtility/DataTableManager.h" + +#include + +//====================================================================== + +namespace LevelManagerNamespace +{ + bool m_installed = false; + + // level data + struct LevelRecord + { + int16 level; + int xp_required; + int health; + }; + + std::map ms_levelRecords; + typedef std::map::iterator LevelRecordsIterator; + + + // xp multipliers + // map xp_type_nameCrc to multiplier + std::map ms_xpTypeRecords; + typedef std::map::iterator XpRecordsIterator; + + + // skill data + struct SkillRecord + { + uint32 xp_type_name_Crc; + int xp_cost; + }; + + std::map ms_skillRecords; + typedef std::map::iterator SkillRecordsIterator; + + + int ms_numLevels = 0; + int ms_maxLevel = 0; + + + LevelRecord const * getLevelRecord(int xp); + + + inline int getXpValueForType(uint32 expTypeCrc, int xpBaseValue) + { + int value = 0; + + // look up the xp type and only add the xp if the type is found + XpRecordsIterator xpItr = ms_xpTypeRecords.find(expTypeCrc); + + if (xpItr != ms_xpTypeRecords.end()) + { + const int multiplier = (*xpItr).second; + value = xpBaseValue * multiplier; + } + + return value; + } + +}; + +using namespace LevelManagerNamespace; + +//====================================================================== + +void LevelManager::install() +{ + if(m_installed) + return; + m_installed = true; + + DataTable *playerLevelDatatable = DataTableManager::getTable("datatables/player/player_level.iff", true); + + if (playerLevelDatatable) + { + ms_numLevels = playerLevelDatatable->getNumRows(); + + const int levelColumn = playerLevelDatatable->findColumnNumber("level"); + const int xp_requiredColumn = playerLevelDatatable->findColumnNumber("xp_required"); + const int health_grantedColumn = playerLevelDatatable->findColumnNumber("health_granted"); + const int xp_typeColumn = playerLevelDatatable->findColumnNumber("xp_type"); + const int xp_multiplierColumn = playerLevelDatatable->findColumnNumber("xp_multiplier"); + + + // @NOTE: there are basically two independent tables in this data file + // there is level information and xp type information + // these are independent and have diffent lengths, so I'm putting the info + // into two different data structures + int i; + for(i = 0; i < ms_numLevels; ++i) + { + LevelRecord levelRecord; + + levelRecord.level = (int16) playerLevelDatatable->getIntValue(levelColumn, i); + levelRecord.xp_required = playerLevelDatatable->getIntValue(xp_requiredColumn, i); + levelRecord.health = playerLevelDatatable->getIntValue(health_grantedColumn, i); + + ms_levelRecords.insert(std::make_pair(levelRecord.level, levelRecord)); + + std::string xpTypeName = playerLevelDatatable->getStringValue(xp_typeColumn, i); + if (!xpTypeName.empty()) + { + const uint32 xpTypeNameCrc = Crc::calculate(xpTypeName.c_str()); + const int xpMultiplier = playerLevelDatatable->getIntValue(xp_multiplierColumn, i); + ms_xpTypeRecords.insert(std::make_pair(xpTypeNameCrc, xpMultiplier)); + } + if(levelRecord.level > ms_maxLevel) + ms_maxLevel = levelRecord.level; + } + DataTableManager::close("datatables/player/player_level.iff"); + } + + DataTable *skillDatatable = DataTableManager::getTable("datatables/skill/skills.iff", true); + + if (skillDatatable) + { + const int numSkillRows = skillDatatable->getNumRows(); + + const int skill_nameColumn = skillDatatable->findColumnNumber("NAME"); + const int type_nameColumn = skillDatatable->findColumnNumber("XP_TYPE"); + const int xp_costColumn = skillDatatable->findColumnNumber("XP_COST"); + + int i; + for(i = 0; i < numSkillRows; i++) + { + SkillRecord skillRecord; + + std::string skillName = skillDatatable->getStringValue(skill_nameColumn, i); + uint32 skillNameCrc = Crc::calculate(skillName.c_str()); + + std::string xpTypeName = skillDatatable->getStringValue(type_nameColumn, i); + skillRecord.xp_type_name_Crc = Crc::calculate(xpTypeName.c_str()); + + skillRecord.xp_cost = skillDatatable->getIntValue(xp_costColumn, i); + + ms_skillRecords.insert(std::make_pair(skillNameCrc, skillRecord)); + } + DataTableManager::close("datatables/skill/skills.iff"); + } + + ExitChain::add(LevelManager::remove, "LevelManager::remove", 0, false); +} + +//====================================================================== + +void LevelManager::remove() +{ + +} + +void LevelManager::setLevelDataFromXp(LevelData &levelData, int xp) +{ + LevelRecord const * levelRecord = getLevelRecord(xp); + + if (levelRecord) + { + levelData.currentLevel = levelRecord->level; + levelData.currentLevelXp = levelRecord->xp_required; + levelData.currentHealth = levelRecord->health; + } + else + { + // assume level 0 + levelData.currentLevel = 0; + levelData.currentLevelXp = 0; + levelData.currentHealth = 0; + } +} + +//====================================================================== +// This method forces the specified level and sets the creatures +// levelxp and health based on the level (not the skills) +// +void LevelManager::setLevelDataFromLevel(LevelData &levelData, int newLevel) +{ + LevelRecordsIterator it = ms_levelRecords.find(newLevel); + if(it == ms_levelRecords.end()) + { + bool issueWarning = true; + + if (!ms_levelRecords.empty()) + { + // find the max level and set levelData to the max if possible + // assuming that we're asking for a level that is higher than + // possible + std::map::reverse_iterator last = ms_levelRecords.rbegin(); + + int const highestLevel = last->first; + + if (newLevel > highestLevel) + { + LevelRecord const &levelRecord = last->second; + levelData.currentLevel = levelRecord.level; + levelData.currentLevelXp = levelRecord.xp_required; + levelData.currentHealth = levelRecord.health; + issueWarning = false; + } + } + + WARNING(issueWarning, ("setLevelDataFromLevel: Invalid level specified[%d]\n", newLevel)); + } + else + { + LevelRecord const &levelRecord = it->second; + levelData.currentLevel = levelRecord.level; + levelData.currentLevelXp = levelRecord.xp_required; + levelData.currentHealth = levelRecord.health; + } +} + +//====================================================================== +// This method calculates the level data based upon the level XP +// +void LevelManager::calculateLevelData(int currentLevelXp, LevelData &levelData) +{ + levelData.currentLevelXp = currentLevelXp; + + // get the health for this record + LevelRecord const * levelRecord = getLevelRecord(levelData.currentLevelXp); + if (levelRecord) + { + levelData.currentHealth = levelRecord->health; + levelData.currentLevel = levelRecord->level; + } + else + { + WARNING(true, ("calculateLevelData: Couldn't find level for xp value [%d]\n", levelData.currentLevelXp)); + } +} + +//====================================================================== +// Updates the xp and, if necessary, the level and health based on the added skill +// +void LevelManager::addSkillToLevelData(LevelData &levelData, std::string const &skillName) +{ + updateLevelDataWithSkill(levelData, skillName, false); +} + +//====================================================================== +// Updates the xp and, if necessary, the level and health based on the added skill +// +void LevelManager::removeSkillFromLevelData(LevelData &levelData, std::string const &skillName) +{ + updateLevelDataWithSkill(levelData, skillName, true); +} + + +//====================================================================== +// Updates the xp and, if necessary, the level and health based on the added skill +// +void LevelManager::addXpToLevelData(LevelData &levelData, std::string const &experienceType, int xp) +{ + CrcLowerString crcExpType(experienceType.c_str()); + + levelData.currentLevelXp += getXpValueForType(crcExpType.getCrc(), xp); + + LevelRecord const * levelRecord = getLevelRecord(levelData.currentLevelXp); + + if (levelRecord) + { + levelData.currentLevel = levelRecord->level; + levelData.currentHealth = levelRecord->health; + } + else + { + WARNING(true, ("updateLevelDataWithSkill: Couldn't find level for xp value [%d]\n", levelData.currentLevelXp)); + } +} + +//====================================================================== +// Returns the total xp for the specified skill +// +int LevelManager::getSkillXpValue(CrcLowerString const &skillName) +{ + int value = 0; + + SkillRecordsIterator itr = ms_skillRecords.find(skillName.getCrc()); + + if (itr != ms_skillRecords.end()) + { + int xpBaseValue = (*itr).second.xp_cost; + uint32 xpTypeNameCrc = (*itr).second.xp_type_name_Crc; + + value = getXpValueForType(xpTypeNameCrc, xpBaseValue); + } + + return value; +} + +//====================================================================== +// Updates the xp and therefore level and health based on the specified +// skill (and whether it was revoked) +// +void LevelManager::updateLevelDataWithSkill(LevelData &levelData, std::string const &skillName, bool revoked) +{ + CrcLowerString crcSkillName(skillName.c_str()); + const int skillValue = getSkillXpValue(crcSkillName); + + levelData.currentLevelXp += revoked ? -skillValue : skillValue; + + LevelRecord const * levelRecord = getLevelRecord(levelData.currentLevelXp); + + if (levelRecord) + { + levelData.currentLevel = levelRecord->level; + levelData.currentHealth = levelRecord->health; + } + else + { + WARNING(true, ("updateLevelDataWithSkill: Couldn't find level for xp value [%d]\n", levelData.currentLevelXp)); + } +} + +//====================================================================== +// Find the level corresponding to the xp value and +// returns null if not found +LevelRecord const * LevelManagerNamespace::getLevelRecord(int xp) +{ + LevelRecordsIterator itr = ms_levelRecords.begin(); + LevelRecordsIterator nextItr = itr; + while (itr != ms_levelRecords.end()) + { + LevelRecord const & currentRecord = (*itr).second; + ++nextItr; + if (nextItr != ms_levelRecords.end()) + { + const LevelRecord & nextRecord = (*nextItr).second; + { + if (xp < nextRecord.xp_required) + { + return ¤tRecord; + } + } + } + else + { + // no more levels, so return this (the last) one + return ¤tRecord; + } + + ++itr; + } + + WARNING(true, ("getLevelRecord: Couldn't find level for xp value[%d]\n", xp)); + + return NULL; +} + +//====================================================================== + +LevelManager::LevelData::LevelData() +: currentLevel(0) +, currentLevelXp(0) +, currentHealth(0) +{ +} + +//====================================================================== + +LevelManager::LevelData::LevelData(int16 level, int levelXp) +: currentLevel(level) +, currentLevelXp(levelXp) +, currentHealth(0) +{ +} + +//---------------------------------------------------------------------- + +int LevelManager::getRequiredXpToReachLevel(int16 level) +{ + LevelData levelData; + + setLevelDataFromLevel(levelData, level); + + LevelRecord const * const levelRecord = getLevelRecord(levelData.currentLevelXp); + + int const xp = (levelRecord != 0) ? levelRecord->xp_required : 0; + return xp; +} + +//---------------------------------------------------------------------- + +bool LevelManager::canSkillIncreaseLevel(std::string const &skillName) +{ + CrcLowerString crcExpType(skillName.c_str()); + + int const xp = getXpValueForType(crcExpType.getCrc(), 1); + + return (xp >= 1); +} + +//---------------------------------------------------------------------- + +int LevelManager::getMaxLevel() +{ + return ms_maxLevel; +} + +//====================================================================== diff --git a/engine/shared/library/sharedSkillSystem/src/shared/LevelManager.h b/engine/shared/library/sharedSkillSystem/src/shared/LevelManager.h new file mode 100644 index 00000000..dafb2ba7 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/shared/LevelManager.h @@ -0,0 +1,58 @@ +//====================================================================== +// +// LevelManager.h +// copyright (c) 2005 Sony Online Entertainment +// +//====================================================================== + +#ifndef INCLUDED_LevelManager_H +#define INCLUDED_LevelManager_H + +//====================================================================== + +class CrcLowerString; + +//---------------------------------------------------------------------- + +class LevelManager +{ +public: + + struct LevelData + { + LevelData(); + LevelData(int16 level, int levelXp); + int16 currentLevel; + int currentLevelXp; + int currentHealth; + }; + + static void install(); + static void remove(); + + static void setLevelDataFromXp(LevelData &levelData, int xp); + static void setLevelDataFromLevel(LevelData &levelData, int newLevel); + + static void addXpToLevelData(LevelData &levelData, std::string const &experienceType, int xp); + + static void calculateLevelData(int currentLevelXp, LevelData &levelData); + + static void addSkillToLevelData(LevelData &levelData, std::string const &skillName); + static void removeSkillFromLevelData(LevelData &levelData, std::string const &skillName); + + static bool canSkillIncreaseLevel(std::string const & skillName); + static int getRequiredXpToReachLevel(int16 level); + + static int getMaxLevel(); + + static int getSkillXpValue(CrcLowerString const &skillName); + +protected: + + static void updateLevelDataWithSkill(LevelData &levelData, std::string const &skillName, bool revoked); +}; + + +//====================================================================== + +#endif diff --git a/engine/shared/library/sharedSkillSystem/src/shared/SkillManager.cpp b/engine/shared/library/sharedSkillSystem/src/shared/SkillManager.cpp new file mode 100644 index 00000000..81eaf0c3 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/shared/SkillManager.cpp @@ -0,0 +1,212 @@ +// SkillManager.cpp +// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "sharedSkillSystem/FirstSharedSkillSystem.h" +#include "sharedSkillSystem/SkillManager.h" + +#include "sharedFoundation/ExitChain.h" +#include "sharedFoundation/PointerDeleter.h" +#include "sharedSkillSystem/SkillObject.h" +#include "sharedUtility/DataTable.h" +#include "sharedUtility/DataTableManager.h" +#include "sharedDebug/InstallTimer.h" + +#include +#include +#include + +SkillManager *SkillManager::ms_instance = NULL; +const std::string &SkillManager::cms_skillsDatatableName = "datatables/skill/skills.iff"; + +//----------------------------------------------------------------- + +namespace +{ + bool ensureProperSkillName (const std::string & str) + { + static std::string valid; + static bool init = false; + + if (!init) + { + valid.reserve (38); + int c = 0; + + for (c = 'a'; c <= 'z'; ++c) + valid.append (1, c); + + for (c = '0'; c <= '9'; ++c) + valid.append (1, c); + + valid.append (1, '_'); + valid.append (1, '-'); + init = true; + } + + return str.find_first_not_of (valid) == str.npos; + } +} + +//--------------------------------------------------------------------- + +SkillManager::SkillManager() : +m_skillMap(new SkillMap), +m_skillTable(DataTableManager::getTable(cms_skillsDatatableName, true)/*new DataTable*/), +m_xpLimitMap(new XpLimitMap), +m_xpLimitTable(DataTableManager::getTable("datatables/skill/xp_limits.iff", true)) +{ +} + +//--------------------------------------------------------------------- + +SkillManager::~SkillManager() +{ + std::for_each (m_skillMap->begin(), m_skillMap->end(), PointerDeleterPairSecond ()); + delete m_skillMap; + delete m_xpLimitMap; + m_skillMap = 0; + m_skillTable = 0; + m_xpLimitMap = 0; + m_xpLimitTable = 0; +} + +//---------------------------------------------------------------------- + +void SkillManager::install() +{ + InstallTimer const installTimer("SkillManager::install"); + + DEBUG_FATAL (ms_instance, ("SkillManager already installed")); + ms_instance = new SkillManager(); + ms_instance->getRoot (); + ms_instance->initXpLimits(); + ExitChain::add (SkillManager::remove, "SkillManager"); +} + +//---------------------------------------------------------------------- + +void SkillManager::remove() +{ + DEBUG_FATAL (!ms_instance, ("SkillManager not installed")); + delete ms_instance; + ms_instance = NULL; +} + +//---------------------------------------------------------------------- + +SkillManager & SkillManager::getInstance () +{ + //DEBUG_FATAL (!ms_instance, ("SkillManager not installed")); + if (!ms_instance) + { + install(); + } + return *ms_instance; +} + +//----------------------------------------------------------------- + +const SkillObject * SkillManager::getRoot () +{ + static const std::string rootname ("skill_system_root"); + return getSkill (rootname); +} + +//--------------------------------------------------------------------- + +const SkillObject * SkillManager::getSkill(const std::string & skillName) +{ + if (skillName.empty () || !ensureProperSkillName (skillName)) + return 0; + + const SkillMap::const_iterator f = m_skillMap->find(skillName); + if(f == m_skillMap->end()) + return loadSkill(skillName); + else + return (*f).second; +} + +//----------------------------------------------------------------------- + +const SkillObject * SkillManager::loadSkill(const std::string & skillName) +{ + if (skillName.empty () || !ensureProperSkillName (skillName)) + return 0; + + SkillObject * result = 0; + + const SkillMap::const_iterator f = m_skillMap->find(skillName); + if(f != m_skillMap->end()) + { + result = f->second; + } + else + { + SkillObject * const newSkill = new SkillObject; + + m_skillMap->insert(std::make_pair (skillName, newSkill)); + result = newSkill; + + // Guard against skills table having been closed somewhere via DataTableManager. + m_skillTable = DataTableManager::getTable(cms_skillsDatatableName, true); + + if (!newSkill->load(*m_skillTable, skillName)) + { + WARNING (true, ("SkillManager failed to load skill [%s]", skillName.c_str ())); + delete newSkill; + result = 0; + m_skillMap->erase (skillName); +// (*skillMap) [skillName] = 0; + } + } + + return result; +} + +//--------------------------------------------------------------------- + +uint32 SkillManager::getDefaultXpLimit(const std::string & experienceType) +{ + if (m_xpLimitMap != NULL) + { + XpLimitMap::const_iterator result = m_xpLimitMap->find(experienceType); + if (result != m_xpLimitMap->end()) + return (*result).second; + } + return static_cast(-1); +} + +//--------------------------------------------------------------------- + +void SkillManager::initXpLimits() +{ + if (m_xpLimitTable == NULL) + { + WARNING(true, ("SkillManager::initXpLimits, m_xpLimitTable not initialized")); + return; + } + + if (m_xpLimitMap == NULL) + { + WARNING(true, ("SkillManager::initXpLimits, m_xpLimitMap not initialized")); + return; + } + + int count = m_xpLimitTable->getNumRows(); + for (int i = 0; i < count; ++i) + { + const std::string & xpType = m_xpLimitTable->getStringValue(0, i); + if (!xpType.empty()) + { + if (xpType == "end") + break; + m_xpLimitMap->insert(std::make_pair(xpType, m_xpLimitTable->getIntValue(1, i))); + } + } +} + +//--------------------------------------------------------------------- + diff --git a/engine/shared/library/sharedSkillSystem/src/shared/SkillManager.h b/engine/shared/library/sharedSkillSystem/src/shared/SkillManager.h new file mode 100644 index 00000000..3a38ec42 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/shared/SkillManager.h @@ -0,0 +1,60 @@ +// SkillManager.h +// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +#ifndef _SkillManager_H +#define _SkillManager_H + +//--------------------------------------------------------------------- +#pragma warning (disable : 4786 ) + +class SkillObject; +class DataTable; + +//--------------------------------------------------------------------- + +class SkillManager +{ +public: + typedef stdhash_map::fwd SkillMap; + typedef stdhash_map::fwd XpLimitMap; + + virtual ~SkillManager (); + + const SkillObject * getSkill (const std::string & skillName); + const SkillMap & getSkillMap () const; + const SkillObject * getRoot (); + uint32 getDefaultXpLimit(const std::string & experienceType); + + static SkillManager & getInstance (); + + static void install (); + static void remove (); + +protected: + SkillManager (); +private: + SkillManager (const SkillManager & source); + SkillManager & operator = (const SkillManager & rhs); + const SkillObject * loadSkill (const std::string & skillName); + void initXpLimits (); + +private: + SkillMap * m_skillMap; + DataTable * m_skillTable; + XpLimitMap * m_xpLimitMap; + DataTable * m_xpLimitTable; + static SkillManager * ms_instance; + static const std::string & cms_skillsDatatableName; +}; + +//----------------------------------------------------------------------- + +inline const SkillManager::SkillMap & SkillManager::getSkillMap() const +{ + return *NON_NULL(m_skillMap); +} + +//--------------------------------------------------------------------- + +#endif // _SkillManager_H diff --git a/engine/shared/library/sharedSkillSystem/src/shared/SkillObject.cpp b/engine/shared/library/sharedSkillSystem/src/shared/SkillObject.cpp new file mode 100644 index 00000000..016703cd --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/shared/SkillObject.cpp @@ -0,0 +1,561 @@ +// SkillObject.cpp +// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "sharedSkillSystem/FirstSharedSkillSystem.h" +#include "sharedSkillSystem/SkillObject.h" + +#include "sharedSkillSystem/SkillManager.h" +#include "sharedUtility/DataTable.h" + +#include "UnicodeUtils.h" + +#include + +const std::string SkillObject::ms_skillLabel = "NAME"; +const std::string SkillObject::ms_prerequisiteSkillsLabel = "SKILLS_REQUIRED"; +const std::string SkillObject::ms_prerequisiteExperienceTypeLabel = "XP_TYPE"; +const std::string SkillObject::ms_prerequisiteExperienceAmountLabel = "XP_COST"; +const std::string SkillObject::ms_prerequisiteExperienceLimitLabel = "XP_CAP"; +const std::string SkillObject::ms_prerequisiteSpeciesLabel = "SPECIES_REQUIRED"; +const std::string SkillObject::ms_commandsLabel = "COMMANDS"; +const std::string SkillObject::ms_statisticsModifiersLabel = "SKILL_MODS"; +const std::string SkillObject::ms_parentLabel = "PARENT"; +const std::string SkillObject::ms_schematicsGrantedLabel = "SCHEMATICS_GRANTED"; +const std::string SkillObject::ms_isTitleLabel = "IS_TITLE"; +const std::string SkillObject::ms_isProfessionLabel = "IS_PROFESSION"; +const std::string SkillObject::ms_isSearchableLabel = "SEARCHABLE"; + +//----------------------------------------------------------------- + +namespace +{ + int s_recursionCountDepends = 0; + const int s_recursionCountDependsMax = 7; + + //---------------------------------------------------------------------- + + typedef stdvector::fwd StringVector; + inline void tokenizeList (const std::string & str, StringVector & sv, int row, const std::string & columnName) + { + UNREF (row); + UNREF (columnName); + + size_t endpos = 0; + std::string token; + static const char * const whitespace = ","; + + DEBUG_WARNING (str.find (" \n\r\t") != std::string::npos, ("SkillObject Cell string [%s] row %d column [%s] contains spaces or other invalid characters", row, columnName.c_str ())); + + while (Unicode::getFirstToken (str, endpos, endpos, token, whitespace)) + { + sv.push_back (token); + if (endpos == std::string::npos) + break; + + ++endpos; + } + } +} + +//--------------------------------------------------------------------- + +SkillObject::SkillData::SkillData() : +prerequisiteSkills (), +prerequisiteExperience (), +prerequisiteSpecies (), +prerequisiteFactionStanding (), +skillName ("UNINITIALIZED SKILL"), +nextSkillBoxes (), +prevSkill (0), +commandsProvided (), +schematicsGranted (), +statisticModifiers (), +isProfession (false), +isTitle (false), +isSearchable (false) +{ +} + +//--------------------------------------------------------------------- + +SkillObject::SkillData::SkillData(const SkillData & source) : +prerequisiteSkills (source.prerequisiteSkills), +prerequisiteExperience (source.prerequisiteExperience), +prerequisiteSpecies (source.prerequisiteSpecies), +prerequisiteFactionStanding (source.prerequisiteFactionStanding), +skillName (source.skillName), +nextSkillBoxes (source.nextSkillBoxes), +prevSkill (0), +commandsProvided (source.commandsProvided), +schematicsGranted (source.schematicsGranted), +statisticModifiers (source.statisticModifiers), +isProfession (source.isProfession), +isTitle (source.isTitle), +isSearchable (source.isSearchable) +{ +} + +//--------------------------------------------------------------------- + +SkillObject::SkillData::~SkillData() +{ +} + +//--------------------------------------------------------------------- + +SkillObject::SkillData & SkillObject::SkillData::operator = (const SkillData & rhs) +{ + if(&rhs != this) + { + prerequisiteSkills = rhs.prerequisiteSkills; + prerequisiteExperience = rhs.prerequisiteExperience; + prerequisiteSpecies = rhs.prerequisiteSpecies; + prerequisiteFactionStanding = rhs.prerequisiteFactionStanding; + skillName = rhs.skillName; + nextSkillBoxes = rhs.nextSkillBoxes; + commandsProvided = rhs.commandsProvided; + schematicsGranted = rhs.schematicsGranted; + statisticModifiers = rhs.statisticModifiers; + isProfession = rhs.isProfession; + isTitle = rhs.isTitle; + isSearchable = rhs.isSearchable; + } + return *this; +} + +//--------------------------------------------------------------------- + +SkillObject::SkillObject() : +skillData() +{ +} + +//--------------------------------------------------------------------- + +SkillObject::~SkillObject() +{ +} + +//--------------------------------------------------------------------- + +const SkillObject::SkillVector & SkillObject::getNextSkillBoxes() const +{ + return skillData.nextSkillBoxes; +} + +//----------------------------------------------------------------------- + +const SkillObject * SkillObject::getPrevSkill() const +{ + return skillData.prevSkill; +} + +//--------------------------------------------------------------------- + +const SkillObject::SkillData & SkillObject::getSkillData() const +{ + return skillData; +} + +//--------------------------------------------------------------------- + +const SkillObject::ExperienceVector & SkillObject::getPrerequisiteExperienceVector () const +{ + return skillData.prerequisiteExperience; +} + +//----------------------------------------------------------------- + +const SkillObject::ExperiencePair * SkillObject::getPrerequisiteExperience () const +{ + if (skillData.prerequisiteExperience.empty ()) + return 0; + else + return &skillData.prerequisiteExperience.front (); +} + +//--------------------------------------------------------------------- + +const SkillObject::SpeciesFlagVector & SkillObject::getPrerequisiteSpecies() const +{ + return skillData.prerequisiteSpecies; +} + +//--------------------------------------------------------------------- + +const SkillObject::GenericModVector & SkillObject::getPrerequisiteFactionStanding() const +{ + return skillData.prerequisiteFactionStanding; +} + +//--------------------------------------------------------------------- + +const SkillObject::SkillVector & SkillObject::getPrerequisiteSkills() const +{ + return skillData.prerequisiteSkills; +} + +//--------------------------------------------------------------------- + +const std::string & SkillObject::getSkillName() const +{ + return skillData.skillName; +} + +//--------------------------------------------------------------------- + +const SkillObject::StringVector & SkillObject::getCommandsProvided() const +{ + return skillData.commandsProvided; +} + +//--------------------------------------------------------------------- + +const SkillObject::StringVector & SkillObject::getSchematicsGranted() const +{ + return skillData.schematicsGranted; +} + +//--------------------------------------------------------------------- + +const std::vector > & SkillObject::getStatisticModifiers() const +{ + return skillData.statisticModifiers; +} + +//----------------------------------------------------------------------- + +SkillObject::SkillData & SkillObject::getSkillData() +{ + return skillData; +} + +//----------------------------------------------------------------------- + +const bool SkillObject::hasCommand(const std::string & commandName) const +{ + return std::binary_search (skillData.commandsProvided.begin (), skillData.commandsProvided.end (), commandName); +} + +//----------------------------------------------------------------------- +/** get primary category for this skill */ + +const SkillObject * SkillObject::findCategory() const +{ + const SkillObject * p = this; + + for (;;) + { + if (p) + { + //-- the categories are at the 2nd level of the heirarchy + + if (p->skillData.prevSkill && p->skillData.prevSkill->skillData.prevSkill == 0) + { + return p; + } + + p = p->skillData.prevSkill; + } + else + { + break; + } + } + + return 0; +} + +//----------------------------------------------------------------------- + +const bool SkillObject::isProfession() const +{ + return skillData.isProfession; +} + +//----------------------------------------------------------------------- + +const bool SkillObject::isTitle() const +{ + return skillData.isTitle; +} + +//----------------------------------------------------------------------- + +const bool SkillObject::isSearchable() const +{ + return skillData.isSearchable; +} + +//--------------------------------------------------------------------- + +void SkillObject::loadPrerequisiteSkills(DataTable &dataTable, int skillRow) +{ + const std::string & cellString = dataTable.getStringValue(SkillObject::ms_prerequisiteSkillsLabel, skillRow); + StringVector sv; + sv.clear (); + tokenizeList (cellString, sv, skillRow, SkillObject::ms_prerequisiteSkillsLabel); + skillData.prerequisiteSkills.reserve (sv.size ()); + + SkillManager & manager = SkillManager::getInstance (); + + for (StringVector::const_iterator it = sv.begin (); it != sv.end (); ++it) + { + const std::string & skillName = *it; + const SkillObject * const skill = manager.getSkill (skillName); + if (skill) + skillData.prerequisiteSkills.push_back(skill); + else + WARNING (true, ("prerequisiteSkills skill [%s] does not exist", skillName.c_str ())); + } + + std::sort (skillData.prerequisiteSkills.begin (), skillData.prerequisiteSkills.end ()); +} + +//---------------------------------------------------------------------- + +void SkillObject::loadPrerequisiteExperience(DataTable &dataTable, int skillRow) +{ + const int xpAmount = dataTable.getIntValue(SkillObject::ms_prerequisiteExperienceAmountLabel, skillRow); + const int xpLimit = dataTable.getIntValue(SkillObject::ms_prerequisiteExperienceLimitLabel, skillRow); + if (xpAmount > 0 || xpLimit > 0) + { + const std::string & experienceType = dataTable.getStringValue(SkillObject::ms_prerequisiteExperienceTypeLabel, skillRow); + if (!experienceType.empty ()) + skillData.prerequisiteExperience.push_back(std::make_pair(experienceType, std::make_pair(xpAmount, xpLimit))); + else + WARNING (true, ("Nonzero experience specified but empty experience name on row %d", skillRow)); + } +} + +//--------------------------------------------------------------------- + +void SkillObject::loadPrerequisiteSpecies(DataTable &dataTable, int skillRow) +{ + const std::string & cellString = dataTable.getStringValue(SkillObject::ms_prerequisiteSpeciesLabel, skillRow); + static StringVector sv; + sv.clear (); + tokenizeList (cellString, sv, skillRow, SkillObject::ms_prerequisiteSpeciesLabel); + skillData.prerequisiteSpecies.reserve (sv.size ()); + + for (StringVector::const_iterator it = sv.begin (); it != sv.end (); ++it) + skillData.prerequisiteSpecies.push_back (std::make_pair (*it, true)); +} + +//--------------------------------------------------------------------- + +void SkillObject::loadCommands(DataTable &dataTable, int skillRow) +{ + const std::string & cellString = dataTable.getStringValue(SkillObject::ms_commandsLabel, skillRow); + static StringVector sv; + sv.clear (); + tokenizeList (cellString, sv, skillRow, SkillObject::ms_commandsLabel); + skillData.commandsProvided.reserve (sv.size ()); + + for (StringVector::const_iterator it = sv.begin (); it != sv.end (); ++it) + skillData.commandsProvided.push_back (*it); + + std::sort (skillData.commandsProvided.begin (), skillData.commandsProvided.end ()); +} + +//--------------------------------------------------------------------- + +void SkillObject::loadSchematicsGranted(DataTable &dataTable, int skillRow) +{ + const std::string & cellString = dataTable.getStringValue(SkillObject::ms_schematicsGrantedLabel, skillRow); + static StringVector sv; + sv.clear (); + tokenizeList (cellString, sv, skillRow, SkillObject::ms_schematicsGrantedLabel); + skillData.schematicsGranted.reserve (sv.size ()); + + for (StringVector::const_iterator it = sv.begin (); it != sv.end (); ++it) + skillData.schematicsGranted.push_back (*it); + + std::sort (skillData.schematicsGranted.begin (), skillData.schematicsGranted.end ()); +} + +//--------------------------------------------------------------------- + +void SkillObject::loadStatisticsModifiers(DataTable &dataTable, int skillRow) +{ + const std::string & cellString = dataTable.getStringValue(SkillObject::ms_statisticsModifiersLabel, skillRow); + static StringVector sv; + sv.clear (); + tokenizeList (cellString, sv, skillRow, SkillObject::ms_statisticsModifiersLabel); + skillData.statisticModifiers.reserve (sv.size ()); + + for (StringVector::const_iterator it = sv.begin (); it != sv.end (); ++it) + { + const std::string & statEntry = *it; + const size_t splitPos = statEntry.find ('='); + + if (splitPos == std::string::npos) + WARNING (true, ("Statistic modifier without an = [%s], skill=%s", statEntry.c_str(), skillData.skillName.c_str())); + else + { + const char * const statValueString = statEntry.c_str () + splitPos + 1; + const std::string & statValueName = statEntry.substr (0, splitPos); + const int32 modifier = atoi (statValueString); + skillData.statisticModifiers.push_back(std::make_pair(statValueName, modifier)); + } + } +} + +//--------------------------------------------------------------------- + +void SkillObject::connectLinks(DataTable &dataTable, const std::string & parentName) +{ + if (!parentName.empty ()) + { + const SkillObject * const parent = SkillManager::getInstance().getSkill (parentName); + if (parent) + { + skillData.prevSkill = parent; + } + } + + std::string nextSkillSearchName = skillData.skillName; + if (nextSkillSearchName == "skill_system_root") + { + nextSkillSearchName.clear (); + } + + int rows = dataTable.getNumRows(); + for (int i = 0; i < rows; i++) + { + const std::string & tmpParent = dataTable.getStringValue(SkillObject::ms_parentLabel, i); + + if (tmpParent == nextSkillSearchName) + { + const std::string & nextSkillName = dataTable.getStringValue(SkillObject::ms_skillLabel, i); + const SkillObject * const nextSkill = SkillManager::getInstance().getSkill(nextSkillName); + if (nextSkill) + { + skillData.nextSkillBoxes.push_back(nextSkill); + } + else + { + WARNING (true, ("Could not find skill %s in DataTable", nextSkillName.c_str())); + } + } + } + +} + +//--------------------------------------------------------------------- + +bool SkillObject::load(DataTable & dataTable, const std::string & skillName) +{ + if (skillName == "skill_system_root") + { + skillData = SkillData(); + skillData.skillName = skillName; + connectLinks (dataTable, ""); + return true; + } + + const int skillColumn = dataTable.findColumnNumber (SkillObject::ms_skillLabel); + if (skillColumn == -1) + { + WARNING (true, ("SkillObject::load Could not find column %s in DataTable", SkillObject::ms_skillLabel.c_str())); + return false; + } + + const int skillRow = dataTable.searchColumnString (skillColumn, skillName); + if (skillRow == -1) + { + skillData = SkillData(); + WARNING (true, ("SkillObject::load Could not find skill %s in DataTable", skillName.c_str())); + return false; + } + + skillData = SkillData(); + + skillData.skillName = skillName; + + loadPrerequisiteSkills (dataTable, skillRow); + loadPrerequisiteExperience (dataTable, skillRow); + loadPrerequisiteSpecies (dataTable, skillRow); + + std::string parent = dataTable.getStringValue(SkillObject::ms_parentLabel, skillRow); + if (parent.empty ()) + { + parent = "skill_system_root"; + } + connectLinks (dataTable, parent); + + loadCommands (dataTable, skillRow); + loadSchematicsGranted (dataTable, skillRow); + loadStatisticsModifiers (dataTable, skillRow); + + skillData.isTitle = dataTable.getIntValue(SkillObject::ms_isTitleLabel, skillRow) != 0; + skillData.isProfession = dataTable.getIntValue(SkillObject::ms_isProfessionLabel, skillRow) != 0; + skillData.isSearchable = dataTable.getIntValue(SkillObject::ms_isSearchableLabel, skillRow) != 0; + + return true; +} + +//---------------------------------------------------------------------- + +const SkillObject * SkillObject::findProfessionForSkill () const +{ + const SkillObject * s = this; + + while (s) + { + if (s->isProfession ()) + return s; + + s = s->getPrevSkill (); + } + + return 0; +} + +//----------------------------------------------------------------- + +bool SkillObject::dependsUponSkill (const SkillObject & skill, bool immediatePrereqsOnly) const +{ + bool result = false; + + ++s_recursionCountDepends; + + if (s_recursionCountDepends >= s_recursionCountDependsMax) + { + WARNING (true, ("recursion max hit in skill dependency check")); + } + else if (this == &skill) + { + result = true; + } + else + { + const SkillVector & preReqs = getPrerequisiteSkills(); + for (SkillVector::const_iterator it = preReqs.begin (); it != preReqs.end (); ++it) + { + const SkillObject * const prereq = NON_NULL (*it); + + if(immediatePrereqsOnly) + { + if(prereq == &skill) + result = true; + } + else + { + if (prereq->dependsUponSkill (skill)) + { + result = true; + } + } + } + } + + --s_recursionCountDepends; + + return result; +} + +//--------------------------------------------------------------------- diff --git a/engine/shared/library/sharedSkillSystem/src/shared/SkillObject.h b/engine/shared/library/sharedSkillSystem/src/shared/SkillObject.h new file mode 100644 index 00000000..abade511 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/shared/SkillObject.h @@ -0,0 +1,115 @@ +// SkillObject.h +// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +#ifndef _SkillObject_H +#define _SkillObject_H + +#include +#include + +class DataTable; + +//--------------------------------------------------------------------- + +class SkillObject +{ +public: + SkillObject(); + virtual ~SkillObject(); + bool load(DataTable & file, const std::string & skillName); + + typedef stdvector::fwd SkillVector; + typedef std::pair XpPair; // xp needed, xp limit + typedef std::pair ExperiencePair; + typedef stdvector::fwd ExperienceVector; + typedef std::pair GenericMod; + typedef stdvector::fwd GenericModVector; + typedef stdvector::fwd StringVector; + typedef std::pair SpeciesFlag; + typedef stdvector::fwd SpeciesFlagVector; + + const SkillObject * findCategory () const; + + const StringVector & getCommandsProvided () const; + const StringVector & getSchematicsGranted () const; + const SkillVector & getNextSkillBoxes () const; + const ExperienceVector & getPrerequisiteExperienceVector () const; + const ExperiencePair * getPrerequisiteExperience () const; + const GenericModVector & getPrerequisiteFactionStanding () const; + const SkillVector & getPrerequisiteSkills () const; + const SpeciesFlagVector & getPrerequisiteSpecies () const; + const SkillObject * getPrevSkill () const; + const std::string & getSkillName () const; + const GenericModVector & getStatisticModifiers () const; + const bool hasCommand (const std::string & commandName) const; + const bool isProfession () const; + const bool isTitle () const; + const bool isSearchable () const; + + const SkillObject * findProfessionForSkill () const; + + bool dependsUponSkill (const SkillObject & skill, bool immediatePrereqsOnly = false) const; + + + struct SkillData + { + SkillData(); + SkillData(const SkillData & source); + ~SkillData(); + SkillData & operator = (const SkillData & rhs); + + // prerequisites + SkillVector prerequisiteSkills; + ExperienceVector prerequisiteExperience; + SpeciesFlagVector prerequisiteSpecies; + GenericModVector prerequisiteFactionStanding; + + // descriptors + std::string skillName; + SkillVector nextSkillBoxes; + const SkillObject * prevSkill; + + // effects + StringVector commandsProvided; + StringVector schematicsGranted; + std::vector > statisticModifiers; + bool isProfession; + bool isTitle; + bool isSearchable; + }; + + const SkillData & getSkillData() const; + SkillData & getSkillData(); + +private: + SkillObject(const SkillObject & source); + SkillObject & operator = (const SkillObject & rhs); + SkillData skillData; + + static const std::string ms_skillLabel; + static const std::string ms_prerequisiteSkillsLabel; + static const std::string ms_prerequisiteExperienceTypeLabel; + static const std::string ms_prerequisiteExperienceAmountLabel; + static const std::string ms_prerequisiteExperienceLimitLabel; + static const std::string ms_prerequisiteSpeciesLabel; + static const std::string ms_commandsLabel; + static const std::string ms_statisticsModifiersLabel; + static const std::string ms_parentLabel; + static const std::string ms_schematicsGrantedLabel; + static const std::string ms_isTitleLabel; + static const std::string ms_isProfessionLabel; + static const std::string ms_isSearchableLabel; + + void loadPrerequisiteSkills (DataTable & file, int skillRow); + void loadPrerequisiteExperience (DataTable & file, int skillRow); + void loadPrerequisiteSpecies (DataTable & file, int skillRow); + void loadCommands (DataTable & file, int skillRow); + void loadSchematicsGranted (DataTable & file, int skillRow); + void loadStatisticsModifiers (DataTable & file, int skillRow); + void connectLinks (DataTable & file, const std::string & parentName); +}; + +//--------------------------------------------------------------------- + +#endif // _SkillObject_H diff --git a/engine/shared/library/sharedSkillSystem/src/shared/SkillObjectArchive.cpp b/engine/shared/library/sharedSkillSystem/src/shared/SkillObjectArchive.cpp new file mode 100644 index 00000000..2af80372 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/shared/SkillObjectArchive.cpp @@ -0,0 +1,45 @@ +//====================================================================== +// +// SkillObjectArchive.cpp +// copyright (c) 2002 Sony Online Entertainment +// +//====================================================================== + +#include "sharedSkillSystem/FirstSharedSkillSystem.h" +#include "sharedSkillSystem/SkillObjectArchive.h" + +#include "sharedSkillSystem/SkillObject.h" +#include "sharedSkillSystem/SkillManager.h" +#include "Archive/Archive.h" + +//====================================================================== + +namespace Archive +{ + //---------------------------------------------------------------------- + + void get(ReadIterator & source, const SkillObject *& target) + { + std::string name; + Archive::get (source, name); + + if (name.empty ()) + target = 0; + else + { + target = SkillManager::getInstance ().getSkill (name); + } + } + + //----------------------------------------------------------------------- + + void put(ByteStream & target, const SkillObject * const & source) + { + if (source) + Archive::put (target, source->getSkillName ()); + else + Archive::put (target, std::string ()); + } +} + +//====================================================================== diff --git a/engine/shared/library/sharedSkillSystem/src/shared/SkillObjectArchive.h b/engine/shared/library/sharedSkillSystem/src/shared/SkillObjectArchive.h new file mode 100644 index 00000000..85b7c4ca --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/shared/SkillObjectArchive.h @@ -0,0 +1,29 @@ +//====================================================================== +// +// SkillObjectArchive.h +// copyright (c) 2002 Sony Online Entertainment +// +//====================================================================== + +#ifndef INCLUDED_SkillObjectArchive_H +#define INCLUDED_SkillObjectArchive_H + +//====================================================================== + +#if WIN32 +#pragma warning (disable:4800) // forcing value to bool +#endif + +#include "Archive/ByteStream.h" + +class SkillObject; + +namespace Archive +{ + void get(ReadIterator & source, const SkillObject *& target); + void put(ByteStream & target, const SkillObject * const& source); +} + +//====================================================================== + +#endif diff --git a/engine/shared/library/sharedSkillSystem/src/win32/FirstSharedSkillSystem.cpp b/engine/shared/library/sharedSkillSystem/src/win32/FirstSharedSkillSystem.cpp new file mode 100644 index 00000000..0b610d18 --- /dev/null +++ b/engine/shared/library/sharedSkillSystem/src/win32/FirstSharedSkillSystem.cpp @@ -0,0 +1,8 @@ +// FirstSharedSkillSystem.cpp +// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "sharedSkillSystem/FirstSharedSkillSystem.h" +