From a54bb653de6444ebb98c48e21d81e7f7e20f5a94 Mon Sep 17 00:00:00 2001 From: aleos89 Date: Fri, 8 Jan 2016 12:27:10 -0500 Subject: [PATCH 1/4] Randomized Start Point * Fixes #805 --- conf/char_athena.conf | 8 ++++--- src/char/char.c | 50 +++++++++++++++++++++++++++++-------------- src/char/char.h | 5 ++++- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/conf/char_athena.conf b/conf/char_athena.conf index 5d8c12ec46..6e40aa9496 100644 --- a/conf/char_athena.conf +++ b/conf/char_athena.conf @@ -108,9 +108,11 @@ autosave_time: 60 save_log: yes // Starting point for new characters -// Format: ,, -start_point: iz_int,97,90 -start_point_pre: new_1-1,53,111 +// Format: ,,{:,,...} +// Max number of start points is MAX_STARTPOINT in char.h (default 5) +// Location is randomly picked on character creation. +start_point: iz_int,97,90,iz_int01,97,90,iz_int02,97,90,iz_int03,97,90,iz_int04,97,90 +start_point_pre: new_1-1,53,111,new_2-1,53,111,new_3-1,53,111,new_4-1,53,111,new_5-1,53,111 // Starting items for new characters // Max number of items is MAX_STARTITEM in char.c (default 32) diff --git a/src/char/char.c b/src/char/char.c index 3950732514..3188a34f88 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -1421,7 +1421,7 @@ int char_make_new_char_sql(struct char_session_data* sd, char* name_, int str, i char name[NAME_LENGTH]; char esc_name[NAME_LENGTH*2+1]; uint32 char_id; - int flag, k; + int flag, k, start_point_idx = rand() % charserv_config.start_point_count; safestrncpy(name, name_, NAME_LENGTH); normalize_name(name,TRIM_CHARS); @@ -1473,7 +1473,7 @@ int char_make_new_char_sql(struct char_session_data* sd, char* name_, int str, i "'%d', '%d', '%s', '%d', '%d','%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d')", schema_config.char_db, sd->account_id , slot, esc_name, charserv_config.start_zeny, 48, str, agi, vit, int_, dex, luk, (40 * (100 + vit)/100) , (40 * (100 + vit)/100 ), (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color, - mapindex_id2name(charserv_config.start_point.map), charserv_config.start_point.x, charserv_config.start_point.y, mapindex_id2name(charserv_config.start_point.map), charserv_config.start_point.x, charserv_config.start_point.y) ) + mapindex_id2name(charserv_config.start_point[start_point_idx].map), charserv_config.start_point[start_point_idx].x, charserv_config.start_point[start_point_idx].y, mapindex_id2name(charserv_config.start_point[start_point_idx].map), charserv_config.start_point[start_point_idx].x, charserv_config.start_point[start_point_idx].y) ) { Sql_ShowDebug(sql_handle); return -2; //No, stop the procedure! @@ -1485,7 +1485,7 @@ int char_make_new_char_sql(struct char_session_data* sd, char* name_, int str, i "'%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d')", schema_config.char_db, sd->account_id , slot, esc_name, charserv_config.start_zeny, str, agi, vit, int_, dex, luk, (40 * (100 + vit)/100) , (40 * (100 + vit)/100 ), (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color, - mapindex_id2name(charserv_config.start_point.map), charserv_config.start_point.x, charserv_config.start_point.y, mapindex_id2name(charserv_config.start_point.map), charserv_config.start_point.x, charserv_config.start_point.y) ) + mapindex_id2name(charserv_config.start_point[start_point_idx].map), charserv_config.start_point[start_point_idx].x, charserv_config.start_point[start_point_idx].y, mapindex_id2name(charserv_config.start_point[start_point_idx].map), charserv_config.start_point[start_point_idx].x, charserv_config.start_point[start_point_idx].y) ) { Sql_ShowDebug(sql_handle); return -2; //No, stop the procedure! @@ -2635,9 +2635,10 @@ void char_set_defaults(){ charserv_config.char_check_db =1; //see const.h to change those default - charserv_config.start_point.map = mapindex_name2id(MAP_DEFAULT_NAME); - charserv_config.start_point.x = MAP_DEFAULT_X; - charserv_config.start_point.y = MAP_DEFAULT_Y; + charserv_config.start_point[0].map = mapindex_name2id(MAP_DEFAULT_NAME); + charserv_config.start_point[0].x = MAP_DEFAULT_X; + charserv_config.start_point[0].y = MAP_DEFAULT_Y; + charserv_config.start_point_count = 0; charserv_config.console = 0; charserv_config.max_connect_user = -1; @@ -2747,17 +2748,34 @@ bool char_config_read(const char* cfgName, bool normal){ #else } else if (strcmpi(w1, "start_point_pre") == 0) { #endif - char map[MAP_NAME_LENGTH_EXT]; - short x, y; - if (sscanf(w2, "%15[^,],%6hd,%6hd", map, &x, &y) < 3){ - ShowWarning( "Specified start_point has an invalid format.\n" ); - continue; + int i = 0, fields_length = 3 + 1; + char *lineitem, **fields; + + fields = (char**)aMalloc(fields_length * sizeof(char*)); + lineitem = strtok(w2, ":"); + + while (lineitem != NULL) { + int n = sv_split(lineitem, strlen(lineitem), 0, ',', fields, fields_length, SV_NOESCAPE_NOTERMINATE); + + if (n + 1 < fields_length) { + ShowDebug("start_point: not enough arguments for %s! Skipping...\n", lineitem); + lineitem = strtok(NULL, ":"); //next itemline + continue; + } + if (i > MAX_STARTPOINT) { + ShowDebug("start_point: too many start points, only %d are allowed! Ignoring parameter %s...\n", MAX_STARTPOINT, lineitem); + } else { + charserv_config.start_point[i].map = mapindex_name2id(fields[1]); + if (!charserv_config.start_point[i].map) + ShowError("Specified start_point %s not found in map-index cache.\n", charserv_config.start_point[i].map); + charserv_config.start_point[i].x = max(0, atoi(fields[2])); + charserv_config.start_point[i].y = max(0, atoi(fields[3])); + charserv_config.start_point_count++; + } + lineitem = strtok(NULL, ":"); //next itemline + i++; } - charserv_config.start_point.map = mapindex_name2id(map); - if (!charserv_config.start_point.map) - ShowError("Specified start_point %s not found in map-index cache.\n", map); - charserv_config.start_point.x = x; - charserv_config.start_point.y = y; + aFree(fields); } else if (strcmpi(w1, "start_zeny") == 0) { charserv_config.start_zeny = atoi(w2); if (charserv_config.start_zeny < 0) diff --git a/src/char/char.h b/src/char/char.h index 6ac44a0202..c7e9e2899a 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -15,6 +15,8 @@ extern int login_fd; //login file descriptor extern int char_fd; //char file descriptor +#define MAX_STARTPOINT 5 + enum E_CHARSERVER_ST { CHARSERVER_ST_RUNNING = CORE_ST_LAST, CHARSERVER_ST_STARTING, @@ -142,7 +144,8 @@ struct CharServ_Config { int log_inter; // loggin inter or not [devil] int char_check_db; ///cheking sql-table at begining ? - struct point start_point; // Initial position the player will spawn on server + struct point start_point[MAX_STARTPOINT]; // Initial position the player will spawn on server + short start_point_count; int console; int max_connect_user; int gm_allow_group; From b7eb62ffb40a30a572bcccfd382ac6dda1840379 Mon Sep 17 00:00:00 2001 From: aleos89 Date: Fri, 8 Jan 2016 13:33:24 -0500 Subject: [PATCH 2/4] Follow up to a54bb65 * Fixed the config format. * Adjusted atcommand go to properly place players on renewal mode. --- conf/char_athena.conf | 4 ++-- src/common/mapindex.h | 8 +++++++- src/map/atcommand.c | 4 ++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/conf/char_athena.conf b/conf/char_athena.conf index 6e40aa9496..ea0524b493 100644 --- a/conf/char_athena.conf +++ b/conf/char_athena.conf @@ -111,8 +111,8 @@ save_log: yes // Format: ,,{:,,...} // Max number of start points is MAX_STARTPOINT in char.h (default 5) // Location is randomly picked on character creation. -start_point: iz_int,97,90,iz_int01,97,90,iz_int02,97,90,iz_int03,97,90,iz_int04,97,90 -start_point_pre: new_1-1,53,111,new_2-1,53,111,new_3-1,53,111,new_4-1,53,111,new_5-1,53,111 +start_point: iz_int,97,90:iz_int01,97,90:iz_int02,97,90:iz_int03,97,90:iz_int04,97,90 +start_point_pre: new_1-1,53,111:new_2-1,53,111:new_3-1,53,111:new_4-1,53,111:new_5-1,53,111 // Starting items for new characters // Max number of items is MAX_STARTITEM in char.c (default 32) diff --git a/src/common/mapindex.h b/src/common/mapindex.h index ec36d0e034..ec04750936 100644 --- a/src/common/mapindex.h +++ b/src/common/mapindex.h @@ -4,6 +4,8 @@ #ifndef _MAPINDEX_H_ #define _MAPINDEX_H_ +#include "../config/renewal.h" + #define MAX_MAPINDEX 2000 //Some definitions for the mayor city maps. @@ -31,7 +33,11 @@ #define MAP_RACHEL "rachel" #define MAP_VEINS "veins" #define MAP_JAIL "sec_pri" -#define MAP_NOVICE "new_1-1" +#ifdef RENEWAL + #define MAP_NOVICE "iz_int" +#else + #define MAP_NOVICE "new_1-1" +#endif #define MAP_MOSCOVIA "moscovia" #define MAP_MIDCAMP "mid_camp" #define MAP_MANUK "manuk" diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 7a19bc2e44..4aed60fa13 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -1840,7 +1840,11 @@ ACMD_FUNC(go) { MAP_UMBALA, 89, 157 }, // 12=Umbala { MAP_NIFLHEIM, 21, 153 }, // 13=Niflheim { MAP_LOUYANG, 217, 40 }, // 14=Louyang +#ifdef RENEWAL + { MAP_NOVICE, 97, 90 }, // 15=Training Grounds (Renewal) +#else { MAP_NOVICE, 53, 111 }, // 15=Training Grounds +#endif { MAP_JAIL, 23, 61 }, // 16=Prison { MAP_JAWAII, 249, 127 }, // 17=Jawaii { MAP_AYOTHAYA, 151, 117 }, // 18=Ayothaya From b98fe0b5973ed0decaee02381ce86081aeca8945 Mon Sep 17 00:00:00 2001 From: aleos89 Date: Wed, 20 Jan 2016 10:18:26 -0500 Subject: [PATCH 3/4] Cleanup * Moved parsing for start_point and start_items to separate functions. * Moved startitem struct to mmo.h and declared start_items in the charserv_config. * Adjusted the MAP_DEFAULT_NAME for pre-renewal to the correct map. --- src/char/char.c | 161 +++++++++++++++++++++++++++------------------ src/char/char.h | 6 +- src/common/mmo.h | 5 ++ src/config/const.h | 2 +- 4 files changed, 108 insertions(+), 66 deletions(-) diff --git a/src/char/char.c b/src/char/char.c index 3188a34f88..bc984d9bec 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -53,13 +53,6 @@ static char* msg_table[CHAR_MAX_MSG]; // Login Server messages_conf // other is char_id unsigned int save_flag = 0; -#define MAX_STARTITEM 32 -struct startitem { - int nameid; //Item ID - int amount; //Number of items - int pos; //Position (for auto-equip) -} start_items[MAX_STARTITEM+1]; - // Advanced subnet check [LuzZza] struct s_subnet { uint32 mask; @@ -1494,8 +1487,8 @@ int char_make_new_char_sql(struct char_session_data* sd, char* name_, int str, i //Retrieve the newly auto-generated char id char_id = (int)Sql_LastInsertId(sql_handle); //Give the char the default items - for (k = 0; k <= MAX_STARTITEM && start_items[k].nameid != 0; k ++) { - if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%hu', '%d', '%d', '%d')", schema_config.inventory_db, char_id, start_items[k].nameid, start_items[k].amount, start_items[k].pos, 1) ) + for (k = 0; k <= MAX_STARTITEM && charserv_config.start_items[k].nameid != 0; k ++) { + if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%hu', '%hu', '%hu', '%d')", schema_config.inventory_db, char_id, charserv_config.start_items[k].nameid, charserv_config.start_items[k].amount, charserv_config.start_items[k].pos, 1) ) Sql_ShowDebug(sql_handle); } @@ -2634,12 +2627,19 @@ void char_set_defaults(){ charserv_config.log_inter = 1; // loggin inter or not [devil] charserv_config.char_check_db =1; - //see const.h to change those default + // See const.h to change the default values charserv_config.start_point[0].map = mapindex_name2id(MAP_DEFAULT_NAME); charserv_config.start_point[0].x = MAP_DEFAULT_X; charserv_config.start_point[0].y = MAP_DEFAULT_Y; charserv_config.start_point_count = 0; + charserv_config.start_items[0].nameid = 1201; + charserv_config.start_items[0].amount = 1; + charserv_config.start_items[0].pos = 2; + charserv_config.start_items[1].nameid = 2301; + charserv_config.start_items[1].amount = 1; + charserv_config.start_items[1].pos = 16; + charserv_config.console = 0; charserv_config.max_connect_user = -1; charserv_config.gm_allow_group = -1; @@ -2652,6 +2652,92 @@ void char_set_defaults(){ charserv_config.default_map_y = 191; } +/** + * Split start_point configuration values. + * @param w2_value: Value from w2 + */ +static void char_config_split_startpoint(char *w2_value) +{ + char *lineitem, **fields, config_name[20]; + int i = 0, fields_length = 3 + 1; + + memset(config_name, 0, sizeof(config_name)); + +#ifdef RENEWAL + strcat(config_name, "start_point"); +#else + strcat(config_name, "start_point_pre"); +#endif + + fields = (char **)aMalloc(fields_length * sizeof(char *)); + lineitem = strtok(w2_value, ":"); + + while (lineitem != NULL) { + int n = sv_split(lineitem, strlen(lineitem), 0, ',', fields, fields_length, SV_NOESCAPE_NOTERMINATE); + + if (n + 1 < fields_length) { + ShowDebug("%s: not enough arguments for %s! Skipping...\n", config_name, lineitem); + lineitem = strtok(NULL, ":"); //next lineitem + continue; + } + if (i > MAX_STARTPOINT) + ShowDebug("%s: too many start points, only %d are allowed! Ignoring parameter %s...\n", config_name, MAX_STARTPOINT, lineitem); + else { + charserv_config.start_point[i].map = mapindex_name2id(fields[1]); + if (!charserv_config.start_point[i].map) { + ShowError("Start point %s not found in map-index cache. Setting to default location.\n", charserv_config.start_point[i].map); + charserv_config.start_point[i].map = mapindex_name2id(MAP_DEFAULT_NAME); + charserv_config.start_point[i].x = MAP_DEFAULT_X; + charserv_config.start_point[i].y = MAP_DEFAULT_Y; + } else { + charserv_config.start_point[i].x = max(0, atoi(fields[2])); + charserv_config.start_point[i].y = max(0, atoi(fields[3])); + } + charserv_config.start_point_count++; + } + lineitem = strtok(NULL, ":"); //next lineitem + i++; + } + aFree(fields); +} + +/** + * Split start_items configuration values. + * @param w2_value: Value from w2 + */ +static void char_config_split_startitem(char *w2_value) +{ + char *lineitem, **fields, config_name[20]; + int i = 0, fields_length = 3 + 1; + + memset(config_name, 0, sizeof(config_name)); + + strcat(config_name, "start_items"); + + fields = (char **)aMalloc(fields_length * sizeof(char *)); + lineitem = strtok(w2_value, ":"); + + while (lineitem != NULL) { + int n = sv_split(lineitem, strlen(lineitem), 0, ',', fields, fields_length, SV_NOESCAPE_NOTERMINATE); + + if (n + 1 < fields_length) { + ShowDebug("%s: not enough arguments for %s! Skipping...\n", config_name, lineitem); + lineitem = strtok(NULL, ":"); //next lineitem + continue; + } + if (i > MAX_STARTITEM) + ShowDebug("%s: too many start items, only %d are allowed! Ignoring parameter %s...\n", config_name, MAX_STARTITEM, lineitem); + else { + charserv_config.start_items[i].nameid = max(0, atoi(fields[1])); + charserv_config.start_items[i].amount = max(0, atoi(fields[2])); + charserv_config.start_items[i].pos = max(0, atoi(fields[3])); + } + lineitem = strtok(NULL, ":"); //next lineitem + i++; + } + aFree(fields); +} + bool char_config_read(const char* cfgName, bool normal){ char line[1024], w1[1024], w2[1024]; FILE* fp = fopen(cfgName, "r"); @@ -2748,63 +2834,13 @@ bool char_config_read(const char* cfgName, bool normal){ #else } else if (strcmpi(w1, "start_point_pre") == 0) { #endif - int i = 0, fields_length = 3 + 1; - char *lineitem, **fields; - - fields = (char**)aMalloc(fields_length * sizeof(char*)); - lineitem = strtok(w2, ":"); - - while (lineitem != NULL) { - int n = sv_split(lineitem, strlen(lineitem), 0, ',', fields, fields_length, SV_NOESCAPE_NOTERMINATE); - - if (n + 1 < fields_length) { - ShowDebug("start_point: not enough arguments for %s! Skipping...\n", lineitem); - lineitem = strtok(NULL, ":"); //next itemline - continue; - } - if (i > MAX_STARTPOINT) { - ShowDebug("start_point: too many start points, only %d are allowed! Ignoring parameter %s...\n", MAX_STARTPOINT, lineitem); - } else { - charserv_config.start_point[i].map = mapindex_name2id(fields[1]); - if (!charserv_config.start_point[i].map) - ShowError("Specified start_point %s not found in map-index cache.\n", charserv_config.start_point[i].map); - charserv_config.start_point[i].x = max(0, atoi(fields[2])); - charserv_config.start_point[i].y = max(0, atoi(fields[3])); - charserv_config.start_point_count++; - } - lineitem = strtok(NULL, ":"); //next itemline - i++; - } - aFree(fields); + char_config_split_startpoint(w2); } else if (strcmpi(w1, "start_zeny") == 0) { charserv_config.start_zeny = atoi(w2); if (charserv_config.start_zeny < 0) charserv_config.start_zeny = 0; } else if (strcmpi(w1, "start_items") == 0) { - int i=0; - char *lineitem, **fields; - int fields_length = 3+1; - fields = (char**)aMalloc(fields_length*sizeof(char*)); - - lineitem = strtok(w2, ":"); - while (lineitem != NULL) { - int n = sv_split(lineitem, strlen(lineitem), 0, ',', fields, fields_length, SV_NOESCAPE_NOTERMINATE); - if(n+1 < fields_length){ - ShowDebug("start_items: not enough arguments for %s! Skipping...\n",lineitem); - lineitem = strtok(NULL, ":"); //next itemline - continue; - } - if(i > MAX_STARTITEM){ - ShowDebug("start_items: too many items, only %d are allowed! Ignoring parameter %s...\n",MAX_STARTITEM,lineitem); - } else { - start_items[i].nameid = max(0,atoi(fields[1])); - start_items[i].amount = max(0,atoi(fields[2])); - start_items[i].pos = max(0,atoi(fields[3])); - } - lineitem = strtok(NULL, ":"); //next itemline - i++; - } - aFree(fields); + char_config_split_startitem(w2); } else if(strcmpi(w1,"log_char")==0) { //log char or not [devil] charserv_config.log_char = atoi(w2); } else if (strcmpi(w1, "unknown_char_name") == 0) { @@ -2886,7 +2922,6 @@ bool char_config_read(const char* cfgName, bool normal){ return true; } - /* * Message conf function */ diff --git a/src/char/char.h b/src/char/char.h index c7e9e2899a..166b460c70 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -16,6 +16,7 @@ extern int login_fd; //login file descriptor extern int char_fd; //char file descriptor #define MAX_STARTPOINT 5 +#define MAX_STARTITEM 32 enum E_CHARSERVER_ST { CHARSERVER_ST_RUNNING = CORE_ST_LAST, @@ -144,8 +145,9 @@ struct CharServ_Config { int log_inter; // loggin inter or not [devil] int char_check_db; ///cheking sql-table at begining ? - struct point start_point[MAX_STARTPOINT]; // Initial position the player will spawn on server - short start_point_count; + struct point start_point[MAX_STARTPOINT]; // Initial position the player will spawn on the server + short start_point_count; // Number of positions read + struct startitem start_items[MAX_STARTITEM]; // Initial items the player with spawn with on the server int console; int max_connect_user; int gm_allow_group; diff --git a/src/common/mmo.h b/src/common/mmo.h index 8aac2f82f1..e106fcfc81 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -219,6 +219,11 @@ struct point { short x,y; }; +struct startitem { + unsigned short nameid, amount; + short pos; +}; + enum e_skill_flag { SKILL_FLAG_PERMANENT, diff --git a/src/config/const.h b/src/config/const.h index dc759f400e..75950908f6 100644 --- a/src/config/const.h +++ b/src/config/const.h @@ -103,7 +103,7 @@ #define MAP_DEFAULT_X 97 #define MAP_DEFAULT_Y 90 #else - #define MAP_DEFAULT_NAME "new_zone01" + #define MAP_DEFAULT_NAME "new_1-1" #define MAP_DEFAULT_X 53 #define MAP_DEFAULT_Y 111 #endif From af773a94a9f17590ce0e945ef53949a7e2e7620d Mon Sep 17 00:00:00 2001 From: aleos89 Date: Wed, 20 Jan 2016 12:52:10 -0500 Subject: [PATCH 4/4] Follow up to b98fe0b * Added a check if allocation fails. --- src/char/char.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/char/char.c b/src/char/char.c index bc984d9bec..7839743313 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -2670,6 +2670,8 @@ static void char_config_split_startpoint(char *w2_value) #endif fields = (char **)aMalloc(fields_length * sizeof(char *)); + if (fields == NULL) + return; // Failed to allocate memory. lineitem = strtok(w2_value, ":"); while (lineitem != NULL) { @@ -2715,6 +2717,8 @@ static void char_config_split_startitem(char *w2_value) strcat(config_name, "start_items"); fields = (char **)aMalloc(fields_length * sizeof(char *)); + if (fields == NULL) + return; // Failed to allocate memory. lineitem = strtok(w2_value, ":"); while (lineitem != NULL) {