Browse Source

Converted txt guild experience database to yaml (#5995)

* Converts the Skill Tree Tables file into YAML.
* Includes CSV2YAML converter.

Co-authored-by: Aleos <aleos89@users.noreply.github.com>
Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
Atemo 3 years ago
parent
commit
7ade6d8c86

+ 39 - 0
db/exp_guild.yml

@@ -0,0 +1,39 @@
+# This file is a part of rAthena.
+#   Copyright(C) 2021 rAthena Development Team
+#   https://rathena.org - https://github.com/rathena
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+###########################################################################
+# Guild Experience Database
+###########################################################################
+#
+# Guild Experience Settings
+#
+###########################################################################
+# - Level                Level required.
+#   Exp                  Experience required to level up.
+###########################################################################
+
+Header:
+  Type: GUILD_EXP_DB
+  Version: 1
+
+Footer:
+  Imports:
+  - Path: db/pre-re/exp_guild.yml
+    Mode: Prerenewal
+  - Path: db/re/exp_guild.yml
+    Mode: Renewal
+  - Path: db/import/exp_guild.yml

+ 0 - 2
db/import-tmpl/exp_guild.txt

@@ -1,2 +0,0 @@
-// Guild Experience Tables
-

+ 31 - 0
db/import-tmpl/exp_guild.yml

@@ -0,0 +1,31 @@
+# This file is a part of rAthena.
+#   Copyright(C) 2021 rAthena Development Team
+#   https://rathena.org - https://github.com/rathena
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+###########################################################################
+# Guild Experience Database
+###########################################################################
+#
+# Guild Experience Settings
+#
+###########################################################################
+# - Level                Level required.
+#   Exp                  Experience required to level up.
+###########################################################################
+
+Header:
+  Type: GUILD_EXP_DB
+  Version: 1

+ 0 - 50
db/pre-re/exp_guild.txt

@@ -1,50 +0,0 @@
-// Guild Experience Tables
-2000000
-4000000
-8000000
-14000000
-22000000
-32000000
-44000000
-58000000
-74000000
-92000000
-112000000
-134000000
-158000000
-184000000
-212000000
-242000000
-274000000
-308000000
-344000000
-382000000
-422000000
-464000000
-508000000
-554000000
-602000000
-652000000
-704000000
-758000000
-814000000
-872000000
-932000000
-994000000
-1058000000
-1124000000
-1192000000
-1262000000
-1334000000
-1408000000
-1484000000
-1562000000
-1642000000
-1724000000
-1808000000
-1894000000
-1999999999
-1999999999
-1999999999
-1999999999
-1999999999

+ 131 - 0
db/pre-re/exp_guild.yml

@@ -0,0 +1,131 @@
+# This file is a part of rAthena.
+#   Copyright(C) 2021 rAthena Development Team
+#   https://rathena.org - https://github.com/rathena
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+###########################################################################
+# Guild Experience Database
+###########################################################################
+#
+# Guild Experience Settings
+#
+###########################################################################
+# - Level                Level required.
+#   Exp                  Experience required to level up.
+###########################################################################
+
+Header:
+  Type: GUILD_EXP_DB
+  Version: 1
+
+Body:
+  - Level: 1
+    Exp: 2000000
+  - Level: 2
+    Exp: 4000000
+  - Level: 3
+    Exp: 8000000
+  - Level: 4
+    Exp: 14000000
+  - Level: 5
+    Exp: 22000000
+  - Level: 6
+    Exp: 32000000
+  - Level: 7
+    Exp: 44000000
+  - Level: 8
+    Exp: 58000000
+  - Level: 9
+    Exp: 74000000
+  - Level: 10
+    Exp: 92000000
+  - Level: 11
+    Exp: 112000000
+  - Level: 12
+    Exp: 134000000
+  - Level: 13
+    Exp: 158000000
+  - Level: 14
+    Exp: 184000000
+  - Level: 15
+    Exp: 212000000
+  - Level: 16
+    Exp: 242000000
+  - Level: 17
+    Exp: 274000000
+  - Level: 18
+    Exp: 308000000
+  - Level: 19
+    Exp: 344000000
+  - Level: 20
+    Exp: 382000000
+  - Level: 21
+    Exp: 422000000
+  - Level: 22
+    Exp: 464000000
+  - Level: 23
+    Exp: 508000000
+  - Level: 24
+    Exp: 554000000
+  - Level: 25
+    Exp: 602000000
+  - Level: 26
+    Exp: 652000000
+  - Level: 27
+    Exp: 704000000
+  - Level: 28
+    Exp: 758000000
+  - Level: 29
+    Exp: 814000000
+  - Level: 30
+    Exp: 872000000
+  - Level: 31
+    Exp: 932000000
+  - Level: 32
+    Exp: 994000000
+  - Level: 33
+    Exp: 1058000000
+  - Level: 34
+    Exp: 1124000000
+  - Level: 35
+    Exp: 1192000000
+  - Level: 36
+    Exp: 1262000000
+  - Level: 37
+    Exp: 1334000000
+  - Level: 38
+    Exp: 1408000000
+  - Level: 39
+    Exp: 1484000000
+  - Level: 40
+    Exp: 1562000000
+  - Level: 41
+    Exp: 1642000000
+  - Level: 42
+    Exp: 1724000000
+  - Level: 43
+    Exp: 1808000000
+  - Level: 44
+    Exp: 1894000000
+  - Level: 45
+    Exp: 1999999999
+  - Level: 46
+    Exp: 1999999999
+  - Level: 47
+    Exp: 1999999999
+  - Level: 48
+    Exp: 1999999999
+  - Level: 49
+    Exp: 1999999999

+ 0 - 52
db/re/exp_guild.txt

@@ -1,52 +0,0 @@
-// Guild Experience Tables
-100000
-400000
-900000
-1600000
-2500000
-3600000
-4900000
-6400000
-8100000
-10000000
-12100000
-14400000
-16900000
-19600000
-22500000
-25600000
-28900000
-32400000
-36100000
-40000000
-44100000
-48400000
-52900000
-57600000
-62500000
-67600000
-72900000
-78400000
-84100000
-90000000
-96100000
-102400000
-108900000
-115600000
-122500000
-129600000
-136900000
-144400000
-152100000
-160000000
-168100000
-176400000
-184900000
-193600000
-202500000
-211600000
-220900000
-230400000
-240100000
-250000000
-

+ 133 - 0
db/re/exp_guild.yml

@@ -0,0 +1,133 @@
+# This file is a part of rAthena.
+#   Copyright(C) 2021 rAthena Development Team
+#   https://rathena.org - https://github.com/rathena
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+###########################################################################
+# Guild Experience Database
+###########################################################################
+#
+# Guild Experience Settings
+#
+###########################################################################
+# - Level                Level required.
+#   Exp                  Experience required to level up.
+###########################################################################
+
+Header:
+  Type: GUILD_EXP_DB
+  Version: 1
+
+Body:
+  - Level: 1
+    Exp: 100000
+  - Level: 2
+    Exp: 400000
+  - Level: 3
+    Exp: 900000
+  - Level: 4
+    Exp: 1600000
+  - Level: 5
+    Exp: 2500000
+  - Level: 6
+    Exp: 3600000
+  - Level: 7
+    Exp: 4900000
+  - Level: 8
+    Exp: 6400000
+  - Level: 9
+    Exp: 8100000
+  - Level: 10
+    Exp: 10000000
+  - Level: 11
+    Exp: 12100000
+  - Level: 12
+    Exp: 14400000
+  - Level: 13
+    Exp: 16900000
+  - Level: 14
+    Exp: 19600000
+  - Level: 15
+    Exp: 22500000
+  - Level: 16
+    Exp: 25600000
+  - Level: 17
+    Exp: 28900000
+  - Level: 18
+    Exp: 32400000
+  - Level: 19
+    Exp: 36100000
+  - Level: 20
+    Exp: 40000000
+  - Level: 21
+    Exp: 44100000
+  - Level: 22
+    Exp: 48400000
+  - Level: 23
+    Exp: 52900000
+  - Level: 24
+    Exp: 57600000
+  - Level: 25
+    Exp: 62500000
+  - Level: 26
+    Exp: 67600000
+  - Level: 27
+    Exp: 72900000
+  - Level: 28
+    Exp: 78400000
+  - Level: 29
+    Exp: 84100000
+  - Level: 30
+    Exp: 90000000
+  - Level: 31
+    Exp: 96100000
+  - Level: 32
+    Exp: 102400000
+  - Level: 33
+    Exp: 108900000
+  - Level: 34
+    Exp: 115600000
+  - Level: 35
+    Exp: 122500000
+  - Level: 36
+    Exp: 129600000
+  - Level: 37
+    Exp: 136900000
+  - Level: 38
+    Exp: 144400000
+  - Level: 39
+    Exp: 152100000
+  - Level: 40
+    Exp: 160000000
+  - Level: 41
+    Exp: 168100000
+  - Level: 42
+    Exp: 176400000
+  - Level: 43
+    Exp: 184900000
+  - Level: 44
+    Exp: 193600000
+  - Level: 45
+    Exp: 202500000
+  - Level: 46
+    Exp: 211600000
+  - Level: 47
+    Exp: 220900000
+  - Level: 48
+    Exp: 230400000
+  - Level: 49
+    Exp: 240100000
+  # - Level: 50
+    # Exp: 250000000

+ 10 - 0
doc/yaml/db/exp_guild.yml

@@ -0,0 +1,10 @@
+###########################################################################
+# Guild Experience Database
+###########################################################################
+#
+# Guild Experience Settings
+#
+###########################################################################
+# - Level                Level required.
+#   Exp                  Experience required to level up.
+###########################################################################

+ 69 - 43
src/char/int_guild.cpp

@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #define __STDC_WANT_LIB_EXT1__ 1
 #include <string.h>
+#include <yaml-cpp/yaml.h>
 
 #include "../common/cbasetypes.hpp"
 #include "../common/malloc.hpp"
@@ -38,8 +39,6 @@ static const char dataToHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9
 static DBMap* guild_db_; // int guild_id -> struct guild*
 static DBMap *castle_db;
 
-static t_exp guild_exp[MAX_GUILDLEVEL];
-
 int mapif_parse_GuildLeave(int fd,int guild_id,uint32 account_id,uint32 char_id,int flag,const char *mes);
 int mapif_guild_broken(int guild_id,int flag);
 bool guild_check_empty(struct guild *g);
@@ -637,21 +636,6 @@ struct guild_castle* inter_guildcastle_fromsql(int castle_id)
 }
 
 
