diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.c | 242 | ||||
-rw-r--r-- | src/map/battle.h | 14 | ||||
-rw-r--r-- | src/map/clif.c | 42 | ||||
-rw-r--r-- | src/map/clif.h | 1 | ||||
-rw-r--r-- | src/map/guild.c | 13 | ||||
-rw-r--r-- | src/map/itemdb.c | 188 | ||||
-rw-r--r-- | src/map/map.h | 16 | ||||
-rw-r--r-- | src/map/mob.c | 58 | ||||
-rw-r--r-- | src/map/npc.c | 3 | ||||
-rw-r--r-- | src/map/pc.c | 123 | ||||
-rw-r--r-- | src/map/pc.h | 3 | ||||
-rw-r--r-- | src/map/script.c | 64 | ||||
-rw-r--r-- | src/map/skill.c | 286 | ||||
-rw-r--r-- | src/map/skill.h | 19 |
14 files changed, 747 insertions, 325 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index ba8d22197..22ad51609 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -544,9 +544,10 @@ int battle_get_baseatk(struct block_list *bl) nullpo_retr(1, bl); sc_data=battle_get_sc_data(bl); - if(bl->type==BL_PC && (struct map_session_data *)bl) + if(bl->type==BL_PC && (struct map_session_data *)bl) { batk = ((struct map_session_data *)bl)->base_atk; //設定されているbase_atk - else { //それ以外なら + batk += ((struct map_session_data *)bl)->weapon_atk[((struct map_session_data *)bl)->status.weapon]; + } else { //それ以外なら int str,dstr; str = battle_get_str(bl); //STR dstr = str/10; @@ -935,6 +936,8 @@ int battle_get_speed(struct block_list *bl) speed -= (speed*(sc_data[SC_WINDWALK].val1*2))/100; if(sc_data[SC_SLOWDOWN].timer!=-1) speed = speed*150/100; + if(sc_data[SC_SPEEDUP0].timer!=-1) + speed -= speed*25/100; } if(speed < 1) speed = 1; return speed; @@ -1647,12 +1650,16 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i else if(g && guild_checkskill(g,GD_APPROVAL) <= 0) damage=0;//正規ギルド承認がないとダメージ無し else if (battle_config.guild_max_castles != 0 && guild_checkcastles(g)>=battle_config.guild_max_castles) - damage = 0; // [MouseJstr] + damage = 0; // [MouseJstr] } else damage = 0; } if(map[bl->m].flag.gvg && damage > 0) { //GvG + if(bl->type == BL_MOB){ //defenseがあればダメージが減るらしい? + struct guild_castle *gc=guild_mapname2gc(map[bl->m].name); + if (gc) damage -= damage*(gc->defense/100)*(battle_config.castle_defense_rate/100); + } if(flag&BF_WEAPON) { if(flag&BF_SHORT) damage=damage*battle_config.gvg_short_damage_rate/100; @@ -1682,6 +1689,33 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i } /*========================================== + * HP/SP吸収の計算 + *------------------------------------------ + */ +int battle_calc_drain(int damage, int rate, int per, int val) +{ + int diff = 0; + + if (damage <= 0 || rate <= 0) + return 0; + + if (per && rand()%100 < rate) { + diff = (damage * per) / 100; + if (diff == 0) { + if (per > 0) + diff = 1; + else + diff = -1; + } + } + + if (val && rand()%100 < rate) { + diff += val; + } + return diff; +} + +/*========================================== * 修練ダメージ *------------------------------------------ */ @@ -1925,7 +1959,7 @@ static struct Damage battle_calc_pet_weapon_attack( hitrate = (hitrate*(100+5*skill_lv))/100; break; case SM_MAGNUM: // マグナムブレイク - damage = damage*(5*skill_lv +(wflag)?65:115 )/100; + damage = damage*(5*skill_lv + (wflag?65:115))/100; break; case MC_MAMMONITE: // メマーナイト damage = damage*(100+ 50*skill_lv)/100; @@ -2045,6 +2079,7 @@ static struct Damage battle_calc_pet_weapon_attack( hitrate= 1000000; break; case AM_DEMONSTRATION: // デモンストレーション + hitrate= 1000000; damage = damage*(100+ 20*skill_lv)/100; damage2 = damage2*(100+ 20*skill_lv)/100; break; @@ -2127,7 +2162,7 @@ static struct Damage battle_calc_pet_weapon_attack( if( skill_num!=NPC_CRITICALSLASH ){ // 対 象の防御力によるダメージの減少 // ディバインプロテクション(ここでいいのかな?) - if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && def1 < 1000000 ) { //DEF, VIT無視 + if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && skill_num != AM_ACIDTERROR && def1 < 1000000 ) { //DEF, VIT無視 int t_def; target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penalty_count_lv); if(battle_config.vit_penalty_type > 0) { @@ -2392,9 +2427,9 @@ static struct Damage battle_calc_mob_weapon_attack( // ソニックブロー if(sc_data){ //状態異常中のダメージ追加 if(sc_data[SC_OVERTHRUST].timer!=-1) // オーバートラスト - damage += damage*(5*sc_data[SC_OVERTHRUST].val1)/100; + damage += damage*(5*sc_data[SC_OVERTHRUST].val1)/100; if(sc_data[SC_TRUESIGHT].timer!=-1) // トゥルーサイト - damage += damage*(2*sc_data[SC_TRUESIGHT].val1)/100; + damage += damage*(2*sc_data[SC_TRUESIGHT].val1)/100; if(sc_data[SC_BERSERK].timer!=-1) // バーサーク damage += damage*2; if(sc_data && sc_data[SC_AURABLADE].timer!=-1) //[DracoRPG] @@ -2413,7 +2448,7 @@ static struct Damage battle_calc_mob_weapon_attack( hitrate = (hitrate*(100+5*skill_lv))/100; break; case SM_MAGNUM: // マグナムブレイク - damage = damage*(5*skill_lv +(wflag)?65:115 )/100; + damage = damage*(5*skill_lv +(wflag?65:115))/100; break; case MC_MAMMONITE: // メマーナイト damage = damage*(100+ 50*skill_lv)/100; @@ -2540,6 +2575,7 @@ static struct Damage battle_calc_mob_weapon_attack( hitrate= 1000000; break; case AM_DEMONSTRATION: // デモンストレーション + hitrate = 1000000; damage = damage*(100+ 20*skill_lv)/100; damage2 = damage2*(100+ 20*skill_lv)/100; break; @@ -2622,7 +2658,7 @@ static struct Damage battle_calc_mob_weapon_attack( if( skill_num!=NPC_CRITICALSLASH ){ // 対 象の防御力によるダメージの減少 // ディバインプロテクション(ここでいいのかな?) - if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && def1 < 1000000) { //DEF, VIT無視 + if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && skill_num != KN_AUTOCOUNTER && def1 < 1000000) { //DEF, VIT無視 int t_def; target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penalty_count_lv); if(battle_config.vit_penalty_type > 0) { @@ -2988,9 +3024,9 @@ static struct Damage battle_calc_pc_weapon_attack( { damage += atkmax; damage2 += atkmax_; - if(sd->atk_rate != 100) { - damage = (damage * sd->atk_rate)/100; - damage2 = (damage2 * sd->atk_rate)/100; + if(sd->atk_rate != 100 || sd->weapon_atk_rate != 0) { + damage = (damage * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100; + damage2 = (damage2 * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100; } if(sd->state.arrow_atk) damage += sd->arrow_atk; @@ -3038,9 +3074,9 @@ static struct Damage battle_calc_pc_weapon_attack( damage2 += atkmin_ + rand() % (atkmax_-atkmin_ + 1); else damage2 += atkmin_ ; - if(sd->atk_rate != 100) { - damage = (damage * sd->atk_rate)/100; - damage2 = (damage2 * sd->atk_rate)/100; + if(sd->atk_rate != 100 || sd->weapon_atk_rate != 0) { + damage = (damage * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100; + damage2 = (damage2 * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100; } if(sd->state.arrow_atk) { @@ -3119,8 +3155,8 @@ static struct Damage battle_calc_pc_weapon_attack( hitrate = (hitrate*(100+5*skill_lv))/100; break; case SM_MAGNUM: // マグナムブレイク - damage = damage*(5*skill_lv +(wflag)?65:115 )/100; - damage2 = damage2*(5*skill_lv +(wflag)?65:115 )/100; + damage = damage*(5*skill_lv +(wflag?65:115) )/100; + damage2 = damage2*(5*skill_lv +(wflag?65:115) )/100; break; case MC_MAMMONITE: // メマーナイト damage = damage*(100+ 50*skill_lv)/100; @@ -3327,11 +3363,15 @@ static struct Damage battle_calc_pc_weapon_attack( case AM_DEMONSTRATION: // デモンストレーション damage = damage*(100+ 20*skill_lv)/100; damage2 = damage2*(100+ 20*skill_lv)/100; + no_cardfix = 1; break; case AM_ACIDTERROR: // アシッドテラー hitrate = 1000000; damage = damage*(100+ 40*skill_lv)/100; damage2 = damage2*(100+ 40*skill_lv)/100; + s_ele = 0; + s_ele_ = 0; + no_cardfix = 1; break; case MO_FINGEROFFENSIVE: //指弾 if(battle_config.finger_offensive_type == 0) { @@ -3374,11 +3414,6 @@ static struct Damage battle_calc_pc_weapon_attack( damage2 = damage2*(240+ 60*skill_lv)/100; break; case BA_MUSICALSTRIKE: // ミュージカルストライク - if(!sd->state.arrow_atk && sd->arrow_atk > 0) { - int arr = rand()%(sd->arrow_atk+1); - damage += arr; - damage2 += arr; - } damage = damage*(60+ 40 * skill_lv)/100; damage2 = damage2*(60+ 40 * skill_lv)/100; if(sd->arrow_ele > 0) { @@ -3386,7 +3421,6 @@ static struct Damage battle_calc_pc_weapon_attack( s_ele_ = sd->arrow_ele; } flag=(flag&~BF_RANGEMASK)|BF_LONG; - sd->state.arrow_atk = 1; break; case DC_THROWARROW: // 矢撃ち if(!sd->state.arrow_atk && sd->arrow_atk > 0) { @@ -3443,11 +3477,6 @@ static struct Damage battle_calc_pc_weapon_attack( damage2 += damage2*(30*skill_lv)/100; break; case CG_ARROWVULCAN: /* アローバルカン */ - if(!sd->state.arrow_atk && sd->arrow_atk > 0) { - int arr = rand()%(sd->arrow_atk+1); - damage += arr; - damage2 += arr; - } damage = damage*(200+100*skill_lv)/100; damage2 = damage2*(200+100*skill_lv)/100; div_=9; @@ -3456,7 +3485,6 @@ static struct Damage battle_calc_pc_weapon_attack( s_ele_ = sd->arrow_ele; } flag=(flag&~BF_RANGEMASK)|BF_LONG; - sd->state.arrow_atk = 1; break; case AS_SPLASHER: /* ベナムスプラッシャー */ damage = damage*(200+20*skill_lv+20*pc_checkskill(sd,AS_POISONREACT))/100; @@ -3520,7 +3548,7 @@ static struct Damage battle_calc_pc_weapon_attack( if( skill_num!=NPC_CRITICALSLASH ){ // 対 象の防御力によるダメージの減少 // ディバインプロテクション(ここでいいのかな?) - if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && def1 < 1000000) { //DEF, VIT無視 + if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && skill_num != AM_ACIDTERROR && def1 < 1000000) { //DEF, VIT無視 int t_def; target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penalty_count_lv); if(battle_config.vit_penalty_type > 0) { @@ -3582,11 +3610,23 @@ static struct Damage battle_calc_pc_weapon_attack( // 状態異常中のダメージ追加でクリティカルにも有効なスキル if (sc_data) { // エンチャントデッドリーポイズン - if(sc_data[SC_EDP].timer != -1 && skill_num != ASC_BREAKER && skill_num != ASC_METEORASSAULT) { + if(!no_cardfix && sc_data[SC_EDP].timer != -1 && skill_num != ASC_BREAKER && skill_num != ASC_METEORASSAULT) { damage += damage * (150 + sc_data[SC_EDP].val1 * 50) / 100; - damage2 += damage2 * (150 + sc_data[SC_EDP].val1 * 50) / 100; no_cardfix = 1; } + if (!skill_num && !(t_mode&0x20) && sc_data[SC_SACRIFICE].timer != -1) { + int mhp = battle_get_max_hp(src); + int dmg = mhp * (5 + sc_data[SC_SACRIFICE].val1 * 5) / 1000; + pc_heal(sd, -dmg, 0); + damage = dmg * (90 + sc_data[SC_SACRIFICE].val1 * 15) / 100; + damage2 = 0; + hitrate = 1000000; + s_ele = 0; + s_ele_ = 0; + sc_data[SC_SACRIFICE].val2 --; + if (sc_data[SC_SACRIFICE].val2 == 0) + skill_status_change_end(src, SC_SACRIFICE,-1); + } } // 精錬ダメージの追加 @@ -4178,7 +4218,7 @@ struct Damage battle_calc_magic_attack( break; case WZ_STORMGUST: // ストームガスト MATK_FIX( skill_lv*40+100 ,100 ); - blewcount|=0x10000; +// blewcount|=0x10000; break; case AL_HOLYLIGHT: // ホーリーライト MATK_FIX( 125,100 ); @@ -4387,6 +4427,8 @@ struct Damage battle_calc_misc_attack( damage=(dex/10+int_/2+skill*3+40)*2; if(flag > 1) damage /= flag; + if(battle_get_mode(target) & 0x40) + damage = 1; break; case TF_THROWSTONE: // 石投げ @@ -4424,12 +4466,17 @@ struct Damage battle_calc_misc_attack( break; case SN_FALCONASSAULT: /* ファルコンアサルト */ #ifdef TWILIGHT - skill = pc_checkskill(sd,HT_BLITZBEAT); - damage=(100+50*skill_lv+(dex/10+int_/2+skill*3+40)*2) * 2; + if( sd==NULL || (skill = pc_checkskill(sd,HT_BLITZBEAT)) <= 0) + skill=0; #else - skill = pc_checkskill(sd,HT_STEELCROW); // Celest - damage=((150+50*skill_lv)*(dex/10+int_/2+skill*3+40)*2)/100; + if( sd==NULL || (skill = pc_checkskill(sd,HT_STEELCROW)) <= 0) + skill=0; + damage=((150+50*skill_lv)*(dex/10+int_/2+skill*3+40)*2)/100; // [Celest] #endif + if(flag > 1) + damage /= flag; + if(battle_get_mode(target) & 0x40) + damage = 1; break; } @@ -4706,29 +4753,25 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target, if(!f) pc_heal(sd,0,-sp); } } - if(wd.flag&BF_WEAPON && src != target && (wd.damage > 0 || wd.damage2 > 0)) { + if (wd.flag&BF_WEAPON && src != target && (wd.damage > 0 || wd.damage2 > 0)) { int hp = 0,sp = 0; - if(sd->hp_drain_rate && sd->hp_drain_per > 0 && wd.damage > 0 && rand()%100 < sd->hp_drain_rate) { - hp += (wd.damage * sd->hp_drain_per)/100; - if(sd->hp_drain_rate > 0 && hp < 1) hp = 1; - else if(sd->hp_drain_rate < 0 && hp > -1) hp = -1; - } - if(sd->hp_drain_rate_ && sd->hp_drain_per_ > 0 && wd.damage2 > 0 && rand()%100 < sd->hp_drain_rate_) { - hp += (wd.damage2 * sd->hp_drain_per_)/100; - if(sd->hp_drain_rate_ > 0 && hp < 1) hp = 1; - else if(sd->hp_drain_rate_ < 0 && hp > -1) hp = -1; - } - if(sd->sp_drain_rate && sd->sp_drain_per > 0 && wd.damage > 0 && rand()%100 < sd->sp_drain_rate) { - sp += (wd.damage * sd->sp_drain_per)/100; - if(sd->sp_drain_rate > 0 && sp < 1) sp = 1; - else if(sd->sp_drain_rate < 0 && sp > -1) sp = -1; + if (!battle_config.left_cardfix_to_right) { // 二刀流左手カードの吸収系効果を右手に追加しない場合 + hp += battle_calc_drain(wd.damage, sd->hp_drain_rate, sd->hp_drain_per, sd->hp_drain_value); + hp += battle_calc_drain(wd.damage2, sd->hp_drain_rate_, sd->hp_drain_per_, sd->hp_drain_value_); + sp += battle_calc_drain(wd.damage, sd->sp_drain_rate, sd->sp_drain_per, sd->sp_drain_value); + sp += battle_calc_drain(wd.damage2, sd->sp_drain_rate_, sd->sp_drain_per_, sd->sp_drain_value_); + } else { // 二刀流左手カードの吸収系効果を右手に追加する場合 + int hp_drain_rate = sd->hp_drain_rate + sd->hp_drain_rate_; + int hp_drain_per = sd->hp_drain_per + sd->hp_drain_per_; + int hp_drain_value = sd->hp_drain_value + sd->hp_drain_value_; + int sp_drain_rate = sd->sp_drain_rate + sd->sp_drain_rate_; + int sp_drain_per = sd->sp_drain_per + sd->sp_drain_per_; + int sp_drain_value = sd->sp_drain_value + sd->sp_drain_value_; + hp += battle_calc_drain(wd.damage, hp_drain_rate, hp_drain_per, hp_drain_value); + sp += battle_calc_drain(wd.damage, sp_drain_rate, sp_drain_per, sp_drain_value); } - if(sd->sp_drain_rate_ && sd->sp_drain_per_ > 0 && wd.damage2 > 0 && rand()%100 < sd->sp_drain_rate_) { - sp += (wd.damage2 * sd->sp_drain_per_)/100; - if(sd->sp_drain_rate_ > 0 && sp < 1) sp = 1; - else if(sd->sp_drain_rate_ < 0 && sp > -1) sp = -1; - } - if(hp || sp) pc_heal(sd,hp,sp); + + if (hp || sp) pc_heal(sd, hp, sp); } } @@ -4753,13 +4796,12 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target, skill_status_change_end(target,SC_POISONREACT,-1); } } - if(t_sc_data && t_sc_data[SC_BLADESTOP_WAIT].timer != -1){ - if (!(src->type == BL_MOB && mob_db[((struct mob_data *)src)->class].mode&0x20)) { - int lv = t_sc_data[SC_BLADESTOP_WAIT].val1; - skill_status_change_end(target,SC_BLADESTOP_WAIT,-1); - skill_status_change_start(src,SC_BLADESTOP,lv,1,(int)src,(int)target,skill_get_time2(MO_BLADESTOP,lv),0); - skill_status_change_start(target,SC_BLADESTOP,lv,2,(int)target,(int)src,skill_get_time2(MO_BLADESTOP,lv),0); - } + if (t_sc_data && t_sc_data[SC_BLADESTOP_WAIT].timer != -1 && + !(battle_get_mode(src)&0x20)) { // ボスには無効 + int lv = t_sc_data[SC_BLADESTOP_WAIT].val1; + skill_status_change_end(target,SC_BLADESTOP_WAIT,-1); + skill_status_change_start(src,SC_BLADESTOP,lv,1,(int)src,(int)target,skill_get_time2(MO_BLADESTOP,lv),0); + skill_status_change_start(target,SC_BLADESTOP,lv,2,(int)target,(int)src,skill_get_time2(MO_BLADESTOP,lv),0); } if(t_sc_data && t_sc_data[SC_SPLASHER].timer!=-1) //殴ったので対象のベナムスプラッシャー状態を解除 skill_status_change_end(target,SC_SPLASHER,-1); @@ -4989,17 +5031,8 @@ int battle_check_range(struct block_list *src,struct block_list *bl,int range) if(src->m != bl->m) // 違うマップ return 0; - if( range>0 && range < arange ) {// 遠すぎる -// be lenient if the skill was cast before we have moved to the correct position [Celest] - /* Celest: Hmm, bl isn't necessarily BL_PC... i think i'll test this more first >.< */ - /*if (src->type == BL_PC && bl->type == BL_PC) { - struct map_session_data *sd; - nullpo_retr(0, (sd=(struct map_session_data *)bl)); - if (sd->walktimer != -1 && !((arange-=battle_config.skill_range_leniency)<=range)) - return 0; - } - else*/ return 0; - } + if( range>0 && range < arange ) // 遠すぎる + return 0; if( arange<2 ) // 同じマスか隣接 return 1; @@ -5128,6 +5161,11 @@ static const struct { { "natural_heal_skill_interval", &battle_config.natural_heal_skill_interval}, { "natural_heal_weight_rate", &battle_config.natural_heal_weight_rate }, { "item_name_override_grffile", &battle_config.item_name_override_grffile}, + { "item_equip_override_grffile", &battle_config.item_equip_override_grffile}, // [Celest] + { "item_slots_override_grffile", &battle_config.item_slots_override_grffile}, // [Celest] + { "indoors_override_grffile", &battle_config.indoors_override_grffile}, // [Celest] + { "skill_sp_override_grffile", &battle_config.skill_sp_override_grffile}, // [Celest] + { "cardillust_read_grffile", &battle_config.cardillust_read_grffile}, // [Celest] { "arrow_decrement", &battle_config.arrow_decrement }, { "max_aspd", &battle_config.max_aspd }, { "max_hp", &battle_config.max_hp }, @@ -5202,8 +5240,26 @@ static const struct { { "invite_request_check", &battle_config.invite_request_check }, { "skill_removetrap_type", &battle_config.skill_removetrap_type }, { "disp_experience", &battle_config.disp_experience }, - { "castle_defense_rate", &battle_config.castle_defense_rate }, - { "riding_weight", &battle_config.riding_weight }, + { "castle_defense_rate", &battle_config.castle_defense_rate }, + { "riding_weight", &battle_config.riding_weight }, + { "hp_rate", &battle_config.hp_rate }, + { "sp_rate", &battle_config.sp_rate }, + { "gm_can_drop_lv", &battle_config.gm_can_drop_lv }, + { "disp_hpmeter", &battle_config.disp_hpmeter }, + { "bone_drop", &battle_config.bone_drop }, + { "item_rate_details", &battle_config.item_rate_details }, + { "item_rate_1", &battle_config.item_rate_1 }, + { "item_rate_10", &battle_config.item_rate_10 }, + { "item_rate_100", &battle_config.item_rate_100 }, + { "item_rate_1000", &battle_config.item_rate_1000 }, + { "item_rate_1_min", &battle_config.item_rate_1_min }, + { "item_rate_1_max", &battle_config.item_rate_1_max }, + { "item_rate_10_min", &battle_config.item_rate_10_min }, + { "item_rate_10_max", &battle_config.item_rate_10_max }, + { "item_rate_100_min", &battle_config.item_rate_100_min }, + { "item_rate_100_max", &battle_config.item_rate_100_max }, + { "item_rate_1000_min", &battle_config.item_rate_1000_min }, + { "item_rate_1000_max", &battle_config.item_rate_1000_max }, { "item_rate_common", &battle_config.item_rate_common }, // Added by RoVeRT { "item_rate_equip", &battle_config.item_rate_equip }, { "item_rate_card", &battle_config.item_rate_card }, // End Addition @@ -5362,6 +5418,11 @@ void battle_set_defaults() { battle_config.natural_heal_skill_interval=10000; battle_config.natural_heal_weight_rate=50; battle_config.item_name_override_grffile=1; + battle_config.item_equip_override_grffile=1; // [Celest] + battle_config.item_slots_override_grffile=1; // [Celest] + battle_config.indoors_override_grffile=1; // [Celest] + battle_config.skill_sp_override_grffile=1; // [Celest] + battle_config.cardillust_read_grffile=1; // [Celest] battle_config.arrow_decrement=1; battle_config.max_aspd = 199; battle_config.max_hp = 32500; @@ -5405,7 +5466,6 @@ void battle_set_defaults() { battle_config.mob_changetarget_byskill = 0; battle_config.pc_attack_direction_change = 1; battle_config.monster_attack_direction_change = 1; - battle_config.pc_undead_nofreeze = 0; battle_config.pc_land_skill_limit = 1; battle_config.monster_land_skill_limit = 1; battle_config.party_skill_penalty = 1; @@ -5437,6 +5497,26 @@ void battle_set_defaults() { battle_config.invite_request_check = 1; battle_config.skill_removetrap_type = 0; battle_config.disp_experience = 0; + battle_config.castle_defense_rate = 100; + battle_config.riding_weight = 0; + battle_config.hp_rate = 100; + battle_config.sp_rate = 100; + battle_config.gm_can_drop_lv = 0; + battle_config.disp_hpmeter = 0; + battle_config.bone_drop = 0; + battle_config.item_rate_details = 0; + battle_config.item_rate_1 = 100; + battle_config.item_rate_10 = 100; + battle_config.item_rate_100 = 100; + battle_config.item_rate_1000 = 100; + battle_config.item_rate_1_min = 1; + battle_config.item_rate_1_max = 9; + battle_config.item_rate_10_min = 10; + battle_config.item_rate_10_max = 99; + battle_config.item_rate_100_min = 100; + battle_config.item_rate_100_max = 999; + battle_config.item_rate_1000_min = 1000; + battle_config.item_rate_1000_max = 10000; battle_config.item_rate_common = 100; battle_config.item_rate_equip = 100; battle_config.item_rate_card = 100; @@ -5530,6 +5610,10 @@ void battle_validate_conf() { battle_config.max_aspd = 10; if(battle_config.max_aspd > 1000) battle_config.max_aspd = 1000; + if(battle_config.hp_rate < 0) + battle_config.hp_rate = 1; + if(battle_config.sp_rate < 0) + battle_config.sp_rate = 1; if(battle_config.max_hp > 1000000) battle_config.max_hp = 1000000; if(battle_config.max_hp < 100) diff --git a/src/map/battle.h b/src/map/battle.h index 616a65061..fb3d3e4e2 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -212,6 +212,11 @@ extern struct Battle_Config { int natural_heal_skill_interval; int natural_heal_weight_rate; int item_name_override_grffile; + int indoors_override_grffile; // [Celest] + int skill_sp_override_grffile; // [Celest] + int cardillust_read_grffile; + int item_equip_override_grffile; + int item_slots_override_grffile; int arrow_decrement; int max_aspd; int max_hp; @@ -253,7 +258,6 @@ extern struct Battle_Config { int mob_changetarget_byskill; int pc_attack_direction_change; int monster_attack_direction_change; - int pc_undead_nofreeze; int pc_land_skill_limit; int monster_land_skill_limit; int party_skill_penalty; @@ -314,6 +318,14 @@ extern struct Battle_Config { int castle_defense_rate; int riding_weight; int backstab_bow_penalty; + int hp_rate; + int sp_rate; + int gm_can_drop_lv; + int disp_hpmeter; + int bone_drop; + int item_rate_details,item_rate_1,item_rate_10,item_rate_100,item_rate_1000; //ドロップレート詳細 + int item_rate_1_min,item_rate_10_min,item_rate_100_min,item_rate_1000_min; //ドロップレート詳細min + int item_rate_1_max,item_rate_10_max,item_rate_100_max,item_rate_1000_max; //ドロップレート詳細max int night_at_start; // added by [Yor] int day_duration; // added by [Yor] diff --git a/src/map/clif.c b/src/map/clif.c index 1467493bb..ffa3acd9d 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -2387,6 +2387,8 @@ int clif_updatestatus(struct map_session_data *sd,int type) break; case SP_HP: WFIFOL(fd,4)=sd->status.hp; + if(battle_config.disp_hpmeter) + clif_hpmeter(sd); break; case SP_SP: WFIFOL(fd,4)=sd->status.sp; @@ -5774,6 +5776,46 @@ int clif_party_hp(struct party *p,struct map_session_data *sd) return 0; } /*========================================== + * GMへ場所とHP通知 + *------------------------------------------ + */ +int clif_hpmeter(struct map_session_data *sd) +{ + struct map_session_data *md; + unsigned char buf[16]; + unsigned char buf2[16]; + int i; + + nullpo_retr(0, sd); + + WBUFW(buf,0)=0x107; + WBUFL(buf,2)=sd->bl.id; + WBUFW(buf,6)=sd->bl.x; + WBUFW(buf,8)=sd->bl.y; + + for(i=0;i<fd_max;i++){ + if(session[i] && (md=session[i]->session_data) && md->state.auth && + md->bl.m == sd->bl.m && pc_isGM(md) && sd != md){ + memcpy(WFIFOP(i,0),buf,packet_len_table[0x107]); + WFIFOSET(i,packet_len_table[0x107]); + } + } + + WBUFW(buf2,0)=0x106; + WBUFL(buf2,2)=sd->status.account_id; + WBUFW(buf2,6)=(sd->status.hp > 0x7fff)? 0x7fff:sd->status.hp; + WBUFW(buf2,8)=(sd->status.max_hp > 0x7fff)? 0x7fff:sd->status.max_hp; + for(i=0;i<fd_max;i++){ + if(session[i] && (md=session[i]->session_data) && md->state.auth && + md->bl.m == md->bl.m && pc_isGM(md) && sd != md){ + memcpy(WFIFOP(i,0),buf2,packet_len_table[0x106]); + WFIFOSET(i,packet_len_table[0x106]); + } + } + + return 0; +} +/*========================================== * パーティ場所移動(未使用) *------------------------------------------ */ diff --git a/src/map/clif.h b/src/map/clif.h index cf03820b1..01c28a28f 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -218,6 +218,7 @@ int clif_party_message(struct party *p,int account_id,char *mes,int len); int clif_party_move(struct party *p,struct map_session_data *sd,int online); int clif_party_xy(struct party *p,struct map_session_data *sd); int clif_party_hp(struct party *p,struct map_session_data *sd); +int clif_hpmeter(struct map_session_data *sd); // guild int clif_guild_created(struct map_session_data *sd,int flag); diff --git a/src/map/guild.c b/src/map/guild.c index 83da2a809..7d73692c9 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -1191,10 +1191,17 @@ int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id int flag,const char *name1,const char *name2) { struct guild *g[2]; - int guild_id[2]={guild_id1,guild_id2}; - const char *guild_name[2]={name1,name2}; - struct map_session_data *sd[2]={map_id2sd(account_id1),map_id2sd(account_id2)}; + int guild_id[2]; + const char *guild_name[2]; + struct map_session_data *sd[2]; int j,i; + + guild_id[0] = guild_id1; + guild_id[1] = guild_id2; + guild_name[0] = name1; + guild_name[1] = name2; + sd[0] = map_id2sd(account_id1); + sd[1] = map_id2sd(account_id2); g[0]=guild_search(guild_id1); g[1]=guild_search(guild_id2); diff --git a/src/map/itemdb.c b/src/map/itemdb.c index a68fb3664..49d2a8387 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -40,6 +40,9 @@ static int itemdb_read_sqldb(void); static int itemdb_read_randomitem(); static int itemdb_read_itemavail(void); static int itemdb_read_itemnametable(void); +static int itemdb_read_itemslottable(void); +static int itemdb_read_itemslotcounttable(void); +static int itemdb_read_cardillustnametable(void); static int itemdb_read_noequip(void); static int itemdb_read_norefine(void); void itemdb_reload(void); @@ -99,14 +102,15 @@ int itemdb_searchrandomid(int flags) struct { int nameid,count; struct random_item_data *list; - } data[] ={ - { 0,0,NULL }, - { blue_box_default ,blue_box_count ,blue_box }, - { violet_box_default,violet_box_count ,violet_box }, - { card_album_default,card_album_count ,card_album }, - { gift_box_default ,gift_box_count ,gift_box }, - { scroll_default ,scroll_count ,scroll }, - }; + } data[6]; + + // for BCC32 compile error + data[0].nameid = 0; data[0].count = 0; data[0].list = NULL; + data[1].nameid = blue_box_default; data[1].count = blue_box_count; data[1].list = blue_box; + data[2].nameid = violet_box_default; data[2].count = violet_box_count; data[2].list = violet_box; + data[3].nameid = card_album_default; data[3].count = card_album_count; data[3].list = card_album; + data[4].nameid = gift_box_default; data[4].count = gift_box_count; data[4].list = gift_box; + data[5].nameid = scroll_default; data[5].count = scroll_count; data[5].list = scroll; if(flags>=1 && flags<=5){ nameid=data[flags].nameid; @@ -239,67 +243,40 @@ int itemdb_isdropable(int nameid) return 1; } -// -// 初期化 -// -/*========================================== - * - *------------------------------------------ - */ -static int itemdb_read_itemslottable(void) -{ - char *buf,*p; - int s; - - buf=grfio_read("data\\itemslottable.txt"); - if(buf==NULL) - return -1; - s=grfio_size("data\\itemslottable.txt"); - buf[s]=0; - for(p=buf;p-buf<s;){ - int nameid,equip; - sscanf(p,"%d#%d#",&nameid,&equip); - itemdb_search(nameid)->equip=equip; - p=strchr(p,10); - if(!p) break; - p++; - p=strchr(p,10); - if(!p) break; - p++; - } - free(buf); - - return 0; -} - -#ifndef TXT_ONLY /*==================================== * Removed item_value_db, don't re-add *------------------------------------ */ static void itemdb_read(void) { - itemdb_read_itemslottable(); - - if (db_use_sqldbs) - { - itemdb_read_sqldb(); - } - else - { + #ifndef TXT_ONLY + if (db_use_sqldbs) + { + itemdb_read_sqldb(); + } + else + { + itemdb_readdb(); + } + /* not TXT_ONLY */ + #else itemdb_readdb(); - } + #endif /* TXT_ONLY */ itemdb_read_randomitem(); itemdb_read_itemavail(); itemdb_read_noequip(); itemdb_read_norefine(); - - if (!battle_config.item_name_override_grffile) + if (battle_config.cardillust_read_grffile) + itemdb_read_cardillustnametable(); + if (battle_config.item_equip_override_grffile) + itemdb_read_itemslottable(); + if (battle_config.item_slots_override_grffile) + itemdb_read_itemslotcounttable(); + if (battle_config.item_name_override_grffile) itemdb_read_itemnametable(); } -#endif /* not TXT_ONLY */ /*========================================== * アイテムデータベースの読み込み *------------------------------------------ @@ -559,7 +536,7 @@ static int itemdb_read_itemnametable(void) return 0; } -#ifdef TXT_ONLY + /*========================================== * カードイラストのリソース名前テーブルを読み込む *------------------------------------------ @@ -595,7 +572,74 @@ static int itemdb_read_cardillustnametable(void) return 0; } -#endif /* TXT_ONLY */ + +// +// 初期化 +// +/*========================================== + * + *------------------------------------------ + */ +static int itemdb_read_itemslottable(void) +{ + char *buf,*p; + int s; + + buf=grfio_read("data\\itemslottable.txt"); + if(buf==NULL) + return -1; + s=grfio_size("data\\itemslottable.txt"); + buf[s]=0; + for(p=buf;p-buf<s;){ + int nameid,equip; + sscanf(p,"%d#%d#",&nameid,&equip); + itemdb_search(nameid)->equip=equip; + p=strchr(p,10); + if(!p) break; + p++; + p=strchr(p,10); + if(!p) break; + p++; + } + free(buf); + sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\itemslottable.txt"); + ShowStatus(tmp_output); + + return 0; +} + +/*========================================== + * + *------------------------------------------ + */ +static int itemdb_read_itemslotcounttable(void) +{ + char *buf,*p; + int s; + + buf=grfio_read("data\\itemslotcounttable.txt"); + if(buf==NULL) + return -1; + s=grfio_size("data\\itemslotcounttable.txt"); + buf[s]=0; + for(p=buf;p-buf<s;){ + int nameid,slot; + sscanf(p,"%d#%d#",&nameid,&slot); + itemdb_search(nameid)->slot=slot; + p=strchr(p,10); + if(!p) break; + p++; + p=strchr(p,10); + if(!p) break; + p++; + } + free(buf); + sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\itemslotcounttable.txt"); + ShowStatus(tmp_output); + + return 0; +} + /*========================================== * 装備制限ファイル読み出し *------------------------------------------ @@ -650,8 +694,18 @@ static int itemdb_read_norefine(void) struct item_data *id; // To-do: let it read from a text file later int cant_refine[] = { - 0, 1243, 1530, 2110, 2112, 2264, 2298, 2352, 2410, 2413, - 2414, 2509, 2510, 5008, 5046, 5049, 5050, 5053, 5055, 5098 + 1243, 1530, 2110, 2112, 2201, 2202, 2203, 2204, 2205, 2210, + 2212, 2218, 2219, 2237, 2238, 2239, 2240, 2241, 2242, 2243, + 2250, 2253, 2260, 2262, 2263, 2264, 2265, 2266, 2267, 2268, + 2269, 2270, 2271, 2276, 2278, 2279, 2281, 2282, 2286, 2288, + 2289, 2290, 2291, 2292, 2293, 2295, 2296, 2297, 2298, 2352, + 2410, 2413, 2414, 2509, 2510, 2601, 2602, 2603, 2604, 2605, + 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, + 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626, + 2627, 2628, 2629, 2630, 2631, 2634, 2635, 2636, 2637, 2638, + 2639, 2640, 5004, 5005, 5006, 5008, 5014, 5015, 5037, 5039, + 5040, 5043, 5046, 5049, 5050, 5051, 5053, 5054, 5055, 5058, + 5068, 5074, 5085, 5086, 5087, 5088, 5089, 5090, 5096, 5098, 0 }; for (i=0; i < (int)(sizeof(cant_refine) / sizeof(cant_refine[0])); i++) { @@ -885,24 +939,6 @@ void itemdebugtxt() fclose(dfp); } */ -#ifdef TXT_ONLY -/*==================================== - * Removed item_value_db, don't re-add - *------------------------------------ - */ -static void itemdb_read(void) -{ - itemdb_read_itemslottable(); - itemdb_readdb(); - itemdb_read_randomitem(); - itemdb_read_itemavail(); - itemdb_read_noequip(); - itemdb_read_norefine(); - itemdb_read_cardillustnametable(); - if (!battle_config.item_name_override_grffile) - itemdb_read_itemnametable(); -} -#endif /* TXT_ONLY */ /*========================================== * *------------------------------------------ diff --git a/src/map/map.h b/src/map/map.h index e1a2096c6..5067d6928 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -163,6 +163,7 @@ struct map_session_data { struct mmo_charstatus status; struct item_data *inventory_data[MAX_INVENTORY]; short equip_index[11]; + unsigned short unbreakable_equip; int weight,max_weight; int cart_weight,cart_max_weight,cart_num,cart_max_num; char mapname[24]; @@ -237,6 +238,7 @@ struct map_session_data { int watk_,watk_2,atkmods_[3],addele_[10],addrace_[12],addsize_[3]; //二刀流のために追加 int atk_ele_,star_,overrefine_; //二刀流のために追加 int base_atk,atk_rate; + int weapon_atk[16],weapon_atk_rate[16]; int arrow_atk,arrow_ele,arrow_cri,arrow_hit,arrow_range; int arrow_addele[10],arrow_addrace[12],arrow_addsize[3],arrow_addeff[10],arrow_addeff2[10]; int nhealhp,nhealsp,nshealhp,nshealsp,nsshealhp,nsshealsp; @@ -487,6 +489,14 @@ enum { NONE_ATTACKABLE,ATTACKABLE }; enum { ATK_LUCKY=1,ATK_FLEE,ATK_DEF}; // 囲まれペナルティ計算用 +// 装備コード +enum { + EQP_WEAPON = 0x0002, // 右手 + EQP_ARMOR = 0x0010, // 体 + EQP_SHIELD = 0x0020, // 左手 + EQP_HELM = 0x0100, // 頭上段 +}; + struct map_data { char name[24]; unsigned char *gat; // NULLなら下のmap_data_other_serverとして扱う @@ -592,10 +602,12 @@ enum { SP_MAGIC_DAMAGE_RETURN,SP_RANDOM_ATTACK_INCREASE,SP_ALL_STATS,SP_AGI_VIT,SP_AGI_DEX_STR,SP_PERFECT_HIDE, // 1071-1076 SP_DISGUISE,SP_CLASSCHANGE, // 1077-1078 SP_HP_DRAIN_VALUE,SP_SP_DRAIN_VALUE, // 1079-1080 + SP_WEAPON_ATK,SP_WEAPON_ATK_RATE, // 1081-1082 SP_RESTART_FULL_RECORVER=2000,SP_NO_CASTCANCEL,SP_NO_SIZEFIX,SP_NO_MAGIC_DAMAGE,SP_NO_WEAPON_DAMAGE,SP_NO_GEMSTONE, // 2000-2005 - SP_NO_CASTCANCEL2,SP_INFINITE_ENDURE,SP_UNBREAKABLE_WEAPON,SP_UNBREAKABLE_ARMOR, SP_UNBREAKABLE_HELM, // 2006-2010 - SP_LONG_ATK_RATE // 2011 - celest + SP_NO_CASTCANCEL2,SP_INFINITE_ENDURE,SP_UNBREAKABLE_WEAPON,SP_UNBREAKABLE_ARMOR, SP_UNBREAKABLE_HELM, + SP_UNBREAKABLE_SHIELD, // 2006-2011 + SP_LONG_ATK_RATE // 2012 - celest }; enum { diff --git a/src/map/mob.c b/src/map/mob.c index 27cacb377..1b2792df6 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -37,6 +37,8 @@ struct mob_db mob_db[2001]; +#define CLASSCHANGE_BOSS_NUM 21 + /*========================================== * Local prototype declaration (only required thing) *------------------------------------------ @@ -2093,7 +2095,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type) int mvp_damage,max_hp; unsigned int tick = gettick(); struct map_session_data *mvp_sd = NULL, *second_sd = NULL,*third_sd = NULL; - double dmg_rate,tdmg,temp; + double tdmg,temp; struct item item; int ret; int drop_rate; @@ -2348,12 +2350,12 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type) } } - // [MouseJstr] - if((map[md->bl.m].flag.pvp == 0) || (battle_config.pvp_exp == 1)) { + // [MouseJstr] + if((map[md->bl.m].flag.pvp == 0) || (battle_config.pvp_exp == 1)) { - if((double)max_hp < tdmg) +/* if((double)max_hp < tdmg) dmg_rate = ((double)max_hp) / tdmg; - else dmg_rate = 1; + else dmg_rate = 1;*/ // 経験値の分配 for(i=0;i<DAMAGELOG_SIZE;i++){ @@ -2363,7 +2365,8 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type) if(tmpsd[i]==NULL || tmpsd[i]->bl.m != md->bl.m) continue; /* jAthena's exp formula - per = ((double)md->dmglog[i].dmg)*(9.+(double)((count > 6)? 6:count))/10./((double)max_hp) * dmg_rate; + // per = ((double)md->dmglog[i].dmg)*(9.+(double)((count > 6)? 6:count))/10./((double)max_hp) * dmg_rate; + per = ((double)md->dmglog[i].dmg)*(9.+(double)((count > 6)? 6:count))/10./tdmg; temp = ((double)mob_db[md->class].base_exp * (double)battle_config.base_exp_rate / 100. * per); base_exp = (temp > 2147483647.)? 0x7fffffff:(int)temp; if(mob_db[md->class].base_exp > 0 && base_exp < 1) base_exp = 1; @@ -2891,7 +2894,7 @@ int mob_summonslave(struct mob_data *md2,int *value,int amount,int flag) if(value[0]<=1000 || value[0]>MAX_MOB_DB) // 値が異常なら召喚を止める return 0; - while(count < 5 && value[count] > 1000 && value[count] <= 2000) count++; + while(count < 21 && value[count] > 1000 && value[count] <= 2000) count++; if(count < 1) return 0; for(k=0;k<count;k++) { @@ -3884,7 +3887,46 @@ static int mob_readdb(void) ratemin = battle_config.item_drop_common_min; ratemax = battle_config.item_drop_common_max; } - rate = (rate / 100) * atoi(str[30+i*2]); + if (battle_config.item_rate_details == 1) { //ドロップレート詳細項目が1の時 レート=x/100倍 + if (rate < 10) + rate = rate * battle_config.item_rate_1/100; + else if (rate >= 10 && rate < 100) + rate = rate * battle_config.item_rate_10/100; + else if (rate >= 100 && rate < 1000) + rate = rate * battle_config.item_rate_100/100; + else rate = rate * battle_config.item_rate_1000/100; + } + else if (battle_config.item_rate_details == 2) { //ドロップレート詳細項目が2の時 レート=x/100倍 min max 指定 + if (rate >= 1 && rate < 10) { + if (rate * battle_config.item_rate_1/100 < battle_config.item_rate_1_min) + rate = battle_config.item_rate_1_min; + else if (rate * battle_config.item_rate_1/100 > battle_config.item_rate_1_max) + rate = battle_config.item_rate_1_max; + else rate = rate * battle_config.item_rate_1/100; + } + else if (rate >= 10 && rate < 100) { + if (rate * battle_config.item_rate_10/100 < battle_config.item_rate_10_min) + rate = battle_config.item_rate_10_min; + else if (rate * battle_config.item_rate_10/100 > battle_config.item_rate_10_max) + rate = battle_config.item_rate_10_max; + else rate = rate * battle_config.item_rate_10/100; + } + else if (rate >= 100 && rate < 1000) { + if (rate * battle_config.item_rate_100/100 < battle_config.item_rate_100_min) + rate = battle_config.item_rate_100_min; + else if (rate * battle_config.item_rate_100/100 > battle_config.item_rate_100_max) + rate = battle_config.item_rate_100_max; + else rate = rate * battle_config.item_rate_100/100; + } + else if (rate >= 1000) { + if (rate * battle_config.item_rate_1000/100 < battle_config.item_rate_1000_min) + rate = battle_config.item_rate_1000_min; + else if (rate * battle_config.item_rate_1000/100 > battle_config.item_rate_1000_max) + rate = battle_config.item_rate_1000_max; + else rate = rate * battle_config.item_rate_1000/100; + } + } + rate = rate * atoi(str[30+i*2])/100; rate = (rate < ratemin)? ratemin: (rate > ratemax)? ratemax: rate; mob_db[class].dropitem[i].p = rate; } diff --git a/src/map/npc.c b/src/map/npc.c index e8ead8d29..bb6b9138c 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -2303,7 +2303,8 @@ int do_init_npc(void) char c = '-'; // indoorrswtable.txt and etcinfo.txt [Celest] - npc_read_indoors(); + if (battle_config.indoors_override_grffile) + npc_read_indoors(); //npc_read_weather(); ev_db=strdb_init(24); diff --git a/src/map/pc.c b/src/map/pc.c index 09b8b8c4d..306360ed5 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -588,6 +588,52 @@ int pc_isequip(struct map_session_data *sd,int n) return 1; } +//装備破壊 +int pc_break_equip(struct map_session_data *sd, unsigned short where) +{ + struct item_data* item; + int i; + int sc; + char output[255]; + + if(sd == NULL) + return -1; + if(sd->unbreakable_equip & where) + return 0; + switch (where) { + case EQP_WEAPON: + sc = SC_CP_WEAPON; + break; + case EQP_ARMOR: + sc = SC_CP_ARMOR; + break; + case EQP_SHIELD: + sc = SC_CP_SHIELD; + break; + case EQP_HELM: + sc = SC_CP_HELM; + break; + default: + return 0; + } + if( sd->sc_data && sd->sc_data[sc].timer != -1 ) + return 0; + + for (i=0;i<MAX_INVENTORY;i++) { + if (sd->status.inventory[i].equip & where) { + item=sd->inventory_data[i]; + sd->status.inventory[i].attribute = 1; + pc_unequipitem(sd,i,0); + break; + } + } + sprintf(output, "%s has broken.",item->jname); + clif_emotion(&sd->bl,23); + clif_displaymessage(sd->fd, output); + clif_equiplist(sd); + return 0; +} + /*========================================== * Weapon Breaking [Valaris] *------------------------------------------ @@ -1230,8 +1276,8 @@ int pc_calcstatus(struct map_session_data* sd,int first) sd->matk1 =0; sd->matk2 =0; sd->speed = DEFAULT_WALK_SPEED ; - sd->hprate=100; - sd->sprate=100; + sd->hprate=battle_config.hp_rate; + sd->sprate=battle_config.sp_rate; sd->castrate=100; sd->dsprate=100; sd->base_atk=0; @@ -1254,6 +1300,8 @@ int pc_calcstatus(struct map_session_data* sd,int first) memset(&sd->special_state,0,sizeof(sd->special_state)); memset(sd->weapon_coma_ele,0,sizeof(sd->weapon_coma_ele)); memset(sd->weapon_coma_race,0,sizeof(sd->weapon_coma_race)); + memset(sd->weapon_atk,0,sizeof(sd->weapon_atk)); + memset(sd->weapon_atk_rate,0,sizeof(sd->weapon_atk_rate)); sd->watk_ = 0; //二刀流用(?) sd->watk_2 = 0; @@ -1307,6 +1355,9 @@ int pc_calcstatus(struct map_session_data* sd,int first) sd->short_weapon_damage_return = sd->long_weapon_damage_return = 0; sd->magic_damage_return = 0; //AppleGirl Was Here sd->random_attack_increase_add = sd->random_attack_increase_per = 0; + sd->hp_drain_value = sd->hp_drain_value_ = sd->sp_drain_value = sd->sp_drain_value_ = 0; + sd->unbreakable_equip = 0; + if(!sd->disguiseflag && sd->disguise) { sd->disguise=0; @@ -1549,6 +1600,10 @@ int pc_calcstatus(struct map_session_data* sd,int first) if(sd->sc_data[SC_CHASEWALK].val4) sd->paramb[0] += (1<<(sd->sc_data[SC_CHASEWALK].val1-1)); // increases strength after 10 seconds } + if(sd->sc_data[SC_SLOWDOWN].timer!=-1) + sd->speed = sd->speed*150/100; + if(sd->sc_data[SC_SPEEDUP0].timer!=-1) + sd->speed -= sd->speed*25/100; if(sd->sc_data[SC_BLESSING].timer!=-1){ // ブレッシング sd->paramb[0]+= sd->sc_data[SC_BLESSING].val1; sd->paramb[3]+= sd->sc_data[SC_BLESSING].val1; @@ -2210,6 +2265,10 @@ int pc_calcspeed (struct map_session_data *sd) } if(sd->sc_data[SC_CURSE].timer!=-1) sd->speed += 450; + if(sd->sc_data[SC_SLOWDOWN].timer!=-1) + sd->speed = sd->speed*150/100; + if(sd->sc_data[SC_SPEEDUP0].timer!=-1) + sd->speed -= sd->speed*25/100; } if(sd->status.option&2 && (skill = pc_checkskill(sd,RG_TUNNELDRIVE))>0 ) @@ -2546,6 +2605,22 @@ int pc_bonus(struct map_session_data *sd,int type,int val) if(sd->state.lr_flag != 2) sd->special_state.infinite_endure = 1; break; + case SP_UNBREAKABLE_WEAPON: + if(sd->state.lr_flag != 2) + sd->unbreakable_equip |= EQP_WEAPON; + break; + case SP_UNBREAKABLE_ARMOR: + if(sd->state.lr_flag != 2) + sd->unbreakable_equip |= EQP_ARMOR; + break; + case SP_UNBREAKABLE_HELM: + if(sd->state.lr_flag != 2) + sd->unbreakable_equip |= EQP_HELM; + break; + case SP_UNBREAKABLE_SHIELD: + if(sd->state.lr_flag != 2) + sd->unbreakable_equip |= EQP_SHIELD; + break; case SP_SPLASH_RANGE: if(sd->state.lr_flag != 2 && sd->splash_range < val) sd->splash_range = val; @@ -2837,6 +2912,14 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) sd->random_attack_increase_per += val; } break; + case SP_WEAPON_ATK: + if(sd->state.lr_flag != 2) + sd->weapon_atk[type2]+=val; + break; + case SP_WEAPON_ATK_RATE: + if(sd->state.lr_flag != 2) + sd->weapon_atk_rate[type2]+=val; + break; default: if(battle_config.error_log) printf("pc_bonus2: unknown type %d %d %d!\n",type,type2,val); @@ -3203,7 +3286,8 @@ int pc_dropitem(struct map_session_data *sd,int n,int amount) sd->status.inventory[n].amount < amount || sd->trade_partner != 0 || sd->vender_id != 0 || sd->status.inventory[n].amount <= 0 || - itemdb_isdropable(sd->status.inventory[n].nameid) == 0) // Celest + itemdb_isdropable(sd->status.inventory[n].nameid) == 0 || // Celest + pc_candrop(sd,sd->status.inventory[n].nameid)) return 1; map_addflooritem(&sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, NULL, NULL, NULL, 0); pc_delitem(sd, n, amount, 0); @@ -3279,6 +3363,8 @@ int pc_isUseitem(struct map_session_data *sd,int n) if(item == NULL) return 0; + if(item->type != 0 && item->type != 2) + return 0; if((nameid == 605) && map[sd->bl.m].flag.gvg) return 0; if(nameid == 601 && (map[sd->bl.m].flag.noteleport || map[sd->bl.m].flag.gvg)) { @@ -3432,6 +3518,10 @@ int pc_putitemtocart(struct map_session_data *sd,int idx,int amount) { nullpo_retr(0, sd); nullpo_retr(0, item_data = &sd->status.inventory[idx]); + if(itemdb_isdropable(sd->status.inventory[idx].nameid) == 0) + return 1; + if(pc_candrop(sd,sd->status.inventory[idx].nameid)==1) + return 1; if (item_data->nameid==0 || item_data->amount<amount || sd->vender_id) return 1; if (pc_cart_additem(sd,item_data,amount) == 0) @@ -3836,6 +3926,7 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt intif_save_petdata(sd->status.account_id,&sd->pet); chrif_save(sd); storage_storage_save(sd); + storage_delete(sd->status.account_id); chrif_changemapserver(sd, mapname, x, y, ip, port); return 0; } @@ -4174,6 +4265,8 @@ static int pc_walk(int tid,unsigned int tick,int id,int data) i = 1; sd->walktimer=add_timer(tick+i,pc_walk,id,sd->walkpath.path_pos); } + if(battle_config.disp_hpmeter) + clif_hpmeter(sd); return 0; } @@ -5498,6 +5591,18 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage) clif_updatestatus(sd,SP_HP); pc_calcstatus(sd,0); + if(battle_config.bone_drop==2 + || (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp)){ // ドクロドロップ + struct item item_tmp; + memset(&item_tmp,0,sizeof(item_tmp)); + item_tmp.nameid=7005; + item_tmp.identify=1; + item_tmp.card[0]=0x00fe; + item_tmp.card[1]=0; + *((unsigned long *)(&item_tmp.card[2]))=sd->char_id; /* キャラID */ + map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); + } + // activate Steel body if a super novice dies at 99+% exp [celest] if (s_class.job == 23) { if ((i=pc_nextbaseexp(sd))<=0) @@ -6287,6 +6392,18 @@ int pc_setriding(struct map_session_data *sd) } /*========================================== + * アイテムドロップ可不可判定 + *------------------------------------------ + */ +int pc_candrop(struct map_session_data *sd,int item_id) +{ + int level; + if((level=pc_isGM(sd))>0 && level < battle_config.gm_can_drop_lv) // search only once [Celest] + return 1; + return 0; +} + +/*========================================== * script用??の値を?む *------------------------------------------ */ diff --git a/src/map/pc.h b/src/map/pc.h index b40b11ac2..1f294ce92 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -162,7 +162,8 @@ int pc_divorce(struct map_session_data *sd); struct map_session_data *pc_get_partner(struct map_session_data *sd); int pc_set_gm_level(int account_id, int level); void pc_setstand(struct map_session_data *sd); - +int pc_break_equip(struct map_session_data *sd, unsigned short where); +int pc_candrop(struct map_session_data *sd,int item_id); struct pc_base_job{ int job; //職業、ただし転生職や養子職の場合は元の職業を返す(廃プリ→プリ) diff --git a/src/map/script.c b/src/map/script.c index 5c6b89092..5d9d60385 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -274,6 +274,7 @@ int buildin_petloot(struct script_state *st); // pet looting [Valaris] int buildin_petheal(struct script_state *st); // pet healing [Valaris] int buildin_petmag(struct script_state *st); // pet magnificat [Valaris] int buildin_petskillattack(struct script_state *st); // pet skill attacks [Valaris] +int buildin_skilleffect(struct script_state *st); // skill effects [Celest] int buildin_npcskilleffect(struct script_state *st); // skill effects for npcs [Valaris] int buildin_specialeffect(struct script_state *st); // special effect script [Valaris] int buildin_specialeffect2(struct script_state *st); // special effect script [Valaris] @@ -292,6 +293,8 @@ int buildin_getmapxy(struct script_state *st); //get map position for player/np int buildin_checkoption1(struct script_state *st); // [celest] int buildin_checkoption2(struct script_state *st); // [celest] int buildin_guildgetexp(struct script_state *st); // [celest] +int buildin_skilluseid(struct script_state *st); // originally by Qamera [celest] +int buildin_skillusepos(struct script_state *st); // originally by Qamera [celest] void push_val(struct script_stack *stack,int type,int val); int run_func(struct script_state *st); @@ -481,6 +484,7 @@ struct { {buildin_petheal,"petheal","iii"}, // [Valaris] {buildin_petmag,"petmag","iiii"}, // [Valaris] {buildin_petskillattack,"petskillattack","iiii"}, // [Valaris] + {buildin_skilleffect,"skilleffect","ii"}, // skill effect [Celest] {buildin_npcskilleffect,"npcskilleffect","iiii"}, // npc skill effect [Valaris] {buildin_specialeffect,"specialeffect","i"}, // npc skill effect [Valaris] {buildin_specialeffect2,"specialeffect2","i"}, // skill effect on players[Valaris] @@ -504,6 +508,9 @@ struct { {buildin_checkoption1,"checkoption1","i"}, {buildin_checkoption2,"checkoption2","i"}, {buildin_guildgetexp,"guildgetexp","i"}, + {buildin_skilluseid,"skilluseid","ii"}, // originally by Qamera [Celest] + {buildin_skilluseid,"doskill","ii"}, // since a lot of scripts would already use 'doskill'... + {buildin_skillusepos,"skillusepos","iiii"}, // [Celest] {NULL,NULL,NULL}, }; int buildin_message(struct script_state *st); // [MouseJstr] @@ -2323,7 +2330,8 @@ int buildin_getitem(struct script_state *st) return 0; if((flag = pc_additem(sd,&item_tmp,amount))) { clif_additem(sd,0,0,flag); - map_addflooritem(&item_tmp,amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); + if(!pc_candrop(sd,nameid)) + map_addflooritem(&item_tmp,amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0); } } @@ -5827,6 +5835,24 @@ int buildin_petskillattack(struct script_state *st) return 0; } + +/*========================================== + * Scripted skill effects [Celest] + *------------------------------------------ + */ +int buildin_skilleffect(struct script_state *st) +{ + struct map_session_data *sd; + + int skillid=conv_num(st,& (st->stack->stack_data[st->start+2])); + int skilllv=conv_num(st,& (st->stack->stack_data[st->start+3])); + sd=script_rid2sd(st); + + clif_skill_nodamage(&sd->bl,&sd->bl,skillid,skilllv,1); + + return 0; +} + /*========================================== * NPC skill effects [Valaris] *------------------------------------------ @@ -6284,6 +6310,42 @@ int buildin_getmapxy(struct script_state *st){ return 0; } +/*===================================================== + * Allows players to use a skill - by Qamera + *----------------------------------------------------- + */ +int buildin_skilluseid (struct script_state *st) +{ + int skid,sklv; + struct map_session_data *sd; + + skid=conv_num(st,& (st->stack->stack_data[st->start+2])); + sklv=conv_num(st,& (st->stack->stack_data[st->start+3])); + sd=script_rid2sd(st); + skill_use_id(sd,sd->status.account_id,skid,sklv); + + return 0; +} + +/*===================================================== + * Allows players to use a skill on a position [Celest] + *----------------------------------------------------- + */ +int buildin_skillusepos(struct script_state *st) +{ + int skid,sklv,x,y; + struct map_session_data *sd; + + skid=conv_num(st,& (st->stack->stack_data[st->start+2])); + sklv=conv_num(st,& (st->stack->stack_data[st->start+3])); + x=conv_num(st,& (st->stack->stack_data[st->start+4])); + y=conv_num(st,& (st->stack->stack_data[st->start+5])); + + sd=script_rid2sd(st); + skill_use_pos(sd,x,y,skid,sklv); + + return 0; +} // // 実行部main diff --git a/src/map/skill.c b/src/map/skill.c index dacd08e88..21c5bd954 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -231,7 +231,8 @@ int SkillStatusChangeTable[]={ /* skill.hのenumのSC_***とあわせること */ SC_BASILICA, -1,-1,-1, SC_MAGICPOWER, - -1,-1, + -1, + SC_SACRIFICE, SC_GOSPEL, /* 370- */ -1,-1,-1,-1,-1,-1,-1,-1, @@ -2335,7 +2336,7 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s case LK_HEADCRUSH: /* ヘッドクラッシュ */ case LK_JOINTBEAT: /* ジョイントビ?ト */ case PA_PRESSURE: /* プレッシャ? */ - case PA_SACRIFICE: /* サクリファイス */ +// case PA_SACRIFICE: /* サクリファイス */ case SN_SHARPSHOOTING: /* シャ?プシュ?ティング */ case CG_ARROWVULCAN: /* アロ?バルカン */ case ASC_BREAKER: /* ソウルブレ?カ? */ @@ -2538,12 +2539,11 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s /* 個別にダメ?ジを?える */ if(bl->id!=skill_area_temp[1]) skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0x0500); - } - else { - int damage; + } else { +/* int damage; map_freeblock_lock(); damage = skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0); - if(damage > 0) { + if(damage > 0) {*/ int i,c; /* 他人から聞いた動きなので間違ってる可能性大&?率が?いっす>< */ c = skill_get_blewcount(skillid,skilllv); if(map[bl->m].flag.gvg) c = 0; @@ -2565,16 +2565,18 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s skill_area_temp[1]=bl->id; skill_area_temp[2]=bl->x; skill_area_temp[3]=bl->y; + skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0); + /* その後タ?ゲット以外の範??の敵全?に?理を行う */ map_foreachinarea(skill_area_sub, bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,0, src,skillid,skilllv,tick, flag|BCT_ENEMY|1, skill_castend_damage_id); - battle_damage(src,bl,damage,1); +/* battle_damage(src,bl,damage,1); if(rdamage > 0) battle_damage(bl,src,rdamage,0); } - map_freeblock_unlock(); + map_freeblock_unlock();*/ } break; @@ -2597,7 +2599,7 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s case WZ_EARTHSPIKE: /* アーススパイク */ case AL_HEAL: /* ヒール */ case AL_HOLYLIGHT: /* ホーリーライト */ - case MG_FROSTDIVER: /* フロストダイバー */ +// case MG_FROSTDIVER: /* フロストダイバー */ case WZ_JUPITEL: /* ユピテルサンダー */ case NPC_DARKJUPITEL: /*闇ユピテル*/ case NPC_MAGICALATTACK: /* MOB:魔法打?攻? */ @@ -2606,6 +2608,28 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); break; + case MG_FROSTDIVER: /* フロストダイバー */ + { + struct status_change *sc_data = battle_get_sc_data(bl); + int sc_def_mdef, rate, damage; + sc_def_mdef = 100 - (3 + battle_get_mdef(bl) + battle_get_luk(bl)/3); + rate = (skilllv*3+35)*sc_def_mdef/100-(battle_get_int(bl)+battle_get_luk(bl))/15; + rate = rate<=5?5:rate; + if (sc_data && sc_data[SC_FREEZE].timer != -1) { + skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); + } else if (sd) { + clif_skill_fail(sd,skillid,0,0); + break; + } + damage = skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); + if (battle_get_hp(bl) > 0 && damage > 0 && rand()%100 < rate) { + skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); + } else if (sd) { + clif_skill_fail(sd,skillid,0,0); + } + break; + } + case WZ_WATERBALL: /* ウォ?タ?ボ?ル */ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag); if(skilllv>1) @@ -2849,7 +2873,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int struct mob_data *md=NULL; struct mob_data *dstmd=NULL; int i,abra_skillid=0,abra_skilllv; - int sc_def_vit,sc_def_mdef,strip_fix,strip_time,strip_per; + int sc_def_vit,sc_def_mdef,strip_time,strip_per; int sc_dex,sc_luk; //クラスチェンジ用ボスモンスタ?ID int changeclass[]={1038,1039,1046,1059,1086,1087,1112,1115 @@ -2872,7 +2896,6 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int sc_def_vit = 100 - (3 + battle_get_vit(bl) + battle_get_luk(bl)/3); //sc_def_vit = 100 - (3 + battle_get_vit(bl) + battle_get_luk(bl)/3); sc_def_mdef = 100 - (3 + battle_get_mdef(bl) + battle_get_luk(bl)/3); - strip_fix = battle_get_dex(src) - battle_get_dex(bl); if(bl->type==BL_PC){ nullpo_retr(1, dstsd=(struct map_session_data *)bl); @@ -2887,8 +2910,6 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int sc_def_vit=0; if(sc_def_mdef < 0) sc_def_mdef=0; - if(strip_fix < 0) - strip_fix=0; if(bl == NULL || bl->prev == NULL) return 1; @@ -3231,6 +3252,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int case ST_REJECTSWORD: /* リジェクトソ?ド */ case HW_MAGICPOWER: /* 魔法力?幅 */ case PF_MEMORIZE: /* メモライズ */ + case PA_SACRIFICE: case ASC_EDP: // [Celest] clif_skill_nodamage(src,bl,skillid,skilllv,1); skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0 ); @@ -3713,6 +3735,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int case MG_STONECURSE: /* スト?ンカ?ス */ { + struct status_change *sc_data = battle_get_sc_data(bl); // Level 6-10 doesn't consume a red gem if it fails [celest] int i, gem_flag = 1; if (bl->type==BL_MOB && battle_get_mode(bl)&0x20) { @@ -3722,7 +3745,12 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int clif_skill_nodamage(src,bl,skillid,skilllv,1); if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage ) break; - if( rand()%100 < skilllv*4+20 && !battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl))) + if (sc_data && sc_data[SC_STONE].timer != -1) { + skill_status_change_end(bl,SC_STONE,-1); + if (sd) + clif_skill_fail(sd,skillid,0,0); + } + else if( rand()%100 < skilllv*4+20 && !battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl))) skill_status_change_start(bl,SC_STONE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); else if(sd) { if (skilllv > 5) gem_flag = 0; @@ -3876,105 +3904,67 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int break; case RG_STRIPWEAPON: /* ストリップウェポン */ - { - struct status_change *tsc_data = battle_get_sc_data(bl); - - if(tsc_data && tsc_data[SC_CP_WEAPON].timer != -1 ) + case RG_STRIPSHIELD: /* ストリップシールド */ + case RG_STRIPARMOR: /* ストリップアーマー */ + case RG_STRIPHELM: /* ストリップヘルム */ + { + struct status_change *tsc_data = battle_get_sc_data(bl); + int scid, equip, strip_fix; + scid = SkillStatusChangeTable[skillid]; + switch (skillid) { + case RG_STRIPWEAPON: + equip = EQP_WEAPON; break; - strip_per = 5+2*skilllv+strip_fix/5; - strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - if(rand()%100 < strip_per){ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 ); - if(dstsd){ - for(i=0;i<MAX_INVENTORY;i++){ - if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & 0x0002){ - pc_unequipitem(dstsd,i,3); - break; - } - } - } - } - } - break; - - case RG_STRIPSHIELD: /* ストリップシ?ルド */ - { - struct status_change *tsc_data = battle_get_sc_data(bl); - - if(tsc_data && tsc_data[SC_CP_SHIELD].timer != -1 ) + case RG_STRIPSHIELD: + equip = EQP_SHIELD; break; - strip_per = 5+2*skilllv+strip_fix/5; - strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - if(rand()%100 < strip_per){ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 ); - if(dstsd){ - for(i=0;i<MAX_INVENTORY;i++){ - if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & 0x0020){ - pc_unequipitem(dstsd,i,3); - break; - } - } - } - } - } - break; - - case RG_STRIPARMOR: /* ストリップア?マ? */ - { - struct status_change *tsc_data = battle_get_sc_data(bl); - - if(tsc_data && tsc_data[SC_CP_ARMOR].timer != -1 ) + case RG_STRIPARMOR: + equip = EQP_ARMOR; break; - strip_per = 5+2*skilllv+strip_fix/5; - strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - if(rand()%100 < strip_per){ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 ); - if(dstsd){ - for(i=0;i<MAX_INVENTORY;i++){ - if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & 0x0010){ - pc_unequipitem(dstsd,i,3); - break; - } - } - } - } + case RG_STRIPHELM: + equip = EQP_HELM; + break; + default: + return 1; } - break; - case RG_STRIPHELM: /* ストリップヘルム */ - { - struct status_change *tsc_data = battle_get_sc_data(bl); - - if(tsc_data && tsc_data[SC_CP_HELM].timer != -1 ) - break; - strip_per = 5+2*skilllv+strip_fix/5; - strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - if(rand()%100 < strip_per){ - clif_skill_nodamage(src,bl,skillid,skilllv,1); - skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 ); - if(dstsd){ - for(i=0;i<MAX_INVENTORY;i++){ - if(dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & 0x0100){ - pc_unequipitem(dstsd,i,3); - break; - } - } + if (tsc_data && tsc_data[scid].timer != -1) + break; + + strip_fix = battle_get_dex(src) - battle_get_dex(bl); + if(strip_fix < 0) + strip_fix=0; + strip_per = 5+2*skilllv+strip_fix/5; + if (rand()%100 >= strip_per) + break; + + if (dstsd) { + for (i=0;i<MAX_INVENTORY;i++) { + if (dstsd->status.inventory[i].equip && dstsd->status.inventory[i].equip & equip){ + pc_unequipitem(dstsd,i,0); + break; } } + if (i == MAX_INVENTORY) + break; } + clif_skill_nodamage(src,bl,skillid,skilllv,1); + strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; + skill_status_change_start(bl,scid,skilllv,0,0,0,strip_time,0 ); break; + } // Full Strip [Celest] case ST_FULLSTRIP: { struct status_change *tsc_data = battle_get_sc_data(bl); - int c=0, i, j; + int c=0, i, j, strip_fix; int striplist[2][4] = { { 0, 0, 0, 0 }, { 0x0002, 0x0020, 0x0010, 0x0100 } }; + strip_fix = battle_get_dex(src) - battle_get_dex(bl); + if(strip_fix < 0) + strip_fix=0; strip_per = 5+2*skilllv+strip_fix/5; strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; for (i=0; i<4; i++) { @@ -5170,13 +5160,14 @@ int skill_castend_map( struct map_session_data *sd,int skill_num, const char *ma case AL_WARP: /* ワ?プポ?タル */ { - const struct point *p[]={ - &sd->status.save_point,&sd->status.memo_point[0], - &sd->status.memo_point[1],&sd->status.memo_point[2], - }; + const struct point *p[4]; struct skill_unit_group *group; int i; int maxcount=0; + p[0] = &sd->status.save_point; + p[1] = &sd->status.memo_point[0]; + p[2] = &sd->status.memo_point[1]; + p[3] = &sd->status.memo_point[2]; if((maxcount = skill_get_maxcount(sd->skillid)) > 0) { int c; @@ -7390,6 +7381,11 @@ int skill_castfix( struct block_list *bl, int time ) castnodex=skill_get_castnodex(skill, lv); + /* サフラギウム */ + if(sc_data && sc_data[SC_SUFFRAGIUM].timer!=-1 ) + time=time*(100-sc_data[SC_SUFFRAGIUM].val1*15)/100; + skill_status_change_end( bl, SC_SUFFRAGIUM, -1); + if(time==0) return 0; if(castnodex > 0 && bl->type==BL_PC) @@ -7400,17 +7396,10 @@ int skill_castfix( struct block_list *bl, int time ) time=time*battle_config.cast_rate/100; } - /* サフラギウム */ - if(sc_data) { - if ( sc_data[SC_SUFFRAGIUM].timer!=-1 ){ - time=time*(100-sc_data[SC_SUFFRAGIUM].val1*15)/100; - skill_status_change_end( bl, SC_SUFFRAGIUM, -1); - } - /* ブラギの詩 */ - if( sc_data[SC_POEMBRAGI].timer!=-1 ) - time=time*(100-(sc_data[SC_POEMBRAGI].val1*3+sc_data[SC_POEMBRAGI].val2 - +(sc_data[SC_POEMBRAGI].val3>>16)))/100; - } + /* ブラギの詩 */ + if(sc_data && sc_data[SC_POEMBRAGI].timer!=-1) + time=time*(100-(sc_data[SC_POEMBRAGI].val1*3+sc_data[SC_POEMBRAGI].val2 + +(sc_data[SC_POEMBRAGI].val3>>16)))/100; return (time>0)?time:0; } @@ -7426,7 +7415,8 @@ int skill_delayfix( struct block_list *bl, int time ) sc_data = battle_get_sc_data(bl); if(time<=0) - return 0; + return ( battle_get_adelay(bl) / 2 ); + if(bl->type == BL_PC) { if( battle_config.delay_dependon_dex ) /* dexの影響を計算する */ @@ -7629,7 +7619,7 @@ int skill_use_id( struct map_session_data *sd, int target_id, range = skill_get_range(skill_num,skill_lv); if(range < 0) range = battle_get_range(&sd->bl) - (range + 1); - if(!battle_check_range(&sd->bl,bl,range) ) + if(!battle_check_range(&sd->bl,bl,range + 1) ) return 0; if(bl->type==BL_PC) { @@ -7721,6 +7711,9 @@ int skill_use_id( struct map_session_data *sd, int target_id, case PF_MEMORIZE: /* メモライズ */ casttime = 12000; break; + case HW_MAGICPOWER: + casttime = 700; + break; case GD_BATTLEORDER: case GD_REGENERATION: case GD_RESTORE: @@ -7736,11 +7729,6 @@ int skill_use_id( struct map_session_data *sd, int target_id, skill_status_change_end(&sd->bl, SC_MEMORIZE, -1); } - // instant cast attack skills depend on aspd as delay [celest] - if (casttime == 0 && delay == 0 && skill_db[skill_num].skill_type == BF_WEAPON) { - delay = battle_get_adelay (&sd->bl) * battle_config.delay_rate / 100; - } - if(battle_config.pc_skill_log) printf("PC %d skill use target_id=%d skill=%d lv=%d cast=%d\n",sd->bl.id,target_id,skill_num,skill_lv,casttime); @@ -7787,10 +7775,6 @@ int skill_use_id( struct map_session_data *sd, int target_id, skill_castend_id(sd->skilltimer,tick,sd->bl.id,0); } - //マジックパワ?の?果終了 - //if(sc_data && sc_data[SC_MAGICPOWER].timer != -1 && skill_num != HW_MAGICPOWER) - // skill_status_change_end(&sd->bl,SC_MAGICPOWER,-1); // moved - return 0; } @@ -7877,6 +7861,9 @@ int skill_use_pos( struct map_session_data *sd, range = skill_get_range(skill_num,skill_lv); if(range < 0) range = battle_get_range(&sd->bl) - (range + 1); +// be lenient if the skill was cast before we have moved to the correct position [Celest] + if (sd->walktimer != -1) + range += battle_config.skill_range_leniency; if(!battle_check_range(&sd->bl,&bl,range) ) return 0; @@ -8693,6 +8680,7 @@ int skill_status_change_end(struct block_list* bl, int type, int tid) case SC_MARIONETTE: case SC_MARIONETTE2: case SC_SLOWDOWN: + case SC_SPEEDUP0: /* case SC_LEADERSHIP: case SC_GLORYWOUNDS: case SC_SOULCOLD: @@ -8980,23 +8968,10 @@ int skill_status_change_timer(int tid, unsigned int tick, int id, int data) break; case SC_SIGHT: /* サイト */ - { - const int range=7; - map_foreachinarea( skill_status_change_timer_sub, - bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,0, - bl,type,tick); - - if( (--sc_data[type].val2)>0 ){ - sc_data[type].timer=add_timer( /* タイマ?再設定 */ - 250+tick, skill_status_change_timer, - bl->id, data); - return 0; - } - } - break; case SC_RUWACH: /* ルアフ */ { - const int range=5; + int range = 5; + if ( type == SC_SIGHT ) range = 7; map_foreachinarea( skill_status_change_timer_sub, bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,0, bl,type,tick); @@ -9215,6 +9190,7 @@ int skill_status_change_timer(int tid, unsigned int tick, int id, int data) case SC_MEMORIZE: /* メモライズ */ case SC_BROKNWEAPON: case SC_BROKNARMOR: + case SC_SACRIFICE: // if(sc_data[type].timer==tid) sc_data[type].timer=add_timer( 1000*600+tick,skill_status_change_timer, bl->id, data ); return 0; @@ -9679,6 +9655,13 @@ int skill_status_change_start(struct block_list *bl, int type, int val1, int val if(sc_data[SC_CARTBOOST].timer!=-1 ) /* カ?トブ?スト */ skill_status_change_end(bl,SC_CARTBOOST,-1); break; + case SC_MAGICPOWER: + calc_flag = 1; + val2 = 1; + break; + case SC_SACRIFICE: + val2 = 5; + break; case SC_FLAMELAUNCHER: /* フレ?ムランチャ? */ skill_encchant_eremental_end(bl,SC_FLAMELAUNCHER); break; @@ -9919,9 +9902,29 @@ int skill_status_change_start(struct block_list *bl, int type, int val1, int val } break; - /* option2 */ - case SC_POISON: /* 毒 */ + /* option2 */ case SC_DPOISON: /* 猛毒 */ + { + int mhp = battle_get_max_hp(bl); + int hp = battle_get_hp(bl); + // MHP?1/4???????? + if (hp > mhp>>2) { + if(bl->type == BL_PC) { + int diff = mhp*10/100; + if (hp - diff < mhp>>2) + hp = hp - (mhp>>2); + pc_heal((struct map_session_data *)bl, -hp, 0); + } else if(bl->type == BL_MOB) { + struct mob_data *md = (struct mob_data *)bl; + hp -= mhp*15/100; + if (hp > mhp>>2) + md->hp = hp; + else + md->hp = mhp>>2; + } + } + } // fall through + case SC_POISON: /* 毒 */ calc_flag = 1; if(!(flag&2)) { int sc_def = 100 - (battle_get_vit(bl) + battle_get_luk(bl)/5); @@ -10127,7 +10130,6 @@ int skill_status_change_start(struct block_list *bl, int type, int val1, int val case SC_CARTBOOST: /* カ?トブ?スト */ case SC_TRUESIGHT: /* トゥル?サイト */ case SC_SPIDERWEB: /* スパイダ?ウェッブ */ - case SC_MAGICPOWER: /* 魔法力?幅 */ calc_flag = 1; break; @@ -10161,6 +10163,7 @@ int skill_status_change_start(struct block_list *bl, int type, int val1, int val break; case SC_SLOWDOWN: + case SC_SPEEDUP0: calc_flag = 1; break; @@ -12049,7 +12052,8 @@ void skill_reload(void) int do_init_skill(void) { skill_readdb(); - skill_read_skillspamount(); + if (battle_config.skill_sp_override_grffile) + skill_read_skillspamount(); add_timer_func_list(skill_unit_timer,"skill_unit_timer"); add_timer_func_list(skill_castend_id,"skill_castend_id"); diff --git a/src/map/skill.h b/src/map/skill.h index 4d1319599..5baf42024 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -313,10 +313,9 @@ enum { // struct map_session_data の status_changeの番?テ?ブル SC_SPIDERWEB =180, /* スパイダ?ウェッブ */ SC_MEMORIZE =181, /* メモライズ */ -// SC_DPOISON =182, /* 猛毒 */ - -// SC_EDP =183, /* エフェクトが判明したら移動 */ - + SC_DPOISON =182, /* 猛毒 */ + SC_EDP =183, /* エフェクトが判明したら移動 */ + SC_SACRIFICE =184, /* サクリファイス */ SC_WEDDING =187, //結婚用(結婚衣裳になって?くのが?いとか) SC_NOCHAT =188, //赤エモ?態 SC_SPLASHER =189, /* ベナムスプラッシャ? */ @@ -326,25 +325,27 @@ enum { // struct map_session_data の status_changeの番?テ?ブル // Used by English Team SC_BROKNARMOR =32, SC_BROKNWEAPON =33, + SC_SPEEDUP0 =41, // for skill speedup + SC_SPEEDUP1 =42, // for skill speedup SC_SLOWDOWN =45, // for skill slowdown SC_AUTOBERSERK =46, SC_SIGHTTRASHER =73, // SC_BASILICA =125, // 125 is the same id as joint break SC_BASILICA =102, // temporarily use this before an actual id is found [celest] - SC_EDP =114, // +// SC_EDP =114, // SC_MARIONETTE2 =122, // Marionette target SC_ENSEMBLE =159, SC_FOGWALL =178, SC_GOSPEL =179, - SC_LANDPROTECTOR =182, - SC_ADAPTATION =183, - SC_CHASEWALK =184, SC_ATKPOT =185, // [Valaris] SC_MATKPOT =186, // [Valaris] SC_MINDBREAKER =191, SC_SPELLBREAKER =192, - SC_DPOISON =193, /* 猛毒 */ + SC_LANDPROTECTOR =193, +// SC_DPOISON =193, /* 猛毒 */ SC_BLOCKSKILL =194, // for disallowing the use of a skill for a time period + SC_ADAPTATION =195, + SC_CHASEWALK =196, /* SC_LEADERSHIP =196, // temporarily disabled - they're too buggy =/ SC_GLORYWOUNDS =197, SC_SOULCOLD =198, |