diff --git a/conf/char_athena.conf b/conf/char_athena.conf index 5d8c12ec46..ea0524b493 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 7240373675..8da260480c 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; @@ -1423,7 +1416,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); @@ -1475,7 +1468,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! @@ -1487,7 +1480,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! @@ -1496,8 +1489,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); } @@ -2636,10 +2629,18 @@ 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 - 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; + // 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; @@ -2653,6 +2654,96 @@ 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 *)); + if (fields == NULL) + return; // Failed to allocate memory. + 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 *)); + if (fields == NULL) + return; // Failed to allocate memory. + 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"); @@ -2749,46 +2840,13 @@ 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; - } - 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; + 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) { @@ -2870,7 +2928,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 6ac44a0202..166b460c70 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -15,6 +15,9 @@ 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, CHARSERVER_ST_STARTING, @@ -142,7 +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; // Initial position the player will spawn on server + 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/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/common/mmo.h b/src/common/mmo.h index d286635709..0d6da54d73 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 diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 1445e0a770..bef6977945 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -1874,7 +1874,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