Cleaned up remaining TODO for Achievements (#4446)
* Converts labels to camelCase. * Converts labels to plural where needed. * Converts Target MobID to use the Sprite name. * Converts Rewards ItemID to use the Aegis name. * Dependents now checks for duplicate IDs. * Dependents now properly supports import methods. * Added YAMLUpgrade tool to convert previous YAML databases to new format. * Removes the unique index value for Dependent Achievement ID. * Adds support for the AG_CHATTING achievement types triggered by script (achievementupdate script command). * AG_CHATTING map type achievements are still disabled as behavior is unknown. * AG_HEAR and AG_SEE are now dropped and those achievements have been converted to AG_CHATTING. * Converts the group constants to how Aegis names them. Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
This commit is contained in:
parent
0af4a9b40c
commit
5aa9f75343
2
.gitignore
vendored
2
.gitignore
vendored
@ -43,6 +43,7 @@ Thumbs.db
|
||||
/mapcache
|
||||
/nbproject
|
||||
/yaml2sql
|
||||
/yamlupgrade
|
||||
|
||||
# /3rdparty/libconfig/
|
||||
/3rdparty/libconfig/Makefile
|
||||
@ -122,6 +123,7 @@ Thumbs.db
|
||||
/runserver.bat
|
||||
/serv.bat
|
||||
/yaml2sql.bat
|
||||
/yamlupgrade.bat
|
||||
|
||||
# dlls
|
||||
/libmysql.dll
|
||||
|
@ -16,70 +16,34 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
# Renewal Achievement Database
|
||||
# Achievement Database
|
||||
###########################################################################
|
||||
#
|
||||
# Achievement Settings
|
||||
#
|
||||
###########################################################################
|
||||
# ID - Unique achievement ID.
|
||||
###########################################################################
|
||||
# Group - Achievement group type. Each achievement type calls a specific
|
||||
# objective check.
|
||||
# Valid groups:
|
||||
# AG_ADD_FRIEND
|
||||
# AG_ADVENTURE
|
||||
# AG_BABY
|
||||
# AG_BATTLE
|
||||
# AG_CHATTING
|
||||
# AG_CHATTING_COUNT
|
||||
# AG_CHATTING_CREATE
|
||||
# AG_CHATTING_DYING
|
||||
# AG_EAT
|
||||
# AG_GET_ITEM
|
||||
# AG_GET_ZENY
|
||||
# AG_GOAL_ACHIEVE
|
||||
# AG_GOAL_LEVEL
|
||||
# AG_GOAL_STATUS
|
||||
# AG_HEAR
|
||||
# AG_JOB_CHANGE
|
||||
# AG_MARRY
|
||||
# AG_PARTY
|
||||
# AG_ENCHANT_FAIL
|
||||
# AG_ENCHANT_SUCCESS
|
||||
# AG_SEE
|
||||
# AG_SPEND_ZENY
|
||||
# AG_TAMING
|
||||
###########################################################################
|
||||
# Name - Achievement name. Used when sending rewards through RODEX.
|
||||
###########################################################################
|
||||
# Target - A list of monster ID and count values that the achievement
|
||||
# requires. The target count can also be used for achievements that keep
|
||||
# a counter while not being related to monster kills.
|
||||
# Capped at MAX_ACHIEVEMENT_OBJECTIVES.
|
||||
###########################################################################
|
||||
# Condition - A conditional statement that must be met for the achievement
|
||||
# to be considered complete.
|
||||
###########################################################################
|
||||
# Map - A map name that is used for the AG_CHATTING type which increments
|
||||
# the counter based on the player's map.
|
||||
###########################################################################
|
||||
# Dependent: - A list of achievement IDs that need to be completed before
|
||||
# this achievement is considered complete.
|
||||
###########################################################################
|
||||
# Reward - A list of rewards that are given on completion. All fields are
|
||||
# optional.
|
||||
# ItemID: Item ID
|
||||
# Amount: Amount of Item ID (default 1)
|
||||
# Script: Bonus Script
|
||||
# TitleID: Title ID
|
||||
###########################################################################
|
||||
# Score - Achievement points that are given on completion.
|
||||
# - Id Achievement ID.
|
||||
# Group Achievement group type. (Defaut: None)
|
||||
# Name Achievement name.
|
||||
# Targets: List of targets the achievement requires. (Default: null)
|
||||
# - Id Index value used for import methods.
|
||||
# Mob Target mob. (Default: 0)
|
||||
# Count Target count. (Default: 1)
|
||||
# Condition Conditional statement that must be met for the achievement to be considered complete. (Default: null)
|
||||
# Map Map name that is used for the AG_CHATTING type. (Default: -1)
|
||||
# Dependents: List of achievements that need to be completed before this achievement is considered complete. (Default: null)
|
||||
# - Id: <bool> Achievement ID pre-requisite.
|
||||
# Rewards: List of rewards that are given on completion. (Default: null)
|
||||
# Item Item name.
|
||||
# Amount Amount of item. (Default: 1)
|
||||
# Script Bonus Script. (Default: null)
|
||||
# TitleId Title ID. (Default: 0)
|
||||
# Score Achievement points that are given on completion. (Default: 0)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: ACHIEVEMENT_DB
|
||||
Version: 1
|
||||
Version: 2
|
||||
|
||||
Footer:
|
||||
Imports:
|
||||
|
@ -22,9 +22,8 @@
|
||||
# Achievement Level Settings
|
||||
#
|
||||
###########################################################################
|
||||
# Level - Achievement Level
|
||||
###########################################################################
|
||||
# Points - Required total scoring points to reach this level.
|
||||
# - Level Achievement Level.
|
||||
# Points Required total scoring points to reach this level.
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
|
@ -16,67 +16,31 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
# Custom Achievement Database
|
||||
# Achievement Database
|
||||
###########################################################################
|
||||
#
|
||||
# Achievement Settings
|
||||
#
|
||||
###########################################################################
|
||||
# ID - Unique achievement ID.
|
||||
###########################################################################
|
||||
# Group - Achievement group type. Each achievement type calls a specific
|
||||
# objective check.
|
||||
# Valid groups:
|
||||
# AG_ADD_FRIEND
|
||||
# AG_ADVENTURE
|
||||
# AG_BABY
|
||||
# AG_BATTLE
|
||||
# AG_CHATTING
|
||||
# AG_CHATTING_COUNT
|
||||
# AG_CHATTING_CREATE
|
||||
# AG_CHATTING_DYING
|
||||
# AG_EAT
|
||||
# AG_GET_ITEM
|
||||
# AG_GET_ZENY
|
||||
# AG_GOAL_ACHIEVE
|
||||
# AG_GOAL_LEVEL
|
||||
# AG_GOAL_STATUS
|
||||
# AG_HEAR
|
||||
# AG_JOB_CHANGE
|
||||
# AG_MARRY
|
||||
# AG_PARTY
|
||||
# AG_ENCHANT_FAIL
|
||||
# AG_ENCHANT_SUCCESS
|
||||
# AG_SEE
|
||||
# AG_SPEND_ZENY
|
||||
# AG_TAMING
|
||||
###########################################################################
|
||||
# Name - Achievement name. Used when sending rewards through RODEX.
|
||||
###########################################################################
|
||||
# Target - A list of monster ID and count values that the achievement
|
||||
# requires. The target count can also be used for achievements that keep
|
||||
# a counter while not being related to monster kills.
|
||||
# Capped at MAX_ACHIEVEMENT_OBJECTIVES.
|
||||
###########################################################################
|
||||
# Condition - A conditional statement that must be met for the achievement
|
||||
# to be considered complete.
|
||||
###########################################################################
|
||||
# Map - A map name that is used for the AG_CHATTING type which increments
|
||||
# the counter based on the player's map.
|
||||
###########################################################################
|
||||
# Dependent: - A list of achievement IDs that need to be completed before
|
||||
# this achievement is considered complete.
|
||||
###########################################################################
|
||||
# Reward - A list of rewards that are given on completion. All fields are
|
||||
# optional.
|
||||
# ItemID: Item ID
|
||||
# Amount: Amount of Item ID (default 1)
|
||||
# Script: Bonus Script
|
||||
# TitleID: Title ID
|
||||
###########################################################################
|
||||
# Score - Achievement points that are given on completion.
|
||||
# - Id Achievement ID.
|
||||
# Group Achievement group type. (Defaut: None)
|
||||
# Name Achievement name.
|
||||
# Targets: List of targets the achievement requires. (Default: null)
|
||||
# - Id Index value used for import methods.
|
||||
# Mob Target mob. (Default: 0)
|
||||
# Count Target count. (Default: 1)
|
||||
# Condition Conditional statement that must be met for the achievement to be considered complete. (Default: null)
|
||||
# Map Map name that is used for the AG_CHATTING type. (Default: -1)
|
||||
# Dependents: List of achievements that need to be completed before this achievement is considered complete. (Default: null)
|
||||
# - Id: <bool> Achievement ID pre-requisite.
|
||||
# Rewards: List of rewards that are given on completion. (Default: null)
|
||||
# Item Item name.
|
||||
# Amount Amount of item. (Default: 1)
|
||||
# Script Bonus Script. (Default: null)
|
||||
# TitleId Title ID. (Default: 0)
|
||||
# Score Achievement points that are given on completion. (Default: 0)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: ACHIEVEMENT_DB
|
||||
Version: 1
|
||||
Version: 2
|
||||
|
@ -16,15 +16,14 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
# Import Achievement Level Database
|
||||
# Achievement Level Database
|
||||
###########################################################################
|
||||
#
|
||||
# Achievement Level Settings
|
||||
#
|
||||
###########################################################################
|
||||
# Level - Achievement Level
|
||||
###########################################################################
|
||||
# Points - Required total scoring points to reach this level.
|
||||
# - Level Achievement Level.
|
||||
# Points Required total scoring points to reach this level.
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,15 +16,14 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
# Pre-Renewal Achievement Level Database
|
||||
# Achievement Level Database
|
||||
###########################################################################
|
||||
#
|
||||
# Achievement Level Settings
|
||||
#
|
||||
###########################################################################
|
||||
# Level - Achievement Level
|
||||
###########################################################################
|
||||
# Points - Required total scoring points to reach this level.
|
||||
# - Level Achievement Level.
|
||||
# Points Required total scoring points to reach this level.
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,15 +16,14 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
# Renewal Achievement Level Database
|
||||
# Achievement Level Database
|
||||
###########################################################################
|
||||
#
|
||||
# Achievement Level Settings
|
||||
#
|
||||
###########################################################################
|
||||
# Level - Achievement Level
|
||||
###########################################################################
|
||||
# Points - Required total scoring points to reach this level.
|
||||
# - Level Achievement Level.
|
||||
# Points Required total scoring points to reach this level.
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
|
26
db/readme.md
26
db/readme.md
@ -18,20 +18,18 @@ We want to add our own custom achievement that can be given to a player via an N
|
||||
|
||||
#### /db/import/achievement_db.yml
|
||||
|
||||
|
||||
Achievements:
|
||||
- ID: 280000
|
||||
Group: "AG_GOAL_ACHIEVE"
|
||||
Name: "Emperio"
|
||||
Reward:
|
||||
TitleID: 1035
|
||||
Score: 50
|
||||
- ID: 280001
|
||||
Group: "AG_GOAL_ACHIEVE"
|
||||
Name: "Staff"
|
||||
Reward:
|
||||
TitleID: 1036
|
||||
Score: 50
|
||||
- Id: 280000
|
||||
Group: None
|
||||
Name: Emperio
|
||||
Reward:
|
||||
TitleId: 1035
|
||||
Score: 50
|
||||
- Id: 280001
|
||||
Group: None
|
||||
Name: Staff
|
||||
Reward:
|
||||
TitleId: 1036
|
||||
Score: 50
|
||||
|
||||
|
||||
### Instances
|
||||
|
@ -3,59 +3,60 @@
|
||||
//===== By: ==================================================
|
||||
//= rAthena Dev Team
|
||||
//===== Last Updated: ========================================
|
||||
//= 20190226
|
||||
//= 20200220
|
||||
//===== Description: =========================================
|
||||
//= Explanation of the achievements_db.yml file and structure.
|
||||
//============================================================
|
||||
|
||||
---------------------------------------
|
||||
|
||||
ID: Unique achievement ID.
|
||||
Id: Unique achievement ID.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Group: Achievement group type. Each achievement type calls a specific objective check.
|
||||
Valid groups:
|
||||
AG_ADD_FRIEND - Triggered when a player adds a friend.
|
||||
AG_ADVENTURE - Does not trigger automatically. These are triggered by the achievementcomplete script command.
|
||||
AG_BABY - Triggered when a player becomes a baby job.
|
||||
AG_BATTLE - Triggered when a player kills a monster.
|
||||
AG_CHATTING - Unknown.
|
||||
AG_CHATTING_COUNT - Triggered when a player has a chatroom open and others join.
|
||||
AG_CHATTING_CREATE - Triggered when a player creates a chatroom.
|
||||
AG_CHATTING_DYING - Triggered when a player creates a chatroom and dies with it open.
|
||||
AG_EAT - Unknown.
|
||||
AG_GET_ITEM - Triggered when a player gets an item that has a specific sell value.
|
||||
AG_GET_ZENY - Triggered when a player gets a specific amount of zeny at once.
|
||||
AG_GOAL_ACHIEVE - Triggered when a player's achievement rank levels up.
|
||||
AG_GOAL_LEVEL - Triggered when a player's base level or job level changes.
|
||||
AG_GOAL_STATUS - Triggered when a player's base stats changes.
|
||||
AG_HEAR - Unknown.
|
||||
AG_JOB_CHANGE - Triggered when a player's job changes.
|
||||
AG_MARRY - Triggered when two players get married.
|
||||
AG_PARTY - Triggered when a player creates a party.
|
||||
AG_ENCHANT_FAIL - Triggered when a player fails to refine an equipment.
|
||||
AG_ENCHANT_SUCCESS - Triggered when a player successfully refines an equipment.
|
||||
AG_SEE - Unknown.
|
||||
AG_SPEND_ZENY - Triggered when a player spends any amount of zeny on vendors.
|
||||
AG_TAMING - Triggered when a player tames a monster.
|
||||
None - Can be used for custom achievements that are given through a script with no trigger events.
|
||||
Add_Friend - Triggered when a player adds a friend.
|
||||
Adventure - Does not trigger automatically. These are triggered by the achievementcomplete script command.
|
||||
Baby - Triggered when a player becomes a baby job.
|
||||
Battle - Triggered when a player kills a monster.
|
||||
Chatting - Aegis uses this when talking to a NPC. These are triggered by the achievementupdate script command.
|
||||
Chatting_Count - Triggered when a player has a chatroom open and others join.
|
||||
Chatting_Create - Triggered when a player creates a chatroom.
|
||||
Chatting_Dying - Triggered when a player creates a chatroom and dies with it open.
|
||||
Eat - Unknown.
|
||||
Get_Item - Triggered when a player gets an item that has a specific sell value.
|
||||
Get_Zeny - Triggered when a player gets a specific amount of zeny at once.
|
||||
Goal_Achieve - Triggered when a player's achievement rank levels up.
|
||||
Goal_Level - Triggered when a player's base level or job level changes.
|
||||
Goal_Status - Triggered when a player's base stats changes.
|
||||
Job_Change - Triggered when a player's job changes.
|
||||
Marry - Triggered when two players get married.
|
||||
Party - Triggered when a player creates a party.
|
||||
Enchant_Fail - Triggered when a player fails to refine an equipment.
|
||||
Enchant_Success - Triggered when a player successfully refines an equipment.
|
||||
Spend_Zeny - Triggered when a player spends any amount of zeny on vendors.
|
||||
Taming - Triggered when a player tames a monster.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Name: Achievement name. Not read into source but used for quick look ups.
|
||||
Name: Achievement name. Used when sending rewards through RODEX.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Target: A list of monster ID and count values that the achievement requires.
|
||||
Targets: A list of monster names and count values that the achievement requires.
|
||||
The target count can also be used for achievements that keep a counter while not being related to monster kills.
|
||||
Capped at MAX_ACHIEVEMENT_OBJECTIVES.
|
||||
|
||||
Example:
|
||||
// Player must kill 5 Scorpions and 10 Poring.
|
||||
Target:
|
||||
- MobID: 1001
|
||||
Targets:
|
||||
- Id: 0
|
||||
Mob: SCORPION
|
||||
Count: 5
|
||||
- MobID: 1002
|
||||
- Id: 1
|
||||
Mob: PORING
|
||||
Count: 10
|
||||
|
||||
Example 2:
|
||||
@ -63,7 +64,7 @@ Example 2:
|
||||
// and not checked for a total (UI_Type = 1).
|
||||
// IE: In the achievement_list.lub file, UI_Type 0 is displayed as non-incremental while 1 shows a progress bar of completion for the achievement.
|
||||
Condition: " ARG0 >= 100 "
|
||||
Target:
|
||||
Targets:
|
||||
- Id: 0 // Array index value
|
||||
Count: 100
|
||||
|
||||
@ -84,19 +85,30 @@ Example 2:
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Map: A map name that is used for the AG_CHATTING type which increments the counter based on the player's map.
|
||||
Map: A map name that is used for the Chatting group which increments the counter based on the player's map.
|
||||
NOTICE: This option is currently disabled until the official behavior is confirmed.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Dependent: A list of achievement IDs that need to be completed before this achievement is considered complete.
|
||||
Dependents: A list of achievement IDs that need to be completed before this achievement is considered complete.
|
||||
|
||||
Example:
|
||||
// Player must complete achievements 10001 and 10002 first.
|
||||
Dependents:
|
||||
10001: true
|
||||
10002: true
|
||||
|
||||
// Used with the import, dependent achievements can be disabled. The player now only requires completion of achievement 10001.
|
||||
Dependents:
|
||||
10002: false
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Reward: A list of rewards that are given on completion. All fields are optional.
|
||||
ItemID: Item ID
|
||||
Amount: Amount of Item ID (default 1)
|
||||
Rewards: A list of rewards that are given on completion. All fields are optional.
|
||||
Item: Item Name
|
||||
Amount: Amount of Item (Default: 1)
|
||||
Script: Bonus Script
|
||||
TitleID: Title ID
|
||||
TitleId: Title ID
|
||||
|
||||
---------------------------------------
|
||||
|
||||
|
25
doc/yaml/db/achievement_db.yml
Normal file
25
doc/yaml/db/achievement_db.yml
Normal file
@ -0,0 +1,25 @@
|
||||
###########################################################################
|
||||
# Achievement Database
|
||||
###########################################################################
|
||||
#
|
||||
# Achievement Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - Id Achievement ID.
|
||||
# Group Achievement group type. (Defaut: None)
|
||||
# Name Achievement name.
|
||||
# Targets: List of targets the achievement requires. (Default: null)
|
||||
# - Id Index value used for import methods.
|
||||
# Mob Target mob. (Default: 0)
|
||||
# Count Target count. (Default: 1)
|
||||
# Condition Conditional statement that must be met for the achievement to be considered complete. (Default: null)
|
||||
# Map Map name that is used for the AG_CHATTING type. (Default: -1)
|
||||
# Dependents: List of achievements that need to be completed before this achievement is considered complete. (Default: null)
|
||||
# - Id: <bool> Achievement ID pre-requisite.
|
||||
# Rewards: List of rewards that are given on completion. (Default: null)
|
||||
# Item Item name.
|
||||
# Amount Amount of item. (Default: 1)
|
||||
# Script Bonus Script. (Default: null)
|
||||
# TitleId Title ID. (Default: 0)
|
||||
# Score Achievement points that are given on completion. (Default: 0)
|
||||
###########################################################################
|
15
rAthena.sln
15
rAthena.sln
@ -83,6 +83,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml2sql", "src\tool\yaml2s
|
||||
{352B45B3-FE88-4431-9D89-48CF811446DB} = {352B45B3-FE88-4431-9D89-48CF811446DB}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yamlupgrade", "src\tool\yamlupgrade.vcxproj", "{9115C6D1-520A-4540-B4FE-95F3C923FE2C}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{61D6A599-6BED-4154-A9FC-40553BD972E0} = {61D6A599-6BED-4154-A9FC-40553BD972E0}
|
||||
{352B45B3-FE88-4431-9D89-48CF811446DB} = {352B45B3-FE88-4431-9D89-48CF811446DB}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
@ -171,6 +177,14 @@ Global
|
||||
{CDBBB260-B245-44EC-80FB-3F9421885E40}.Release|Win32.Build.0 = Release|Win32
|
||||
{CDBBB260-B245-44EC-80FB-3F9421885E40}.Release|x64.ActiveCfg = Release|x64
|
||||
{CDBBB260-B245-44EC-80FB-3F9421885E40}.Release|x64.Build.0 = Release|x64
|
||||
{9115C6D1-520A-4540-B4FE-95F3C923FE2C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9115C6D1-520A-4540-B4FE-95F3C923FE2C}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9115C6D1-520A-4540-B4FE-95F3C923FE2C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9115C6D1-520A-4540-B4FE-95F3C923FE2C}.Debug|x64.Build.0 = Debug|x64
|
||||
{9115C6D1-520A-4540-B4FE-95F3C923FE2C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9115C6D1-520A-4540-B4FE-95F3C923FE2C}.Release|Win32.Build.0 = Release|Win32
|
||||
{9115C6D1-520A-4540-B4FE-95F3C923FE2C}.Release|x64.ActiveCfg = Release|x64
|
||||
{9115C6D1-520A-4540-B4FE-95F3C923FE2C}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -187,6 +201,7 @@ Global
|
||||
{61D6A599-6BED-4154-A9FC-40553BD972E0} = {6ABA1767-6242-4CA0-BA22-A30972DC8918}
|
||||
{5A9059F2-4933-49A2-BEE6-CC67F66FA070} = {9F328FE9-129D-4C0C-820B-BE4AA5996652}
|
||||
{CDBBB260-B245-44EC-80FB-3F9421885E40} = {9F328FE9-129D-4C0C-820B-BE4AA5996652}
|
||||
{9115C6D1-520A-4540-B4FE-95F3C923FE2C} = {9F328FE9-129D-4C0C-820B-BE4AA5996652}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {026DA20F-820C-40AA-983E-0E231EA90AD5}
|
||||
|
@ -50,8 +50,7 @@ const std::string AchievementDatabase::getDefaultLocation(){
|
||||
uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
uint32 achievement_id;
|
||||
|
||||
// TODO: doesnt match camel case
|
||||
if( !this->asUInt32( node, "ID", achievement_id ) ){
|
||||
if( !this->asUInt32( node, "Id", achievement_id ) ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -59,11 +58,7 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
bool exists = achievement != nullptr;
|
||||
|
||||
if( !exists ){
|
||||
if( !this->nodeExists( node, "Group" ) ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !this->nodeExists( node, "Name" ) ){
|
||||
if( !this->nodesExist( node, { "Name" } ) ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -78,14 +73,18 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string group_name_constant = "AG_" + group_name;
|
||||
int64 constant;
|
||||
|
||||
if( !script_get_constant( group_name.c_str(), &constant ) ){
|
||||
this->invalidWarning( node, "achievement_read_db_sub: Invalid group %s for achievement %d, skipping.\n", group_name.c_str(), achievement_id );
|
||||
if( !script_get_constant( group_name_constant.c_str(), &constant ) ){
|
||||
this->invalidWarning( node, "Invalid Group %s for achievement %d, skipping.\n", group_name.c_str(), achievement_id );
|
||||
return 0;
|
||||
}
|
||||
|
||||
achievement->group = (e_achievement_group)constant;
|
||||
} else {
|
||||
if (!exists)
|
||||
achievement->group = AG_NONE;
|
||||
}
|
||||
|
||||
if( this->nodeExists( node, "Name" ) ){
|
||||
@ -98,15 +97,10 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
achievement->name = name;
|
||||
}
|
||||
|
||||
if( this->nodeExists( node, "Target" ) ){
|
||||
const YAML::Node& targets = node["Target"];
|
||||
if( this->nodeExists( node, "Targets" ) ){
|
||||
const YAML::Node& targets = node["Targets"];
|
||||
|
||||
for( const YAML::Node& targetNode : targets ){
|
||||
if( achievement->targets.size() >= MAX_ACHIEVEMENT_OBJECTIVES ){
|
||||
this->invalidWarning( targetNode, "Node \"Target\" list exceeds the maximum of %d, skipping.\n", MAX_ACHIEVEMENT_OBJECTIVES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 targetId;
|
||||
|
||||
if( !this->asUInt16( targetNode, "Id", targetId ) ){
|
||||
@ -114,16 +108,16 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
}
|
||||
|
||||
if( targetId >= MAX_ACHIEVEMENT_OBJECTIVES ){
|
||||
this->invalidWarning( targetNode["Id"], "Node \"Id\" is out of valid range [0,%d], skipping.\n", MAX_ACHIEVEMENT_OBJECTIVES );
|
||||
return 0;
|
||||
this->invalidWarning( targetNode["Id"], "Target Id is out of valid range [0,%d], skipping.\n", MAX_ACHIEVEMENT_OBJECTIVES );
|
||||
continue;
|
||||
}
|
||||
|
||||
std::shared_ptr<achievement_target> target = rathena::util::map_find( achievement->targets, targetId );
|
||||
bool targetExists = target != nullptr;
|
||||
|
||||
if( !targetExists ){
|
||||
if( !this->nodeExists( targetNode, "Count" ) && !this->nodeExists( targetNode, "MobID" ) ){
|
||||
this->invalidWarning( targetNode, "Node \"Target\" has no data specified, skipping.\n" );
|
||||
if( !this->nodeExists( targetNode, "Count" ) && !this->nodeExists( targetNode, "Mob" ) ){
|
||||
this->invalidWarning( targetNode, "Target has no data specified, skipping.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -137,30 +131,43 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( count == 0 ){
|
||||
if( targetExists ){
|
||||
achievement->targets.erase( targetId );
|
||||
continue;
|
||||
}else{
|
||||
this->invalidWarning( targetNode["Count"], "Target count has to be > 0, skipping.\n" );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
target->count = count;
|
||||
}else{
|
||||
if( !targetExists ){
|
||||
target->count = 0;
|
||||
target->count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if( this->nodeExists( targetNode, "MobID" ) ){
|
||||
if( this->nodeExists( targetNode, "Mob" ) ){
|
||||
if( achievement->group != AG_BATTLE && achievement->group != AG_TAMING ){
|
||||
this->invalidWarning( targets, "Node \"MobID\" is only supported for targets in group AG_BATTLE or AG_TAMING, skipping.\n" );
|
||||
this->invalidWarning( targets, "Target Mob is only supported for targets in group AG_BATTLE or AG_TAMING, skipping.\n" );
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string mob_name;
|
||||
|
||||
if( !this->asString( targetNode, "Mob", mob_name ) ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 mob_id;
|
||||
std::shared_ptr<s_mob_db> mob = mobdb_search_aegisname( mob_name.c_str() );
|
||||
|
||||
// TODO: not camel case
|
||||
if( !this->asUInt32( targetNode, "MobID", mob_id ) ){
|
||||
if (mob == nullptr) {
|
||||
this->invalidWarning(targetNode["Mob"], "Target Mob %s does not exist, skipping.\n", mob_name.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( mob_db.find( mob_id ) == nullptr ){
|
||||
this->invalidWarning( targetNode["MobID"], "Unknown monster ID %d, skipping.\n", mob_id );
|
||||
return 0;
|
||||
}
|
||||
uint32 mob_id = mob->vd.class_;
|
||||
|
||||
if( !this->mobexists( mob_id ) ){
|
||||
this->achievement_mobs.push_back( mob_id );
|
||||
@ -195,12 +202,13 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
|
||||
achievement->condition = parse_script( condition.c_str(), this->getCurrentFile().c_str(), node["Condition"].Mark().line + 1, SCRIPT_IGNORE_EXTERNAL_BRACKETS );
|
||||
}else{
|
||||
achievement->condition = nullptr;
|
||||
if (!exists)
|
||||
achievement->condition = nullptr;
|
||||
}
|
||||
|
||||
if( this->nodeExists( node, "Map" ) ){
|
||||
if( achievement->group != AG_CHAT ){
|
||||
this->invalidWarning( node, "Node \"Map\" can only be used with the group AG_CHATTING, skipping.\n" );
|
||||
if( achievement->group != AG_CHATTING ){
|
||||
this->invalidWarning( node, "Map can only be used with the group AG_CHATTING, skipping.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -213,7 +221,7 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
achievement->mapindex = map_mapname2mapid( mapname.c_str() );
|
||||
|
||||
if( achievement->mapindex == -1 ){
|
||||
this->invalidWarning( node["Map"], "Unknown map name '%s'.\n", mapname.c_str() );
|
||||
this->invalidWarning( node["Map"], "Map %s does not exist, skipping.\n", mapname.c_str() );
|
||||
return 0;
|
||||
}
|
||||
}else{
|
||||
@ -222,43 +230,51 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
}
|
||||
}
|
||||
|
||||
if( this->nodeExists( node, "Dependent" ) ){
|
||||
for( const YAML::Node& subNode : node["Dependent"] ){
|
||||
uint32 dependent_achievement_id;
|
||||
if( this->nodeExists( node, "Dependents" ) ){
|
||||
const YAML::Node &dependentNode = node["Dependents"];
|
||||
|
||||
if( !this->asUInt32( subNode, "Id", dependent_achievement_id ) ){
|
||||
for( const auto it : dependentNode ){
|
||||
uint32 dependent_achievement_id = it.first.as<uint32>();
|
||||
bool active;
|
||||
|
||||
if (!this->asBool(dependentNode, std::to_string(dependent_achievement_id), active))
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: import logic for clearing => continue
|
||||
// TODO: change to set to prevent multiple entries with the same id?
|
||||
achievement->dependent_ids.push_back( dependent_achievement_id );
|
||||
if (active) {
|
||||
if (std::find(achievement->dependent_ids.begin(), achievement->dependent_ids.end(), dependent_achievement_id) != achievement->dependent_ids.end()) {
|
||||
this->invalidWarning(dependentNode, "Dependent achievement %d is already part of the list, skipping.\n", dependent_achievement_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (achievement->dependent_ids.size() >= MAX_ACHIEVEMENT_DEPENDENTS) {
|
||||
this->invalidWarning(dependentNode, "Maximum amount (%d) of dependent achievements reached, skipping.\n", MAX_ACHIEVEMENT_DEPENDENTS);
|
||||
break;
|
||||
}
|
||||
|
||||
achievement->dependent_ids.push_back(dependent_achievement_id);
|
||||
} else
|
||||
util::vector_erase_if_exists(achievement->dependent_ids, dependent_achievement_id);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: not plural
|
||||
if( this->nodeExists( node, "Reward" ) ){
|
||||
const YAML::Node& rewardNode = node["Reward"];
|
||||
if( this->nodeExists( node, "Rewards" ) ){
|
||||
const YAML::Node& rewardNode = node["Rewards"];
|
||||
|
||||
// TODO: not camel case
|
||||
if( this->nodeExists( rewardNode, "ItemID" ) ){
|
||||
t_itemid itemId;
|
||||
if( this->nodeExists( rewardNode, "Item" ) ){
|
||||
std::string item_name;
|
||||
|
||||
if( !this->asUInt32( rewardNode, "ItemID", itemId ) ){
|
||||
if( !this->asString( rewardNode, "Item", item_name ) ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !itemdb_exists( itemId ) ){
|
||||
this->invalidWarning( rewardNode["ItemID"], "Unknown item with ID %u.\n", itemId );
|
||||
struct item_data *item = itemdb_search_aegisname(item_name.c_str());
|
||||
|
||||
if (item == nullptr) {
|
||||
this->invalidWarning(rewardNode["Item"], "Reward Item %s does not exist, skipping.\n", item_name.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
achievement->rewards.nameid = itemId;
|
||||
|
||||
if( achievement->rewards.amount == 0 ){
|
||||
// Default the amount to 1
|
||||
achievement->rewards.amount = 1;
|
||||
}
|
||||
achievement->rewards.nameid = item->nameid;
|
||||
}
|
||||
|
||||
if( this->nodeExists( rewardNode, "Amount" ) ){
|
||||
@ -269,6 +285,9 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
}
|
||||
|
||||
achievement->rewards.amount = amount;
|
||||
} else {
|
||||
if (!exists)
|
||||
achievement->rewards.amount = 1;
|
||||
}
|
||||
|
||||
if( this->nodeExists( rewardNode, "Script" ) ){
|
||||
@ -285,18 +304,26 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
|
||||
achievement->rewards.script = parse_script( script.c_str(), this->getCurrentFile().c_str(), achievement_id, SCRIPT_IGNORE_EXTERNAL_BRACKETS );
|
||||
}else{
|
||||
achievement->rewards.script = nullptr;
|
||||
if (!exists)
|
||||
achievement->rewards.script = nullptr;
|
||||
}
|
||||
|
||||
// TODO: not camel case
|
||||
if( this->nodeExists( rewardNode, "TitleID" ) ){
|
||||
if( this->nodeExists( rewardNode, "TitleId" ) ){
|
||||
uint32 title;
|
||||
|
||||
if( !this->asUInt32( rewardNode, "TitleID", title ) ){
|
||||
if( !this->asUInt32( rewardNode, "TitleId", title ) ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (title < TITLE_BASE || title > TITLE_MAX) {
|
||||
this->invalidWarning(rewardNode["TitleId"], "Reward Title ID %u does not exist (%hu~%hu), skipping.\n", title, TITLE_BASE, TITLE_MAX);
|
||||
return 0;
|
||||
}
|
||||
|
||||
achievement->rewards.title_id = title;
|
||||
} else {
|
||||
if (!exists)
|
||||
achievement->rewards.title_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,6 +335,9 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
}
|
||||
|
||||
achievement->score = score;
|
||||
} else {
|
||||
if (!exists)
|
||||
achievement->score = 0;
|
||||
}
|
||||
|
||||
if( !exists ){
|
||||
@ -317,6 +347,25 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){
|
||||
return 1;
|
||||
}
|
||||
|
||||
void AchievementDatabase::loadingFinished(){
|
||||
for (const auto &achit : achievement_db) {
|
||||
const std::shared_ptr<s_achievement_db> ach = achit.second;
|
||||
|
||||
for (auto dep = ach->dependent_ids.begin(); dep != ach->dependent_ids.end(); dep++) {
|
||||
if (!achievement_db.exists(*dep)) {
|
||||
ShowWarning("achievement_read_db: An invalid Dependent ID %d was given for Achievement %d. Removing from list.\n", *dep, ach->achievement_id);
|
||||
dep = ach->dependent_ids.erase(dep);
|
||||
|
||||
if (dep == ach->dependent_ids.end()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ach->dependent_ids.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
|
||||
AchievementDatabase achievement_db;
|
||||
|
||||
/**
|
||||
@ -507,8 +556,8 @@ bool achievement_check_dependent(struct map_session_data *sd, int achievement_id
|
||||
|
||||
// Check if the achievement has a dependent
|
||||
// If so, then do a check on all dependents to see if they're complete
|
||||
for (int i = 0; i < adb->dependent_ids.size(); i++) {
|
||||
if (!achievement_done(sd, adb->dependent_ids[i]))
|
||||
for (const auto &depit : adb->dependent_ids) {
|
||||
if (!achievement_done(sd, depit))
|
||||
return false; // One of the dependent is not complete!
|
||||
}
|
||||
|
||||
@ -850,6 +899,19 @@ bool achievement_check_condition( struct script_code* condition, struct map_sess
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if an achievement's target count is complete
|
||||
* @param ad: Achievement data
|
||||
* @param current_count: Current target data
|
||||
* @return True if all target values meet the requirements or false otherwise
|
||||
*/
|
||||
static bool achievement_target_complete(std::shared_ptr<s_achievement_db> ad, std::array<int, MAX_ACHIEVEMENT_OBJECTIVES> current_count) {
|
||||
return std::find_if(ad->targets.begin(), ad->targets.end(),
|
||||
[current_count](const std::pair<uint16, std::shared_ptr<achievement_target>> &target) -> bool {
|
||||
return current_count[target.first] < target.second->count;
|
||||
}) == ad->targets.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update achievement objectives.
|
||||
* @param sd: Player to update
|
||||
@ -892,9 +954,9 @@ static bool achievement_update_objectives(struct map_session_data *sd, std::shar
|
||||
switch (group) {
|
||||
case AG_ADD_FRIEND:
|
||||
case AG_BABY:
|
||||
case AG_CHAT_COUNT:
|
||||
case AG_CHAT_CREATE:
|
||||
case AG_CHAT_DYING:
|
||||
case AG_CHATTING_COUNT:
|
||||
case AG_CHATTING_CREATE:
|
||||
case AG_CHATTING_DYING:
|
||||
case AG_GET_ITEM:
|
||||
case AG_GET_ZENY:
|
||||
case AG_GOAL_LEVEL:
|
||||
@ -902,8 +964,8 @@ static bool achievement_update_objectives(struct map_session_data *sd, std::shar
|
||||
case AG_JOB_CHANGE:
|
||||
case AG_MARRY:
|
||||
case AG_PARTY:
|
||||
case AG_REFINE_FAIL:
|
||||
case AG_REFINE_SUCCESS:
|
||||
case AG_ENCHANT_FAIL:
|
||||
case AG_ENCHANT_SUCCESS:
|
||||
if (!ad->condition)
|
||||
return false;
|
||||
|
||||
@ -914,15 +976,9 @@ static bool achievement_update_objectives(struct map_session_data *sd, std::shar
|
||||
complete = true;
|
||||
break;
|
||||
case AG_SPEND_ZENY:
|
||||
//case AG_CHAT: // No information on trigger events
|
||||
if (ad->targets.empty() || !ad->condition)
|
||||
return false;
|
||||
|
||||
//if (group == AG_CHAT) {
|
||||
// if (ad->mapindex > -1 && sd->bl.m != ad->mapindex)
|
||||
// return false;
|
||||
//}
|
||||
|
||||
for (const auto &it : ad->targets) {
|
||||
if (current_count[it.first] < it.second->count)
|
||||
current_count[it.first] += update_count[it.first];
|
||||
@ -933,11 +989,7 @@ static bool achievement_update_objectives(struct map_session_data *sd, std::shar
|
||||
|
||||
changed = true;
|
||||
|
||||
if (std::find_if(ad->targets.begin(), ad->targets.end(),
|
||||
[current_count](const std::pair<uint16, std::shared_ptr<achievement_target>> &target) -> bool {
|
||||
return current_count[target.first] < target.second->count;
|
||||
}
|
||||
) == ad->targets.end())
|
||||
if (achievement_target_complete(ad, current_count))
|
||||
complete = true;
|
||||
break;
|
||||
case AG_BATTLE:
|
||||
@ -955,13 +1007,38 @@ static bool achievement_update_objectives(struct map_session_data *sd, std::shar
|
||||
if (!changed)
|
||||
return false;
|
||||
|
||||
if (std::find_if(ad->targets.begin(), ad->targets.end(),
|
||||
[current_count](const std::pair<uint16, std::shared_ptr<achievement_target>> &target) -> bool {
|
||||
return current_count[target.first] < target.second->count;
|
||||
}
|
||||
) == ad->targets.end())
|
||||
if (achievement_target_complete(ad, current_count))
|
||||
complete = true;
|
||||
break;
|
||||
case AG_GOAL_ACHIEVE:
|
||||
if (!achievement_check_condition(ad->condition, sd)) // Parameters weren't met
|
||||
return false;
|
||||
|
||||
changed = true;
|
||||
complete = true;
|
||||
break;
|
||||
/*
|
||||
case AG_CHATTING:
|
||||
if (ad->targets.empty())
|
||||
return false;
|
||||
|
||||
if (ad->mapindex > -1 && sd->bl.m != ad->mapindex)
|
||||
return false;
|
||||
|
||||
for (const auto &it : ad->targets) {
|
||||
if (current_count[it.first] < it.second->count) {
|
||||
current_count[it.first]++;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed)
|
||||
return false;
|
||||
|
||||
if (achievement_target_complete(ad, current_count))
|
||||
complete = true;
|
||||
break;
|
||||
*/
|
||||
}
|
||||
|
||||
if( isNew ){
|
||||
@ -1022,15 +1099,8 @@ void achievement_update_objective(struct map_session_data *sd, enum e_achievemen
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
switch(group) {
|
||||
case AG_CHAT: //! TODO: Not sure how this works officially
|
||||
// These have no objective use.
|
||||
break;
|
||||
default:
|
||||
for (auto &ach : achievement_db)
|
||||
achievement_update_objectives(sd, ach.second, group, count);
|
||||
break;
|
||||
}
|
||||
for (auto &ach : achievement_db)
|
||||
achievement_update_objectives(sd, ach.second, group, count);
|
||||
|
||||
// Remove variables that might have been set
|
||||
for (int i = 0; i < arg_count; i++){
|
||||
@ -1069,34 +1139,11 @@ int achievement_update_objective_sub(block_list *bl, va_list ap)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads achievements from the achievement db.
|
||||
*/
|
||||
void achievement_read_db(void)
|
||||
{
|
||||
achievement_db.load();
|
||||
|
||||
for (auto &achit : achievement_db) {
|
||||
const auto ach = achit.second;
|
||||
|
||||
for (int i = 0; i < ach->dependent_ids.size(); i++) {
|
||||
if (!achievement_db.exists(ach->dependent_ids[i])) {
|
||||
ShowWarning("achievement_read_db: An invalid Dependent ID %d was given for Achievement %d. Removing from list.\n", ach->dependent_ids[i], ach->achievement_id);
|
||||
ach->dependent_ids.erase(ach->dependent_ids.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
achievement_level_db.load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the achievement database
|
||||
*/
|
||||
void achievement_db_reload(void)
|
||||
{
|
||||
if (!battle_config.feature_achievement)
|
||||
return;
|
||||
do_final_achievement();
|
||||
do_init_achievement();
|
||||
}
|
||||
@ -1108,7 +1155,8 @@ void do_init_achievement(void)
|
||||
{
|
||||
if (!battle_config.feature_achievement)
|
||||
return;
|
||||
achievement_read_db();
|
||||
achievement_db.load();
|
||||
achievement_level_db.load();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1129,7 +1177,7 @@ s_achievement_db::s_achievement_db()
|
||||
, targets()
|
||||
, dependent_ids()
|
||||
, condition(nullptr)
|
||||
, mapindex(0)
|
||||
, mapindex(-1)
|
||||
, rewards()
|
||||
, score(0)
|
||||
, has_dependent(0)
|
||||
|
@ -24,23 +24,21 @@ enum e_achievement_group {
|
||||
AG_ADVENTURE,
|
||||
AG_BABY,
|
||||
AG_BATTLE,
|
||||
AG_CHAT,
|
||||
AG_CHAT_COUNT,
|
||||
AG_CHAT_CREATE,
|
||||
AG_CHAT_DYING,
|
||||
AG_CHATTING,
|
||||
AG_CHATTING_COUNT,
|
||||
AG_CHATTING_CREATE,
|
||||
AG_CHATTING_DYING,
|
||||
AG_EAT,
|
||||
AG_GET_ITEM,
|
||||
AG_GET_ZENY,
|
||||
AG_GOAL_ACHIEVE,
|
||||
AG_GOAL_LEVEL,
|
||||
AG_GOAL_STATUS,
|
||||
AG_HEAR,
|
||||
AG_JOB_CHANGE,
|
||||
AG_MARRY,
|
||||
AG_PARTY,
|
||||
AG_REFINE_FAIL,
|
||||
AG_REFINE_SUCCESS,
|
||||
AG_SEE,
|
||||
AG_ENCHANT_FAIL,
|
||||
AG_ENCHANT_SUCCESS,
|
||||
AG_SPEND_ZENY,
|
||||
AG_TAMING,
|
||||
AG_MAX
|
||||
@ -65,6 +63,12 @@ enum e_achievement_info {
|
||||
ACHIEVEINFO_MAX,
|
||||
};
|
||||
|
||||
enum e_title_table : uint16 {
|
||||
TITLE_NONE = 0,
|
||||
TITLE_BASE = 1000,
|
||||
TITLE_MAX = 1046,
|
||||
};
|
||||
|
||||
struct achievement_target {
|
||||
int mob;
|
||||
int count;
|
||||
@ -95,17 +99,17 @@ struct s_achievement_db {
|
||||
|
||||
class AchievementDatabase : public TypesafeYamlDatabase<uint32, s_achievement_db>{
|
||||
private:
|
||||
// Avoids checking achievements on every mob killed
|
||||
std::vector<uint32> achievement_mobs;
|
||||
std::vector<uint32> achievement_mobs; // Avoids checking achievements on every mob killed
|
||||
|
||||
public:
|
||||
AchievementDatabase() : TypesafeYamlDatabase( "ACHIEVEMENT_DB", 1 ){
|
||||
AchievementDatabase() : TypesafeYamlDatabase( "ACHIEVEMENT_DB", 2 ){
|
||||
|
||||
}
|
||||
|
||||
void clear();
|
||||
const std::string getDefaultLocation();
|
||||
uint64 parseBodyNode( const YAML::Node& node );
|
||||
void loadingFinished();
|
||||
|
||||
// Additional
|
||||
bool mobexists(uint32 mob_id);
|
||||
|
@ -2353,7 +2353,7 @@ ACMD_FUNC(refine)
|
||||
clif_additem(sd, i, 1, 0);
|
||||
pc_equipitem(sd, i, current_position);
|
||||
clif_misceffect(&sd->bl, 3);
|
||||
achievement_update_objective(sd, AG_REFINE_SUCCESS, 2, sd->inventory_data[i]->wlv, sd->inventory.u.items_inventory[i].refine);
|
||||
achievement_update_objective(sd, AG_ENCHANT_SUCCESS, 2, sd->inventory_data[i]->wlv, sd->inventory.u.items_inventory[i].refine);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
@ -109,9 +109,9 @@ int chat_createpcchat(struct map_session_data* sd, const char* title, const char
|
||||
clif_dispchat(cd,0);
|
||||
|
||||
if (status_isdead(&sd->bl))
|
||||
achievement_update_objective(sd, AG_CHAT_DYING, 1, 1);
|
||||
achievement_update_objective(sd, AG_CHATTING_DYING, 1, 1);
|
||||
else
|
||||
achievement_update_objective(sd, AG_CHAT_CREATE, 1, 1);
|
||||
achievement_update_objective(sd, AG_CHATTING_CREATE, 1, 1);
|
||||
} else
|
||||
clif_createchat(sd,1);
|
||||
|
||||
@ -173,7 +173,7 @@ int chat_joinchat(struct map_session_data* sd, int chatid, const char* pass)
|
||||
clif_dispchat(cd, 0); //Reported number of changes to the people around
|
||||
|
||||
if (cd->owner->type == BL_PC)
|
||||
achievement_update_objective(map_id2sd(cd->owner->id), AG_CHAT_COUNT, 1, cd->users);
|
||||
achievement_update_objective(map_id2sd(cd->owner->id), AG_CHATTING_COUNT, 1, cd->users);
|
||||
|
||||
chat_triggerevent(cd); //Event
|
||||
|
||||
|
@ -10337,6 +10337,8 @@ static bool clif_process_message(struct map_session_data* sd, bool whisperFormat
|
||||
if (battle_config.hom_idle_no_share && sd->hd && battle_config.idletime_hom_option&IDLE_CHAT)
|
||||
sd->idletime_hom = last_tick;
|
||||
|
||||
//achievement_update_objective(sd, AG_CHATTING, 1, 1); // !TODO: Confirm how this achievement is triggered
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -9257,7 +9257,7 @@ BUILDIN_FUNC(successrefitem) {
|
||||
clif_additem(sd,i,1,0);
|
||||
pc_equipitem(sd,i,ep);
|
||||
clif_misceffect(&sd->bl,3);
|
||||
achievement_update_objective(sd, AG_REFINE_SUCCESS, 2, sd->inventory_data[i]->wlv, sd->inventory.u.items_inventory[i].refine);
|
||||
achievement_update_objective(sd, AG_ENCHANT_SUCCESS, 2, sd->inventory_data[i]->wlv, sd->inventory.u.items_inventory[i].refine);
|
||||
if (sd->inventory.u.items_inventory[i].refine == battle_config.blacksmith_fame_refine_threshold &&
|
||||
sd->inventory.u.items_inventory[i].card[0] == CARD0_FORGE &&
|
||||
sd->status.char_id == (int)MakeDWord(sd->inventory.u.items_inventory[i].card[2],sd->inventory.u.items_inventory[i].card[3]))
|
||||
@ -9307,7 +9307,7 @@ BUILDIN_FUNC(failedrefitem) {
|
||||
clif_refine(sd->fd,1,i,sd->inventory.u.items_inventory[i].refine); //notify client of failure
|
||||
pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
|
||||
clif_misceffect(&sd->bl,2); // display failure effect
|
||||
achievement_update_objective(sd, AG_REFINE_FAIL, 1, 1);
|
||||
achievement_update_objective(sd, AG_ENCHANT_FAIL, 1, 1);
|
||||
script_pushint(st, 1);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
@ -9356,7 +9356,7 @@ BUILDIN_FUNC(downrefitem) {
|
||||
clif_additem(sd,i,1,0);
|
||||
pc_equipitem(sd,i,ep);
|
||||
clif_misceffect(&sd->bl,2);
|
||||
achievement_update_objective(sd, AG_REFINE_FAIL, 1, sd->inventory.u.items_inventory[i].refine);
|
||||
achievement_update_objective(sd, AG_ENCHANT_FAIL, 1, sd->inventory.u.items_inventory[i].refine);
|
||||
script_pushint(st, sd->inventory.u.items_inventory[i].refine);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
@ -5211,29 +5211,27 @@
|
||||
export_constant(USW_ALL);
|
||||
|
||||
/* achievement groups */
|
||||
export_constant2("AG_ADD_FRIEND", AG_ADD_FRIEND);
|
||||
export_constant2("AG_ADVENTURE", AG_ADVENTURE);
|
||||
export_constant2("AG_BABY", AG_BABY);
|
||||
export_constant2("AG_BATTLE", AG_BATTLE);
|
||||
export_constant2("AG_CHATTING", AG_CHAT);
|
||||
export_constant2("AG_CHATTING_COUNT", AG_CHAT_COUNT);
|
||||
export_constant2("AG_CHATTING_CREATE", AG_CHAT_CREATE);
|
||||
export_constant2("AG_CHATTING_DYING", AG_CHAT_DYING);
|
||||
export_constant2("AG_EAT", AG_EAT);
|
||||
export_constant2("AG_GET_ITEM", AG_GET_ITEM);
|
||||
export_constant2("AG_GET_ZENY", AG_GET_ZENY);
|
||||
export_constant2("AG_GOAL_ACHIEVE", AG_GOAL_ACHIEVE);
|
||||
export_constant2("AG_GOAL_LEVEL", AG_GOAL_LEVEL);
|
||||
export_constant2("AG_GOAL_STATUS", AG_GOAL_STATUS);
|
||||
export_constant2("AG_HEAR", AG_HEAR);
|
||||
export_constant2("AG_JOB_CHANGE", AG_JOB_CHANGE);
|
||||
export_constant2("AG_MARRY", AG_MARRY);
|
||||
export_constant2("AG_PARTY", AG_PARTY);
|
||||
export_constant2("AG_ENCHANT_FAIL", AG_REFINE_FAIL);
|
||||
export_constant2("AG_ENCHANT_SUCCESS", AG_REFINE_SUCCESS);
|
||||
export_constant2("AG_SEE", AG_SEE);
|
||||
export_constant2("AG_SPEND_ZENY", AG_SPEND_ZENY);
|
||||
export_constant2("AG_TAMING", AG_TAMING);
|
||||
export_constant(AG_ADD_FRIEND);
|
||||
export_constant(AG_ADVENTURE);
|
||||
export_constant(AG_BABY);
|
||||
export_constant(AG_BATTLE);
|
||||
export_constant(AG_CHATTING);
|
||||
export_constant(AG_CHATTING_COUNT);
|
||||
export_constant(AG_CHATTING_CREATE);
|
||||
export_constant(AG_CHATTING_DYING);
|
||||
export_constant(AG_EAT);
|
||||
export_constant(AG_GET_ITEM);
|
||||
export_constant(AG_GET_ZENY);
|
||||
export_constant(AG_GOAL_ACHIEVE);
|
||||
export_constant(AG_GOAL_LEVEL);
|
||||
export_constant(AG_GOAL_STATUS);
|
||||
export_constant(AG_JOB_CHANGE);
|
||||
export_constant(AG_MARRY);
|
||||
export_constant(AG_PARTY);
|
||||
export_constant(AG_ENCHANT_FAIL);
|
||||
export_constant(AG_ENCHANT_SUCCESS);
|
||||
export_constant(AG_SPEND_ZENY);
|
||||
export_constant(AG_TAMING);
|
||||
|
||||
/* achievement info */
|
||||
export_constant(ACHIEVEINFO_COUNT1);
|
||||
|
@ -17687,7 +17687,7 @@ void skill_weaponrefine(struct map_session_data *sd, int idx)
|
||||
clif_upgrademessage(sd, 0, item->nameid);
|
||||
clif_inventorylist(sd);
|
||||
clif_refine(sd->fd,0,idx,item->refine);
|
||||
achievement_update_objective(sd, AG_REFINE_SUCCESS, 2, ditem->wlv, item->refine);
|
||||
achievement_update_objective(sd, AG_ENCHANT_SUCCESS, 2, ditem->wlv, item->refine);
|
||||
if (ep)
|
||||
pc_equipitem(sd,idx,ep);
|
||||
clif_misceffect(&sd->bl,3);
|
||||
@ -17713,7 +17713,7 @@ void skill_weaponrefine(struct map_session_data *sd, int idx)
|
||||
pc_unequipitem(sd,idx,3);
|
||||
clif_upgrademessage(sd, 1, item->nameid);
|
||||
clif_refine(sd->fd,1,idx,item->refine);
|
||||
achievement_update_objective(sd, AG_REFINE_FAIL, 1, 1);
|
||||
achievement_update_objective(sd, AG_ENCHANT_FAIL, 1, 1);
|
||||
pc_delitem(sd,idx,1,0,2, LOG_TYPE_OTHER);
|
||||
clif_misceffect(&sd->bl,2);
|
||||
clif_emotion(&sd->bl, ET_HUK);
|
||||
|
@ -18,12 +18,14 @@ CSV2YAML_OBJ = obj_all/csv2yaml.o
|
||||
|
||||
YAML2SQL_OBJ = obj_all/yaml2sql.o
|
||||
|
||||
YAMLUPGRADE_OBJ = obj_all/yamlupgrade.o
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
#####################################################################
|
||||
.PHONY : all mapcache csv2yaml yaml2sql clean help
|
||||
.PHONY : all mapcache csv2yaml yaml2sql yamlupgrade clean help
|
||||
|
||||
all: mapcache csv2yaml yaml2sql
|
||||
all: mapcache csv2yaml yaml2sql yamlupgrade
|
||||
|
||||
mapcache: obj_all $(MAPCACHE_OBJ) $(COMMON_DIR_OBJ)
|
||||
@echo " LD $@"
|
||||
@ -37,18 +39,23 @@ yaml2sql: obj_all $(YAML2SQL_OBJ) $(COMMON_DIR_OBJ) $(YAML_CPP_AR)
|
||||
@echo " LD $@"
|
||||
@@CXX@ @LDFLAGS@ -o ../../yaml2sql@EXEEXT@ $(YAML2SQL_OBJ) $(COMMON_DIR_OBJ) $(YAML_CPP_AR) @LIBS@
|
||||
|
||||
yamlupgrade: obj_all $(YAMLUPGRADE_OBJ) $(COMMON_DIR_OBJ) $(YAML_CPP_AR)
|
||||
@echo " LD $@"
|
||||
@@CXX@ @LDFLAGS@ -o ../../yamlupgrade@EXEEXT@ $(YAMLUPGRADE_OBJ) $(COMMON_DIR_OBJ) ../common/obj/database.o $(YAML_CPP_AR) @LIBS@
|
||||
|
||||
clean:
|
||||
@echo " CLEAN tool"
|
||||
@rm -rf obj_all/*.o ../../mapcache@EXEEXT@ ../../csv2yaml@EXEEXT@ ../../yaml2sql@EXEEXT@
|
||||
@rm -rf obj_all/*.o ../../mapcache@EXEEXT@ ../../csv2yaml@EXEEXT@ ../../yaml2sql@EXEEXT@ ../../yamlupgrade@EXEEXT@
|
||||
|
||||
help:
|
||||
@echo "possible targets are 'mapcache' 'csv2yaml' 'yaml2sql' 'all' 'clean' 'help'"
|
||||
@echo "'mapcache' - mapcache generator"
|
||||
@echo "'csv2yaml' - converts TXT databases to YAML"
|
||||
@echo "'yaml2sql' - converts YAML databases to SQL"
|
||||
@echo "'all' - builds all above targets"
|
||||
@echo "'clean' - cleans builds and objects"
|
||||
@echo "'help' - outputs this message"
|
||||
@echo "possible targets are 'mapcache' 'csv2yaml' 'yaml2sql' 'yamlupgrade' 'all' 'clean' 'help'"
|
||||
@echo "'mapcache' - mapcache generator"
|
||||
@echo "'csv2yaml' - converts TXT databases to YAML"
|
||||
@echo "'yaml2sql' - converts YAML databases to SQL"
|
||||
@echo "'yamlupgrade' - upgrades YAML databases to latest version"
|
||||
@echo "'all' - builds all above targets"
|
||||
@echo "'clean' - cleans builds and objects"
|
||||
@echo "'help' - outputs this message"
|
||||
|
||||
#####################################################################
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
384
src/tool/csv2yaml.hpp
Normal file
384
src/tool/csv2yaml.hpp
Normal file
@ -0,0 +1,384 @@
|
||||
// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#ifndef CSV2YAML_HPP
|
||||
#define CSV2YAML_HPP
|
||||
|
||||
#include "yaml.hpp"
|
||||
|
||||
// Required constant and structure definitions
|
||||
#define MAX_GUILD_SKILL_REQUIRE 5
|
||||
#define MAX_SKILL_ITEM_REQUIRE 10
|
||||
#define MAX_SKILL_STATUS_REQUIRE 3
|
||||
#define MAX_SKILL_EQUIP_REQUIRE 10
|
||||
#define MAX_QUEST_DROPS 3
|
||||
#define MAX_MAP_PER_INSTANCE 255
|
||||
|
||||
// Database to memory maps
|
||||
struct s_skill_unit_csv : s_skill_db {
|
||||
std::string target_str;
|
||||
int unit_flag_csv;
|
||||
};
|
||||
|
||||
std::unordered_map<uint16, s_skill_require> skill_require;
|
||||
std::unordered_map<uint16, s_skill_db> skill_cast;
|
||||
std::unordered_map<uint16, s_skill_db> skill_castnodex;
|
||||
std::unordered_map<uint16, s_skill_unit_csv> skill_unit;
|
||||
std::unordered_map<uint16, s_skill_copyable> skill_copyable;
|
||||
std::unordered_map<uint16, s_skill_db> skill_nearnpc;
|
||||
|
||||
static unsigned int level_penalty[3][CLASS_MAX][MAX_LEVEL * 2 + 1];
|
||||
|
||||
struct s_item_flag_csv2yaml {
|
||||
bool buyingstore, dead_branch, group, guid, broadcast, bindOnEquip, delay_consume;
|
||||
e_item_drop_effect dropEffect;
|
||||
};
|
||||
|
||||
struct s_item_delay_csv2yaml {
|
||||
uint32 delay;
|
||||
std::string sc;
|
||||
};
|
||||
|
||||
struct s_item_stack_csv2yaml {
|
||||
uint16 amount;
|
||||
bool inventory, cart, storage, guild_storage;
|
||||
};
|
||||
|
||||
struct s_item_nouse_csv2yaml {
|
||||
uint16 override;
|
||||
bool sitting;
|
||||
};
|
||||
|
||||
struct s_item_trade_csv2yaml {
|
||||
uint16 override;
|
||||
bool drop, trade, trade_partner, sell, cart, storage, guild_storage, mail, auction;
|
||||
};
|
||||
|
||||
std::unordered_map<t_itemid, t_itemid> item_avail;
|
||||
std::unordered_map<t_itemid, bool> item_buyingstore;
|
||||
std::unordered_map<t_itemid, s_item_flag_csv2yaml> item_flag;
|
||||
std::unordered_map<t_itemid, s_item_delay_csv2yaml> item_delay;
|
||||
std::unordered_map<t_itemid, s_item_stack_csv2yaml> item_stack;
|
||||
std::unordered_map<t_itemid, s_item_nouse_csv2yaml> item_nouse;
|
||||
std::unordered_map<t_itemid, s_item_trade_csv2yaml> item_trade;
|
||||
|
||||
struct s_random_opt_group_csv : s_random_opt_group {
|
||||
std::vector<uint16> rate;
|
||||
};
|
||||
|
||||
std::unordered_map<uint16, std::string> rand_opt_db;
|
||||
std::unordered_map<uint16, s_random_opt_group_csv> rand_opt_group;
|
||||
|
||||
static std::map<std::string, int> um_mapid2jobname {
|
||||
{ "Novice", JOB_NOVICE }, // Novice and Super Novice share the same value
|
||||
{ "SuperNovice", JOB_NOVICE },
|
||||
{ "Swordman", JOB_SWORDMAN },
|
||||
{ "Mage", JOB_MAGE },
|
||||
{ "Archer", JOB_ARCHER },
|
||||
{ "Acolyte", JOB_ACOLYTE },
|
||||
{ "Merchant", JOB_MERCHANT },
|
||||
{ "Thief", JOB_THIEF },
|
||||
{ "Knight", JOB_KNIGHT },
|
||||
{ "Priest", JOB_PRIEST },
|
||||
{ "Wizard", JOB_WIZARD },
|
||||
{ "Blacksmith", JOB_BLACKSMITH },
|
||||
{ "Hunter", JOB_HUNTER },
|
||||
{ "Assassin", JOB_ASSASSIN },
|
||||
{ "Crusader", JOB_CRUSADER },
|
||||
{ "Monk", JOB_MONK },
|
||||
{ "Sage", JOB_SAGE },
|
||||
{ "Rogue", JOB_ROGUE },
|
||||
{ "Alchemist", JOB_ALCHEMIST },
|
||||
{ "BardDancer", JOB_BARD }, // Bard and Dancer share the same value
|
||||
{ "BardDancer", JOB_DANCER },
|
||||
{ "Gunslinger", JOB_GUNSLINGER },
|
||||
{ "Ninja", JOB_NINJA },
|
||||
{ "Taekwon", 21 },
|
||||
{ "StarGladiator", 22 },
|
||||
{ "SoulLinker", 23 },
|
||||
// { "Gangsi", 26 },
|
||||
// { "DeathKnight", 27 },
|
||||
// { "DarkCollector", 28 },
|
||||
#ifdef RENEWAL
|
||||
{ "KagerouOboro", 29 }, // Kagerou and Oboro share the same value
|
||||
{ "Rebellion", 30 },
|
||||
{ "Summoner", 31 },
|
||||
#endif
|
||||
};
|
||||
|
||||
static std::unordered_map<std::string, equip_pos> um_equipnames {
|
||||
{ "Head_Low", EQP_HEAD_LOW },
|
||||
{ "Head_Mid", EQP_HEAD_MID },
|
||||
{ "Head_Top", EQP_HEAD_TOP },
|
||||
{ "Right_Hand", EQP_HAND_R },
|
||||
{ "Left_Hand", EQP_HAND_L },
|
||||
{ "Armor", EQP_ARMOR },
|
||||
{ "Shoes", EQP_SHOES },
|
||||
{ "Garment", EQP_GARMENT },
|
||||
{ "Right_Accessory", EQP_ACC_R },
|
||||
{ "Left_Accessory", EQP_ACC_L },
|
||||
{ "Costume_Head_Top", EQP_COSTUME_HEAD_TOP },
|
||||
{ "Costume_Head_Mid", EQP_COSTUME_HEAD_MID },
|
||||
{ "Costume_Head_Low", EQP_COSTUME_HEAD_LOW },
|
||||
{ "Costume_Garment", EQP_COSTUME_GARMENT },
|
||||
{ "Ammo", EQP_AMMO },
|
||||
{ "Shadow_Armor", EQP_SHADOW_ARMOR },
|
||||
{ "Shadow_Weapon", EQP_SHADOW_WEAPON },
|
||||
{ "Shadow_Shield", EQP_SHADOW_SHIELD },
|
||||
{ "Shadow_Shoes", EQP_SHADOW_SHOES },
|
||||
{ "Shadow_Right_Accessory", EQP_SHADOW_ACC_R },
|
||||
{ "Shadow_Left_Accessory", EQP_SHADOW_ACC_L },
|
||||
};
|
||||
|
||||
// Initialize Random Option constants
|
||||
void init_random_option_constants() {
|
||||
#define export_constant2(a, b) script_set_constant_(a, b, a, false, false)
|
||||
|
||||
export_constant2("RDMOPT_VAR_MAXHPAMOUNT", 1);
|
||||
export_constant2("RDMOPT_VAR_MAXSPAMOUNT", 2);
|
||||
export_constant2("RDMOPT_VAR_STRAMOUNT", 3);
|
||||
export_constant2("RDMOPT_VAR_AGIAMOUNT", 4);
|
||||
export_constant2("RDMOPT_VAR_VITAMOUNT", 5);
|
||||
export_constant2("RDMOPT_VAR_INTAMOUNT", 6);
|
||||
export_constant2("RDMOPT_VAR_DEXAMOUNT", 7);
|
||||
export_constant2("RDMOPT_VAR_LUKAMOUNT", 8);
|
||||
export_constant2("RDMOPT_VAR_MAXHPPERCENT", 9);
|
||||
export_constant2("RDMOPT_VAR_MAXSPPERCENT", 10);
|
||||
export_constant2("RDMOPT_VAR_HPACCELERATION", 11);
|
||||
export_constant2("RDMOPT_VAR_SPACCELERATION", 12);
|
||||
export_constant2("RDMOPT_VAR_ATKPERCENT", 13);
|
||||
export_constant2("RDMOPT_VAR_MAGICATKPERCENT", 14);
|
||||
export_constant2("RDMOPT_VAR_PLUSASPD", 15);
|
||||
export_constant2("RDMOPT_VAR_PLUSASPDPERCENT", 16);
|
||||
export_constant2("RDMOPT_VAR_ATTPOWER", 17);
|
||||
export_constant2("RDMOPT_VAR_HITSUCCESSVALUE", 18);
|
||||
export_constant2("RDMOPT_VAR_ATTMPOWER", 19);
|
||||
export_constant2("RDMOPT_VAR_ITEMDEFPOWER", 20);
|
||||
export_constant2("RDMOPT_VAR_MDEFPOWER", 21);
|
||||
export_constant2("RDMOPT_VAR_AVOIDSUCCESSVALUE", 22);
|
||||
export_constant2("RDMOPT_VAR_PLUSAVOIDSUCCESSVALUE", 23);
|
||||
export_constant2("RDMOPT_VAR_CRITICALSUCCESSVALUE", 24);
|
||||
export_constant2("RDMOPT_ATTR_TOLERACE_NOTHING", 25);
|
||||
export_constant2("RDMOPT_ATTR_TOLERACE_WATER", 26);
|
||||
export_constant2("RDMOPT_ATTR_TOLERACE_GROUND", 27);
|
||||
export_constant2("RDMOPT_ATTR_TOLERACE_FIRE", 28);
|
||||
export_constant2("RDMOPT_ATTR_TOLERACE_WIND", 29);
|
||||
export_constant2("RDMOPT_ATTR_TOLERACE_POISON", 30);
|
||||
export_constant2("RDMOPT_ATTR_TOLERACE_SAINT", 31);
|
||||
export_constant2("RDMOPT_ATTR_TOLERACE_DARKNESS", 32);
|
||||
export_constant2("RDMOPT_ATTR_TOLERACE_TELEKINESIS", 33);
|
||||
export_constant2("RDMOPT_ATTR_TOLERACE_UNDEAD", 34);
|
||||
export_constant2("RDMOPT_ATTR_TOLERACE_ALLBUTNOTHING", 35);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_NOTHING_USER", 36);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_NOTHING_TARGET", 37);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_WATER_USER", 38);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_WATER_TARGET", 39);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_GROUND_USER", 40);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_GROUND_TARGET", 41);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_FIRE_USER", 42);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_FIRE_TARGET", 43);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_WIND_USER", 44);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_WIND_TARGET", 45);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_POISON_USER", 46);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_POISON_TARGET", 47);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_SAINT_USER", 48);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_SAINT_TARGET", 49);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_DARKNESS_USER", 50);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_DARKNESS_TARGET", 51);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_TELEKINESIS_USER", 52);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_TELEKINESIS_TARGET", 53);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_UNDEAD_USER", 54);
|
||||
export_constant2("RDMOPT_DAMAGE_PROPERTY_UNDEAD_TARGET", 55);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_NOTHING_USER", 56);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_NOTHING_TARGET", 57);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_WATER_USER", 58);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_WATER_TARGET", 59);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_GROUND_USER", 60);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_GROUND_TARGET", 61);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_FIRE_USER", 62);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_FIRE_TARGET", 63);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_WIND_USER", 64);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_WIND_TARGET", 65);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_POISON_USER", 66);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_POISON_TARGET", 67);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_SAINT_USER", 68);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_SAINT_TARGET", 69);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_DARKNESS_USER", 70);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_DARKNESS_TARGET", 71);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_TELEKINESIS_USER", 72);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_TELEKINESIS_TARGET", 73);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_UNDEAD_USER", 74);
|
||||
export_constant2("RDMOPT_MDAMAGE_PROPERTY_UNDEAD_TARGET", 75);
|
||||
export_constant2("RDMOPT_BODY_ATTR_NOTHING", 76);
|
||||
export_constant2("RDMOPT_BODY_ATTR_WATER", 77);
|
||||
export_constant2("RDMOPT_BODY_ATTR_GROUND", 78);
|
||||
export_constant2("RDMOPT_BODY_ATTR_FIRE", 79);
|
||||
export_constant2("RDMOPT_BODY_ATTR_WIND", 80);
|
||||
export_constant2("RDMOPT_BODY_ATTR_POISON", 81);
|
||||
export_constant2("RDMOPT_BODY_ATTR_SAINT", 82);
|
||||
export_constant2("RDMOPT_BODY_ATTR_DARKNESS", 83);
|
||||
export_constant2("RDMOPT_BODY_ATTR_TELEKINESIS", 84);
|
||||
export_constant2("RDMOPT_BODY_ATTR_UNDEAD", 85);
|
||||
export_constant2("RDMOPT_RACE_TOLERACE_NOTHING", 87);
|
||||
export_constant2("RDMOPT_RACE_TOLERACE_UNDEAD", 88);
|
||||
export_constant2("RDMOPT_RACE_TOLERACE_ANIMAL", 89);
|
||||
export_constant2("RDMOPT_RACE_TOLERACE_PLANT", 90);
|
||||
export_constant2("RDMOPT_RACE_TOLERACE_INSECT", 91);
|
||||
export_constant2("RDMOPT_RACE_TOLERACE_FISHS", 92);
|
||||
export_constant2("RDMOPT_RACE_TOLERACE_DEVIL", 93);
|
||||
export_constant2("RDMOPT_RACE_TOLERACE_HUMAN", 94);
|
||||
export_constant2("RDMOPT_RACE_TOLERACE_ANGEL", 95);
|
||||
export_constant2("RDMOPT_RACE_TOLERACE_DRAGON", 96);
|
||||
export_constant2("RDMOPT_RACE_DAMAGE_NOTHING", 97);
|
||||
export_constant2("RDMOPT_RACE_DAMAGE_UNDEAD", 98);
|
||||
export_constant2("RDMOPT_RACE_DAMAGE_ANIMAL", 99);
|
||||
export_constant2("RDMOPT_RACE_DAMAGE_PLANT", 100);
|
||||
export_constant2("RDMOPT_RACE_DAMAGE_INSECT", 101);
|
||||
export_constant2("RDMOPT_RACE_DAMAGE_FISHS", 102);
|
||||
export_constant2("RDMOPT_RACE_DAMAGE_DEVIL", 103);
|
||||
export_constant2("RDMOPT_RACE_DAMAGE_HUMAN", 104);
|
||||
export_constant2("RDMOPT_RACE_DAMAGE_ANGEL", 105);
|
||||
export_constant2("RDMOPT_RACE_DAMAGE_DRAGON", 106);
|
||||
export_constant2("RDMOPT_RACE_MDAMAGE_NOTHING", 107);
|
||||
export_constant2("RDMOPT_RACE_MDAMAGE_UNDEAD", 108);
|
||||
export_constant2("RDMOPT_RACE_MDAMAGE_ANIMAL", 109);
|
||||
export_constant2("RDMOPT_RACE_MDAMAGE_PLANT", 110);
|
||||
export_constant2("RDMOPT_RACE_MDAMAGE_INSECT", 111);
|
||||
export_constant2("RDMOPT_RACE_MDAMAGE_FISHS", 112);
|
||||
export_constant2("RDMOPT_RACE_MDAMAGE_DEVIL", 113);
|
||||
export_constant2("RDMOPT_RACE_MDAMAGE_HUMAN", 114);
|
||||
export_constant2("RDMOPT_RACE_MDAMAGE_ANGEL", 115);
|
||||
export_constant2("RDMOPT_RACE_MDAMAGE_DRAGON", 116);
|
||||
export_constant2("RDMOPT_RACE_CRI_PERCENT_NOTHING", 117);
|
||||
export_constant2("RDMOPT_RACE_CRI_PERCENT_UNDEAD", 118);
|
||||
export_constant2("RDMOPT_RACE_CRI_PERCENT_ANIMAL", 119);
|
||||
export_constant2("RDMOPT_RACE_CRI_PERCENT_PLANT", 120);
|
||||
export_constant2("RDMOPT_RACE_CRI_PERCENT_INSECT", 121);
|
||||
export_constant2("RDMOPT_RACE_CRI_PERCENT_FISHS", 122);
|
||||
export_constant2("RDMOPT_RACE_CRI_PERCENT_DEVIL", 123);
|
||||
export_constant2("RDMOPT_RACE_CRI_PERCENT_HUMAN", 124);
|
||||
export_constant2("RDMOPT_RACE_CRI_PERCENT_ANGEL", 125);
|
||||
export_constant2("RDMOPT_RACE_CRI_PERCENT_DRAGON", 126);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_DEF_PERCENT_NOTHING", 127);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_DEF_PERCENT_UNDEAD", 128);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_DEF_PERCENT_ANIMAL", 129);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_DEF_PERCENT_PLANT", 130);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_DEF_PERCENT_INSECT", 131);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_DEF_PERCENT_FISHS", 132);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_DEF_PERCENT_DEVIL", 133);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_DEF_PERCENT_HUMAN", 134);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_DEF_PERCENT_ANGEL", 135);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_DEF_PERCENT_DRAGON", 136);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_MDEF_PERCENT_NOTHING", 137);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_MDEF_PERCENT_UNDEAD", 138);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_MDEF_PERCENT_ANIMAL", 139);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_MDEF_PERCENT_PLANT", 140);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_MDEF_PERCENT_INSECT", 141);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_MDEF_PERCENT_FISHS", 142);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_MDEF_PERCENT_DEVIL", 143);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_MDEF_PERCENT_HUMAN", 144);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_MDEF_PERCENT_ANGEL", 145);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_MDEF_PERCENT_DRAGON", 146);
|
||||
export_constant2("RDMOPT_CLASS_DAMAGE_NORMAL_TARGET", 147);
|
||||
export_constant2("RDMOPT_CLASS_DAMAGE_BOSS_TARGET", 148);
|
||||
export_constant2("RDMOPT_CLASS_DAMAGE_NORMAL_USER", 149);
|
||||
export_constant2("RDMOPT_CLASS_DAMAGE_BOSS_USER", 150);
|
||||
export_constant2("RDMOPT_CLASS_MDAMAGE_NORMAL", 151);
|
||||
export_constant2("RDMOPT_CLASS_MDAMAGE_BOSS", 152);
|
||||
export_constant2("RDMOPT_CLASS_IGNORE_DEF_PERCENT_NORMAL", 153);
|
||||
export_constant2("RDMOPT_CLASS_IGNORE_DEF_PERCENT_BOSS", 154);
|
||||
export_constant2("RDMOPT_CLASS_IGNORE_MDEF_PERCENT_NORMAL", 155);
|
||||
export_constant2("RDMOPT_CLASS_IGNORE_MDEF_PERCENT_BOSS", 156);
|
||||
export_constant2("RDMOPT_DAMAGE_SIZE_SMALL_TARGET", 157);
|
||||
export_constant2("RDMOPT_DAMAGE_SIZE_MIDIUM_TARGET", 158);
|
||||
export_constant2("RDMOPT_DAMAGE_SIZE_LARGE_TARGET", 159);
|
||||
export_constant2("RDMOPT_DAMAGE_SIZE_SMALL_USER", 160);
|
||||
export_constant2("RDMOPT_DAMAGE_SIZE_MIDIUM_USER", 161);
|
||||
export_constant2("RDMOPT_DAMAGE_SIZE_LARGE_USER", 162);
|
||||
export_constant2("RDMOPT_DAMAGE_SIZE_PERFECT", 163);
|
||||
export_constant2("RDMOPT_DAMAGE_CRI_TARGET", 164);
|
||||
export_constant2("RDMOPT_DAMAGE_CRI_USER", 165);
|
||||
export_constant2("RDMOPT_RANGE_ATTACK_DAMAGE_TARGET", 166);
|
||||
export_constant2("RDMOPT_RANGE_ATTACK_DAMAGE_USER", 167);
|
||||
export_constant2("RDMOPT_HEAL_VALUE", 168);
|
||||
export_constant2("RDMOPT_HEAL_MODIFY_PERCENT", 169);
|
||||
export_constant2("RDMOPT_DEC_SPELL_CAST_TIME", 170);
|
||||
export_constant2("RDMOPT_DEC_SPELL_DELAY_TIME", 171);
|
||||
export_constant2("RDMOPT_DEC_SP_CONSUMPTION", 172);
|
||||
export_constant2("RDMOPT_WEAPON_ATTR_NOTHING", 175);
|
||||
export_constant2("RDMOPT_WEAPON_ATTR_WATER", 176);
|
||||
export_constant2("RDMOPT_WEAPON_ATTR_GROUND", 177);
|
||||
export_constant2("RDMOPT_WEAPON_ATTR_FIRE", 178);
|
||||
export_constant2("RDMOPT_WEAPON_ATTR_WIND", 179);
|
||||
export_constant2("RDMOPT_WEAPON_ATTR_POISON", 180);
|
||||
export_constant2("RDMOPT_WEAPON_ATTR_SAINT", 181);
|
||||
export_constant2("RDMOPT_WEAPON_ATTR_DARKNESS", 182);
|
||||
export_constant2("RDMOPT_WEAPON_ATTR_TELEKINESIS", 183);
|
||||
export_constant2("RDMOPT_WEAPON_ATTR_UNDEAD", 184);
|
||||
export_constant2("RDMOPT_WEAPON_INDESTRUCTIBLE", 185);
|
||||
export_constant2("RDMOPT_BODY_INDESTRUCTIBLE", 186);
|
||||
export_constant2("RDMOPT_MDAMAGE_SIZE_SMALL_TARGET", 187);
|
||||
export_constant2("RDMOPT_MDAMAGE_SIZE_MIDIUM_TARGET", 188);
|
||||
export_constant2("RDMOPT_MDAMAGE_SIZE_LARGE_TARGET", 189);
|
||||
export_constant2("RDMOPT_MDAMAGE_SIZE_SMALL_USER", 190);
|
||||
export_constant2("RDMOPT_MDAMAGE_SIZE_MIDIUM_USER", 191);
|
||||
export_constant2("RDMOPT_MDAMAGE_SIZE_LARGE_USER", 192);
|
||||
export_constant2("RDMOPT_ATTR_TOLERACE_ALL", 193);
|
||||
export_constant2("RDMOPT_RACE_WEAPON_TOLERACE_NOTHING", 194);
|
||||
export_constant2("RDMOPT_RACE_WEAPON_TOLERACE_UNDEAD", 195);
|
||||
export_constant2("RDMOPT_RACE_WEAPON_TOLERACE_ANIMAL", 196);
|
||||
export_constant2("RDMOPT_RACE_WEAPON_TOLERACE_PLANT", 197);
|
||||
export_constant2("RDMOPT_RACE_WEAPON_TOLERACE_INSECT", 198);
|
||||
export_constant2("RDMOPT_RACE_WEAPON_TOLERACE_FISHS", 199);
|
||||
export_constant2("RDMOPT_RACE_WEAPON_TOLERACE_DEVIL", 200);
|
||||
export_constant2("RDMOPT_RACE_WEAPON_TOLERACE_HUMAN", 201);
|
||||
export_constant2("RDMOPT_RACE_WEAPON_TOLERACE_ANGEL", 202);
|
||||
export_constant2("RDMOPT_RACE_WEAPON_TOLERACE_DRAGON", 203);
|
||||
export_constant2("RDMOPT_RACE_TOLERACE_PLAYER_HUMAN", 206);
|
||||
export_constant2("RDMOPT_RACE_TOLERACE_PLAYER_DORAM", 207);
|
||||
export_constant2("RDMOPT_RACE_DAMAGE_PLAYER_HUMAN", 208);
|
||||
export_constant2("RDMOPT_RACE_DAMAGE_PLAYER_DORAM", 209);
|
||||
export_constant2("RDMOPT_RACE_MDAMAGE_PLAYER_HUMAN", 210);
|
||||
export_constant2("RDMOPT_RACE_MDAMAGE_PLAYER_DORAM", 211);
|
||||
export_constant2("RDMOPT_RACE_CRI_PERCENT_PLAYER_HUMAN", 212);
|
||||
export_constant2("RDMOPT_RACE_CRI_PERCENT_PLAYER_DORAM", 213);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_DEF_PERCENT_PLAYER_HUMAN", 214);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_DEF_PERCENT_PLAYER_DORAM", 215);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_MDEF_PERCENT_PLAYER_HUMAN", 216);
|
||||
export_constant2("RDMOPT_RACE_IGNORE_MDEF_PERCENT_PLAYER_DORAM", 217);
|
||||
export_constant2("RDMOPT_MELEE_ATTACK_DAMAGE_TARGET", 219);
|
||||
export_constant2("RDMOPT_MELEE_ATTACK_DAMAGE_USER", 220);
|
||||
|
||||
#undef export_constant2
|
||||
}
|
||||
|
||||
static bool guild_read_guildskill_tree_db( char* split[], int columns, int current );
|
||||
static bool pet_read_db( const char* file );
|
||||
static bool skill_parse_row_magicmushroomdb(char *split[], int column, int current);
|
||||
static bool skill_parse_row_abradb(char* split[], int columns, int current);
|
||||
static bool skill_parse_row_spellbookdb(char* split[], int columns, int current);
|
||||
static bool mob_readdb_mobavail(char *str[], int columns, int current);
|
||||
static bool skill_parse_row_requiredb(char* split[], int columns, int current);
|
||||
static bool skill_parse_row_castdb(char* split[], int columns, int current);
|
||||
static bool skill_parse_row_castnodexdb(char* split[], int columns, int current);
|
||||
static bool skill_parse_row_unitdb(char* split[], int columns, int current);
|
||||
static bool skill_parse_row_copyabledb(char* split[], int columns, int current);
|
||||
static bool skill_parse_row_nonearnpcrangedb(char* split[], int columns, int current);
|
||||
static bool skill_parse_row_skilldb(char* split[], int columns, int current);
|
||||
static bool quest_read_db(char *split[], int columns, int current);
|
||||
static bool instance_readdb_sub(char* str[], int columns, int current);
|
||||
static bool itemdb_read_itemavail(char *str[], int columns, int current);
|
||||
static bool itemdb_read_buyingstore(char* fields[], int columns, int current);
|
||||
static bool itemdb_read_flag(char* fields[], int columns, int current);
|
||||
static bool itemdb_read_itemdelay(char* str[], int columns, int current);
|
||||
static bool itemdb_read_stack(char* fields[], int columns, int current);
|
||||
static bool itemdb_read_nouse(char* fields[], int columns, int current);
|
||||
static bool itemdb_read_itemtrade(char* fields[], int columns, int current);
|
||||
static bool itemdb_read_db(const char *file);
|
||||
static bool itemdb_read_randomopt(const char* file);
|
||||
static bool itemdb_read_randomopt_group(char *str[], int columns, int current);
|
||||
static bool itemdb_randomopt_group_yaml(void);
|
||||
static bool pc_readdb_levelpenalty(char* fields[], int columns, int current);
|
||||
static bool pc_levelpenalty_yaml();
|
||||
|
||||
#endif /* CSV2YAML_HPP */
|
@ -158,6 +158,10 @@
|
||||
<AdditionalDependencies>ws2_32.lib;$(SolutionDir).vs\build\common-minicore.lib;$(SolutionDir)3rdparty\zlib\lib\$(Platform)\zlib.lib;$(SolutionDir).vs\build\yaml-cpp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="csv2yaml.hpp" />
|
||||
<ClInclude Include="yaml.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\common\database.cpp" />
|
||||
<ClCompile Include="csv2yaml.cpp" />
|
||||
|
@ -10,6 +10,14 @@
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="csv2yaml.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yaml.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="csv2yaml.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
|
657
src/tool/yaml.hpp
Normal file
657
src/tool/yaml.hpp
Normal file
@ -0,0 +1,657 @@
|
||||
// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#ifndef YAML_HPP
|
||||
#define YAML_HPP
|
||||
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <conio.h>
|
||||
#else
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
#include "../common/cbasetypes.hpp"
|
||||
#include "../common/core.hpp"
|
||||
#include "../common/malloc.hpp"
|
||||
#include "../common/mmo.hpp"
|
||||
#include "../common/nullpo.hpp"
|
||||
#include "../common/showmsg.hpp"
|
||||
#include "../common/strlib.hpp"
|
||||
#include "../common/utilities.hpp"
|
||||
#include "../common/utils.hpp"
|
||||
#ifdef WIN32
|
||||
#include "../common/winapi.hpp"
|
||||
#endif
|
||||
|
||||
// Only for constants - do not use functions of it or linking will fail
|
||||
#include "../map/achievement.hpp"
|
||||
#include "../map/battle.hpp"
|
||||
#include "../map/battleground.hpp"
|
||||
#include "../map/channel.hpp"
|
||||
#include "../map/chat.hpp"
|
||||
#include "../map/date.hpp"
|
||||
#include "../map/instance.hpp"
|
||||
#include "../map/mercenary.hpp"
|
||||
#include "../map/mob.hpp"
|
||||
#include "../map/npc.hpp"
|
||||
#include "../map/pc.hpp"
|
||||
#include "../map/pet.hpp"
|
||||
#include "../map/quest.hpp"
|
||||
#include "../map/script.hpp"
|
||||
#include "../map/skill.hpp"
|
||||
#include "../map/storage.hpp"
|
||||
|
||||
using namespace rathena;
|
||||
|
||||
#ifndef WIN32
|
||||
int getch(void) {
|
||||
struct termios oldattr, newattr;
|
||||
int ch;
|
||||
tcgetattr(STDIN_FILENO, &oldattr);
|
||||
newattr = oldattr;
|
||||
newattr.c_lflag &= ~(ICANON | ECHO);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
|
||||
ch = getchar();
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
|
||||
return ch;
|
||||
}
|
||||
#endif
|
||||
|
||||
YAML::Node inNode;
|
||||
YAML::Emitter body;
|
||||
|
||||
// Constants for conversion
|
||||
std::unordered_map<t_itemid, std::string> aegis_itemnames;
|
||||
std::unordered_map<uint32, t_itemid> aegis_itemviewid;
|
||||
std::unordered_map<uint16, std::string> aegis_mobnames;
|
||||
std::unordered_map<uint16, std::string> aegis_skillnames;
|
||||
std::unordered_map<const char *, int64> constants;
|
||||
|
||||
// Implement the function instead of including the original version by linking
|
||||
void script_set_constant_(const char *name, int64 value, const char *constant_name, bool isparameter, bool deprecated) {
|
||||
constants[name] = value;
|
||||
}
|
||||
|
||||
const char *constant_lookup(int32 value, const char *prefix) {
|
||||
nullpo_retr(nullptr, prefix);
|
||||
|
||||
for (auto const &pair : constants) {
|
||||
// Same prefix group and same value
|
||||
if (strncasecmp(pair.first, prefix, strlen(prefix)) == 0 && pair.second == value) {
|
||||
return pair.first;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int64 constant_lookup_int(const char *constant) {
|
||||
nullpo_retr(-100, constant);
|
||||
|
||||
for (auto const &pair : constants) {
|
||||
if (strlen(pair.first) == strlen(constant) && strncasecmp(pair.first, constant, strlen(constant)) == 0) {
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
return -100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a file exists.
|
||||
* @param path: File to check for
|
||||
* @return True if file exists or false otherwise
|
||||
*/
|
||||
bool fileExists(const std::string &path) {
|
||||
std::ifstream in;
|
||||
|
||||
in.open(path);
|
||||
|
||||
if (in.is_open()) {
|
||||
in.close();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt for confirmation.
|
||||
* @param fmt: Message to print
|
||||
* @param va_arg: Any arguments needed for message
|
||||
* @return True on yes or false otherwise
|
||||
*/
|
||||
bool askConfirmation(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
_vShowMessage(MSG_NONE, fmt, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
char c = getch();
|
||||
|
||||
if (c == 'Y' || c == 'y') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a YAML header version
|
||||
* @param node: YAML node
|
||||
* @return Version number
|
||||
*/
|
||||
uint32 getHeaderVersion(YAML::Node &node) {
|
||||
return node["Header"]["Version"].as<uint32>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a file if it exists.
|
||||
* @param file: File stream
|
||||
* @param name: File name
|
||||
* @param newLine: Append new line at end of copy
|
||||
*/
|
||||
void copyFileIfExists(std::ofstream &file, const std::string &name, bool newLine) {
|
||||
std::string path = "doc/yaml/db/" + name + ".yml";
|
||||
|
||||
if (fileExists(path)) {
|
||||
std::ifstream source(path, std::ios::binary);
|
||||
|
||||
std::istreambuf_iterator<char> begin_source(source);
|
||||
std::istreambuf_iterator<char> end_source;
|
||||
std::ostreambuf_iterator<char> begin_dest(file);
|
||||
copy(begin_source, end_source, begin_dest);
|
||||
|
||||
source.close();
|
||||
|
||||
if (newLine) {
|
||||
file << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares header for output.
|
||||
* @param file: File stream
|
||||
* @param type: Database type
|
||||
* @param version: Database version
|
||||
* @param name: File name
|
||||
*/
|
||||
void prepareHeader(std::ofstream &file, const std::string &type, uint32 version, const std::string &name) {
|
||||
copyFileIfExists(file, "license", false);
|
||||
copyFileIfExists(file, name, true);
|
||||
|
||||
YAML::Emitter header(file);
|
||||
|
||||
header << YAML::BeginMap;
|
||||
header << YAML::Key << "Header";
|
||||
header << YAML::BeginMap;
|
||||
header << YAML::Key << "Type" << YAML::Value << type;
|
||||
header << YAML::Key << "Version" << YAML::Value << version;
|
||||
header << YAML::EndMap;
|
||||
header << YAML::EndMap;
|
||||
|
||||
file << "\n";
|
||||
file << "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares footer for output.
|
||||
* @param file: File stream
|
||||
*/
|
||||
void prepareFooter(std::ostream &file) {
|
||||
if (!inNode["Footer"].IsDefined())
|
||||
return;
|
||||
|
||||
if (inNode["Body"].IsDefined()) {
|
||||
file << "\n";
|
||||
file << "\n";
|
||||
}
|
||||
|
||||
YAML::Emitter footer(file);
|
||||
|
||||
footer << YAML::BeginMap;
|
||||
footer << YAML::Key << "Footer";
|
||||
footer << YAML::BeginMap;
|
||||
footer << YAML::Key << "Imports";
|
||||
footer << YAML::BeginSeq;
|
||||
for (const YAML::Node &import : inNode["Footer"]["Imports"]) {
|
||||
footer << YAML::BeginMap;
|
||||
footer << YAML::Key << "Path" << YAML::Value << import["Path"];
|
||||
if (import["Mode"].IsDefined())
|
||||
footer << YAML::Key << "Mode" << YAML::Value << import["Mode"];
|
||||
footer << YAML::EndMap;
|
||||
}
|
||||
footer << YAML::EndSeq;
|
||||
footer << YAML::EndMap;
|
||||
footer << YAML::EndMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares body for output.
|
||||
*/
|
||||
void prepareBody(void) {
|
||||
body << YAML::BeginMap;
|
||||
body << YAML::Key << "Body";
|
||||
body << YAML::BeginSeq;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalizes body's output.
|
||||
*/
|
||||
void finalizeBody(void) {
|
||||
body << YAML::EndSeq;
|
||||
body << YAML::EndMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split the string with ':' as separator and put each value for a skilllv
|
||||
* @param str: String to split
|
||||
* @param val: Array of MAX_SKILL_LEVEL to put value into
|
||||
* @return 0:error, x:number of value assign (should be MAX_SKILL_LEVEL)
|
||||
*/
|
||||
int skill_split_atoi(char *str, int *val) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_SKILL_LEVEL; i++) {
|
||||
if (!str)
|
||||
break;
|
||||
val[i] = atoi(str);
|
||||
str = strchr(str, ':');
|
||||
if (str)
|
||||
*str++ = 0;
|
||||
}
|
||||
|
||||
if (i == 0) // No data found.
|
||||
return 0;
|
||||
|
||||
if (i == 1) // Single value, have the whole range have the same value.
|
||||
return 1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split string to int by constant value (const.txt) or atoi()
|
||||
* @param *str: String input
|
||||
* @param *val: Temporary storage
|
||||
* @param *delim: Delimiter (for multiple value support)
|
||||
* @param min_value: Minimum value. If the splitted value is less or equal than this, will be skipped
|
||||
* @param max: Maximum number that can be allocated
|
||||
* @return count: Number of success
|
||||
*/
|
||||
uint8 skill_split_atoi2(char *str, int64 *val, const char *delim, int min_value, uint16 max) {
|
||||
uint8 i = 0;
|
||||
char *p = strtok(str, delim);
|
||||
|
||||
while (p != NULL) {
|
||||
int64 n = min_value;
|
||||
|
||||
trim(p);
|
||||
|
||||
if (ISDIGIT(p[0])) // If using numeric
|
||||
n = atoi(p);
|
||||
else {
|
||||
n = constant_lookup_int(p);
|
||||
p = strtok(NULL, delim);
|
||||
}
|
||||
|
||||
if (n > min_value) {
|
||||
val[i] = n;
|
||||
i++;
|
||||
if (i >= max)
|
||||
break;
|
||||
}
|
||||
p = strtok(NULL, delim);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split string to int
|
||||
* @param str: String input
|
||||
* @param val1: Temporary storage to first value
|
||||
* @param val2: Temporary storage to second value
|
||||
*/
|
||||
static void itemdb_re_split_atoi(char* str, int* val1, int* val2) {
|
||||
int i, val[2];
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!str)
|
||||
break;
|
||||
val[i] = atoi(str);
|
||||
str = strchr(str, ':');
|
||||
if (str)
|
||||
*str++ = 0;
|
||||
}
|
||||
if (i == 0) {
|
||||
*val1 = *val2 = 0;
|
||||
return; // no data found
|
||||
}
|
||||
if (i == 1) { // Single Value
|
||||
*val1 = val[0];
|
||||
*val2 = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// We assume we have 2 values.
|
||||
*val1 = val[0];
|
||||
*val2 = val[1];
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if array contains level specific data
|
||||
* @param arr: Array to check
|
||||
* @return True if level specific or false for same for all levels
|
||||
*/
|
||||
static bool isMultiLevel(int arr[]) {
|
||||
uint8 count = 0;
|
||||
|
||||
for (uint8 i = 0; i < MAX_SKILL_LEVEL; i++) {
|
||||
if (arr[i] != 0)
|
||||
count++;
|
||||
}
|
||||
|
||||
return (count < 2 ? false : true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to upper case characters based on specific cases.
|
||||
* @param name: String to convert
|
||||
* @return Converted string
|
||||
*/
|
||||
std::string name2Upper(std::string name) {
|
||||
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
|
||||
name[0] = toupper(name[0]);
|
||||
|
||||
for (size_t i = 0; i < name.size(); i++) {
|
||||
if (name[i - 1] == '_' || (name[i - 2] == '1' && name[i - 1] == 'h') || (name[i - 2] == '2' && name[i - 1] == 'h'))
|
||||
name[i] = toupper(name[i]);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
// Constant loading functions
|
||||
static bool parse_item_constants_txt(const char *path) {
|
||||
uint32 lines = 0, count = 0;
|
||||
char line[1024];
|
||||
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(path, "r");
|
||||
if (fp == NULL) {
|
||||
ShowWarning("itemdb_readdb: File not found \"%s\", skipping.\n", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
// process rows one by one
|
||||
while (fgets(line, sizeof(line), fp))
|
||||
{
|
||||
char *str[32], *p;
|
||||
int i;
|
||||
lines++;
|
||||
if (line[0] == '/' && line[1] == '/')
|
||||
continue;
|
||||
memset(str, 0, sizeof(str));
|
||||
|
||||
p = strstr(line, "//");
|
||||
|
||||
if (p != nullptr) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
p = line;
|
||||
while (ISSPACE(*p))
|
||||
++p;
|
||||
if (*p == '\0')
|
||||
continue;// empty line
|
||||
for (i = 0; i < 19; ++i)
|
||||
{
|
||||
str[i] = p;
|
||||
p = strchr(p, ',');
|
||||
if (p == NULL)
|
||||
break;// comma not found
|
||||
*p = '\0';
|
||||
++p;
|
||||
}
|
||||
|
||||
t_itemid item_id = strtoul(str[0], nullptr, 10);
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
ShowError("itemdb_readdb: Insufficient columns in line %d of \"%s\" (item with id %u), skipping.\n", lines, path, item_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Script
|
||||
if (*p != '{')
|
||||
{
|
||||
ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %u), skipping.\n", lines, path, item_id);
|
||||
continue;
|
||||
}
|
||||
str[19] = p + 1;
|
||||
p = strstr(p + 1, "},");
|
||||
if (p == NULL)
|
||||
{
|
||||
ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %u), skipping.\n", lines, path, item_id);
|
||||
continue;
|
||||
}
|
||||
*p = '\0';
|
||||
p += 2;
|
||||
|
||||
// OnEquip_Script
|
||||
if (*p != '{')
|
||||
{
|
||||
ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %u), skipping.\n", lines, path, item_id);
|
||||
continue;
|
||||
}
|
||||
str[20] = p + 1;
|
||||
p = strstr(p + 1, "},");
|
||||
if (p == NULL)
|
||||
{
|
||||
ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %u), skipping.\n", lines, path, item_id);
|
||||
continue;
|
||||
}
|
||||
*p = '\0';
|
||||
p += 2;
|
||||
|
||||
// OnUnequip_Script (last column)
|
||||
if (*p != '{')
|
||||
{
|
||||
ShowError("itemdb_readdb: Invalid format (OnUnequip_Script column) in line %d of \"%s\" (item with id %u), skipping.\n", lines, path, item_id);
|
||||
continue;
|
||||
}
|
||||
str[21] = p;
|
||||
p = &str[21][strlen(str[21]) - 2];
|
||||
|
||||
if (*p != '}') {
|
||||
/* lets count to ensure it's not something silly e.g. a extra space at line ending */
|
||||
int lcurly = 0, rcurly = 0;
|
||||
|
||||
for (size_t v = 0; v < strlen(str[21]); v++) {
|
||||
if (str[21][v] == '{')
|
||||
lcurly++;
|
||||
else if (str[21][v] == '}') {
|
||||
rcurly++;
|
||||
p = &str[21][v];
|
||||
}
|
||||
}
|
||||
|
||||
if (lcurly != rcurly) {
|
||||
ShowError("itemdb_readdb: Mismatching curly braces in line %d of \"%s\" (item with id %u), skipping.\n", lines, path, item_id);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
str[21] = str[21] + 1; //skip the first left curly
|
||||
*p = '\0'; //null the last right curly
|
||||
|
||||
uint32 view_id = strtoul(str[18], nullptr, 10);
|
||||
char *name = trim(str[1]);
|
||||
|
||||
aegis_itemnames[item_id] = std::string(name);
|
||||
|
||||
if (atoi(str[14]) & (EQP_HELM | EQP_COSTUME_HELM) && util::umap_find(aegis_itemviewid, view_id) == nullptr)
|
||||
aegis_itemviewid[view_id] = item_id;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
ShowStatus("Done reading '" CL_WHITE "%u" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string ItemDatabase::getDefaultLocation() {
|
||||
return std::string(db_path) + "/item_db.yml";
|
||||
}
|
||||
|
||||
uint64 ItemDatabase::parseBodyNode(const YAML::Node& node) {
|
||||
t_itemid nameid;
|
||||
|
||||
if (!this->asUInt32(node, "Id", nameid))
|
||||
return 0;
|
||||
|
||||
if (this->nodeExists(node, "AegisName")) {
|
||||
std::string name;
|
||||
|
||||
if (!this->asString(node, "AegisName", name))
|
||||
return 0;
|
||||
|
||||
aegis_itemnames[nameid] = name;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "View")) {
|
||||
uint32 look;
|
||||
|
||||
if (!this->asUInt32(node, "View", look))
|
||||
return 0;
|
||||
|
||||
if (look > 0) {
|
||||
if (this->nodeExists(node, "Locations")) {
|
||||
const YAML::Node& locationNode = node["Locations"];
|
||||
|
||||
static std::vector<std::string> locations = {
|
||||
"Head_Low",
|
||||
"Head_Mid",
|
||||
"Head_Top",
|
||||
"Costume_Head_Low",
|
||||
"Costume_Head_Mid",
|
||||
"Costume_Head_Top"
|
||||
};
|
||||
|
||||
for (std::string& location : locations) {
|
||||
if (this->nodeExists(locationNode, location)) {
|
||||
bool active;
|
||||
|
||||
if (!this->asBool(locationNode, location, active))
|
||||
return 0;
|
||||
|
||||
aegis_itemviewid[look] = nameid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ItemDatabase::loadingFinished() {
|
||||
}
|
||||
|
||||
ItemDatabase item_db;
|
||||
|
||||
static bool parse_mob_constants_txt(char *split[], int columns, int current) {
|
||||
uint16 mob_id = atoi(split[0]);
|
||||
char *name = trim(split[1]);
|
||||
|
||||
aegis_mobnames[mob_id] = std::string(name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_skill_constants_txt(char *split[], int columns, int current) {
|
||||
uint16 skill_id = atoi(split[0]);
|
||||
char *name = trim(split[16]);
|
||||
|
||||
aegis_skillnames[skill_id] = std::string(name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string SkillDatabase::getDefaultLocation() {
|
||||
return std::string(db_path) + "/skill_db.yml";
|
||||
}
|
||||
|
||||
uint64 SkillDatabase::parseBodyNode(const YAML::Node &node) {
|
||||
t_itemid nameid;
|
||||
|
||||
if (!this->asUInt32(node, "Id", nameid))
|
||||
return 0;
|
||||
|
||||
if (this->nodeExists(node, "Name")) {
|
||||
std::string name;
|
||||
|
||||
if (!this->asString(node, "Name", name))
|
||||
return 0;
|
||||
|
||||
aegis_skillnames[nameid] = name;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SkillDatabase::clear() {
|
||||
TypesafeCachedYamlDatabase::clear();
|
||||
}
|
||||
|
||||
SkillDatabase skill_db;
|
||||
|
||||
const std::string MobDatabase::getDefaultLocation(){
|
||||
return std::string( db_path ) + "/mob_db.yml";
|
||||
}
|
||||
|
||||
uint64 MobDatabase::parseBodyNode(const YAML::Node& node) {
|
||||
uint16 mob_id;
|
||||
|
||||
if (!this->asUInt16(node, "Id", mob_id))
|
||||
return 0;
|
||||
|
||||
if (this->nodeExists(node, "AegisName")) {
|
||||
std::string name;
|
||||
|
||||
if (!this->asString(node, "AegisName", name))
|
||||
return 0;
|
||||
|
||||
aegis_mobnames[mob_id] = name;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MobDatabase::loadingFinished() {};
|
||||
|
||||
MobDatabase mob_db;
|
||||
|
||||
#endif /* YAML_HPP */
|
221
src/tool/yamlupgrade.cpp
Normal file
221
src/tool/yamlupgrade.cpp
Normal file
@ -0,0 +1,221 @@
|
||||
// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#include "yamlupgrade.hpp"
|
||||
|
||||
static bool upgrade_achievement_db(std::string file, const uint32 source_version);
|
||||
|
||||
template<typename Func>
|
||||
bool process(const std::string &type, uint32 version, const std::vector<std::string> &paths, const std::string &name, Func lambda) {
|
||||
for (const std::string &path : paths) {
|
||||
const std::string name_ext = name + ".yml";
|
||||
const std::string from = path + "/" + name_ext;
|
||||
const std::string to = path + "/" + name + "-upgrade.yml";
|
||||
|
||||
inNode.reset();
|
||||
|
||||
if (fileExists(from)) {
|
||||
inNode = YAML::LoadFile(from);
|
||||
uint32 source_version = getHeaderVersion(inNode);
|
||||
|
||||
if (source_version >= version) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!askConfirmation("Found the file \"%s\", which requires an upgrade.\nDo you want to convert it now? (Y/N)\n", from.c_str())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fileExists(to)) {
|
||||
if (!askConfirmation("The file \"%s\" already exists.\nDo you want to replace it? (Y/N)\n", to.c_str())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ShowNotice("Upgrade process has begun.\n");
|
||||
|
||||
std::ofstream out;
|
||||
|
||||
body.~Emitter();
|
||||
new (&body) YAML::Emitter();
|
||||
out.open(to);
|
||||
|
||||
if (!out.is_open()) {
|
||||
ShowError("Can not open file \"%s\" for writing.\n", to.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
prepareHeader(out, type, version, name);
|
||||
if (inNode["Body"].IsDefined()) {
|
||||
prepareBody();
|
||||
|
||||
if (!lambda(path, name_ext, source_version)) {
|
||||
out.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
finalizeBody();
|
||||
out << body.c_str();
|
||||
}
|
||||
prepareFooter(out);
|
||||
// Make sure there is an empty line at the end of the file for git
|
||||
out << "\n";
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int do_init(int argc, char** argv) {
|
||||
const std::string path_db = std::string(db_path);
|
||||
const std::string path_db_mode = path_db + "/" + DBPATH;
|
||||
const std::string path_db_import = path_db + "/" + DBIMPORT;
|
||||
|
||||
// Loads required conversion constants
|
||||
if (fileExists(item_db.getDefaultLocation())) {
|
||||
item_db.load();
|
||||
} else {
|
||||
parse_item_constants_txt((path_db_mode + "item_db.txt").c_str());
|
||||
parse_item_constants_txt((path_db_import + "item_db.txt").c_str());
|
||||
}
|
||||
if (fileExists(mob_db.getDefaultLocation())) {
|
||||
mob_db.load();
|
||||
} else {
|
||||
sv_readdb(path_db_mode.c_str(), "mob_db.txt", ',', 31 + 2 * MAX_MVP_DROP + 2 * MAX_MOB_DROP, 31 + 2 * MAX_MVP_DROP + 2 * MAX_MOB_DROP, -1, &parse_mob_constants_txt, false);
|
||||
sv_readdb(path_db_import.c_str(), "mob_db.txt", ',', 31 + 2 * MAX_MVP_DROP + 2 * MAX_MOB_DROP, 31 + 2 * MAX_MVP_DROP + 2 * MAX_MOB_DROP, -1, &parse_mob_constants_txt, false);
|
||||
}
|
||||
if (fileExists(skill_db.getDefaultLocation())) {
|
||||
skill_db.load();
|
||||
} else {
|
||||
sv_readdb(path_db_mode.c_str(), "skill_db.txt", ',', 18, 18, -1, parse_skill_constants_txt, false);
|
||||
sv_readdb(path_db_import.c_str(), "skill_db.txt", ',', 18, 18, -1, parse_skill_constants_txt, false);
|
||||
}
|
||||
|
||||
// Load constants
|
||||
#define export_constant_npc(a) export_constant(a)
|
||||
#include "../map/script_constants.hpp"
|
||||
|
||||
std::vector<std::string> root_paths = {
|
||||
path_db,
|
||||
path_db_mode,
|
||||
path_db_import
|
||||
};
|
||||
|
||||
if (!process("ACHIEVEMENT_DB", 2, root_paths, "achievement_db", [](const std::string &path, const std::string &name_ext, uint32 source_version) -> bool {
|
||||
return upgrade_achievement_db(path + name_ext, source_version);
|
||||
})) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void do_final(void) {
|
||||
}
|
||||
|
||||
// Implementation of the upgrade functions
|
||||
static bool upgrade_achievement_db(std::string file, const uint32 source_version) {
|
||||
size_t entries = 0;
|
||||
|
||||
for (const auto &input : inNode["Body"]) {
|
||||
body << YAML::BeginMap;
|
||||
body << YAML::Key << "Id" << YAML::Value << input["ID"];
|
||||
|
||||
std::string constant = input["Group"].as<std::string>();
|
||||
|
||||
constant.erase(0, 3); // Remove "AG_"
|
||||
if (constant.compare("Chat") == 0) // Chat -> Chatting
|
||||
constant.insert(4, "ting");
|
||||
else if (constant.compare("Hear") == 0 || constant.compare("See") == 0)
|
||||
constant = "Chatting"; // Aegis treats these as general "Talk to NPC" achievements.
|
||||
else if (constant.compare("Refine") == 0) { // Refine -> Enchant
|
||||
constant.erase(0, 6);
|
||||
constant = "Enchant" + constant;
|
||||
}
|
||||
body << YAML::Key << "Group" << YAML::Value << name2Upper(constant);
|
||||
body << YAML::Key << "Name" << YAML::Value << input["Name"];
|
||||
|
||||
if (input["Target"].IsDefined()) {
|
||||
body << YAML::Key << "Targets";
|
||||
body << YAML::BeginSeq;
|
||||
|
||||
for (const auto &it : input["Target"]) {
|
||||
body << YAML::BeginMap;
|
||||
body << YAML::Key << "Id" << YAML::Value << it["Id"];
|
||||
if (it["MobID"].IsDefined()) {
|
||||
uint16 mob_id = it["MobID"].as<uint16>();
|
||||
std::string *mob_name = util::umap_find(aegis_mobnames, mob_id);
|
||||
|
||||
if (mob_name == nullptr) {
|
||||
ShowWarning("mob_avail reading: Invalid mob-class %hu, Mob not read.\n", mob_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
body << YAML::Key << "Mob" << YAML::Value << *mob_name;
|
||||
}
|
||||
if (it["Count"].IsDefined() && it["Count"].as<int32>() > 1)
|
||||
body << YAML::Key << "Count" << YAML::Value << it["Count"];
|
||||
body << YAML::EndMap;
|
||||
}
|
||||
|
||||
body << YAML::EndSeq;
|
||||
}
|
||||
|
||||
if (input["Condition"].IsDefined())
|
||||
body << YAML::Key << "Condition" << YAML::Value << input["Condition"];
|
||||
|
||||
if (input["Map"].IsDefined())
|
||||
body << YAML::Key << "Map" << YAML::Value << input["Map"];
|
||||
|
||||
if (input["Dependent"].IsDefined()) {
|
||||
body << YAML::Key << "Dependents";
|
||||
body << YAML::BeginMap;
|
||||
|
||||
for (const auto &it : input["Dependent"]) {
|
||||
body << YAML::Key << it["Id"] << YAML::Value << true;
|
||||
}
|
||||
|
||||
body << YAML::EndMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Example usage for adding label at specific version.
|
||||
if (source_version < ?) {
|
||||
body << YAML::Key << "CustomLabel" << YAML::Value << "Unique";
|
||||
}
|
||||
*/
|
||||
|
||||
if (input["Reward"].IsDefined()) {
|
||||
body << YAML::Key << "Rewards";
|
||||
body << YAML::BeginMap;
|
||||
if (input["Reward"]["ItemID"].IsDefined()) {
|
||||
t_itemid item_id = input["Reward"]["ItemID"].as<t_itemid>();
|
||||
std::string *item_name = util::umap_find(aegis_itemnames, item_id);
|
||||
|
||||
if (item_name == nullptr) {
|
||||
ShowError("Reward item name for item ID %u is not known.\n", item_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
body << YAML::Key << "Item" << YAML::Value << *item_name;
|
||||
}
|
||||
if (input["Reward"]["Amount"].IsDefined() && input["Reward"]["Amount"].as<uint16>() > 1)
|
||||
body << YAML::Key << "Amount" << YAML::Value << input["Reward"]["Amount"];
|
||||
if (input["Reward"]["Script"].IsDefined())
|
||||
body << YAML::Key << "Script" << YAML::Value << input["Reward"]["Script"];
|
||||
if (input["Reward"]["TitleID"].IsDefined())
|
||||
body << YAML::Key << "TitleId" << YAML::Value << input["Reward"]["TitleID"];
|
||||
body << YAML::EndMap;
|
||||
}
|
||||
|
||||
body << YAML::Key << "Score" << YAML::Value << input["Score"];
|
||||
|
||||
body << YAML::EndMap;
|
||||
entries++;
|
||||
}
|
||||
|
||||
ShowStatus("Done converting/upgrading '" CL_WHITE "%d" CL_RESET "' achievements in '" CL_WHITE "%s" CL_RESET "'.\n", entries, file.c_str());
|
||||
|
||||
return true;
|
||||
}
|
9
src/tool/yamlupgrade.hpp
Normal file
9
src/tool/yamlupgrade.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#ifndef YAMLUPGRADE_HPP
|
||||
#define YAMLUPGRADE_HPP
|
||||
|
||||
#include "yaml.hpp"
|
||||
|
||||
#endif /* YAMLUPGRADE_HPP */
|
185
src/tool/yamlupgrade.vcxproj
Normal file
185
src/tool/yamlupgrade.vcxproj
Normal file
@ -0,0 +1,185 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{9115C6D1-520A-4540-B4FE-95F3C923FE2C}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>yamlupgrade</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)</OutDir>
|
||||
<IntDir>$(SolutionDir).vs\build\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)</OutDir>
|
||||
<IntDir>$(SolutionDir).vs\build\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)</OutDir>
|
||||
<IntDir>$(SolutionDir).vs\build\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)</OutDir>
|
||||
<IntDir>$(SolutionDir).vs\build\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\yaml-cpp\include\</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;$(SolutionDir).vs\build\common-minicore.lib;$(SolutionDir)3rdparty\zlib\lib\$(Platform)\zlib.lib;$(SolutionDir).vs\build\yaml-cpp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\yaml-cpp\include\</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;$(SolutionDir).vs\build\common-minicore.lib;$(SolutionDir)3rdparty\zlib\lib\$(Platform)\zlib.lib;$(SolutionDir).vs\build\yaml-cpp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\yaml-cpp\include\</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>ws2_32.lib;$(SolutionDir).vs\build\common-minicore.lib;$(SolutionDir)3rdparty\zlib\lib\$(Platform)\zlib.lib;$(SolutionDir).vs\build\yaml-cpp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\yaml-cpp\include\</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>ws2_32.lib;$(SolutionDir).vs\build\common-minicore.lib;$(SolutionDir)3rdparty\zlib\lib\$(Platform)\zlib.lib;$(SolutionDir).vs\build\yaml-cpp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="yaml.hpp" />
|
||||
<ClInclude Include="yamlupgrade.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\common\database.cpp" />
|
||||
<ClCompile Include="yamlupgrade.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\common\database.hpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<Target Name="AfterClean">
|
||||
<Delete Files="$(SolutionDir)zlib.dll" ContinueOnError="true" />
|
||||
<Delete Files="$(SolutionDir)serv.bat" ContinueOnError="true" />
|
||||
<Delete Files="$(SolutionDir)yamlupgrade.bat" ContinueOnError="true" />
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
<Copy SourceFiles="$(SolutionDir)3rdparty\zlib\lib\$(Platform)\zlib.dll" DestinationFolder="$(SolutionDir)" ContinueOnError="true" Condition="!Exists('$(SolutionDir)zlib.dll')" />
|
||||
<Copy SourceFiles="$(SolutionDir)tools\serv.bat" DestinationFolder="$(SolutionDir)" ContinueOnError="true" Condition="!Exists('$(SolutionDir)serv.bat')" />
|
||||
<Copy SourceFiles="$(SolutionDir)tools\yamlupgrade.bat" DestinationFolder="$(SolutionDir)" ContinueOnError="true" Condition="!Exists('$(SolutionDir)yamlupgrade.bat')" />
|
||||
</Target>
|
||||
</Project>
|
34
src/tool/yamlupgrade.vcxproj.filters
Normal file
34
src/tool/yamlupgrade.vcxproj.filters
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{de48fb82-cea1-4318-bd96-9aab02b5b59d}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{82d5c708-a60f-4ae1-8b0d-0aafaa8da273}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="yaml.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yamlupgrade.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="yamlupgrade.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\common\database.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\common\database.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
2
tools/yamlupgrade.bat
Normal file
2
tools/yamlupgrade.bat
Normal file
@ -0,0 +1,2 @@
|
||||
@ECHO OFF
|
||||
CALL serv.bat yamlupgrade.exe YAML UPGRADE
|
Loading…
x
Reference in New Issue
Block a user