From feec60e8c853caeaccfb51745e72b9676dfe042e Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Tue, 18 Aug 2015 22:11:41 +0700 Subject: [PATCH] Bug Fixes: * Fixed some Manhole skill related: * Shouldn't be removed by Crazy Weed, Fixed #580 * Hell's Plant should ignores target under Manhole effect, Fixed #566. * Fixed #536, Neutral Barrier shouldn't miss magic attack and ranged attack that ignores flee. * Fixed #522, Change Material always check the first produce line that matches the item/product requested. Also removed some reduntant checks. * Fixed #568, Gentletouch Cure shouldn't heal Emperium and BG's Barricades. * (Attempt to) Fixed #533 and fixed #212, Ground Drift damage calculation. Signed-off-by: Cydh Ramdh --- db/pre-re/skill_unit_db.txt | 6 +- db/re/item_db.txt | 4 +- db/re/skill_unit_db.txt | 6 +- sql-files/item_db_re.sql | 4 +- src/map/battle.c | 36 ++++++----- src/map/clif.c | 14 +++-- src/map/itemdb.h | 1 + src/map/skill.c | 119 +++++++++++++++++++++--------------- src/map/skill.h | 2 +- src/map/status.c | 8 ++- 10 files changed, 119 insertions(+), 81 deletions(-) diff --git a/db/pre-re/skill_unit_db.txt b/db/pre-re/skill_unit_db.txt index 2412039150..08365305c5 100644 --- a/db/pre-re/skill_unit_db.txt +++ b/db/pre-re/skill_unit_db.txt @@ -122,10 +122,10 @@ 2253,0xd6, , 0, 1,1000,enemy, 0x8002 //RA_FIRINGTRAP 2254,0xd7, , 0, 1,1000,enemy, 0x8002 //RA_ICEBOUNDTRAP -2273,0xe2, , 2, 0, 500,all, 0x000 //NC_NEUTRALBARRIER -2274,0xe3, , 2, 0, 500,friend,0x000 //NC_STEALTHFIELD +2273,0xe2, , 2, 0, -1,all, 0x000 //NC_NEUTRALBARRIER +2274,0xe3, , 2, 0, -1,friend,0x000 //NC_STEALTHFIELD -2299,0xcc, , 0, 1,1000,all, 0xC006 //SC_MANHOLE +2299,0xcc, , 0, 1,1000,all, 0x8006 //SC_MANHOLE 2300,0xcd, , 0, 0,1000,all, 0xC006 //SC_DIMENSIONDOOR 2301,0xce, , 2, 0,1000,all, 0xE00E //SC_CHAOSPANIC 2302,0xcf, , 2, 0, -1,all, 0xE002 //SC_MAELSTROM diff --git a/db/re/item_db.txt b/db/re/item_db.txt index f3f4bcd778..6f83dc0560 100644 --- a/db/re/item_db.txt +++ b/db/re/item_db.txt @@ -6744,7 +6744,7 @@ 12884,Infinite_Concentration_Potion,Infinite Concentration Potion,11,10,,0,,,,0,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_ASPDPOTION0,1800000,4; },{},{} 12885,Infinite_Awakening_Potion,Infinite Awakening Potion,11,10,,0,,,,0,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_ASPDPOTION1,1800000,6; },{},{} 12886,Infinite_Berserk_Potion,Infinite Berserk Potion,11,10,,0,,,,0,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_ASPDPOTION2,1800000,9; },{},{} -12887,C_Wing_Of_Fly,Infinite Flywing,11,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "AL_TELEPORT",1; },{},{} +12887,C_Wing_Of_Fly,Infinite Flywing,11,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ unitskilluseid getcharid(3),"AL_TELEPORT",1; },{},{} 12889,Weapon_Box(Spear),Weapon Box(Spear),2,10,,200,,,,0,0xFFFFFFFF,63,2,,,,,,{},{},{} 12890,Weapon_Box(Mace),Weapon Box(Mace),2,10,,200,,,,0,0xFFFFFFFF,63,2,,,,,,{},{},{} 12891,Weapon_Box(Dagger),Weapon Box(Dagger),2,10,,200,,,,0,0xFFFFFFFF,63,2,,,,,,{},{},{} @@ -9909,7 +9909,7 @@ 22064,Thorny_Shoes,Thorny Shoes,4,0,,1000,,25,,1,0xFFFFFFFF,63,2,64,,,1,,{ bonus bShortWeaponDamageReturn,getrefine()/2; },{},{} 22067,Shoe_of_Witch,Shoe of Witch,4,10,,400,,10,,0,0xFFFFFFFE,63,2,64,,1,1,,{ skill "ALL_CATCRY",1,1; },{},{} // -22508,Para_Team_Mark_,Eden Group Mark,11,0,,0,,,,0,0xFFFFFFFF,63,2,,,,,,{ /*itemskill "AL_TELEPORT",3;*/ unitskilluseid getcharid(3),"AL_TELEPORT",3; },{},{} +22508,Para_Team_Mark_,Eden Group Mark,11,0,,0,,,,0,0xFFFFFFFF,63,2,,,,,,{ unitskilluseid getcharid(3),"AL_TELEPORT",3; },{},{} 22507,Worn-Out-Scroll,Worn-Out-Scroll,3,10,,10,,,,0,,,,,,,,,{},{},{} 22510,King_Wolf_Scroll,King Wolf Scroll,2,10,,10,,,,0,0xFFFFFFFF,63,2,,,,,,{ /*TODO, confirm the rates*/ getitem callfunc("F_Rand",6635,19598,5658,6238,6239),1; },{},{} 22513,King_of_Gift_Box,King of Gift Box,2,10,,100,,,,0,0xFFFFFFFF,63,2,,,,,,{ /*TODO, confirm the rates*/ getitem callfunc("F_Rand",12817,4403,14512),1; },{},{} diff --git a/db/re/skill_unit_db.txt b/db/re/skill_unit_db.txt index ddeb00e382..962c846e3f 100644 --- a/db/re/skill_unit_db.txt +++ b/db/re/skill_unit_db.txt @@ -124,10 +124,10 @@ 2253,0xd6, , 0, 1,1000,enemy, 0x8002 //RA_FIRINGTRAP 2254,0xd7, , 0, 1,1000,enemy, 0x8002 //RA_ICEBOUNDTRAP -2273,0xe2, , 2, 0, 500,all, 0x000 //NC_NEUTRALBARRIER -2274,0xe3, , 2, 0, 500,friend,0x000 //NC_STEALTHFIELD +2273,0xe2, , 2, 0, -1,all, 0x000 //NC_NEUTRALBARRIER +2274,0xe3, , 2, 0, -1,friend,0x000 //NC_STEALTHFIELD -2299,0xcc, , 0, 1,1000,all, 0xC006 //SC_MANHOLE +2299,0xcc, , 0, 1,1000,all, 0x8006 //SC_MANHOLE 2300,0xcd, , 0, 0,1000,all, 0xC006 //SC_DIMENSIONDOOR 2301,0xce, , 2, 0,1000,all, 0xE00E //SC_CHAOSPANIC 2302,0xcf, , 2, 0, -1,all, 0xE002 //SC_MAELSTROM diff --git a/sql-files/item_db_re.sql b/sql-files/item_db_re.sql index 5f897a79cf..7e972a3a95 100644 --- a/sql-files/item_db_re.sql +++ b/sql-files/item_db_re.sql @@ -6775,7 +6775,7 @@ REPLACE INTO `item_db_re` VALUES (12883,'Almighty','Almighty',2,20,NULL,10,NULL, REPLACE INTO `item_db_re` VALUES (12884,'Infinite_Concentration_Potion','Infinite Concentration Potion',11,10,NULL,0,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'sc_start SC_ASPDPOTION0,1800000,4;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (12885,'Infinite_Awakening_Potion','Infinite Awakening Potion',11,10,NULL,0,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'sc_start SC_ASPDPOTION1,1800000,6;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (12886,'Infinite_Berserk_Potion','Infinite Berserk Potion',11,10,NULL,0,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'sc_start SC_ASPDPOTION2,1800000,9;',NULL,NULL); -REPLACE INTO `item_db_re` VALUES (12887,'C_Wing_Of_Fly','Infinite Flywing',11,0,NULL,0,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'itemskill "AL_TELEPORT",1;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (12887,'C_Wing_Of_Fly','Infinite Flywing',11,0,NULL,0,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'unitskilluseid getcharid(3),"AL_TELEPORT",1;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (12889,'Weapon_Box(Spear)','Weapon Box(Spear)',2,10,NULL,200,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); REPLACE INTO `item_db_re` VALUES (12890,'Weapon_Box(Mace)','Weapon Box(Mace)',2,10,NULL,200,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); REPLACE INTO `item_db_re` VALUES (12891,'Weapon_Box(Dagger)','Weapon Box(Dagger)',2,10,NULL,200,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); @@ -9940,7 +9940,7 @@ REPLACE INTO `item_db_re` VALUES (22059,'Aegir_Shoes','Aegir Shoes',4,10,NULL,30 REPLACE INTO `item_db_re` VALUES (22064,'Thorny_Shoes','Thorny Shoes',4,0,NULL,1000,NULL,25,NULL,1,0xFFFFFFFF,63,2,64,NULL,NULL,1,NULL,'bonus bShortWeaponDamageReturn,getrefine()/2;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (22067,'Shoe_of_Witch','Shoe of Witch',4,10,NULL,400,NULL,10,NULL,0,0xFFFFFFFE,63,2,64,NULL,'1',1,NULL,'skill "ALL_CATCRY",1,1;',NULL,NULL); # -REPLACE INTO `item_db_re` VALUES (22508,'Para_Team_Mark_','Eden Group Mark',11,0,NULL,0,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'/*itemskill "AL_TELEPORT",3;*/ unitskilluseid getcharid(3),"AL_TELEPORT",3;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (22508,'Para_Team_Mark_','Eden Group Mark',11,0,NULL,0,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'unitskilluseid getcharid(3),"AL_TELEPORT",3;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (22507,'Worn-Out-Scroll','Worn-Out-Scroll',3,10,NULL,10,NULL,NULL,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); REPLACE INTO `item_db_re` VALUES (22510,'King_Wolf_Scroll','King Wolf Scroll',2,10,NULL,10,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'/*TODO, confirm the rates*/ getitem callfunc("F_Rand",6635,19598,5658,6238,6239),1;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (22513,'King_of_Gift_Box','King of Gift Box',2,10,NULL,100,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'/*TODO, confirm the rates*/ getitem callfunc("F_Rand",12817,4403,14512),1;',NULL,NULL); diff --git a/src/map/battle.c b/src/map/battle.c index cf791b5669..ef0b6035aa 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -930,6 +930,13 @@ bool battle_check_sc(struct block_list *src, struct block_list *target, struct s status_change_end(target, SC_SAFETYWALL, INVALID_TIMER); } + if( (sc->data[SC_NEUTRALBARRIER] || sc->data[SC_NEUTRALBARRIER_MASTER]) && !(skill_get_nk(skill_id)&NK_IGNORE_FLEE) && + (skill_id == NPC_EARTHQUAKE || (d->flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON)) ) + { + d->dmg_lv = ATK_MISS; + return false; + } + if( sc->data[SC_PNEUMA] && (d->flag&(BF_MAGIC|BF_LONG)) == BF_LONG ) { d->dmg_lv = ATK_BLOCK; skill_blown(src,target,skill_get_blewcount(skill_id,skill_lv),-1,0); @@ -1104,11 +1111,6 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam if(sc->data[SC_TATAMIGAESHI] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG) return 0; - if( sc->data[SC_NEUTRALBARRIER] && (skill_id == NPC_EARTHQUAKE || (flag&(BF_LONG|BF_MAGIC)) == BF_LONG) ) { - d->dmg_lv = ATK_MISS; - return 0; - } - //Kaupe blocks damage (skill or otherwise) from players, mobs, homuns, mercenaries. if ((sce = sc->data[SC_KAUPE]) && rnd()%100 < sce->val2) { clif_specialeffect(bl, 462, AREA); @@ -2418,7 +2420,7 @@ static bool is_attack_hitting(struct Damage wd, struct block_list *src, struct b else if (nk&NK_IGNORE_FLEE) return true; - if( sc && (sc->data[SC_NEUTRALBARRIER] || sc->data[SC_NEUTRALBARRIER_MASTER]) && (wd.flag&(BF_LONG|BF_MAGIC)) == BF_LONG ) + if( sc && (sc->data[SC_NEUTRALBARRIER] || sc->data[SC_NEUTRALBARRIER_MASTER]) && (wd.flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON) ) return false; flee = tstatus->flee; @@ -2743,10 +2745,6 @@ static struct Damage battle_calc_element_damage(struct Damage wd, struct block_l //Forced to neutral element wd.damage = battle_attr_fix(src, target, wd.damage, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv); break; - case GS_GROUNDDRIFT: - //Additional 50 * lv neutral damage - wd.damage += battle_attr_fix(src, target, 50 * skill_lv, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv); - break; case GN_CARTCANNON: case KO_HAPPOKUNAI: //Forced to ammo's element @@ -6438,10 +6436,9 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * break; case GS_GROUNDDRIFT: // Official formula [helvetica] - // damage = 50 * skill level - // fixed damage, ignores DEF and benefits from weapon +%ATK cards - md.damage = 50 * skill_lv; - md.damage += battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, 0, md.damage, 0, md.flag|NK_NO_CARDFIX_DEF); // ground drift benefits from weapon atk cards, ignore DEF cards so we don't apply twice + // bonus damage = 50 * skill level (fixed damage) + s_ele = ELE_NEUTRAL; + md.damage = battle_attr_fix(src, target, 50 * skill_lv, s_ele, tstatus->def_ele, tstatus->ele_lv); break; case HVAN_EXPLOSION: //[orn] md.damage = (int64)sstatus->max_hp * (50 + 50 * skill_lv) / 100; @@ -6577,6 +6574,17 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * pc_payzeny(sd,(int)cap_value(md.damage, INT_MIN, INT_MAX),LOG_TYPE_STEAL,NULL); } break; + case GS_GROUNDDRIFT: + { + struct Damage wd = battle_calc_weapon_attack(src,target,skill_id,skill_lv,mflag); + int blewcount = skill_get_blewcount(skill_id, skill_lv); + + md.damage += wd.damage; + // Knockback only from Fire Element (except from bonuses?) + if (mflag != ELE_FIRE && md.blewcount >= blewcount) + md.blewcount -= blewcount; + } + break; } switch(skill_id) { diff --git a/src/map/clif.c b/src/map/clif.c index f76ab480da..e079be1118 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -11831,6 +11831,8 @@ void clif_parse_ProduceMix(int fd,struct map_session_data *sd){ int slot1 = RFIFOW(fd,info->pos[1]); int slot2 = RFIFOW(fd,info->pos[2]); int slot3 = RFIFOW(fd,info->pos[3]); + short produce_idx = -1; + switch( sd->menuskill_id ) { case -1: case AM_PHARMACY: @@ -11846,8 +11848,8 @@ void clif_parse_ProduceMix(int fd,struct map_session_data *sd){ clif_menuskill_clear(sd); return; } - if( skill_can_produce_mix(sd,nameid,sd->menuskill_val, 1) ) - skill_produce_mix(sd,0,nameid,slot1,slot2,slot3, 1); + if( (produce_idx = skill_can_produce_mix(sd,nameid,sd->menuskill_val, 1)) ) + skill_produce_mix(sd,0,nameid,slot1,slot2,slot3,1,produce_idx-1); clif_menuskill_clear(sd); } @@ -11866,6 +11868,8 @@ void clif_parse_Cooking(int fd,struct map_session_data *sd) { int type = RFIFOW(fd,info->pos[0]); unsigned short nameid = RFIFOW(fd,info->pos[1]); int amount = sd->menuskill_val2 ? sd->menuskill_val2 : 1; + short food_idx = -1; + if( type == 6 && sd->menuskill_id != GN_MIX_COOKING && sd->menuskill_id != GN_S_PHARMACY ) return; @@ -11875,8 +11879,8 @@ void clif_parse_Cooking(int fd,struct map_session_data *sd) { clif_menuskill_clear(sd); return; } - if( skill_can_produce_mix(sd,nameid,sd->menuskill_val, amount) ) - skill_produce_mix(sd,(type>1?sd->menuskill_id:0),nameid,0,0,0,amount); + if( (food_idx = skill_can_produce_mix(sd,nameid,sd->menuskill_val, amount)) ) + skill_produce_mix(sd,(type>1?sd->menuskill_id:0),nameid,0,0,0,amount,food_idx-1); clif_menuskill_clear(sd); } @@ -12033,7 +12037,7 @@ void clif_parse_SelectArrow(int fd,struct map_session_data *sd){ skill_arrow_create(sd,nameid); break; case SA_CREATECON: - skill_produce_mix(sd,SA_CREATECON,nameid,0,0,0, 1); + skill_produce_mix(sd,SA_CREATECON,nameid,0,0,0,1,-1); break; case WL_READING_SB: skill_spellbook(sd,nameid); diff --git a/src/map/itemdb.h b/src/map/itemdb.h index a9653e17dd..eb7148b671 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -52,6 +52,7 @@ enum item_itemid ITEMID_WING_OF_BUTTERFLY = 602, ITEMID_ANODYNE = 605, ITEMID_ALOEBERA = 606, + ITEMID_POISON_BOTTLE = 678, ITEMID_EMPTY_BOTTLE = 713, ITEMID_EMPERIUM = 714, ITEMID_YELLOW_GEMSTONE = 715, diff --git a/src/map/skill.c b/src/map/skill.c index 39dd579319..a8d289f497 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -309,6 +309,7 @@ int skill_tree_get_max(uint16 skill_id, int b_class) else return skill_get_max(skill_id); } + int skill_frostjoke_scream(struct block_list *bl,va_list ap); int skill_attack_area(struct block_list *bl,va_list ap); struct skill_unit_group *skill_locate_element_field(struct block_list *bl); // [Skotlex] @@ -7110,7 +7111,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case AL_HOLYWATER: if(sd) { - if (skill_produce_mix(sd, skill_id, ITEMID_HOLY_WATER, 0, 0, 0, 1)) + if (skill_produce_mix(sd, skill_id, ITEMID_HOLY_WATER, 0, 0, 0, 1, -1)) clif_skill_nodamage(src,bl,skill_id,skill_lv,1); else clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); @@ -7142,7 +7143,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case ASC_CDP: if(sd) { clif_skill_nodamage(src,bl,skill_id,skill_lv,1); - skill_produce_mix(sd, skill_id, 678, 0, 0, 0, 1); //Produce a Deadly Poison Bottle. + skill_produce_mix(sd, skill_id, ITEMID_POISON_BOTTLE, 0, 0, 0, 1, -1); //Produce a Poison Bottle. } break; @@ -7349,7 +7350,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (sd) { clif_skill_nodamage(src,bl,skill_id,skill_lv,1); //Prepare 200 White Potions. - if (!skill_produce_mix(sd, skill_id, ITEMID_WHITE_POTION, 0, 0, 0, 200)) + if (!skill_produce_mix(sd, skill_id, ITEMID_WHITE_POTION, 0, 0, 0, 200, -1)) clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); } break; @@ -7357,28 +7358,29 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (sd) { clif_skill_nodamage(src,bl,skill_id,skill_lv,1); //Prepare 200 Slim White Potions. - if (!skill_produce_mix(sd, skill_id, ITEMID_WHITE_SLIM_POTION, 0, 0, 0, 200)) + if (!skill_produce_mix(sd, skill_id, ITEMID_WHITE_SLIM_POTION, 0, 0, 0, 200, -1)) clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); } break; case AM_TWILIGHT3: if (sd) { int ebottle = pc_search_inventory(sd,ITEMID_EMPTY_BOTTLE); + short alcohol_idx = -1, acid_idx = -1, fire_idx = -1; if( ebottle >= 0 ) ebottle = sd->status.inventory[ebottle].amount; //check if you can produce all three, if not, then fail: - if (!skill_can_produce_mix(sd,ITEMID_ALCOHOL,-1, 100) //100 Alcohol - || !skill_can_produce_mix(sd,ITEMID_ACID_BOTTLE,-1, 50) //50 Acid Bottle - || !skill_can_produce_mix(sd,ITEMID_FIRE_BOTTLE,-1, 50) //50 Flame Bottle + if (!(alcohol_idx = skill_can_produce_mix(sd,ITEMID_ALCOHOL,-1, 100)) //100 Alcohol + || !(acid_idx = skill_can_produce_mix(sd,ITEMID_ACID_BOTTLE,-1, 50)) //50 Acid Bottle + || !(fire_idx = skill_can_produce_mix(sd,ITEMID_FIRE_BOTTLE,-1, 50)) //50 Flame Bottle || ebottle < 200 //200 empty bottle are required at total. ) { clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; } clif_skill_nodamage(src,bl,skill_id,skill_lv,1); - skill_produce_mix(sd, skill_id, ITEMID_ALCOHOL, 0, 0, 0, 100); - skill_produce_mix(sd, skill_id, ITEMID_ACID_BOTTLE, 0, 0, 0, 50); - skill_produce_mix(sd, skill_id, ITEMID_FIRE_BOTTLE, 0, 0, 0, 50); + skill_produce_mix(sd, skill_id, ITEMID_ALCOHOL, 0, 0, 0, 100, alcohol_idx-1); + skill_produce_mix(sd, skill_id, ITEMID_ACID_BOTTLE, 0, 0, 0, 50, acid_idx-1); + skill_produce_mix(sd, skill_id, ITEMID_FIRE_BOTTLE, 0, 0, 0, 50, fire_idx-1); } break; case SA_DISPELL: @@ -8779,7 +8781,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case AB_ANCILLA: if( sd ) { clif_skill_nodamage(src,bl,skill_id,skill_lv,1); - skill_produce_mix(sd, skill_id, ITEMID_ANCILLA, 0, 0, 0, 1); + skill_produce_mix(sd, skill_id, ITEMID_ANCILLA, 0, 0, 0, 1, -1); } break; @@ -9557,8 +9559,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui { int heal; - heal = (120 * skill_lv) + (status_get_max_hp(bl) * skill_lv / 100); - status_heal(bl, heal, 0, 0); + if (!dstmd || dstmd->mob_id != MOBID_EMPERIUM || !mob_is_battleground(dstmd)) { + heal = (120 * skill_lv) + (status_get_max_hp(bl) * skill_lv / 100); + status_heal(bl, heal, 0, 0); + } if( (tsc && tsc->opt1) && (rnd()%100 < ((skill_lv * 5) + (status_get_dex(src) + status_get_lv(src)) / 4) - (1 + (rnd() % 10))) ) { status_change_end(bl, SC_STONE, INVALID_TIMER); @@ -10925,7 +10929,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) skill_check_unit_range(src,ud->skillx,ud->skilly,ud->skill_id,ud->skill_lv) ) { - if (sd) clif_skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0); + if (sd) clif_skill_fail(sd,ud->skill_id,USESKILL_FAIL_DUPLICATE_RANGEIN,0); break; } if( src->type&battle_config.skill_nofootset && @@ -12331,30 +12335,37 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_ case GS_GROUNDDRIFT: { - int element[5]={ELE_WIND,ELE_DARK,ELE_POISON,ELE_WATER,ELE_FIRE}; + // Ground Drift Element is decided when it's placed. + int ele = skill_get_ele(skill_id, skill_lv); + int element[5] = { ELE_WIND, ELE_DARK, ELE_POISON, ELE_WATER, ELE_FIRE }; - val1 = status->rhw.ele; - if (!val1) - val1=element[rnd()%5]; + if (ele == -3) + val1 = element[rnd()%5]; // Use random from available unit visual? + else if (ele == -2) + val1 = status_get_attack_sc_element(src,sc); + else if (ele == -1) { + val1 = status->rhw.ele; + if (sc && sc->data[SC_ENCHANTARMS]) + val1 = sc->data[SC_ENCHANTARMS]->val2; + } - switch (val1) - { - case ELE_FIRE: - subunt++; - case ELE_WATER: - subunt++; - case ELE_POISON: - subunt++; - case ELE_DARK: - subunt++; - case ELE_WIND: - break; - default: - subunt=rnd()%5; - break; - } + switch (val1) { + case ELE_FIRE: + subunt++; + case ELE_WATER: + subunt++; + case ELE_POISON: + subunt++; + case ELE_DARK: + subunt++; + case ELE_WIND: + break; + default: + subunt = rnd()%5; + break; + } - break; + break; } case GC_POISONSMOKE: if( !(sc && sc->data[SC_POISONINGWEAPON]) ) @@ -12861,6 +12872,14 @@ static int skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, un } break; + case UNT_STEALTHFIELD: + if( bl->id == sg->src_id ) + break; // Dont work on Self (video shows that) + case UNT_NEUTRALBARRIER: + if (!sce) + sc_start(ss, bl,type,100,sg->skill_lv,sg->limit); + break; + case UNT_GD_LEADERSHIP: case UNT_GD_GLORYWOUNDS: case UNT_GD_SOULCOLD: @@ -13397,13 +13416,6 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns skill_castend_damage_id(&src->bl, bl, sg->skill_id, sg->skill_lv, 0, 0);*/ break; - case UNT_STEALTHFIELD: - if( bl->id == sg->src_id ) - break; // Dont work on Self (video shows that) - case UNT_NEUTRALBARRIER: - sc_start(ss, bl,type,100,sg->skill_lv,sg->interval + 100); - break; - case UNT_DIMENSIONDOOR: if( tsd && !map[bl->m].flag.noteleport ) pc_randomwarp(tsd,CLR_TELEPORT); @@ -13470,6 +13482,8 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns break; case UNT_HELLS_PLANT: + if (tsc && tsc->data[SC__MANHOLE]) + break; if( battle_check_target(&unit->bl,bl,BCT_ENEMY) > 0 ) skill_attack(skill_get_type(GN_HELLS_PLANT_ATK), ss, &unit->bl, bl, GN_HELLS_PLANT_ATK, sg->skill_lv, tick, SCSTART_NONE); if( ss != bl) // The caster is the only one who can step on the Plants without destroying them @@ -13658,8 +13672,6 @@ int skill_unit_onout(struct skill_unit *src, struct block_list *bl, unsigned int case UNT_SAFETYWALL: case UNT_PNEUMA: case UNT_EPICLESIS://Arch Bishop - case UNT_NEUTRALBARRIER: - case UNT_STEALTHFIELD: if (sce) status_change_end(bl, type, INVALID_TIMER); break; @@ -13768,6 +13780,8 @@ int skill_unit_onleft(uint16 skill_id, struct block_list *bl, unsigned int tick) case GN_FIRE_EXPANSION_SMOKE_POWDER: case GN_FIRE_EXPANSION_TEAR_GAS: case LG_KINGS_GRACE: + case NC_STEALTHFIELD: + case NC_NEUTRALBARRIER: if (sce) status_change_end(bl, type, INVALID_TIMER); break; @@ -17842,6 +17856,7 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) return 0; } + /*========================================== * Executes on all skill units every SKILLUNITTIMER_INTERVAL miliseconds. *------------------------------------------*/ @@ -18203,9 +18218,10 @@ short skill_can_produce_mix(struct map_session_data *sd, unsigned short nameid, * @param slot2 * @param slot3 * @param qty Amount of requested item + * @param produce_idx Index of produce entry in skill_produce_db[]. (Optional. Assumed the requirements are complete, checked somewhere) * @return True is success, False if failed */ -bool skill_produce_mix(struct map_session_data *sd, uint16 skill_id, unsigned short nameid, int slot1, int slot2, int slot3, int qty) +bool skill_produce_mix(struct map_session_data *sd, uint16 skill_id, unsigned short nameid, int slot1, int slot2, int slot3, int qty, short produce_idx) { int slot[3]; int i, sc, ele, idx, equip, wlv, make_per = 0, flag = 0, skill_lv = 0; @@ -18220,9 +18236,14 @@ bool skill_produce_mix(struct map_session_data *sd, uint16 skill_id, unsigned sh if( sd->skill_id_old == skill_id ) skill_lv = sd->skill_lv_old; - if( !(idx = skill_can_produce_mix(sd,nameid,-1, qty)) ) - return false; - idx--; + if (produce_idx == -1) { + if( !(idx = skill_can_produce_mix(sd,nameid,-1, qty)) ) + return false; + + idx--; + } + else + idx = produce_idx; if (qty < 1) qty = 1; @@ -19166,7 +19187,7 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite } while(n == j && c == n); p--; if ( p > 0 ) { - skill_produce_mix(sd,GN_CHANGEMATERIAL,skill_produce_db[i].nameid,0,0,0,p); + skill_produce_mix(sd,GN_CHANGEMATERIAL,skill_produce_db[i].nameid,0,0,0,p,i); return 1; } } diff --git a/src/map/skill.h b/src/map/skill.h index 958752256e..4298f1f1be 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -487,7 +487,7 @@ bool skill_isNotOk_npcRange(struct block_list *src, uint16 skill_id, uint16 skil // Item creation short skill_can_produce_mix( struct map_session_data *sd, unsigned short nameid, int trigger, int qty); -bool skill_produce_mix( struct map_session_data *sd, uint16 skill_id, unsigned short nameid, int slot1, int slot2, int slot3, int qty ); +bool skill_produce_mix( struct map_session_data *sd, uint16 skill_id, unsigned short nameid, int slot1, int slot2, int slot3, int qty, short produce_idx ); bool skill_arrow_create( struct map_session_data *sd, unsigned short nameid); diff --git a/src/map/status.c b/src/map/status.c index 52312a4bd3..cf5b069e21 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -5886,7 +5886,7 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc, if( sc->data[SC_ANALYZE] ) def -= def * (14 * sc->data[SC_ANALYZE]->val1) / 100; if( sc->data[SC_NEUTRALBARRIER] ) - def += def * (10 + sc->data[SC_NEUTRALBARRIER]->val1 * 5) / 100; + def += def * sc->data[SC_NEUTRALBARRIER]->val2 / 100; if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 2 ) def += sc->data[SC_SHIELDSPELL_REF]->val2; if( sc->data[SC_PRESTIGE] ) @@ -6021,7 +6021,7 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, if(sc->data[SC_BURNING]) mdef -= 25 * mdef / 100; if( sc->data[SC_NEUTRALBARRIER] ) - mdef += mdef * (10 + sc->data[SC_NEUTRALBARRIER]->val1 * 5) / 100; + mdef += mdef * sc->data[SC_NEUTRALBARRIER]->val3 / 100; if(sc->data[SC_ANALYZE]) mdef -= mdef * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100; if(sc->data[SC_SYMPHONYOFLOVER]) @@ -10175,6 +10175,10 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty else val4 = 0; break; + case SC_NEUTRALBARRIER: + val2 = 10 + val1 * 5; // Def + val3 = 10 + val1 * 5; // Mdef + break; /* Rebellion */ case SC_B_TRAP: