Permalink
Browse files

Cleaned up Banding behavior (#3486)

* Fixes #3478.
* Adjusted Banding to use proper party counting functions.
* Corrected the DEF and HP Regen bonus for Banding.
* Banding Defense will no longer stack on itself.
Thanks to @admkakaroto and @exneval!
  • Loading branch information...
aleos89 committed Sep 18, 2018
1 parent e495054 commit 0d77398385fef6dade61532f2456bb1b7367f0c7
Showing with 69 additions and 107 deletions.
  1. +1 −1 db/pre-re/skill_db.txt
  2. +1 −1 db/re/skill_db.txt
  3. +29 −0 src/map/party.cpp
  4. +1 −0 src/map/party.hpp
  5. +0 −94 src/map/pc.cpp
  6. +0 −2 src/map/pc.hpp
  7. +29 −5 src/map/skill.cpp
  8. +2 −0 src/map/skill.hpp
  9. +6 −4 src/map/status.cpp
View
@@ -1115,7 +1115,7 @@
2316,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0, LG_EXEEDBREAK,Exceed Break
2317,2,6,2,-1,0x2,0,5,1,yes,0,0,0,weapon,0,0x0, LG_OVERBRAND,Over Brand
2318,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0, LG_PRESTIGE,Prestige
2319,0,6,4,0,0x3,3,5,1,no,0,0,0,weapon,0,0x0, LG_BANDING,Banding //CHECK Splash isnt needed right? Banding has its own UNIT ID.
2319,0,6,4,0,0x3,3,5,1,no,0,0,0,weapon,0,0x0, LG_BANDING,Banding
2320,0,6,4,-1,0x2,3,5,1,yes,0,0,0,weapon,0,0x1000, LG_MOONSLASHER,Moon Slasher
2321,1,8,2,6,0x2,5,5,-7,yes,0,0,0,weapon,0,0x0, LG_RAYOFGENESIS,Ray of Genesis
2322,0,6,16,0,0x3,1,5,1,yes,0,0,0,none,0,0x0, LG_PIETY,Piety
View
@@ -1121,7 +1121,7 @@
2316,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0, LG_EXEEDBREAK,Exceed Break
2317,2,6,2,-1,0x2,0,5,1,yes,0,0,0,weapon,0,0x0, LG_OVERBRAND,Over Brand
2318,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0, LG_PRESTIGE,Prestige
2319,0,6,4,0,0x3,3,5,1,no,0,0,0,weapon,0,0x0, LG_BANDING,Banding //CHECK Splash isnt needed right? Banding has its own UNIT ID.
2319,0,6,4,0,0x3,3,5,1,no,0,0,0,weapon,0,0x0, LG_BANDING,Banding
2320,0,6,4,-1,0x2,3,5,1,yes,0,0,0,weapon,0,0x1000, LG_MOONSLASHER,Moon Slasher
2321,1,8,2,6,0x2,5,5,-7,yes,0,0,0,weapon,0,0x0, LG_RAYOFGENESIS,Ray of Genesis
2322,0,6,16,0,0x3,1,5,1,yes,0,0,0,none,0,0x0, LG_PIETY,Piety
View
@@ -1249,6 +1249,35 @@ int party_sub_count_class(struct block_list *bl, va_list ap)
return 1;
}
/**
* Special check for Royal Guard's Banding skill.
* @param bl: Object invoking the counter
* @param ap: List of parameters: Check Type
* @return 1 or total HP on success or 0 otherwise
*/
int party_sub_count_banding(struct block_list *bl, va_list ap)
{
struct map_session_data *sd = (TBL_PC *)bl;
int type = va_arg(ap, int); // 0 = Banding Count, 1 = HP Check
if (sd->state.autotrade)
return 0;
if (battle_config.idle_no_share && pc_isidle(sd))
return 0;
if ((sd->class_&MAPID_THIRDMASK) != MAPID_ROYAL_GUARD)
return 0;
if (!sd->sc.data[SC_BANDING])
return 0;
if (type == 1)
return status_get_hp(bl);
return 1;
}
/// Executes 'func' for each party member on the same map and in range (0:whole map)
int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int range,...)
{
View
@@ -89,6 +89,7 @@ int party_share_loot(struct party_data* p, struct map_session_data* sd, struct i
int party_send_dot_remove(struct map_session_data *sd);
int party_sub_count(struct block_list *bl, va_list ap);
int party_sub_count_class(struct block_list *bl, va_list ap);
int party_sub_count_banding(struct block_list *bl, va_list ap);
int party_foreachsamemap(int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range,...);
/*==========================================
View
@@ -339,100 +339,6 @@ void pc_delspiritball(struct map_session_data *sd,int count,int type)
}
}
static int pc_check_banding( struct block_list *bl, va_list ap ) {
int *c, *b_sd;
struct block_list *src;
struct map_session_data *tsd;
struct status_change *sc;
nullpo_ret(bl);
nullpo_ret(tsd = (struct map_session_data*)bl);
nullpo_ret(src = va_arg(ap,struct block_list *));
c = va_arg(ap,int *);
b_sd = va_arg(ap, int *);
if(pc_isdead(tsd))
return 0;
sc = status_get_sc(bl);
if( sc && sc->data[SC_BANDING] )
{
b_sd[(*c)++] = tsd->bl.id;
return 1;
}
return 0;
}
int pc_banding(struct map_session_data *sd, uint16 skill_lv) {
int c;
int b_sd[MAX_PARTY]; // In case of a full Royal Guard party.
int i, j, hp, extra_hp = 0, tmp_qty = 0;
int range = skill_get_splash(LG_BANDING,skill_lv);
nullpo_ret(sd);
c = 0;
memset(b_sd, 0, sizeof(b_sd));
i = party_foreachsamemap(pc_check_banding,sd,range,&sd->bl,&c,&b_sd);
if( c < 1 ) //just recalc status no need to recalc hp
{ // No more Royal Guards in Banding found.
struct status_change *sc;
if( (sc = status_get_sc(&sd->bl)) != NULL && sc->data[SC_BANDING] )
{
sc->data[SC_BANDING]->val2 = 0; // Reset the counter
status_calc_bl(&sd->bl, status_sc2scb_flag(SC_BANDING));
}
return 0;
}
//Add yourself
hp = status_get_hp(&sd->bl);
i++;
// Get total HP of all Royal Guards in party.
for( j = 0; j < i; j++ ){
struct map_session_data *bsd = map_id2sd(b_sd[j]);
if( bsd != NULL )
hp += status_get_hp(&bsd->bl);
}
// Set average HP.
hp = hp / i;
// If a Royal Guard have full HP, give more HP to others that haven't full HP.
for( j = 0; j < i; j++ )
{
int tmp_hp=0;
struct map_session_data *bsd = map_id2sd(b_sd[j]);
if( bsd != NULL && (tmp_hp = hp - status_get_max_hp(&bsd->bl)) > 0 ){
extra_hp += tmp_hp;
tmp_qty++;
}
}
if( extra_hp > 0 && tmp_qty > 0 )
hp += extra_hp / tmp_qty;
for( j = 0; j < i; j++ ){
struct map_session_data *bsd = map_id2sd(b_sd[j]);
if( bsd != NULL )
{
struct status_change *sc;
status_set_hp(&bsd->bl,hp,0); // Set hp
if( (sc = status_get_sc(&bsd->bl)) != NULL && sc->data[SC_BANDING] )
{
sc->data[SC_BANDING]->val2 = c; // Set the counter. It doesn't count your self.
status_calc_bl(&bsd->bl, status_sc2scb_flag(SC_BANDING)); // Set atk and def.
}
}
}
return c;
}
/**
* Increases a player's fame points and displays a notice to him
* @param sd Player
View
@@ -1290,8 +1290,6 @@ bool pc_isautolooting(struct map_session_data *sd, unsigned short nameid);
void pc_overheat(struct map_session_data *sd, int16 heat);
int pc_banding(struct map_session_data *sd, uint16 skill_lv);
void pc_itemcd_do(struct map_session_data *sd, bool load);
uint8 pc_itemcd_add(struct map_session_data *sd, struct item_data *id, unsigned int tick, unsigned short n);
uint8 pc_itemcd_check(struct map_session_data *sd, struct item_data *id, unsigned int tick, unsigned short n);
View
@@ -2366,8 +2366,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
{
struct status_change *sc = status_get_sc(src);
if( sc && sc->data[SC_FORCEOFVANGUARD] && sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 6 ) {
char i;
for( i = 0; i < sc->data[SC_FORCEOFVANGUARD]->val3; i++ )
for(int i = 0; i < sc->data[SC_FORCEOFVANGUARD]->val3; i++ )
pc_addspiritball(sd, skill_get_time(LG_FORCEOFVANGUARD,1),sc->data[SC_FORCEOFVANGUARD]->val3);
}
}
@@ -12247,10 +12246,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case LG_BANDING:
if( sc && sc->data[SC_BANDING] )
status_change_end(src,SC_BANDING,INVALID_TIMER);
else if( (sg = skill_unitsetting(src,skill_id,skill_lv,src->x,src->y,0)) != NULL ) {
else if( (sg = skill_unitsetting(src,skill_id,skill_lv,src->x,src->y,0)) != NULL )
sc_start4(src,src,SC_BANDING,100,skill_lv,0,0,sg->group_id,skill_get_time(skill_id,skill_lv));
if( sd ) pc_banding(sd,skill_lv);
}
clif_skill_nodamage(src,src,skill_id,skill_lv,1);
break;
@@ -17333,6 +17330,33 @@ int skill_detonator(struct block_list *bl, va_list ap)
return 0;
}
/**
* Calculate Royal Guard's Banding bonus
* @param sd: Player data
* @return Number of Royal Guard
*/
int skill_banding_count(struct map_session_data *sd)
{
nullpo_ret(sd);
int range = skill_get_splash(LG_BANDING, 1);
uint8 count = party_foreachsamemap(party_sub_count_banding, sd, range, 0);
unsigned int group_hp = party_foreachsamemap(party_sub_count_banding, sd, range, 1);
// HP is set to the average HP of the Banding group
if (count > 1)
status_set_hp(&sd->bl, group_hp / count, 0);
// Royal Guard count check for Banding
if (sd && sd->status.party_id) {
if (count > MAX_PARTY)
return MAX_PARTY;
else if (count > 1)
return count; // Effect bonus from additional Royal Guards if not above the max
}
return 0;
}
/**
* Rebellion's Bind Trap explosion
* @author [Cydh]
View
@@ -2205,6 +2205,8 @@ int skill_elementalanalysis(struct map_session_data *sd, int n, uint16 skill_lv,
int skill_changematerial(struct map_session_data *sd, int n, unsigned short *item_list); // Genetic Change Material.
int skill_get_elemental_type(uint16 skill_id, uint16 skill_lv);
int skill_banding_count(struct map_session_data *sd);
int skill_is_combo(uint16 skill_id);
void skill_combo_toggle_inf(struct block_list* bl, uint16 skill_id, int inf);
void skill_combo(struct block_list* src,struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int tick);
View
@@ -715,7 +715,7 @@ void initChangeTables(void)
set_sc( LG_FORCEOFVANGUARD , SC_FORCEOFVANGUARD , EFST_FORCEOFVANGUARD , SCB_MAXHP );
set_sc( LG_EXEEDBREAK , SC_EXEEDBREAK , EFST_EXEEDBREAK , SCB_NONE );
set_sc( LG_PRESTIGE , SC_PRESTIGE , EFST_PRESTIGE , SCB_DEF );
set_sc( LG_BANDING , SC_BANDING , EFST_BANDING , SCB_DEF2|SCB_WATK );
set_sc( LG_BANDING , SC_BANDING , EFST_BANDING , SCB_DEF|SCB_WATK|SCB_REGEN );
set_sc( LG_PIETY , SC_BENEDICTIO , EFST_BENEDICTIO , SCB_DEF_ELE );
set_sc( LG_EARTHDRIVE , SC_EARTHDRIVE , EFST_EARTHDRIVE , SCB_DEF|SCB_ASPD );
set_sc( LG_INSPIRATION , SC_INSPIRATION , EFST_INSPIRATION , SCB_WATK|SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK|SCB_HIT|SCB_MAXHP);
@@ -4657,6 +4657,8 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
} else
regen->flag &= ~sce->val4; // Remove regen as specified by val4
}
if (sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 1)
regen->hp += cap_value(regen->hp * 50 / 100, 1, SHRT_MAX);
if(sc->data[SC_GT_REVITALIZE]) {
regen->hp += cap_value(regen->hp * sc->data[SC_GT_REVITALIZE]->val3/100, 1, SHRT_MAX);
regen->state.walk = 1;
@@ -6522,8 +6524,6 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
if(sc->data[SC_SUN_COMFORT])
def2 += sc->data[SC_SUN_COMFORT]->val2;
if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 1 )
def2 += (5 + sc->data[SC_BANDING]->val1) * sc->data[SC_BANDING]->val2;
#ifdef RENEWAL
if (sc->data[SC_SKA])
def2 += 80;
@@ -9333,6 +9333,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
case SC_OBLIVIONCURSE:
case SC_LEECHESEND:
case SC_CURSEDCIRCLE_TARGET:
case SC_BANDING_DEFENCE:
case SC__ENERVATION:
case SC__GROOMY:
case SC__IGNORANCE:
@@ -10631,6 +10632,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
val3 = ((val1 * 15) + (10 * (sd?pc_checkskill(sd,CR_DEFENDER):skill_get_max(CR_DEFENDER)))) * status_get_lv(bl) / 100; // Defence added
break;
case SC_BANDING:
val2 = (sd ? skill_banding_count(sd) : 1);
tick_time = 5000; // [GodLesZ] tick time
break;
case SC_MAGNETICFIELD:
@@ -13351,7 +13353,7 @@ TIMER_FUNC(status_change_timer){
case SC_BANDING:
if( status_charge(bl, 0, 7 - sce->val1) ) {
if( sd ) pc_banding(sd, sce->val1);
sce->val2 = (sd ? skill_banding_count(sd) : 1);
sc_timer_next(5000 + tick);
return 0;
}

1 comment on commit 0d77398

@aleos89

This comment has been minimized.

Show comment
Hide comment
@aleos89

aleos89 Oct 12, 2018

Contributor

Thanks to @Rytech2 for his efforts in gathering the data and releasing it!

Contributor

aleos89 commented on 0d77398 Oct 12, 2018

Thanks to @Rytech2 for his efforts in gathering the data and releasing it!

Please sign in to comment.