From d704f26907c104336bc47fde4e27448dcfa38444 Mon Sep 17 00:00:00 2001 From: celest Date: Wed, 16 Feb 2005 12:46:21 +0000 Subject: Added 3 more of the new card effects git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/stable@1117 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-SVN.txt | 8 ++++-- db/const.txt | 9 ++++-- doc/item_bonus.txt | 7 ++++- src/map/battle.c | 28 ++++++++++++++---- src/map/map.h | 15 ++++++---- src/map/mob.c | 25 +++++++++------- src/map/pc.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++----- src/map/pc.h | 1 + src/map/script.c | 18 ++++++++++++ src/map/status.c | 3 ++ 10 files changed, 162 insertions(+), 35 deletions(-) diff --git a/Changelog-SVN.txt b/Changelog-SVN.txt index bbbe894e7..8b48759d4 100644 --- a/Changelog-SVN.txt +++ b/Changelog-SVN.txt @@ -1,6 +1,10 @@ Date Added 02/16 + * Added 3 more of the new card effects -- check item_bonus.txt [celest] + + * Added 'bonus4' to support the new card effects that might need up to 4 + parameters [celest] * Set 'killerrid' and do PCKillEvent before calling PCDieEvent, thanks to mrmagoo for pointing it out [celest] @@ -11,12 +15,12 @@ Date Added - event_requires_trigger: whether or not a 'set [EventName],1;' has to be defined first for the event to be activated - * Added 10 of the new card effects on the 2/15's patch (still untested and + * Added 8 of the new card effects on the 2/15's patch (still untested and not yet added to the item_db) - Refer to doc/item_bonus.txt for description * Minor rewrites on self and enemy weapon/armor breaking during battle [celest] - * Added missing code for 'bBreakWeaponRate' and 'bBreakWeaponRate' effects + * Added missing code for 'bBreakWeaponRate' and 'bBreakArmorRate' effects [celest] * Added missing code for 'bAddStealRate' effect [celest] * Removed redundant 'infinite_autospell' in map_session_data [celest] diff --git a/db/const.txt b/db/const.txt index e8cd07893..a2f199c0b 100644 --- a/db/const.txt +++ b/db/const.txt @@ -242,6 +242,9 @@ bAutoSpellWhenHit 2017 bSkillAtk 2018 bUnstripable 2019 bAddDamageByClass 2020 +bSPGainValue 2021 +bIgnoreDefMob 2022 +bHPLossRate 2023 Eff_Stone 0 @@ -253,6 +256,7 @@ Eff_Curse 5 Eff_Silence 6 Eff_Confusion 7 Eff_Blind 8 +Eff_Bleeding 9 SC_Stone 128 SC_Freeze 129 @@ -263,6 +267,7 @@ SC_Curse 133 SC_Silence 134 SC_Confusion 135 SC_Blind 136 +SC_Bleeding 137 SC_SpeedPot0 37 SC_SpeedPot1 38 SC_SpeedPot2 39 @@ -275,6 +280,4 @@ SC_Holy 17 SC_Flame 90 SC_Frost 91 SC_Lightning 92 -SC_Seismic 93 -SC_Bleeding 124 -SC_BlockSkill 194 +SC_Seismic 93 \ No newline at end of file diff --git a/doc/item_bonus.txt b/doc/item_bonus.txt index 818a1980f..476c8ff6d 100644 --- a/doc/item_bonus.txt +++ b/doc/item_bonus.txt @@ -144,9 +144,14 @@ bonus bCritAtkRate,n; Increase critical damage by +n% bonus bNoRegen,n; Stops regeneration for n. n: 1=HP, 2=SP bonus bUnstripable,n; Armor cannot be taken off via Strip skills +bonus bSPGainValue,n; When killing a monster by physical attack + gain n amount of sp +bonus bIgnoreDefMob,n; Ignore monster's DEF when attacking. + n:0=All normal monsters, except Bosses + 1=All monsters bonus2 bCriticalAddRace,n,x; Increase critical + n vs. enemies of type x - +bonus2 bHPLossRate,n,x; Lose n amount of hp every x amount of time bonus2 bAddEffWhenHit,n,x; n% chance to cause x state to the enemy when being hit by physical close range damage bonus2 bSkillAtk,n,x; Increase damage of skill n by x% diff --git a/src/map/battle.c b/src/map/battle.c index 35b1d2737..634b04a70 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2365,6 +2365,19 @@ static struct Damage battle_calc_pc_weapon_attack( } t_def = def2*8/10; vitbonusmax = (t_vit/20)*(t_vit/20)-1; + if (tmd) { + if(t_mode & 0x20) { + if(sd->ignore_def_mob & 2) + idef_flag = 1; + if(sd->ignore_def_mob_ & 2) + idef_flag_ = 1; + } else { + if(sd->ignore_def_mob & 1) + idef_flag = 1; + if(sd->ignore_def_mob_ & 1) + idef_flag_ = 1; + } + } if(sd->ignore_def_ele & (1<ignore_def_race & (1<ignore_def_ele_ & (1<ignore_def_race_ & (1<autospell2_id,skilllv)*2/3; if(tsd->status.sp >= sp) { + struct block_list *tbl; + if (tsd->autospell2_type == 0) tbl = target; + else tbl = src; if((i=skill_get_inf(tsd->autospell2_id) == 2) || i == 32) - f = skill_castend_pos2(target,src->x,src->y,tsd->autospell2_id,skilllv,tick,flag); + f = skill_castend_pos2(target,tbl->x,tbl->y,tsd->autospell2_id,skilllv,tick,flag); else { switch( skill_get_nk(tsd->autospell2_id) ) { case 0: case 2: - f = skill_castend_damage_id(target,src,tsd->autospell2_id,skilllv,tick,flag); + f = skill_castend_damage_id(target,tbl,tsd->autospell2_id,skilllv,tick,flag); break; case 1:/* 支援系 */ - if((tsd->autospell2_id==AL_HEAL || (tsd->autospell2_id==ALL_RESURRECTION && src->type != BL_PC)) && - battle_check_undead(status_get_race(src),status_get_elem_type(src))) - f = skill_castend_damage_id(target,src,tsd->autospell2_id,skilllv,tick,flag); + if((tsd->autospell2_id==AL_HEAL || (tsd->autospell2_id==ALL_RESURRECTION && tbl->type != BL_PC)) && + battle_check_undead(status_get_race(tbl),status_get_elem_type(tbl))) + f = skill_castend_damage_id(target,tbl,tsd->autospell2_id,skilllv,tick,flag); else - f = skill_castend_nodamage_id(target,src,tsd->autospell2_id,skilllv,tick,flag); + f = skill_castend_nodamage_id(target,tbl,tsd->autospell2_id,skilllv,tick,flag); break; } } diff --git a/src/map/map.h b/src/map/map.h index 4c5dbb15e..d4cd5084e 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -278,14 +278,17 @@ struct map_session_data { //--- 02/15's new card effects [celest] int crit_atk_rate; int critaddrace[12]; - int no_regen; + short no_regen; int addeff3[10]; - short autospell2_id,autospell2_lv,autospell2_rate; + short autospell2_id,autospell2_lv,autospell2_rate,autospell2_type; int skillatk[2]; unsigned short unstripable_equip; - short add_damage_classid2[10]; + short add_damage_classid2[10],add_damage_class_count2; int add_damage_classrate2[10]; - int add_damage_class_count2; + short sp_gain_value; + short ignore_def_mob, ignore_def_mob_; + int hp_loss_tick, hp_loss_rate; + short hp_loss_value, hp_loss_type; short spiritball, spiritball_old; int spirit_timer[MAX_SKILL_LEVEL]; @@ -626,8 +629,8 @@ enum { SP_UNBREAKABLE_SHIELD, SP_LONG_ATK_RATE, // 2011-2012 SP_CRIT_ATK_RATE, SP_CRITICAL_ADDRACE, SP_NO_REGEN, SP_ADDEFF_WHENHIT, SP_AUTOSPELL_WHENHIT, // 2013-2017 - SP_SKILL_ATK, SP_UNSTRIPABLE, // 2018-2019 - SP_ADD_DAMAGE_BY_CLASS // 2020-2022 + SP_SKILL_ATK, SP_UNSTRIPABLE, SP_ADD_DAMAGE_BY_CLASS, // 2018-2020 + SP_SP_GAIN_VALUE, SP_IGNORE_DEF_MOB, SP_HP_LOSS_RATE // 2021-2023 }; enum { diff --git a/src/map/mob.c b/src/map/mob.c index 15f06f940..b32db9966 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -2164,8 +2164,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type) struct item item; int ret; int drop_rate; - int skill,sp; - + nullpo_retr(0, md); //srcはNULLで呼ばれる場合もあるので、他でチェック max_hp = status_get_max_hp(&md->bl); @@ -2384,14 +2383,20 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type) if(src && src->type == BL_MOB) mob_unlocktarget((struct mob_data *)src,tick); - /* ソウルドレイン */ - if(sd && sd->state.attack_type == BF_MAGIC && (skill=pc_checkskill(sd,HW_SOULDRAIN))>0){ - clif_skill_nodamage(src,&md->bl,HW_SOULDRAIN,skill,1); - sp = (status_get_lv(&md->bl))*(65+15*skill)/100; - if(sd->status.sp + sp > sd->status.max_sp) - sp = sd->status.max_sp - sd->status.sp; - sd->status.sp += sp; - clif_heal(sd->fd,SP_SP,sp); + + if(sd) { + int sp = 0; + if (sd->state.attack_type == BF_MAGIC && (i=pc_checkskill(sd,HW_SOULDRAIN))>0){ /* ソウルドレイン */ + clif_skill_nodamage(src,&md->bl,HW_SOULDRAIN,i,1); + sp += (status_get_lv(&md->bl))*(65+15*i)/100; + } + sp += sd->sp_gain_value; + if (sp > 0) { + if(sd->status.sp + sp > sd->status.max_sp) + sp = sd->status.max_sp - sd->status.sp; + sd->status.sp += sp; + clif_heal(sd->fd,SP_SP,sp); + } } // map外に消えた人は計算から除くので diff --git a/src/map/pc.c b/src/map/pc.c index c8ab8fae4..78d7102b8 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1575,6 +1575,16 @@ int pc_bonus(struct map_session_data *sd,int type,int val) if(sd->state.lr_flag != 2) sd->unstripable_equip |= EQP_ARMOR; break; + case SP_SP_GAIN_VALUE: + if(!sd->state.lr_flag) + sd->sp_gain_value += val; + break; + case SP_IGNORE_DEF_MOB: // 0:normal monsters only, 1:affects boss monsters as well + if(!sd->state.lr_flag) + sd->ignore_def_mob |= 1<state.lr_flag == 1) + sd->ignore_def_mob_ |= 1<state.lr_flag != 2) { + sd->hp_loss_value = type2; + sd->hp_loss_rate = val; + } + break; + default: if(battle_config.error_log) printf("pc_bonus2: unknown type %d %d %d!\n",type,type2,val); @@ -1865,6 +1882,7 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) sd->autospell2_id = type2; sd->autospell2_lv = type3; sd->autospell2_rate = val; + sd->autospell2_type = 1; // enemy } break; default: @@ -1876,6 +1894,26 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) return 0; } +int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4,int val) +{ + switch(type){ + case SP_AUTOSPELL_WHENHIT: + if(sd->state.lr_flag != 2){ + sd->autospell2_id = type2; + sd->autospell2_lv = type3; + sd->autospell2_rate = type4; + sd->autospell2_type = val; // 0: self, 1: enemy + } + break; + default: + if(battle_config.error_log) + printf("pc_bonus4: unknown type %d %d %d %d %d!\n",type,type2,type3,type4,val); + break; + } + + return 0; +} + /*========================================== * スクリプトによるスキル所得 *------------------------------------------ @@ -6513,7 +6551,7 @@ static int pc_natural_heal_sp(struct map_session_data *sd) return 0; } -static int pc_spirit_heal_hp(struct map_session_data *sd,int level) +static int pc_spirit_heal_hp(struct map_session_data *sd) { int bonus_hp,interval = battle_config.natural_heal_skill_interval; @@ -6553,7 +6591,7 @@ static int pc_spirit_heal_hp(struct map_session_data *sd,int level) return 0; } -static int pc_spirit_heal_sp(struct map_session_data *sd,int level) +static int pc_spirit_heal_sp(struct map_session_data *sd) { int bonus_sp,interval = battle_config.natural_heal_skill_interval; @@ -6594,6 +6632,30 @@ static int pc_spirit_heal_sp(struct map_session_data *sd,int level) return 0; } +static int pc_bleeding (struct map_session_data *sd) +{ + int interval, hp; + + nullpo_retr(0, sd); + interval = sd->hp_loss_rate; + hp = sd->hp_loss_value; + + sd->hp_loss_tick += natural_heal_diff_tick; + if(sd->hp_loss_tick >= interval) { + while(sd->hp_loss_tick >= interval) { + sd->hp_loss_tick -= interval; + if (sd->status.hp < hp) + hp = sd->status.hp; + if (sd->hp_loss_type == 0) { + pc_heal(sd,-hp,0); + } else if (sd->hp_loss_type == 1) { + } + sd->hp_loss_tick = 0; + } + } + return 0; +} + /*========================================== * HP/SP 自然回復 各クライアント *------------------------------------------ @@ -6601,15 +6663,17 @@ static int pc_spirit_heal_sp(struct map_session_data *sd,int level) static int pc_natural_heal_sub(struct map_session_data *sd,va_list ap) { int skill; + int tick; nullpo_retr(0, sd); + tick = va_arg(ap,int); // -- moonsoul (if conditions below altered to disallow natural healing if under berserk status) if ((battle_config.natural_heal_weight_rate > 100 || sd->weight*100/sd->max_weight < battle_config.natural_heal_weight_rate) && !pc_isdead(sd) && !pc_ishiding(sd) && //-- cannot regen for 5 minutes after using Berserk --- [Celest] - DIFF_TICK (gettick(), sd->canregen_tick)>=0 && + DIFF_TICK (tick, sd->canregen_tick)>=0 && (sd->sc_data && !(sd->sc_data[SC_POISON].timer != -1 && sd->sc_data[SC_SLOWPOISON].timer == -1) && sd->sc_data[SC_BERSERK].timer == -1 )) { pc_natural_heal_hp(sd); @@ -6617,20 +6681,25 @@ static int pc_natural_heal_sub(struct map_session_data *sd,va_list ap) { sd->sc_data[SC_DANCING].timer == -1 && //ダンス?態ではSPが回復しない sd->sc_data[SC_BERSERK].timer == -1 ) //バ?サ?ク?態ではSPが回復しない pc_natural_heal_sp(sd); - sd->canregen_tick = gettick(); + sd->canregen_tick = tick; } else { sd->hp_sub = sd->inchealhptick = 0; sd->sp_sub = sd->inchealsptick = 0; } if((skill = pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0 && !pc_ishiding(sd) && sd->sc_data[SC_POISON].timer == -1 && sd->sc_data[SC_BERSERK].timer == -1){ - pc_spirit_heal_hp(sd,skill); - pc_spirit_heal_sp(sd,skill); + pc_spirit_heal_hp(sd); + pc_spirit_heal_sp(sd); } else { sd->inchealspirithptick = 0; sd->inchealspiritsptick = 0; } + if (sd->hp_loss_value > 0) + pc_bleeding(sd); + else + sd->hp_loss_tick = 0; + return 0; } @@ -6642,7 +6711,7 @@ int pc_natural_heal(int tid,unsigned int tick,int id,int data) { natural_heal_tick = tick; natural_heal_diff_tick = DIFF_TICK(natural_heal_tick,natural_heal_prev_tick); - clif_foreachclient(pc_natural_heal_sub); + clif_foreachclient(pc_natural_heal_sub, tick); natural_heal_prev_tick = tick; return 0; diff --git a/src/map/pc.h b/src/map/pc.h index 067c3af81..f7fd924fd 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -89,6 +89,7 @@ int pc_checkweighticon(struct map_session_data *sd); int pc_bonus(struct map_session_data*,int,int); int pc_bonus2(struct map_session_data *sd,int,int,int); int pc_bonus3(struct map_session_data *sd,int,int,int,int); +int pc_bonus4(struct map_session_data *sd,int,int,int,int,int); int pc_skill(struct map_session_data*,int,int,int); void pc_blockskill_start (struct map_session_data*,int,int); // [celest] diff --git a/src/map/script.c b/src/map/script.c index 263aba6bc..ce70b29c3 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -150,6 +150,7 @@ int buildin_statusup2(struct script_state *st); int buildin_bonus(struct script_state *st); int buildin_bonus2(struct script_state *st); int buildin_bonus3(struct script_state *st); +int buildin_bonus4(struct script_state *st); int buildin_skill(struct script_state *st); int buildin_addtoskill(struct script_state *st); // [Valaris] int buildin_guildskill(struct script_state *st); @@ -373,6 +374,7 @@ struct { {buildin_bonus,"bonus","ii"}, {buildin_bonus2,"bonus2","iii"}, {buildin_bonus3,"bonus3","iiii"}, + {buildin_bonus4,"bonus4","iiiii"}, {buildin_skill,"skill","ii*"}, {buildin_addtoskill,"addtoskill","ii*"}, // [Valaris] {buildin_guildskill,"guildskill","ii"}, @@ -3185,6 +3187,22 @@ int buildin_bonus3(struct script_state *st) return 0; } + +int buildin_bonus4(struct script_state *st) +{ + int type,type2,type3,type4,val; + struct map_session_data *sd; + + type=conv_num(st,& (st->stack->stack_data[st->start+2])); + type2=conv_num(st,& (st->stack->stack_data[st->start+3])); + type3=conv_num(st,& (st->stack->stack_data[st->start+4])); + type4=conv_num(st,& (st->stack->stack_data[st->start+5])); + val=conv_num(st,& (st->stack->stack_data[st->start+6])); + sd=script_rid2sd(st); + pc_bonus4(sd,type,type2,type3,type4,val); + + return 0; +} /*========================================== * スキル所得 *------------------------------------------ diff --git a/src/map/status.c b/src/map/status.c index d6a8b1a22..55f4326f9 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -276,6 +276,9 @@ int status_calc_pc(struct map_session_data* sd,int first) memset(sd->add_mdef_classrate,0,sizeof(sd->add_mdef_classrate)); memset(sd->add_damage_classid2,0,sizeof(sd->add_damage_classid2)); memset(sd->add_damage_classrate2,0,sizeof(sd->add_damage_classrate2)); + sd->sp_gain_value = 0; + sd->ignore_def_mob = sd->ignore_def_mob_ = 0; + sd->hp_loss_rate = sd->hp_loss_value = sd->hp_loss_type = 0; if(!sd->disguiseflag && sd->disguise) { sd->disguise=0; -- cgit v1.2.3-70-g09d2