summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/battle.c242
-rw-r--r--src/map/battle.h14
-rw-r--r--src/map/clif.c42
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/guild.c13
-rw-r--r--src/map/itemdb.c188
-rw-r--r--src/map/map.h16
-rw-r--r--src/map/mob.c58
-rw-r--r--src/map/npc.c3
-rw-r--r--src/map/pc.c123
-rw-r--r--src/map/pc.h3
-rw-r--r--src/map/script.c64
-rw-r--r--src/map/skill.c286
-rw-r--r--src/map/skill.h19
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,