Index: conf/char_athena.conf =================================================================== --- conf/char_athena.conf (revision 17276) +++ conf/char_athena.conf (working copy) @@ -99,12 +99,10 @@ // 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 items for new characters (max 32) +// Format is: id1,qt1,idn,qtn +start_items: 1201,1,2301,1 -// Starting armor for new characters -start_armor: 2301 - // Starting zeny for new characters start_zeny: 0 Index: src/char/char.c =================================================================== --- src/char/char.c (revision 17276) +++ src/char/char.c (working copy) @@ -147,8 +147,7 @@ int gm_allow_group = -1; int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL; int start_zeny = 0; -int start_weapon = 1201; -int start_armor = 2301; +int start_items[64]; //32 starting items allowed [mkbu95] int guild_exp_rate = 100; // Pincode system @@ -1531,7 +1530,7 @@ 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,14 +1605,10 @@ //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) ) + for (k = 0; k < ARRAYLENGTH(start_items) && start_items[k] != 0; k += 2) { + 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_items[k], start_items[k + 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) ) - Sql_ShowDebug(sql_handle); - } ShowInfo("Created char: account: %d, char: %d, slot: %d, name: %s\n", sd->account_id, char_id, slot, name); return char_id; @@ -4986,14 +4981,27 @@ 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, tmp; + char *split, *split2; + + split = strtok(w2, ","); + while (split != NULL) { + split2 = split; + split = strtok(NULL, ","); + tmp = atoi(split2); + if(i >= ARRAYLENGTH(start_items)){ + ShowDebug("start_items overbound, only %d items are allowed ignoring parameter %d\n",ARRAYLENGTH(start_items)/2,tmp); + } + else + start_items[i] = max(tmp,0); + ++i; + } + + if (i%2) { //we know it must be a even number + ShowError("Specified 'start_items' is missing a parameter. Removing '%d'.\n", start_items[i - 1]); + start_items[i - 1] = 0; + } } else if(strcmpi(w1,"log_char")==0) { //log char or not [devil] log_char = atoi(w2); } else if (strcmpi(w1, "unknown_char_name") == 0) { Index: src/map/map.c =================================================================== --- src/map/map.c (revision 17276) +++ src/map/map.c (working copy) @@ -1420,7 +1420,7 @@ * @amount quantity * @m, @x, @y mapid,x,y * @first_charid, @second_charid, @third_charid, looting priority - * @flag: &1 MVP item. &2 do stacking check. + * @flag: &1 MVP item. &2 do stacking check. &4 bypass dropable chk *------------------------------------------*/ int map_addflooritem(struct item *item_data,int amount,int16 m,int16 x,int16 y,int first_charid,int second_charid,int third_charid,int flags) { @@ -1429,7 +1429,7 @@ nullpo_ret(item_data); - if(battle_config.item_onfloor && (itemdb_traderight(item_data->nameid)&1) ) + if(!(flags&4) && battle_config.item_onfloor && (itemdb_traderight(item_data->nameid)&1) ) return 0; //can't be dropped if(!map_searchrandfreecell(m,&x,&y,flags&2?1:0)) Index: src/map/pet.c =================================================================== --- src/map/pet.c (revision 17276) +++ src/map/pet.c (working copy) @@ -591,7 +591,7 @@ //You lost the pet already. if(!sd->status.pet_id || sd->pd->pet.intimate <= 0 || sd->pd->pet.incuvate) return 1; - + egg_id = itemdb_exists(sd->pd->petDB->EggID); if (egg_id) { if ((egg_id->flag.trade_restriction&0x01) && !pc_inventoryblank(sd)) { @@ -992,7 +992,7 @@ while (ditem) { map_addflooritem(&ditem->item_data,ditem->item_data.amount, list->m,list->x,list->y, - list->first_charid,list->second_charid,list->third_charid,0); + list->first_charid,list->second_charid,list->third_charid,4); ditem_prev = ditem; ditem = ditem->next; ers_free(item_drop_ers, ditem_prev); Index: src/map/atcommand.c =================================================================== --- src/map/atcommand.c (revision 17276) +++ src/map/atcommand.c (working copy) @@ -5510,7 +5510,7 @@ if((flag = pc_additem(sd,&item_tmp,1,LOG_TYPE_COMMAND))) { clif_additem(sd,0,0,flag); - map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); + map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,4); } } Index: src/map/script.c =================================================================== --- src/map/script.c (revision 17276) +++ src/map/script.c (working copy) @@ -6663,7 +6666,7 @@ else item_tmp.identify=itemdb_isidentified(nameid); - map_addflooritem(&item_tmp,amount,m,x,y,0,0,0,0); + map_addflooritem(&item_tmp,amount,m,x,y,0,0,0,4); } return 0; Index: src/map/battle.c =================================================================== --- src/map/battle.c (revision 17276) +++ src/map/battle.c (working copy) @@ -662,7 +662,7 @@ } } 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 @@ 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 @@ } 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 @@ 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 @@ 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 Index: src/map/skill.c =================================================================== --- src/map/skill.c (revision 17276) +++ src/map/skill.c (working copy) @@ -2427,8 +2427,29 @@ * Official Magic Reflection Behavior : damage reflected depends on gears caster wears, not target **/ #if MAGIC_REFLECTION_TYPE - if( dmg.dmg_lv != ATK_MISS )//Wiz SL cancelled and consumed fragment - dmg = battle_calc_attack(BF_MAGIC,bl,bl,skill_id,skill_lv,flag&0xFFF); + if( dmg.dmg_lv != ATK_MISS ){//Wiz SL cancelled and consumed fragment + short s_ele = skill_get_ele(skill_id, skill_lv); + + if (s_ele == -1) // the skill takes the weapon's element + s_ele = sstatus->rhw.ele; + else if (s_ele == -2) //Use status element + s_ele = status_get_attack_sc_element(src,status_get_sc(src)); + else if( s_ele == -3 ) //Use random element + s_ele = rnd()%ELE_MAX; + + dmg.damage = battle_attr_fix(bl, bl, dmg.damage, s_ele, status_get_element(bl), status_get_element_level(bl)); + + if( sc && sc->data[SC_ENERGYCOAT] ) { + struct status_data *status = status_get_status_data(bl); + int per = 100*status->sp / status->max_sp -1; //100% should be counted as the 80~99% interval + per /=20; //Uses 20% SP intervals. + //SP Cost: 1% + 0.5% per every 20% SP + if (!status_charge(bl, 0, (10+5*per)*status->max_sp/1000)) + status_change_end(bl, SC_ENERGYCOAT, INVALID_TIMER); + //Reduction: 6% + 6% every 20% + dmg.damage -= dmg.damage * (6 * (1+per)) / 100; + } + } #endif } if(sc && sc->data[SC_MAGICROD] && src == dsrc) { @@ -15685,7 +15706,7 @@ memset(&item_tmp,0,sizeof(item_tmp)); item_tmp.nameid = group->item_id?group->item_id:ITEMID_TRAP; item_tmp.identify = 1; - map_addflooritem(&item_tmp,1,bl->m,bl->x,bl->y,0,0,0,0); + map_addflooritem(&item_tmp,1,bl->m,bl->x,bl->y,0,0,0,4); } skill_delunit(unit); } Index: src/map/mob.c =================================================================== --- src/map/mob.c (revision 17276) +++ src/map/mob.c (working copy) @@ -1823,7 +1823,7 @@ while (ditem) { map_addflooritem(&ditem->item_data,ditem->item_data.amount, list->m,list->x,list->y, - list->first_charid,list->second_charid,list->third_charid,0); + list->first_charid,list->second_charid,list->third_charid,4); ditem_prev = ditem; ditem = ditem->next; ers_free(item_drop_ers, ditem_prev);