Gravitational Field full official implementation and minor fixes
- Gravitational Field will now work as official servers (bugreport:4897) * Fixed range of Ganbantein (16->14) and Gravitational Field (9->14) * Gravitational Field never misses and can hit hidden targets * Similar to Pressure the damage can not be increased or decreased by any means, it even hits GTB users and users protected by Devotion/Sacrifice * Renewal damage is now 400+100*level every 500ms (200+200*level every 1000ms in pre-renewal) * You can no longer do normal attacks while the skill is active * You now can use skills while the skill is active, however, other skills are unable to deal any damage as long as Gravitational Field is active * Added the possibility to link different skill unit groups together; if a skill unit group gets deleted, the linked skill unit groups are deleted as well; this was needed because when being hit, all Gravitational Fields of the person being hit need to be removed * Gravitational Field can no longer overlap with itself * Pressure and Gravitational Field will now be considered "physical normal attacks" and can consequently trigger Autospells; unlike manually cast spells, Autospells can deal damage while Gravitational Field is active - Fixed that in renewal, weapons with a range of 2 and 3 did depend on DEX instead of STR (fixed #129) * Special thanks to NovaRagnarok for the fix
This commit is contained in:
parent
4e376c49b7
commit
861112b89b
@ -699,8 +699,8 @@
|
||||
480,5,8,1,-1,0,0,5,5,no,0,0,0,weapon,0,0x20000, PA_SHIELDCHAIN,Shield Chain
|
||||
481,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0, HP_MANARECHARGE,Mana Recharge
|
||||
482,0,6,4,0,0x1,0,5,1,no,0,0,0,magic,0,0x0, PF_DOUBLECASTING,Double Casting
|
||||
483,16,6,2,0,0x1,1:2:3:4:5,1,1,no,0,0,0,none,0,0x20, HW_GANBANTEIN,Ganbantein
|
||||
484,9,6,2,2,0x91,0,5,1,yes,0,0x18000,0,misc,0,0x1030, HW_GRAVITATION,Gravitation Field
|
||||
483,14,6,2,0,0x1,1:2:3:4:5,1,1,no,0,0,0,none,0,0x20, HW_GANBANTEIN,Ganbantein
|
||||
484,14,6,2,2,0xD1,0,5,1,yes,0,0x18000,0,misc,0,0x11030, HW_GRAVITATION,Gravitation Field
|
||||
485,-2,6,1,-1,0x8,0,10,1,no,0,0,0,weapon,0,0x4000, WS_CARTTERMINATION,Cart Termination
|
||||
486,0,6,4,0,0x1,0,5,1,no,0,0,0,weapon,0,0x4000, WS_OVERTHRUSTMAX,Maximum Power Thrust
|
||||
487,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x8, CG_LONGINGFREEDOM,Longing for Freedom
|
||||
|
@ -699,8 +699,8 @@
|
||||
480,5,8,1,-1,0,0,5,5,no,0,0,0,weapon,0,0x20000, PA_SHIELDCHAIN,Shield Chain
|
||||
481,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0, HP_MANARECHARGE,Mana Recharge
|
||||
482,0,6,4,0,0x1,0,5,1,no,0,0,0,magic,0,0x0, PF_DOUBLECASTING,Double Casting
|
||||
483,16,6,2,0,0x1,1:2:3:4:5,1,1,no,0,0,0,none,0,0x20, HW_GANBANTEIN,Ganbantein
|
||||
484,9,6,2,2,0x91,0,5,1,yes,0,0x18000,0,misc,0,0x1030, HW_GRAVITATION,Gravitation Field
|
||||
483,14,6,2,0,0x1,1:2:3:4:5,1,1,no,0,0,0,none,0,0x20, HW_GANBANTEIN,Ganbantein
|
||||
484,14,6,2,2,0xD1,0,5,1,yes,0,0x18000,0,misc,0,0x11030, HW_GRAVITATION,Gravitation Field
|
||||
485,-2,6,1,-1,0x8,0,10,1,no,0,0,0,weapon,0,0x4000, WS_CARTTERMINATION,Cart Termination
|
||||
486,0,6,4,0,0x1,0,5,1,no,0,0,0,weapon,0,0x4000, WS_OVERTHRUSTMAX,Maximum Power Thrust
|
||||
487,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x8, CG_LONGINGFREEDOM,Longing for Freedom
|
||||
|
@ -841,15 +841,15 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
|
||||
if( sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
|
||||
return 1;
|
||||
|
||||
if (skill_id == PA_PRESSURE)
|
||||
return damage; //This skill bypass everything else.
|
||||
if (skill_id == PA_PRESSURE || skill_id == HW_GRAVITATION)
|
||||
return damage; //These skills bypass everything else.
|
||||
|
||||
if( sc && sc->count ) { // SC_* that reduce damage to 0.
|
||||
if( sc->data[SC_BASILICA] && !(status_get_mode(src)&MD_BOSS) ) {
|
||||
d->dmg_lv = ATK_BLOCK;
|
||||
return 0;
|
||||
}
|
||||
if( sc->data[SC_WHITEIMPRISON] && skill_id != HW_GRAVITATION ) { // Gravitation and Pressure do damage without removing the effect
|
||||
if( sc->data[SC_WHITEIMPRISON] ) { // Gravitation and Pressure do damage without removing the effect
|
||||
if( skill_id == MG_NAPALMBEAT ||
|
||||
skill_id == MG_SOULSTRIKE ||
|
||||
skill_id == WL_SOULEXPANSION ||
|
||||
@ -6244,7 +6244,11 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
#endif
|
||||
break;
|
||||
case HW_GRAVITATION:
|
||||
#ifdef RENEWAL
|
||||
md.damage = 500+100*skill_lv;
|
||||
#else
|
||||
md.damage = 200+200*skill_lv;
|
||||
#endif
|
||||
md.dmotion = 0; //No flinch animation.
|
||||
break;
|
||||
case NPC_EVILLAND:
|
||||
|
@ -8468,7 +8468,8 @@ bool pc_can_attack( struct map_session_data *sd, int target_id ) {
|
||||
sd->sc.data[SC_TRICKDEAD] ||
|
||||
(sd->sc.data[SC_VOICEOFSIREN] && sd->sc.data[SC_VOICEOFSIREN]->val2 == target_id) ||
|
||||
sd->sc.data[SC_BLADESTOP] ||
|
||||
sd->sc.data[SC_DEEPSLEEP] )
|
||||
sd->sc.data[SC_DEEPSLEEP] ||
|
||||
(sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -1104,6 +1104,11 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
||||
|
||||
case PA_PRESSURE:
|
||||
status_percent_damage(src, bl, 0, 15+5*skill_lv, false);
|
||||
//Fall through
|
||||
case HW_GRAVITATION:
|
||||
//Pressure and Gravitation can trigger physical autospells
|
||||
attack_type |= BF_NORMAL;
|
||||
attack_type |= BF_WEAPON;
|
||||
break;
|
||||
|
||||
case RG_RAID:
|
||||
@ -2843,7 +2848,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
|
||||
{
|
||||
struct Damage dmg;
|
||||
struct status_data *sstatus, *tstatus;
|
||||
struct status_change *tsc;
|
||||
struct status_change *sc, *tsc;
|
||||
struct map_session_data *sd, *tsd;
|
||||
int64 damage;
|
||||
int8 rmdamage = 0;//magic reflected
|
||||
@ -2873,6 +2878,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
|
||||
|
||||
sstatus = status_get_status_data(src);
|
||||
tstatus = status_get_status_data(bl);
|
||||
sc= status_get_sc(src);
|
||||
tsc= status_get_sc(bl);
|
||||
if (tsc && !tsc->count) tsc = NULL; //Don't need it.
|
||||
|
||||
@ -2880,6 +2886,10 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
|
||||
if (tsc && tsc->data[SC_TRICKDEAD])
|
||||
return 0;
|
||||
|
||||
//When Gravitational Field is active, damage can only be dealt by Gravitational Field and Autospells
|
||||
if(sc && sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF && skill_id != HW_GRAVITATION && !sd->state.autocast)
|
||||
return 0;
|
||||
|
||||
dmg = battle_calc_attack(attack_type,src,bl,skill_id,skill_lv,flag&0xFFF);
|
||||
|
||||
//Skotlex: Adjusted to the new system
|
||||
@ -3183,7 +3193,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
|
||||
|
||||
// Instant damage
|
||||
if( !dmg.amotion ) {
|
||||
if( (!tsc || (!tsc->data[SC_DEVOTION] && skill_id != CR_REFLECTSHIELD)) && !shadow_flag )
|
||||
if( (!tsc || (!tsc->data[SC_DEVOTION] && skill_id != CR_REFLECTSHIELD) || skill_id == HW_GRAVITATION) && !shadow_flag )
|
||||
status_fix_damage(src,bl,damage,dmg.dmotion); //Deal damage before knockback to allow stuff like firewall+storm gust combo.
|
||||
if( !status_isdead(bl) && additional_effects )
|
||||
skill_additional_effect(src,bl,skill_id,skill_lv,dmg.flag,dmg.dmg_lv,tick);
|
||||
@ -3206,7 +3216,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
|
||||
battle_delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skill_id,skill_lv,damage,dmg.dmg_lv,dmg.dmotion, additional_effects);
|
||||
}
|
||||
|
||||
if( tsc && tsc->data[SC_DEVOTION] && skill_id != PA_PRESSURE ) {
|
||||
if( tsc && tsc->data[SC_DEVOTION] && skill_id != PA_PRESSURE && skill_id != HW_GRAVITATION ) {
|
||||
struct status_change_entry *sce = tsc->data[SC_DEVOTION];
|
||||
struct block_list *d_bl = map_id2bl(sce->val1);
|
||||
|
||||
@ -11883,6 +11893,7 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
|
||||
{
|
||||
struct skill_unit_group *group;
|
||||
int i, limit, val1 = 0, val2 = 0, val3 = 0;
|
||||
int link_group_id = 0;
|
||||
int target, interval, range, unit_flag, req_item = 0;
|
||||
struct s_skill_unit_layout *layout;
|
||||
struct map_session_data *sd;
|
||||
@ -12203,6 +12214,9 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HW_GRAVITATION:
|
||||
if(sc && sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
|
||||
link_group_id = sc->data[SC_GRAVITATION]->val4;
|
||||
}
|
||||
|
||||
// Init skill unit group
|
||||
@ -12210,6 +12224,7 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
|
||||
group->val1 = val1;
|
||||
group->val2 = val2;
|
||||
group->val3 = val3;
|
||||
group->link_group_id = link_group_id;
|
||||
group->target_flag = target;
|
||||
group->bl_flag = skill_get_unit_bl_target(skill_id);
|
||||
group->state.ammo_consume = (sd && sd->state.arrow_atk && skill_id != GS_GROUNDDRIFT); //Store if this skill needs to consume ammo.
|
||||
@ -16518,6 +16533,7 @@ static int skill_cell_overlap(struct block_list *bl, va_list ap)
|
||||
break;
|
||||
case WZ_ICEWALL:
|
||||
case HP_BASILICA:
|
||||
case HW_GRAVITATION:
|
||||
//These can't be placed on top of themselves (duration can't be refreshed)
|
||||
if (unit->group->skill_id == skill_id)
|
||||
{
|
||||
@ -17076,6 +17092,7 @@ struct skill_unit_group* skill_initunitgroup(struct block_list* src, int count,
|
||||
group->guild_id = status_get_guild_id(src);
|
||||
group->bg_id = bg_team_get_id(src);
|
||||
group->group_id = skill_get_new_group_id();
|
||||
group->link_group_id = 0;
|
||||
group->unit = (struct skill_unit *)aCalloc(count,sizeof(struct skill_unit));
|
||||
group->unit_count = count;
|
||||
group->alive_count = 0;
|
||||
@ -17113,6 +17130,7 @@ int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int li
|
||||
struct block_list* src;
|
||||
struct unit_data *ud;
|
||||
short i, j;
|
||||
int link_group_id;
|
||||
|
||||
if( group == NULL ) {
|
||||
ShowDebug("skill_delunitgroup: group is NULL (source=%s:%d, %s)! Please report this! (#3504)\n", file, line, func);
|
||||
@ -17228,6 +17246,9 @@ int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int li
|
||||
group->group_id = 0;
|
||||
group->unit_count = 0;
|
||||
|
||||
link_group_id = group->link_group_id;
|
||||
group->link_group_id = 0;
|
||||
|
||||
// locate this group, swap with the last entry and delete it
|
||||
ARR_FIND( 0, MAX_SKILLUNITGROUP, i, ud->skillunit[i] == group );
|
||||
ARR_FIND( i, MAX_SKILLUNITGROUP, j, ud->skillunit[j] == NULL );
|
||||
@ -17239,6 +17260,12 @@ int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int li
|
||||
} else
|
||||
ShowError("skill_delunitgroup: Group not found! (src_id: %d skill_id: %d)\n", group->src_id, group->skill_id);
|
||||
|
||||
if(link_group_id) {
|
||||
struct skill_unit_group* group = skill_id2group(link_group_id);
|
||||
if(group)
|
||||
skill_delunitgroup(group);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -233,6 +233,7 @@ struct skill_unit_group {
|
||||
char *valstr; /// String value, used for HT_TALKIEBOX & RG_GRAFFITI
|
||||
int unit_id; /// Unit ID (for client effect)
|
||||
int group_id; /// Skill Group ID
|
||||
int link_group_id; /// Linked group that should be deleted if this one is deleted
|
||||
int unit_count, /// Number of unit at this group
|
||||
alive_count; /// Number of alive unit
|
||||
int item_id; /// Store item used.
|
||||
|
@ -1842,7 +1842,6 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
|
||||
(sc->data[SC_TRICKDEAD] && skill_id != NV_TRICKDEAD)
|
||||
|| (sc->data[SC_AUTOCOUNTER] && !flag && skill_id)
|
||||
|| (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF && skill_id != PA_GOSPEL)
|
||||
|| (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF && flag != 2)
|
||||
)
|
||||
return false;
|
||||
|
||||
@ -2162,7 +2161,7 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct
|
||||
unsigned int status_weapon_atk(struct weapon_atk wa, struct status_data *status)
|
||||
{
|
||||
float str = status->str;
|
||||
if (wa.range > 1)
|
||||
if (wa.range > 3)
|
||||
str = status->dex;
|
||||
// wa.at2 = refinement, wa.atk = base equip atk, wa.atk*str/200 = bonus str
|
||||
return wa.atk + wa.atk2 + (int)(wa.atk * (str/200));
|
||||
|
Loading…
x
Reference in New Issue
Block a user