- Cleaned some of mpeg's updated work.
- Fixed HT_BLITZBEAT hitting neutral characters when it auto-triggers. - Simplified the Tatami Gaeshi code. - Fixed AS_SPLASHER doing full damage on everyone except targetted char instead of the other way around. - Fixed KAENSIN clearing out SUITON cells and viceversa. - The spawn area is now seen as range rather than absolute for mob spawn lines. This means that x,y,10,10 will spawn the mob on a 21x21 grid around the given x,y point. - Some clean up of the mob-spawn code. Now you can specify negative areas, so that a spawn location such as 100,150,0,-1 will spawn a mob always on x=100, but any Y value of the current map. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@8165 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
26a6620863
commit
6daec0f2c0
@ -4,6 +4,18 @@ 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.
|
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||||
|
|
||||||
2006/08/07
|
2006/08/07
|
||||||
|
* Fixed HT_BLITZBEAT hitting neutral characters when it auto-triggers.
|
||||||
|
[Skotlex]
|
||||||
|
* Simplified the Tatami Gaeshi code. [Skotlex]
|
||||||
|
* Fixed AS_SPLASHER doing full damage on everyone except targetted char
|
||||||
|
instead of the other way around. [Skotlex]
|
||||||
|
* Fixed KAENSIN clearing out SUITON cells and viceversa. [Skotlex]
|
||||||
|
* The spawn area is now seen as range rather than absolute for mob spawn
|
||||||
|
lines. This means that x,y,10,10 will spawn the mob on a 21x21 grid around
|
||||||
|
the given x,y point. [Skotlex]
|
||||||
|
* Some clean up of the mob-spawn code. Now you can specify negative areas,
|
||||||
|
so that a spawn location such as 100,150,0,-1 will spawn a mob always on
|
||||||
|
x=100, but any Y value of the current map. [Skotlex]
|
||||||
* Reflected damage will now also have a chance of draining hp/sp. [Skotlex]
|
* Reflected damage will now also have a chance of draining hp/sp. [Skotlex]
|
||||||
* Adjusted the order in which option/sc change packets are sent to match
|
* Adjusted the order in which option/sc change packets are sent to match
|
||||||
Aegis's [Skotlex]
|
Aegis's [Skotlex]
|
||||||
|
@ -885,8 +885,8 @@
|
|||||||
525,1000,1000,0,0,0
|
525,1000,1000,0,0,0
|
||||||
//-- NJ_ZENYNAGE
|
//-- NJ_ZENYNAGE
|
||||||
526,0,5000,0,0,0
|
526,0,5000,0,0,0
|
||||||
//-- NJ_TATAMIGAESHI // Duration1 used for SC_TATAMIGAESHI and ground visual effect and Duration2 for "damage-can-be-done" duration
|
//-- NJ_TATAMIGAESHI // Duration1 is land-effect. Duration2 is the range-inmunity effect
|
||||||
527,0,3000,0,3000,200 // ex> Skill will only hit during 200 first ticks (concretely do only 1 hit just after being casted)
|
527,0,3000,0,500,3000
|
||||||
//-- NJ_KASUMIKIRI // Delay unknown (if there is one)
|
//-- NJ_KASUMIKIRI // Delay unknown (if there is one)
|
||||||
528,0,0,0,30000:60000:90000:120000:150000:180000:210000:240000:270000:300000,0
|
528,0,0,0,30000:60000:90000:120000:150000:180000:210000:240000:270000:300000,0
|
||||||
//-- NJ_SHADOWJUMP // Delay unknown (if there is one)
|
//-- NJ_SHADOWJUMP // Delay unknown (if there is one)
|
||||||
|
@ -89,6 +89,6 @@
|
|||||||
488,0xb9, , 3, 0, -1,all, 0x200 //CG_HERMODE
|
488,0xb9, , 3, 0, -1,all, 0x200 //CG_HERMODE
|
||||||
516,0xba, , 0, 3, 100,enemy, 0x000 //GS_DESPERADO
|
516,0xba, , 0, 3, 100,enemy, 0x000 //GS_DESPERADO
|
||||||
521,0xc2, , 0, 1,1000,enemy, 0x006 //GS_GROUNDDRIFT
|
521,0xc2, , 0, 1,1000,enemy, 0x006 //GS_GROUNDDRIFT
|
||||||
527,0xbc, , -1, 0,2500,enemy, 0x000 //NJ_TATAMIGAESHI
|
527,0xbc, , -1, 0,1000,enemy, 0x000 //NJ_TATAMIGAESHI
|
||||||
535,0xbd, , -1, 0, 200,enemy, 0x008 //NJ_KAENSIN
|
535,0xbd, , -1, 0, 200,enemy, 0x008 //NJ_KAENSIN
|
||||||
538,0xbb,,1:1:1:2:2:2:3:3:3:4,0,-1,all,0x000 //NJ_SUITON
|
538,0xbb,,1:1:1:2:2:2:3:3:3:4,0,-1,all,0x000 //NJ_SUITON
|
||||||
|
@ -2276,21 +2276,13 @@ struct Damage battle_calc_magic_attack(
|
|||||||
|
|
||||||
switch(skill_num){
|
switch(skill_num){
|
||||||
case MG_NAPALMBEAT:
|
case MG_NAPALMBEAT:
|
||||||
|
case MG_FIREBALL:
|
||||||
skillratio += skill_lv*10-30;
|
skillratio += skill_lv*10-30;
|
||||||
break;
|
break;
|
||||||
case MG_SOULSTRIKE:
|
case MG_SOULSTRIKE:
|
||||||
if (battle_check_undead(tstatus->race,tstatus->def_ele))
|
if (battle_check_undead(tstatus->race,tstatus->def_ele))
|
||||||
skillratio += 5*skill_lv;
|
skillratio += 5*skill_lv;
|
||||||
break;
|
break;
|
||||||
case MG_FIREBALL:
|
|
||||||
if(mflag>2)
|
|
||||||
ad.damage = 0;
|
|
||||||
else {
|
|
||||||
int drate[]={100,90,70};
|
|
||||||
MATK_RATE(drate[mflag]);
|
|
||||||
skillratio += 70+10*skill_lv;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MG_FIREWALL:
|
case MG_FIREWALL:
|
||||||
skillratio -= 50;
|
skillratio -= 50;
|
||||||
break;
|
break;
|
||||||
|
@ -859,7 +859,8 @@ struct guardian_data {
|
|||||||
// Expanded to specify all mob-related spawn data by [Skotlex]
|
// Expanded to specify all mob-related spawn data by [Skotlex]
|
||||||
struct spawn_data {
|
struct spawn_data {
|
||||||
short class_; //Class, used because a mob can change it's class
|
short class_; //Class, used because a mob can change it's class
|
||||||
unsigned short m,x,y,xs,ys; //Spawn information (map, point, spawn-area around point)
|
unsigned short m,x,y; //Spawn information (map, point, spawn-area around point)
|
||||||
|
signed short xs,ys;
|
||||||
unsigned short num; //Number of mobs using this structure.
|
unsigned short num; //Number of mobs using this structure.
|
||||||
unsigned int level; //Custom level.
|
unsigned int level; //Custom level.
|
||||||
unsigned int delay1,delay2; //Min delay before respawning after spawn/death
|
unsigned int delay1,delay2; //Min delay before respawning after spawn/death
|
||||||
|
@ -633,28 +633,18 @@ int mob_spawn (struct mob_data *md)
|
|||||||
|
|
||||||
if (md->spawn) { //Respawn data
|
if (md->spawn) { //Respawn data
|
||||||
md->bl.m = md->spawn->m;
|
md->bl.m = md->spawn->m;
|
||||||
|
md->bl.x = md->spawn->x;
|
||||||
|
md->bl.y = md->spawn->y;
|
||||||
|
|
||||||
if ((md->spawn->x == 0 && md->spawn->y == 0) || md->spawn->xs || md->spawn->ys)
|
if ((md->bl.x == 0 && md->bl.y == 0) || md->spawn->xs || md->spawn->ys)
|
||||||
{ //Monster can be spawned on an area.
|
{ //Monster can be spawned on an area.
|
||||||
short x, y, xs, ys;
|
if (!map_search_freecell(NULL, -1,
|
||||||
if (md->spawn->x == 0 && md->spawn->y == 0)
|
&md->bl.x, &md->bl.y, md->spawn->xs, md->spawn->ys,
|
||||||
x = y = xs = ys = -1;
|
battle_config.no_spawn_on_player?4:0)) {
|
||||||
else {
|
|
||||||
x = md->spawn->x;
|
|
||||||
y = md->spawn->y;
|
|
||||||
xs = md->spawn->xs/2;
|
|
||||||
ys = md->spawn->ys/2;
|
|
||||||
}
|
|
||||||
if (!map_search_freecell(NULL, md->spawn->m, &x, &y, xs, ys, battle_config.no_spawn_on_player?5:1)) {
|
|
||||||
// retry again later
|
// retry again later
|
||||||
add_timer(tick+5000,mob_delayspawn,md->bl.id,0);
|
add_timer(tick+5000,mob_delayspawn,md->bl.id,0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
md->bl.x = x;
|
|
||||||
md->bl.y = y;
|
|
||||||
} else {
|
|
||||||
md->bl.x = md->spawn->x;
|
|
||||||
md->bl.y = md->spawn->y;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memset(&md->state, 0, sizeof(md->state));
|
memset(&md->state, 0, sizeof(md->state));
|
||||||
|
@ -2209,17 +2209,18 @@ int npc_parse_mob (char *w1, char *w2, char *w3, char *w4)
|
|||||||
mob.class_ = (short) class_;
|
mob.class_ = (short) class_;
|
||||||
mob.x = (unsigned short)x;
|
mob.x = (unsigned short)x;
|
||||||
mob.y = (unsigned short)y;
|
mob.y = (unsigned short)y;
|
||||||
mob.xs = (unsigned short)xs;
|
mob.xs = (signed short)xs;
|
||||||
mob.ys = (unsigned short)ys;
|
mob.ys = (signed short)ys;
|
||||||
|
|
||||||
if (mob.num > 1 && battle_config.mob_count_rate != 100) {
|
if (mob.num > 1 && battle_config.mob_count_rate != 100) {
|
||||||
if ((mob.num = mob.num * battle_config.mob_count_rate / 100) < 1)
|
if ((mob.num = mob.num * battle_config.mob_count_rate / 100) < 1)
|
||||||
mob.num = 1;
|
mob.num = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (battle_config.force_random_spawn)
|
if (battle_config.force_random_spawn || (mob.x == 0 && mob.y == 0))
|
||||||
{ //Force a random spawn anywhere on the map.
|
{ //Force a random spawn anywhere on the map.
|
||||||
mob.x = mob.y = mob.xs = mob.ys = 0;
|
mob.x = mob.y = 0;
|
||||||
|
mob.xs = mob.ys = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Apply the spawn delay fix [Skotlex]
|
//Apply the spawn delay fix [Skotlex]
|
||||||
|
@ -2082,10 +2082,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
|
|||||||
|
|
||||||
//Only knockback if it's still alive, otherwise a "ghost" is left behind. [Skotlex]
|
//Only knockback if it's still alive, otherwise a "ghost" is left behind. [Skotlex]
|
||||||
if (dmg.blewcount > 0 && !status_isdead(bl))
|
if (dmg.blewcount > 0 && !status_isdead(bl))
|
||||||
{
|
skill_blown(skillid==NJ_TATAMIGAESHI?src:dsrc,bl,dmg.blewcount);
|
||||||
if ( skillid != NJ_TATAMIGAESHI ) skill_blown(dsrc,bl,dmg.blewcount);
|
|
||||||
else skill_blown(src,bl,dmg.blewcount);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Delayed damage must be dealt after the knockback (it needs to know actual position of target)
|
//Delayed damage must be dealt after the knockback (it needs to know actual position of target)
|
||||||
if (dmg.amotion)
|
if (dmg.amotion)
|
||||||
@ -2830,8 +2827,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
|
|||||||
|
|
||||||
//Splash attack skills.
|
//Splash attack skills.
|
||||||
case AS_SPLASHER:
|
case AS_SPLASHER:
|
||||||
if ( (flag&1) && bl->id != skill_area_temp[1] )
|
if ((flag&1) && bl->id == skill_area_temp[1])
|
||||||
{
|
{ //Should do 100% damage on targetted character.
|
||||||
skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, 1);
|
skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2842,19 +2839,21 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
|
|||||||
case MG_NAPALMBEAT:
|
case MG_NAPALMBEAT:
|
||||||
case MG_FIREBALL:
|
case MG_FIREBALL:
|
||||||
case HW_NAPALMVULCAN:
|
case HW_NAPALMVULCAN:
|
||||||
case HT_BLITZBEAT:
|
|
||||||
case NJ_HUUMA:
|
case NJ_HUUMA:
|
||||||
case NJ_BAKUENRYU:
|
case NJ_BAKUENRYU:
|
||||||
if (flag & 1) { //Invoked from map_foreachinarea, skill_area_temp[0] holds number of targets to divide damage by.
|
if (flag&1) //Invoked from map_foreachinarea, skill_area_temp[0] holds number of targets to divide damage by.
|
||||||
skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, skill_area_temp[0]);
|
skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, skill_area_temp[0]);
|
||||||
} else {
|
else {
|
||||||
if ( skillid == NJ_BAKUENRYU ) clif_skill_nodamage(src,bl,skillid,skilllv,1);
|
if ( skillid == NJ_BAKUENRYU ) clif_skill_nodamage(src,bl,skillid,skilllv,1);
|
||||||
skill_area_temp[0] = 0;
|
skill_area_temp[0] = 0;
|
||||||
skill_area_temp[1] = bl->id;
|
skill_area_temp[1] = bl->id;
|
||||||
if ( (skill_get_nk(skillid)&NK_SPLASHSPLIT) || (skillid==HT_BLITZBEAT && flag&0xf00000) ) //Warning, 0x100000 is currently BCT_NEUTRAL, so don't mix it when asking for the enemy. [Skotlex]
|
if (skill_get_nk(skillid)&NK_SPLASHSPLIT)
|
||||||
map_foreachinrange(skill_area_sub, bl,
|
map_foreachinrange(skill_area_sub, bl,
|
||||||
skill_get_splash(skillid, skilllv), BL_CHAR,
|
skill_get_splash(skillid, skilllv), BL_CHAR,
|
||||||
src, skillid, skilllv, tick, flag|BCT_ENEMY, skill_area_sub_count);
|
src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count);
|
||||||
|
else
|
||||||
|
skill_area_temp[0] = 1;
|
||||||
|
|
||||||
map_foreachinrange(skill_area_sub, bl,
|
map_foreachinrange(skill_area_sub, bl,
|
||||||
skill_get_splash(skillid, skilllv), BL_CHAR,
|
skill_get_splash(skillid, skilllv), BL_CHAR,
|
||||||
src, skillid, skilllv, tick, flag|BCT_ENEMY|1,
|
src, skillid, skilllv, tick, flag|BCT_ENEMY|1,
|
||||||
@ -2862,6 +2861,26 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//Done apart because you can't mix the flag with BCT_ENEMY for auto-blitz.
|
||||||
|
case HT_BLITZBEAT:
|
||||||
|
if (flag&1) //Warning, 0x100000 is currently BCT_NEUTRAL, so don't mix it when asking for the enemy. [Skotlex]
|
||||||
|
skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, skill_area_temp[0]);
|
||||||
|
else {
|
||||||
|
skill_area_temp[0] = 0;
|
||||||
|
skill_area_temp[1] = bl->id;
|
||||||
|
//Warning, 0x100000 is currently BCT_NEUTRAL, so don't mix it when asking for the enemy. [Skotlex]
|
||||||
|
if (skillid==HT_BLITZBEAT && flag&0xf00000)
|
||||||
|
map_foreachinrange(skill_area_sub, bl,
|
||||||
|
skill_get_splash(skillid, skilllv), BL_CHAR,
|
||||||
|
src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count);
|
||||||
|
else
|
||||||
|
skill_area_temp[0] = 1;
|
||||||
|
map_foreachinrange(skill_area_sub, bl,
|
||||||
|
skill_get_splash(skillid, skilllv), BL_CHAR,
|
||||||
|
src, skillid, skilllv, tick, BCT_ENEMY|1,
|
||||||
|
skill_castend_damage_id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SM_MAGNUM:
|
case SM_MAGNUM:
|
||||||
if(flag&1)
|
if(flag&1)
|
||||||
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
|
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
|
||||||
@ -3110,8 +3129,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
|
|||||||
int dir = map_calc_dir(src,bl->x,bl->y);
|
int dir = map_calc_dir(src,bl->x,bl->y);
|
||||||
status_change_end(src, SC_HIDING, -1);
|
status_change_end(src, SC_HIDING, -1);
|
||||||
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
|
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
|
||||||
if (unit_movepos(src, bl->x - dirx[dir], bl->y - diry[dir], 0, 0)) // fixed... sorry for this o_O
|
if (unit_movepos(src, bl->x - dirx[dir], bl->y - diry[dir], 0, 0))
|
||||||
clif_slide(src,bl->x - dirx[dir],bl->y - diry[dir]);
|
clif_slide(src,src->x,src->y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NJ_ISSEN:
|
case NJ_ISSEN:
|
||||||
@ -6221,7 +6240,7 @@ int skill_castend_pos2 (struct block_list *src, int x, int y, int skillid, int s
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NJ_TATAMIGAESHI:
|
case NJ_TATAMIGAESHI:
|
||||||
sc_start(src,type,100,skilllv,skill_get_time(skillid,skilllv));
|
sc_start(src,type,100,skilllv,skill_get_time2(skillid,skilllv));
|
||||||
skill_unitsetting(src,skillid,skilllv,src->x,src->y,0);
|
skill_unitsetting(src,skillid,skilllv,src->x,src->y,0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -6632,7 +6651,7 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid,
|
|||||||
if (sd) val1 = sd->status.child;
|
if (sd) val1 = sd->status.child;
|
||||||
break;
|
break;
|
||||||
case NJ_KAENSIN:
|
case NJ_KAENSIN:
|
||||||
skill_clear_group(src, 1); //Delete previous Kaensins
|
skill_clear_group(src, 4); //Delete previous Kaensins
|
||||||
val2 = (skilllv+1)/2 + 4;
|
val2 = (skilllv+1)/2 + 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -7157,17 +7176,6 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
|
|||||||
}
|
}
|
||||||
|
|
||||||
case UNT_TATAMIGAESHI:
|
case UNT_TATAMIGAESHI:
|
||||||
{
|
|
||||||
struct skill_unit_group *sug; // better name needed :D
|
|
||||||
|
|
||||||
if ( (sug = map_find_skill_unit_oncell(bl,bl->x,bl->y,NJ_TATAMIGAESHI,NULL)->group) != NULL )
|
|
||||||
{
|
|
||||||
if ( DIFF_TICK(gettick(), sug->tick) <= skill_get_time2(sg->skill_id, sg->skill_lv) )
|
|
||||||
skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case UNT_DEMONSTRATION:
|
case UNT_DEMONSTRATION:
|
||||||
skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
|
skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
|
||||||
break;
|
break;
|
||||||
@ -9144,10 +9152,13 @@ int skill_clear_group (struct block_list *bl, int flag)
|
|||||||
case SA_VIOLENTGALE:
|
case SA_VIOLENTGALE:
|
||||||
case SA_LANDPROTECTOR:
|
case SA_LANDPROTECTOR:
|
||||||
case NJ_SUITON:
|
case NJ_SUITON:
|
||||||
case NJ_KAENSIN:
|
|
||||||
if (flag&1)
|
if (flag&1)
|
||||||
group[count++]= ud->skillunit[i];
|
group[count++]= ud->skillunit[i];
|
||||||
break;
|
break;
|
||||||
|
case NJ_KAENSIN:
|
||||||
|
if (flag&4)
|
||||||
|
group[count++]= ud->skillunit[i];
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (flag&2 && skill_get_inf2(ud->skillunit[i]->skill_id)&INF2_TRAP)
|
if (flag&2 && skill_get_inf2(ud->skillunit[i]->skill_id)&INF2_TRAP)
|
||||||
group[count++]= ud->skillunit[i];
|
group[count++]= ud->skillunit[i];
|
||||||
@ -9259,7 +9270,7 @@ int skill_landprotector (struct block_list *bl, va_list ap)
|
|||||||
case NJ_SUITON:
|
case NJ_SUITON:
|
||||||
case NJ_KAENSIN:
|
case NJ_KAENSIN:
|
||||||
switch (unit->group->skill_id)
|
switch (unit->group->skill_id)
|
||||||
{ //These override each other.
|
{ //These cannot override each other.
|
||||||
case SA_VOLCANO:
|
case SA_VOLCANO:
|
||||||
case SA_DELUGE:
|
case SA_DELUGE:
|
||||||
case SA_VIOLENTGALE:
|
case SA_VIOLENTGALE:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user