diff --git a/conf/char_athena.conf b/conf/char_athena.conf index 9c7d7dedb6..41a35adc8d 100644 --- a/conf/char_athena.conf +++ b/conf/char_athena.conf @@ -99,11 +99,9 @@ save_log: yes // Start point, Map name followed by coordinates (x,y) start_point: new_1-1,53,111 -// Starting weapon for new characters -start_weapon: 1201 - -// Starting armor for new characters -start_armor: 2301 +// Starting items for new characters (max MAX_STARTITEM) +// Format is: id1,qt1,pos1:idn,qtn,posn:... +start_items: 1201,1,2:2301,1,16 // Starting zeny for new characters start_zeny: 0 diff --git a/src/char/char.c b/src/char/char.c index d4e63faebb..de82cfa461 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -33,6 +33,7 @@ #include #include +#define MAX_STARTITEM 32 #define CHAR_MAX_MSG 300 static char* msg_table[CHAR_MAX_MSG]; // Login Server messages_conf @@ -143,12 +144,16 @@ struct char_session_data { unsigned int char_moves[MAX_CHARS]; // character moves left }; +struct startitem { + int nameid; //item id + int amout; //number of item + int pos; //position for autoequip +} start_items[MAX_STARTITEM+1]; + int max_connect_user = -1; int gm_allow_group = -1; int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL; int start_zeny = 0; -int start_weapon = 1201; -int start_armor = 2301; int guild_exp_rate = 100; // Pincode system @@ -1531,7 +1536,7 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag char name[NAME_LENGTH]; char esc_name[NAME_LENGTH*2+1]; - int char_id, flag; + int char_id, flag, k; safestrncpy(name, name_, NAME_LENGTH); normalize_name(name,TRIM_CHARS); @@ -1606,12 +1611,8 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag //Retrieve the newly auto-generated char id char_id = (int)Sql_LastInsertId(sql_handle); //Give the char the default items - if (start_weapon > 0) { //add Start Weapon (Knife?) - if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `identify`) VALUES ('%d', '%d', '%d', '%d')", inventory_db, char_id, start_weapon, 1, 1) ) - Sql_ShowDebug(sql_handle); - } - if (start_armor > 0) { //Add default armor (cotton shirt?) - if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `identify`) VALUES ('%d', '%d', '%d', '%d')", inventory_db, char_id, start_armor, 1, 1) ) + 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', '%d', '%d', '%d', '%d')", inventory_db, char_id, start_items[k].nameid, start_items[k].amout, start_items[k].pos, 1) ) Sql_ShowDebug(sql_handle); } @@ -4986,14 +4987,31 @@ int char_config_read(const char* cfgName) start_zeny = atoi(w2); if (start_zeny < 0) start_zeny = 0; - } else if (strcmpi(w1, "start_weapon") == 0) { - start_weapon = atoi(w2); - if (start_weapon < 0) - start_weapon = 0; - } else if (strcmpi(w1, "start_armor") == 0) { - start_armor = atoi(w2); - if (start_armor < 0) - start_armor = 0; + } else if (strcmpi(w1, "start_items") == 0) { + int i=0, n=0; + char *lineitem, **fields; + int fields_length = 3+1; + fields = (char**)aMalloc(fields_length*sizeof(char*)); + + lineitem = strtok(w2, ":"); + while (lineitem != NULL) { + n = sv_split(lineitem, strlen(lineitem), 0, ',', fields, fields_length, SV_NOESCAPE_NOTERMINATE); + if(n+1 < fields_length){ + ShowDebug("start_items not enough argument for %s; skipping...\n",lineitem); + lineitem = strtok(NULL, ";"); //next itemline + continue; + } + if(i > MAX_STARTITEM){ + ShowDebug("start_items overbound, only %d items are allowed ignoring parameter %s\n",MAX_STARTITEM,lineitem); + } else { + start_items[i].nameid = max(0,atoi(fields[1])); + start_items[i].amout = max(0,atoi(fields[2])); + start_items[i].pos = max(0,atoi(fields[3])); + } + lineitem = strtok(NULL, ";"); //next itemline + i++; + } + aFree(fields); } else if(strcmpi(w1,"log_char")==0) { //log char or not [devil] log_char = atoi(w2); } else if (strcmpi(w1, "unknown_char_name") == 0) { diff --git a/src/map/battle.c b/src/map/battle.c index c924fc0fe5..f725a7cbfb 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -662,7 +662,7 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li } } cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100; - cardfix=cardfix*(100-tsd->subrace2[s_race2])/100; + cardfix=cardfix*(100-tsd->subrace2[s_race2])/100; cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100; cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100; if( sstatus->race != RC_DEMIHUMAN ) @@ -1189,7 +1189,9 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag break; } } - if( sc->data[SC_POISONINGWEAPON] && skill_id != GC_VENOMPRESSURE && (flag&BF_WEAPON) && damage > 0 && rnd()%100 < sc->data[SC_POISONINGWEAPON]->val3 ) + if( sc->data[SC_POISONINGWEAPON] + && ((flag&BF_WEAPON) && (!skill_id || skill_id == GC_VENOMPRESSURE)) //chk skill type poison_smoke is a unit + && (damage > 0 && rnd()%100 < sc->data[SC_POISONINGWEAPON]->val3 )) //did some dammage and chance ok (why no additional effect ?? sc_start(src,bl,sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON, 1)); if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 ) status_change_spread(src, bl); @@ -1227,9 +1229,9 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag } if( bl->type == BL_MOB && !status_isdead(bl) && src != bl) { - if (damage > 0 ) + if (damage > 0 ) mobskill_event((TBL_MOB*)bl,src,gettick(),flag); - if (skill_id) + if (skill_id) mobskill_event((TBL_MOB*)bl,src,gettick(),MSC_SKILLUSED|(skill_id<<16)); } if( sd ) { @@ -5374,7 +5376,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f if (t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->class_ == MOBID_EMPERIUM && flag&BCT_ENEMY) return 0; //mercenary may not attack Emperium break; - } //end switch actual src + } //end switch actual src switch( s_bl->type ) { //Checks on source master @@ -5389,7 +5391,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f strip_enemy = 0; } else if( sd->duel_group && !((!battle_config.duel_allow_pvp && map[m].flag.pvp) || (!battle_config.duel_allow_gvg && map_flag_gvg(m))) ) - { + { if( t_bl->type == BL_PC && (sd->duel_group == ((TBL_PC*)t_bl)->duel_group) ) return (BCT_ENEMY&flag)?1:-1; // Duel targets can ONLY be your enemy, nothing else. else diff --git a/src/map/pc.c b/src/map/pc.c index f3541e807c..4893dbe9e4 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -8519,7 +8519,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos) if(pos == EQP_ARMS && id->equip == EQP_HAND_R) { //Dual wield capable weapon. - pos = (req_pos&EQP_ARMS); + pos = (req_pos&EQP_ARMS); if (pos == EQP_ARMS) //User specified both slots, pick one for them. pos = sd->equip_index[EQI_HAND_R] >= 0 ? EQP_HAND_L : EQP_HAND_R; }