summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrumpyLittlePanda <samuli.vaara@yahoo.com>2014-11-17 19:09:05 +0200
committerGrumpyLittlePanda <samuli.vaara@yahoo.com>2014-11-17 19:36:52 +0200
commit26cdd53ef2d633e6b7d886bb720e645d85d08e43 (patch)
tree28ce5a36441efe995ccbb47e16f453b12994ae06
parent86d0ab88920099c164f12e440f232634989bc69b (diff)
downloadhercules-26cdd53ef2d633e6b7d886bb720e645d85d08e43.tar.gz
hercules-26cdd53ef2d633e6b7d886bb720e645d85d08e43.tar.bz2
hercules-26cdd53ef2d633e6b7d886bb720e645d85d08e43.tar.xz
hercules-26cdd53ef2d633e6b7d886bb720e645d85d08e43.zip
(Bugs 5237 and 7979)
- Land Protector now behaves more like on official servers * Land Protector now protects from units being placed on it, no matter if they have splash range or not * Land Protector no longer protects from damage from units not outside Land Protector that splash inside * Meteor Storm no longer shows meteors falling if they would land on Land Protector * Pneuma can no longer be placed next to Land Protector * Safety wall no longer consumes gem if cast on LP. * Also cleaned up the code a bit, so the checks are done where they should be done - Ground skill splash ranges updated to their official values * Lord of Vermilion places units in a 11x11 area with 3x3 splash range each * Storm Gust places units in a 9x9 area with 3x3 splash range each * Heaven's Drive places units in a 5x5 area with no splash range * Venom Dust now has a splash range of 3x3 and is consequently larger than before - Storm Gust's knock-back behavior updated to official * Each of Storm Gust's units will knock back "Away from center" * As units in the south-west are processed first, the knock-back direction will usually be north-east * At the edges the knock-back direction will be "to the outside" * Land Protector and Ganbantein will influence the knock-back behavior strongly, e.g. if Storm Gust has a hole in the middle, it will have a "suck in" effect * Added a config option for those who want the old "random direction" behavior from eAthena
-rw-r--r--conf/battle/skill.conf9
-rw-r--r--db/pre-re/skill_unit_db.txt10
-rw-r--r--db/re/skill_unit_db.txt10
-rw-r--r--src/map/battle.c1
-rw-r--r--src/map/battle.h1
-rw-r--r--src/map/skill.c22
-rw-r--r--src/map/unit.c8
7 files changed, 33 insertions, 28 deletions
diff --git a/conf/battle/skill.conf b/conf/battle/skill.conf
index e6828749b..a870b6c85 100644
--- a/conf/battle/skill.conf
+++ b/conf/battle/skill.conf
@@ -293,4 +293,11 @@ mob_max_skilllvl: 100
// 1: Gutter line system without demi gutter bug
// 2-20: Area around caster (2 = 5x5, 3 = 7x7, 4 = 9x9, ..., 20 = 41x41)
// Note: If you knock the target out of the area it will only be hit once and won't do splash damage
-bowling_bash_area: 0 \ No newline at end of file
+bowling_bash_area: 0
+
+// On official servers, Storm Gust consists of 81 units that all deal 3x3 splash damage "away from center". Due to
+// south-western cells being processed first, this usually leads to a knockback to the northeast. Knockback at the
+// edges will be away from SG. Knockback direction can also be influenced by Ganbantein and Land Protector. If you
+// punch a hole into SG it will for example create a "suck in" effect.
+// If you disable this setting, the knockback direction will be completely random (eAthena style).
+stormgust_knockback: yes \ No newline at end of file
diff --git a/db/pre-re/skill_unit_db.txt b/db/pre-re/skill_unit_db.txt
index bba3670e8..196a79d5b 100644
--- a/db/pre-re/skill_unit_db.txt
+++ b/db/pre-re/skill_unit_db.txt
@@ -4,7 +4,7 @@
// target = friend (party +guildmates +neutral players) / party / guild
// ally (party +guildmates) / all / sameguild (guild but no allies) / enemy
// flag 0x001(UF_DEFNOTENEMY) If 'defunit_not_enemy' is set, the target is changed to 'friend'
-// 0x002(UF_NOREITERRATION) Spell cannot be stacked
+// 0x002(UF_NOREITERATION) Spell cannot be stacked
// 0x004(UF_NOFOOTSET) Spell cannot be cast near/on targets
// 0x008(UF_NOOVERLAP) Spell effects do not overlap
// 0x010(UF_PATHCHECK) Only cells with a shootable path will be placed
@@ -35,10 +35,10 @@
79,0x84, , -1, 1,3000,enemy, 0x018 //PR_MAGNUS
80,0x87,0x88, 0, 1,2000,enemy, 0x006 //WZ_FIREPILLAR
83,0x86, , 0, 3,1000,enemy, 0x010 //WZ_METEOR
- 85,0x86, , 0, 6:6:6:6:6:6:6:6:6:6:8,1250,enemy,0x018 //WZ_VERMILION
+ 85,0x86, , 5, 1:1:1:1:1:1:1:1:1:1:3,1250,enemy,0x018 //WZ_VERMILION
87,0x8d, , -1, 0, -1,all, 0x010 //WZ_ICEWALL
- 89,0x86, , 0, 5, 450,enemy, 0x018 //WZ_STORMGUST
- 91,0x86, , 0, 2,1000,enemy, 0x010 //WZ_HEAVENDRIVE
+ 89,0x86, , 4, 1, 450,enemy, 0x018 //WZ_STORMGUST
+ 91,0x86, , 2, 0,1000,enemy, 0x010 //WZ_HEAVENDRIVE
92,0x8e, , 2, 0, -1,enemy, 0x010 //WZ_QUAGMIRE
115,0x90, , 0, 1,1000,enemy, 0x006 //HT_SKIDTRAP
116,0x93, , 0, 1,1000,enemy, 0x006 //HT_LANDMINE
@@ -50,7 +50,7 @@
122,0x8f, , 0, 1,1000,enemy, 0x006 //HT_BLASTMINE
123,0x98, , 0, 1,1000,enemy, 0x006 //HT_CLAYMORETRAP
125,0x99, , 0, 1,1000,all, 0x000 //HT_TALKIEBOX
-140,0x92, , -1, 0,1000,enemy, 0x000 //AS_VENOMDUST
+140,0x92, , -1, 1,1000,enemy, 0x000 //AS_VENOMDUST
220,0xb0, , 0, 0, -1,all, 0x002 //RG_GRAFFITI
229,0xb1, , 0, 1,1000,enemy, 0x006 //AM_DEMONSTRATION
254,0x86, , -1, 0, 300,enemy, 0x010 //CR_GRANDCROSS
diff --git a/db/re/skill_unit_db.txt b/db/re/skill_unit_db.txt
index 1f93d771f..87afd2da2 100644
--- a/db/re/skill_unit_db.txt
+++ b/db/re/skill_unit_db.txt
@@ -4,7 +4,7 @@
// target = friend (party +guildmates +neutral players) / party / guild
// ally (party +guildmates) / all / sameguild (guild but no allies) / enemy
// flag 0x001(UF_DEFNOTENEMY) If 'defunit_not_enemy' is set, the target is changed to 'friend'
-// 0x002(UF_NOREITERRATION) Spell cannot be stacked
+// 0x002(UF_NOREITERATION) Spell cannot be stacked
// 0x004(UF_NOFOOTSET) Spell cannot be cast near/on targets
// 0x008(UF_NOOVERLAP) Spell effects do not overlap
// 0x010(UF_PATHCHECK) Only cells with a shootable path will be placed
@@ -35,10 +35,10 @@
79,0x84, , -1, 1,3000,enemy, 0x018 //PR_MAGNUS
80,0x87,0x88, 0, 1,2000,enemy, 0x006 //WZ_FIREPILLAR
83,0x86, , 0, 3,1000,enemy, 0x010 //WZ_METEOR
- 85,0x86, , 0, 6:6:6:6:6:6:6:6:6:6:8,1250,enemy,0x018 //WZ_VERMILION
+ 85,0x86, , 5, 1:1:1:1:1:1:1:1:1:1:3,1250,enemy,0x018 //WZ_VERMILION
87,0x8d, , -1, 0, -1,all, 0x010 //WZ_ICEWALL
- 89,0x86, , 0, 5, 450,enemy, 0x018 //WZ_STORMGUST
- 91,0x86, , 0, 2,1000,enemy, 0x010 //WZ_HEAVENDRIVE
+ 89,0x86, , 4, 1, 450,enemy, 0x018 //WZ_STORMGUST
+ 91,0x86, , 2, 0,1000,enemy, 0x010 //WZ_HEAVENDRIVE
92,0x8e, , 2, 0, -1,enemy, 0x010 //WZ_QUAGMIRE
115,0x90, , 0, 1,1000,enemy, 0x006 //HT_SKIDTRAP
116,0x93, , 0, 1,1000,enemy, 0x006 //HT_LANDMINE
@@ -50,7 +50,7 @@
122,0x8f, , 0, 1,1000,enemy, 0x006 //HT_BLASTMINE
123,0x98, , 0, 1,1000,enemy, 0x006 //HT_CLAYMORETRAP
125,0x99, , 0, 1,1000,all, 0x000 //HT_TALKIEBOX
-140,0x92, , -1, 0,1000,enemy, 0x000 //AS_VENOMDUST
+140,0x92, , -1, 1,1000,enemy, 0x000 //AS_VENOMDUST
220,0xb0, , 0, 0, -1,all, 0x002 //RG_GRAFFITI
229,0xb1, , 0, 1,1000,enemy, 0x006 //AM_DEMONSTRATION
254,0x86, , -1, 0, 300,enemy, 0x010 //CR_GRANDCROSS
diff --git a/src/map/battle.c b/src/map/battle.c
index 9ee4695f7..1563553d4 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -6839,6 +6839,7 @@ static const struct battle_data {
{ "guild_castle_expulsion", &battle_config.guild_castle_expulsion, 0, 0, 1, },
{ "song_timer_reset", &battle_config.song_timer_reset, 0, 0, 1, },
{ "snap_dodge", &battle_config.snap_dodge, 0, 0, 1, },
+ { "stormgust_knockback", &battle_config.stormgust_knockback, 1, 0, 1, },
{ "monster_chase_refresh", &battle_config.mob_chase_refresh, 1, 0, 30, },
{ "mob_icewall_walk_block", &battle_config.mob_icewall_walk_block, 75, 0, 255, },
{ "boss_icewall_walk_block", &battle_config.boss_icewall_walk_block, 0, 0, 255, },
diff --git a/src/map/battle.h b/src/map/battle.h
index ad879bd1a..e80e0091d 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -482,6 +482,7 @@ struct Battle_Config {
int song_timer_reset; // [csnv]
int snap_dodge; // Enable or disable dodging damage snapping away [csnv]
+ int stormgust_knockback;
int feature_roulette;
};
diff --git a/src/map/skill.c b/src/map/skill.c
index 169f4bcb9..938b36419 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -2658,7 +2658,8 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
break;
// This ensures the storm randomly pushes instead of exactly a cell backwards per official mechanics.
case WZ_STORMGUST:
- dir = rnd()%8;
+ if(!battle_config.stormgust_knockback)
+ dir = rand()%8;
break;
case WL_CRIMSONROCK:
dir = map->calc_dir(bl,skill->area_temp[4],skill->area_temp[5]);
@@ -2856,9 +2857,11 @@ int skill_check_unit_range_sub (struct block_list *bl, va_list ap) {
g_skill_id = su->group->skill_id;
switch (skill_id) {
- case MH_STEINWAND:
- case MG_SAFETYWALL:
case AL_PNEUMA:
+ case MG_SAFETYWALL:
+ if(g_skill_id == SA_LANDPROTECTOR)
+ break;
+ case MH_STEINWAND:
case SC_MAELSTROM:
case SO_ELEMENTAL_SHIELD:
if(g_skill_id != MH_STEINWAND && g_skill_id != MG_SAFETYWALL && g_skill_id != AL_PNEUMA && g_skill_id != SC_MAELSTROM && g_skill_id != SO_ELEMENTAL_SHIELD)
@@ -3303,7 +3306,8 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) {
int x = skl->type>>16, y = skl->type&0xFFFF;
if( path->search_long(NULL, src->m, src->x, src->y, x, y, CELL_CHKWALL) )
skill->unitsetting(src,skl->skill_id,skl->skill_lv,x,y,skl->flag);
- if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
+ if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL)
+ && !map->getcell(src->m, skl->x, skl->y, CELL_CHKLANDPROTECTOR) )
clif->skill_poseffect(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,tick);
}
else if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
@@ -10265,7 +10269,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
tmpx = x - area + rnd()%(area * 2 + 1);
tmpy = y - area + rnd()%(area * 2 + 1);
- if( i == 0 && path->search_long(NULL, src->m, src->x, src->y, tmpx, tmpy, CELL_CHKWALL) )
+ if( i == 0 && path->search_long(NULL, src->m, src->x, src->y, tmpx, tmpy, CELL_CHKWALL)
+ && !map->getcell(src->m, tmpx, tmpy, CELL_CHKLANDPROTECTOR))
clif->skill_poseffect(src,skill_id,skill_lv,tmpx,tmpy,tick);
if( i > 0 )
@@ -11288,8 +11293,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
if (skill->get_unit_flag(skill_id) & UF_RANGEDSINGLEUNIT && i == (layout->count / 2))
val2 |= UF_RANGEDSINGLEUNIT; // center.
- if( range <= 0 )
- map->foreachincell(skill->cell_overlap,src->m,ux,uy,BL_SKILL,skill_id, &alive, src);
+ map->foreachincell(skill->cell_overlap,src->m,ux,uy,BL_SKILL,skill_id, &alive, src);
if( !alive )
continue;
@@ -11344,7 +11348,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
nullpo_ret(sg=src->group);
nullpo_ret(ss=map->id2bl(sg->src_id));
- if( skill->get_type(sg->skill_id) == BF_MAGIC && map->getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) && sg->skill_id != SA_LANDPROTECTOR )
+ if( skill->get_type(sg->skill_id) == BF_MAGIC && map->getcell(src->bl.m, src->bl.x, src->bl.y, CELL_CHKLANDPROTECTOR) && sg->skill_id != SA_LANDPROTECTOR )
return 0; //AoE skills are ineffective. [Skotlex]
sc = status->get_sc(bl);
@@ -16010,7 +16014,7 @@ int skill_unit_timer_sub_onplace(struct block_list* bl, va_list ap) {
nullpo_ret(group);
- if( !(skill->get_inf2(group->skill_id)&(INF2_SONG_DANCE|INF2_TRAP|INF2_NOLP)) && map->getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) )
+ if( !(skill->get_inf2(group->skill_id)&(INF2_SONG_DANCE|INF2_TRAP|INF2_NOLP)) && map->getcell(su->bl.m, su->bl.x, su->bl.y, CELL_CHKLANDPROTECTOR) )
return 0; //AoE skills are ineffective. [Skotlex]
if( battle->check_target(&su->bl,bl,group->target_flag) <= 0 )
diff --git a/src/map/unit.c b/src/map/unit.c
index 2ab13b121..c00a0631d 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -1619,14 +1619,6 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
if( skill->not_ok(skill_id, sd) || !skill->check_condition_castbegin(sd, skill_id, skill_lv) )
return 0;
/**
- * "WHY IS IT HEREE": pneuma cannot be canceled past this point, the client displays the animation even,
- * if we cancel it from nodamage_id, so it has to be here for it to not display the animation.
- **/
- if( skill_id == AL_PNEUMA && map->getcell(src->m, skill_x, skill_y, CELL_CHKLANDPROTECTOR) ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
- /**
* "WHY IS IT HEREE": ice wall cannot be canceled past this point, the client displays the animation even,
* if we cancel it from castend_pos, so it has to be here for it to not display the animation.
**/