From 1765c5b7f0042daf83b6b506a3680009b74c0970 Mon Sep 17 00:00:00 2001 From: skotlex Date: Wed, 3 May 2006 04:02:17 +0000 Subject: - Fixed standing up not really standing you up. - Moved battle_consume_ammo to the end of skill_castend_damage_id, skill_castend_nodamage_id and skill_castend_pos2 rather than battle_calc_weapon_attack. They will trigger when the player's arrow_atk state is active and a ground skill was not invoked. It should fix all issues with splash/ground skills consuming ammo per target rather than once per skill use. - Added structure state to the ground skills, their fields are magic_power, into_abyss and ammo_consume to indicate the states that were previously stored in val3. - Corrected Desperado ammo consumption (should be 10) git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@6455 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 10 ++++++++ db/Changelog.txt | 1 + db/skill_require_db.txt | 2 +- src/map/battle.c | 64 +++++++++++++------------------------------------ src/map/clif.c | 1 + src/map/map.h | 5 ++++ src/map/skill.c | 55 ++++++++++++++++++++++++------------------ 7 files changed, 66 insertions(+), 72 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index eaac28d00..a6546ce9f 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,16 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2006/05/02 + * Fixed standing up not really standing you up. [Skotlex] + * Moved battle_consume_ammo to the end of skill_castend_damage_id, + skill_castend_nodamage_id and skill_castend_pos2 rather than + battle_calc_weapon_attack. They will trigger when the player's arrow_atk + state is active and a ground skill was not invoked. It should fix all + issues with splash/ground skills consuming ammo per target rather than once + per skill use. [Skotlex] + * Added structure state to the ground skills, their fields are magic_power, + into_abyss and ammo_consume to indicate the states that were previously + stored in val3. [Skotlex] * Implemented desperado as explained by Rockman-EXE. The skill-effect is not showing up though, I'll need some logged packets to see what's missing. [Skotlex] diff --git a/db/Changelog.txt b/db/Changelog.txt index 9b2d5af6c..81ed00dcd 100644 --- a/db/Changelog.txt +++ b/db/Changelog.txt @@ -27,6 +27,7 @@ ========================= 05/02 + * Corrected Desperado ammo consumption (should be 10) [Skotlex] * Lowered all card drop rates to 0.01% as they are in Aegis X.2 [Playtester] * Updating old/wrong mob drops to Aegis X.2 drops [Playtester] - progress 10% diff --git a/db/skill_require_db.txt b/db/skill_require_db.txt index 325200a20..dd9181a4a 100644 --- a/db/skill_require_db.txt +++ b/db/skill_require_db.txt @@ -403,7 +403,7 @@ 513,0,0,15:20:25:30:35,0,0,0,17:18,3,1,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GS_DISARM 514,0,0,11:12:13:14:15,0,0,0,17:18,3,1,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GS_PIERCINGSHOT 515,0,0,22:24:26:28:30:32:34:36:38:40,0,0,0,17,3,1,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GS_RAPIDSHOWER -516,0,0,32:34:36:38:40:42:44:46:48:50,0,0,0,17,3,1,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GS_DESPERADO +516,0,0,32:34:36:38:40:42:44:46:48:50,0,0,0,17,3,10,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GS_DESPERADO 517,0,0,30:32:34:36:38:40:42:44:46:48,0,0,0,20,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GS_GATLINGFEVER 518,0,0,3:6:9:12:15:18:21:24:27:30,0,0,0,19,4,1,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GS_DUST 519,0,0,20:25:30:35:40:45:50:55:60:65,0,0,0,19,4,1:2:3:4:5:6:7:8:9:10,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GS_FULLBUSTER diff --git a/src/map/battle.c b/src/map/battle.c index 641e17378..d042ef75f 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -947,12 +947,6 @@ void battle_consume_ammo(TBL_PC*sd, int skill, int lv) if (!battle_config.arrow_decrement) return; - if (skill == AC_SHOWER) { - //Can't consume arrows this way as it triggers per target, gotta wait for the direct invocation with lv -1 - if (lv > 0) - return; - lv *= -1; - } if (skill) { qty = skill_get_ammo_qty(skill, lv); @@ -1071,31 +1065,14 @@ static struct Damage battle_calc_weapon_attack( } } //Set miscellaneous data that needs be filled regardless of hit/miss - if(sd) { - if (!skill_num) //Ammo condition for weapons is lower below. - switch (sd->status.weapon) { - case W_BOW: - case W_REVOLVER: - case W_RIFLE: - case W_SHOTGUN: - case W_GATLING: - case W_GRENADE: - wd.flag=(wd.flag&~BF_RANGEMASK)|BF_LONG; - flag.arrow = 1; - break; - } - } else if (status_get_range(src) > 3) - wd.flag=(wd.flag&~BF_RANGEMASK)|BF_LONG; - - if(skill_num && - (skill_get_ammotype(skill_num) || - (sd && skill_isammotype(sd, skill_num))) - ){ - //Skills that require a consumable are also long-ranged arrow-types + if( + (sd && sd->state.arrow_atk) || + (!sd && ((skill_num && skill_get_ammotype(skill_num)) || status_get_range(src)>3)) + ) { wd.flag=(wd.flag&~BF_RANGEMASK)|BF_LONG; flag.arrow = 1; } - + if(skill_num){ wd.flag=(wd.flag&~BF_SKILLMASK)|BF_SKILL; switch(skill_num) @@ -1164,11 +1141,6 @@ static struct Damage battle_calc_weapon_attack( if(is_boss(target)) //Bosses can't be knocked-back wd.blewcount = 0; - if (sd) - { //Arrow consumption - sd->state.arrow_atk = flag.arrow; - } - /* Apparently counter attack no longer causes you to be critical'ed by mobs. [Skotlex] //Check for counter if(!skill_num) @@ -1186,8 +1158,6 @@ static struct Damage battle_calc_weapon_attack( wd.type=0x0b; wd.dmg_lv=ATK_LUCKY; if (wd.div_ < 0) wd.div_*=-1; - if (sd && flag.arrow) - battle_consume_ammo(sd, skill_num, skill_lv); return wd; } } @@ -1376,8 +1346,6 @@ static struct Damage battle_calc_weapon_attack( if(tsd && tsd->special_state.no_weapon_damage) { if (wd.div_ < 0) wd.div_*=-1; - if (sd && flag.arrow) - battle_consume_ammo(sd, skill_num, skill_lv); return wd; } @@ -2144,11 +2112,8 @@ static struct Damage battle_calc_weapon_attack( if (flag.lh && (flag.hit || wd.damage2>0)) wd.damage2 = 1; if (!(battle_config.skill_min_damage&1)) - { //Do not return if you are supposed to deal greater damage to plants than 1. [Skotlex] - if (sd && flag.arrow) - battle_consume_ammo(sd, skill_num, skill_lv); + //Do not return if you are supposed to deal greater damage to plants than 1. [Skotlex] return wd; - } } if(sd && !skill_num && !flag.cri) @@ -2207,8 +2172,6 @@ static struct Damage battle_calc_weapon_attack( if(wd.damage > 0 && wd.damage2 < 1) wd.damage2 = 1; flag.lh = 1; } - if (flag.arrow) //Consume the arrow. - battle_consume_ammo(sd, skill_num, skill_lv); } if(wd.damage > 0 || wd.damage2 > 0) @@ -3117,11 +3080,13 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target, race = status_get_race(target); ele = status_get_elem_type(target); - if (sd && (sd->status.weapon == W_BOW || (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE)) - && sd->equip_index[10] < 0) - { - clif_arrow_fail(sd,0); - return 0; + if (sd) + { + sd->state.arrow_atk = (sd->status.weapon == W_BOW || (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE)); + if (sd->state.arrow_atk && sd->equip_index[10]<0) { + clif_arrow_fail(sd,0); + return 0; + } } if (sc && sc->data[SC_CLOAKING].timer != -1 && !sc->data[SC_CLOAKING].val4) @@ -3175,6 +3140,9 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target, wd = battle_calc_weapon_attack(src,target, 0, 0,0); + if (sd && sd->state.arrow_atk) //Consume arrow. + battle_consume_ammo(sd, 0, 0); + damage = wd.damage + wd.damage2; if (damage > 0 && src != target) { rdamage = battle_calc_return_damage(target, &damage, wd.flag); diff --git a/src/map/clif.c b/src/map/clif.c index 9e451d968..51f8c5bb2 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -8790,6 +8790,7 @@ void clif_parse_ActionRequest(int fd, struct map_session_data *sd) { clif_send(buf, packet_len_table[0x8a], &sd->bl, SELF); return; } + pc_setstand(sd); skill_gangsterparadise(sd, 0); // ギャングスターパラダイス解除 fixed Valaris skill_rest(sd, 0); // TK_HPTIME standing up mode [Dralnu] WBUFW(buf, 0) = 0x8a; diff --git a/src/map/map.h b/src/map/map.h index c06252b46..59307c071 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -356,6 +356,11 @@ struct skill_unit_group { int group_id; int unit_count,alive_count; struct skill_unit *unit; + struct { + unsigned ammo_consume : 1; + unsigned magic_power : 1; + unsigned into_abyss : 1; + } state; }; struct skill_unit_group_tickset { unsigned int tick; diff --git a/src/map/skill.c b/src/map/skill.c index 751f576d8..80b1bd817 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2732,8 +2732,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s skill_castend_damage_id); //Skill-attack at the end in case it has knockback. [Skotlex] skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0); - if (sd) - battle_consume_ammo(sd, skillid, -skilllv); } break; @@ -3136,6 +3134,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s map_freeblock_unlock(); + if (sd && !(flag&1) && sd->state.arrow_atk) //Consume arrow on last invocation to this skill. + battle_consume_ammo(sd, skillid, skilllv); return 0; } @@ -5104,7 +5104,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in (su->group->src_id == src->id || map_flag_vs(bl->m)) && (skill_get_inf2(su->group->skill_id) & INF2_TRAP)) { - if(sd && su->group->val3 != BD_INTOABYSS) + if(sd && !su->group->state.into_abyss) { //Avoid collecting traps when it does not costs to place them down. [Skotlex] if(battle_config.skill_removetrap_type){ for(i=0;i<10;i++) { @@ -5605,6 +5605,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if (dstmd) //Mob skill event for no damage skills (damage ones are handled in battle_calc_damage) [Skotlex] mobskill_event(dstmd, src, tick, MSC_SKILLUSED|(skillid<<16)); + if (sd && !(flag&1) && sd->state.arrow_atk) //Consume arrow on last invocation to this skill. + battle_consume_ammo(sd, skillid, skilllv); + map_freeblock_unlock(); return 0; } @@ -5976,11 +5979,13 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil case AC_SHOWER: //Ground-placed skill implementation. case GS_DESPERADO: skill_unitsetting(src,skillid,skilllv,x,y,0); + flag|=1;//Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete). break; case RG_GRAFFITI: /* Graffiti [Valaris] */ skill_clear_unitgroup(src); skill_unitsetting(src,skillid,skilllv,x,y,0); + flag|=1; break; case RG_CLEANER: // [Valaris] @@ -5993,6 +5998,7 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil case SA_LANDPROTECTOR: /* ランドプ?テクタ? */ case NJ_SUITON: skill_unitsetting(src,skillid,skilllv,x,y,0); + flag|=1; break; case WZ_METEOR: //?テオスト?ム @@ -6128,6 +6134,7 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil sg = skill_unitsetting(src,skillid,skilllv,x,y,0); sc_start4(src,SkillStatusChangeTable[skillid],100, skilllv,0,BCT_SELF,(int)sg,skill_get_time(skillid,skilllv)); + flag|=1; } break; @@ -6156,12 +6163,11 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil case GS_GROUNDDRIFT: /* グラウンドドリフト*/ case NJ_KAENSIN: /* 火炎陣*/ case NJ_BAKUENRYU: /* 爆炎龍*/ - skill_unitsetting(src,skillid,skilllv,x,y,0); - break; - case NJ_HYOUSYOURAKU: skill_unitsetting(src,skillid,skilllv,x,y,0); + flag|=1; break; + case NJ_RAIGEKISAI: map_foreachinrange(skill_attack_area, src, skill_get_splash(skillid, skilllv), BL_CHAR, @@ -6172,6 +6178,9 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil if (sc && sc->data[SC_MAGICPOWER].timer != -1) status_change_end(&sd->bl,SC_MAGICPOWER,-1); + if (sd && !(flag&1) && sd->state.arrow_atk) //Consume arrow if a ground skill was not invoked. [Skotlex] + battle_consume_ammo(sd, skillid, skilllv); + return 0; } @@ -6387,8 +6396,6 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid, case HT_FLASHER: /* フラッシャ? */ case HT_FREEZINGTRAP: /* フリ?ジングトラップ */ case HT_BLASTMINE: /* ブラストマイン */ - if (sc && sc->data[SC_INTOABYSS].timer != -1) - val3 = BD_INTOABYSS; //Store into abyss state, to know it shouldn't give traps back. [Skotlex] if (map_flag_gvg(src->m)) limit *= 4; // longer trap times in WOE [celest] if (battle_config.vs_traps_bctall && map_flag_vs(src->m) @@ -6515,9 +6522,7 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid, break; } - if (val3==0 && (flag&2 || (sc && sc->data[SC_MAGICPOWER].timer != -1))) - val3 = HW_MAGICPOWER; //Store the magic power flag. [Skotlex] - + nullpo_retr(NULL, group=skill_initunitgroup(src,(count > 0 ? count : layout->count), skillid,skilllv,skill_get_unit_id(skillid,flag&1), limit, interval)); group->val1=val1; @@ -6525,6 +6530,10 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid, group->val3=val3; group->target_flag=target; group->bl_flag= skill_get_unit_bl_target(skillid); + group->state.into_abyss = (sc && sc->data[SC_INTOABYSS].timer != -1); //Store into abyss state, to know it shouldn't give traps back. [Skotlex] + group->state.magic_power = (flag&2 || (sc && sc->data[SC_MAGICPOWER].timer != -1)); //Store the magic power flag. [Skotlex] + group->state.ammo_consume = (sd && sd->state.arrow_atk); //Store if this skill needs to consume ammo. + if(skillid==HT_TALKIEBOX || skillid==RG_GRAFFITI){ group->valstr=(char *) aMallocA(MESSAGE_SIZE*sizeof(char)); @@ -6788,7 +6797,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign ts->tick += sg->interval*(map_count_oncell(bl->m,bl->x,bl->y,0)-1); } //Temporarily set magic power to have it take effect. [Skotlex] - if (sg->val3 == HW_MAGICPOWER && sc && sc->data[SC_MAGICPOWER].timer == -1 && sc->data[SC_MAGICPOWER].val1 > 0) + if (sg->state.magic_power && sc && sc->data[SC_MAGICPOWER].timer == -1 && sc->data[SC_MAGICPOWER].val1 > 0) { if (sd) { //This is needed since we are not going to recall status_calc_pc... @@ -6863,8 +6872,6 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign //Otherwise, Knockback attack. skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); break; - case AC_SHOWER: - sg->val2++; //Store count of hitted enemies to know when to delete an arrow. default: skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); } @@ -6893,7 +6900,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign sg->unit_id = UNT_USED_TRAPS; clif_changetraplook(&src->bl, UNT_USED_TRAPS); sg->limit=DIFF_TICK(tick,sg->tick)+1500; - sg->val3 = BD_INTOABYSS; //Prevent Remove Trap from giving you the trap back. [Skotlex] + sg->state.into_abyss = 1; //Prevent Remove Trap from giving you the trap back. [Skotlex] } break; @@ -6930,7 +6937,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign sg->unit_id = UNT_USED_TRAPS; clif_changetraplook(&src->bl, UNT_FIREPILLAR_ACTIVE); sg->limit=DIFF_TICK(tick,sg->tick)+1500; - sg->val3 = BD_INTOABYSS; //Prevent Remove Trap from giving you the trap back. [Skotlex] + sg->state.into_abyss = 1; //Prevent Remove Trap from giving you the trap back. [Skotlex] break; case UNT_BLASTMINE: @@ -6949,7 +6956,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign sg->unit_id = UNT_USED_TRAPS; clif_changetraplook(&src->bl, UNT_USED_TRAPS); sg->limit=DIFF_TICK(tick,sg->tick)+1500; - sg->val3 = BD_INTOABYSS; //Prevent Remove Trap from giving you the trap back. [Skotlex] + sg->state.into_abyss = 1; //Prevent Remove Trap from giving you the trap back. [Skotlex] break; case UNT_TALKIEBOX: @@ -6961,7 +6968,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign clif_changetraplook(&src->bl, UNT_USED_TRAPS); sg->limit = DIFF_TICK(tick, sg->tick) + 5000; sg->val2 = -1; //踏んだ - sg->val3 = BD_INTOABYSS; //Prevent Remove Trap from giving you the trap back. [Skotlex] + sg->state.into_abyss = 1; //Prevent Remove Trap from giving you the trap back. [Skotlex] } break; @@ -7089,7 +7096,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); break; } - if (sg->val3 == HW_MAGICPOWER && sc && sc->data[SC_MAGICPOWER].timer < 0 && sc->data[SC_MAGICPOWER].val1 > 0) + if (sg->state.magic_power && sc && sc->data[SC_MAGICPOWER].timer < 0 && sc->data[SC_MAGICPOWER].val1 > 0) { //Unset Magic Power. if (sd) { @@ -7148,7 +7155,7 @@ int skill_unit_onout(struct skill_unit *src,struct block_list *bl,unsigned int t if(target && target == bl){ status_change_end(bl,SC_ANKLE,-1); sg->limit=DIFF_TICK(tick,sg->tick)+1000; - sg->val3 = BD_INTOABYSS; //Prevent Remove Trap from giving you the trap back. [Skotlex] + sg->state.into_abyss = 1; //Prevent Remove Trap from giving you the trap back. [Skotlex] } else return 0; @@ -8266,6 +8273,8 @@ int skill_check_condition(struct map_session_data *sd,int skill, int lv, int typ if(!(type&1)) return 1; + sd->state.arrow_atk = ammo?1:0; //Update arrow-atk state on cast-end. + if(delitem_flag) { for(i=0;i<10;i++) { if(index[i] >= 0) @@ -9509,8 +9518,8 @@ int skill_delunitgroup(struct block_list *src, struct skill_unit_group *group) } } - if (group->skill_id == AC_SHOWER && group->val2 && src->type==BL_PC) - battle_consume_ammo((TBL_PC*)src, group->skill_id, -group->skill_lv); //Delete arrow if at least one target was hit. + if (src->type==BL_PC && group->state.ammo_consume) + battle_consume_ammo((TBL_PC*)src, group->skill_id, group->skill_lv); group->alive_count=0; if(group->unit!=NULL){ @@ -9687,7 +9696,7 @@ int skill_unit_timer_sub( struct block_list *bl, va_list ap ) struct block_list *src=map_id2bl(group->src_id); if(group->unit_id == UNT_ANKLESNARE && group->val2); else{ - if(src && src->type==BL_PC && group->val3 != BD_INTOABYSS) + if(src && src->type==BL_PC && !group->state.into_abyss) { //Avoid generating trap items when it did not cost to create them. [Skotlex] struct item item_tmp; memset(&item_tmp,0,sizeof(item_tmp)); -- cgit v1.2.3-70-g09d2