-// Read exp_guild.txt
-bool exp_guild_parse_row(char* split[], int column, int current)
-{
-	t_exp exp = strtoull(split[0], nullptr, 10);
-
-	if (exp > MAX_GUILD_EXP) {
-		ShowError("exp_guild: Invalid exp %" PRIu64 " at line %d, exceeds max of %" PRIu64 "\n", exp, current, MAX_GUILD_EXP);
-		return false;
-	}
-
-	guild_exp[current] = exp;
-	return true;
-}
-
-
 int inter_guild_CharOnline(uint32 char_id, int guild_id)
 {
 	struct guild *g;
@@ -757,23 +741,73 @@ int inter_guild_CharOffline(uint32 char_id, int guild_id)
 	return 1;
 }
 
-// Initialize guild sql
-int inter_guild_sql_init(void)
-{
-	const char *filename[]={ DBPATH"exp_guild.txt", DBIMPORT"/exp_guild.txt"};
-	int i;
+const std::string GuildExpDatabase::getDefaultLocation() {
+	return std::string(db_path) + "/exp_guild.yml";
+}
+
+uint64 GuildExpDatabase::parseBodyNode(const YAML::Node &node) {
+	if (!this->nodesExist(node, { "Level", "Exp" })) {
+		return 0;
+	}
+
+	uint16 level;
+
+	if (!this->asUInt16(node, "Level", level))
+		return 0;
+
+	if (level == 0) {
+		this->invalidWarning(node, "The minimum guild level is 1.\n");
+		return 0;
+	}
+	if (level >= MAX_GUILDLEVEL) {
+		this->invalidWarning(node["Level"], "Guild level %d exceeds maximum level %d, skipping.\n", level, MAX_GUILDLEVEL);
+		return 0;
+	}
+
+	t_exp exp;
+
+	if (!this->asUInt64(node, "Exp", exp))
+		return 0;
+
+	if (exp > MAX_GUILD_EXP) {
+		this->invalidWarning(node["Exp"], "Guild exp %" PRIu64 " exceeds max of %" PRIu64 ".\n", exp, MAX_GUILD_EXP);
+		return 0;
+	}
+
+	std::shared_ptr<s_guild_exp_db> guild_exp = this->find(level);
+	bool exists = guild_exp != nullptr;
+
+	if (!exists) {
+		guild_exp = std::make_shared<s_guild_exp_db>();
+		guild_exp->level = level;
+	}
+
+	guild_exp->exp = static_cast<t_exp>(exp);
+
+	if (!exists)
+		this->put(level, guild_exp);
+
+	return 1;
+}
+
+GuildExpDatabase guild_exp_db;
+
+void GuildExpDatabase::loadingFinished() {
+	for (uint16 level = 1; level < MAX_GUILDLEVEL; level++) {
+		if (this->get_nextexp(level) == 0)
+			ShowError("Missing experience for guild level %d.\n", level);
+	}
+}
+
+// Initialize guild sql and read exp_guild.yml
+void inter_guild_sql_init(void) {
 	//Initialize the guild cache
 	guild_db_= idb_alloc(DB_OPT_RELEASE_DATA);
 	castle_db = idb_alloc(DB_OPT_RELEASE_DATA);
 
-	//Read exp file
-	for(i = 0; i<ARRAYLENGTH(filename); i++){
-		sv_readdb(db_path, filename[i], ',', 1, 1, MAX_GUILDLEVEL, exp_guild_parse_row, i > 0);
-	}
-
+	guild_exp_db.load();
 	add_timer_func_list(guild_save_timer, "guild_save_timer");
 	add_timer(gettick() + 10000, guild_save_timer, 0, 0);
-	return 0;
 }
 
 /**
@@ -835,14 +869,10 @@ bool guild_check_empty(struct guild *g)
 	return i < g->max_member ? false : true; // not empty
 }
 
-t_exp guild_nextexp(int level)
-{
-	if (level == 0)
-		return 1;
-	if (level < 0 || level > MAX_GUILDLEVEL)
-		return 0;
+t_exp GuildExpDatabase::get_nextexp(uint16 level) {
+	std::shared_ptr<s_guild_exp_db> guild_exp = guild_exp_db.find(level);
 
-	return guild_exp[level-1];
+	return ((guild_exp == nullptr) ? 0 : guild_exp->exp);
 }
 
 int guild_checkskill(struct guild *g,int id)
@@ -854,24 +884,20 @@ int guild_checkskill(struct guild *g,int id)
 int guild_calcinfo(struct guild *g)
 {
 	int i,c;
-	t_exp nextexp;
 	struct guild before = *g; // Save guild current values
 
 	if(g->guild_lv<=0)
 		g->guild_lv = 1;
-	nextexp = guild_nextexp(g->guild_lv);
+	g->next_exp = guild_exp_db.get_nextexp(g->guild_lv);
 
 	// Consume guild exp and increase guild level
-	while(g->exp >= nextexp && nextexp > 0){	//fixed guild exp overflow [Kevin]
-		g->exp-=nextexp;
+	while(g->exp >= g->next_exp && g->next_exp > 0 && g->guild_lv < MAX_GUILDLEVEL){
+		g->exp-=g->next_exp;
 		g->guild_lv++;
 		g->skill_point++;
-		nextexp = guild_nextexp(g->guild_lv);
+		g->next_exp = guild_exp_db.get_nextexp(g->guild_lv);
 	}
 
-	// Save next exp step
-	g->next_exp = nextexp;
-
 	// Set the max number of members, Guild Extention skill - currently adds 6 to max per skill lv.
 	g->max_member = 16 + guild_checkskill(g, GD_EXTENSION) * 6;
 	if(g->max_member > MAX_GUILD)

+ 20 - 1
src/char/int_guild.hpp

@@ -4,7 +4,9 @@
 #ifndef INT_GUILD_HPP
 #define INT_GUILD_HPP
 
+#include <string>
 #include "../common/cbasetypes.hpp"
+#include "../common/database.hpp"
 
 enum e_guild_action : uint32 {
 	GS_BASIC = 0x0001,
@@ -25,8 +27,25 @@ enum e_guild_action : uint32 {
 struct guild;
 struct guild_castle;
 
+struct s_guild_exp_db {
+	uint16 level;
+	t_exp exp;
+};
+
+class GuildExpDatabase : public TypesafeYamlDatabase<uint16, s_guild_exp_db> {
+public:
+	GuildExpDatabase() : TypesafeYamlDatabase("GUILD_EXP_DB", 1) {
+
+	}
+
+	const std::string getDefaultLocation();
+	uint64 parseBodyNode(const YAML::Node& node);
+	t_exp get_nextexp(uint16 level);
+	void loadingFinished();
+};
+
 int inter_guild_parse_frommap(int fd);
-int inter_guild_sql_init(void);
+void inter_guild_sql_init(void);
 void inter_guild_sql_final(void);
 int inter_guild_leave(int guild_id,uint32 account_id,uint32 char_id);
 int mapif_parse_BreakGuild(int fd,int guild_id);

+ 1 - 0
src/map/map-server.vcxproj

@@ -307,6 +307,7 @@
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\elemental_skill_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\elemental_skill_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\exp_guild.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\exp_guild.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\exp_homun.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\exp_homun.yml')" />
+    <Copy SourceFiles="$(SolutionDir)db\import-tmpl\exp_guild.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\exp_guild.yml')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\guild_skill_tree.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\guild_skill_tree.yml')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\homun_skill_tree.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\homun_skill_tree.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\homunculus_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\homunculus_db.txt')" />

+ 29 - 0
src/tool/csv2yaml.cpp

@@ -360,6 +360,18 @@ int do_init( int argc, char** argv ){
 		return 0;
 	}
 
+	if (!process("GUILD_EXP_DB", 1, { path_db_mode }, "exp_guild", [](const std::string &path, const std::string &name_ext) -> bool {
+		return sv_readdb(path.c_str(), name_ext.c_str(), ',', 1, 1, MAX_GUILDLEVEL, &exp_guild_parse_row, false);
+	})) {
+		return 0;
+	}
+
+	if (!process("GUILD_EXP_DB", 1, { path_db_import }, "exp_guild", [](const std::string &path, const std::string &name_ext) -> bool {
+		return sv_readdb(path.c_str(), name_ext.c_str(), ',', 1, 1, MAX_GUILDLEVEL, &exp_guild_parse_row, false);
+	})) {
+		return 0;
+	}
+
 	// TODO: add implementations ;-)
 
 	return 0;
@@ -3726,3 +3738,20 @@ static bool guild_read_castledb(char* str[], int columns, int current) {
 	body << YAML::EndMap;
 	return true;
 }
+
+// Copied and adjusted from int_guild.cpp
+static bool exp_guild_parse_row(char* split[], int column, int current) {
+	t_exp exp = strtoull(split[0], nullptr, 10);
+
+	if (exp > MAX_GUILD_EXP) {
+		ShowError("exp_guild: Invalid exp %" PRIu64 " at line %d, exceeds max of %" PRIu64 "\n", exp, current, MAX_GUILD_EXP);
+		return false;
+	}
+
+	body << YAML::BeginMap;
+	body << YAML::Key << "Level" << YAML::Value << (current+1);
+	body << YAML::Key << "Exp" << YAML::Value << exp;
+	body << YAML::EndMap;
+
+	return true;
+}

+ 1 - 0
src/tool/csv2yaml.hpp

@@ -425,5 +425,6 @@ static bool mob_readdb_group_yaml(void);
 static bool skill_parse_row_createarrowdb(char* fields[], int columns, int current);
 static bool pc_read_statsdb(const char* file);
 static bool guild_read_castledb(char* str[], int columns, int current);
+static bool exp_guild_parse_row(char* split[], int column, int current);
 
 #endif /* CSV2YAML_HPP */