- Added structure s_addeffect to handle status change additions. Cleaned up relevant code. It is now possible to specify ANY status change, not just the basic ones.
- Added support for bonus3 bAddEff/bAddEffWhenHit as follows: bonus3 bAddEff/bAddEffWhenHit, <SC value>, <rate>, <target flag>. Target flag is 0: Self. 1: Enemy. 2: Both. - Added these descriptions to doc/item_bonus.txt git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@7514 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
8b8b55bdf7
commit
4c36924fce
@ -4,6 +4,13 @@ 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.
|
||||
|
||||
2006/07/04
|
||||
* Added structure s_addeffect to handle status change additions. Cleaned up
|
||||
relevant code. It is now possible to specify ANY status change, not just
|
||||
the basic ones. NOTE that the code is proof-read, but untested! [Skotlex]
|
||||
* Added support for bonus3 bAddEff/bAddEffWhenHit as follows: [Skotlex]
|
||||
bonus3 bAddEff/bAddEffWhenHit, <SC value>, <rate>, <target flag>.
|
||||
Target flag is 0: Self. 1: Enemy. 2: Both.
|
||||
* Added these descriptions to doc/item_bonus.txt [Skotlex]
|
||||
* Added a check when joining a chat to make sure the target object is of
|
||||
type BL_CHAT. [Skotlex]
|
||||
2006/07/03
|
||||
|
@ -147,9 +147,9 @@ bonus bDamageWhenUnequip,n; You lose n HP when the item is unequipped
|
||||
bonus2 bCriticalAddRace,n,r; Critical + n vs. enemies of race r
|
||||
r: 0=Formless, 1=Undead, 2=Brute, 3=Plant, 4=Insect, 5=Fish, 6=Demon, 7=Demi-Human, 8=Angel, 9=Dragon, 10=Boss monster, 11=Other than (normal monster) boss monster
|
||||
bonus2 bHPLossRate,n,x; Lose n HP every x milliseconds
|
||||
bonus2 bAddEffWhenHit,n,x; n% chance to cause x state to the enemy when
|
||||
bonus2 bAddEffWhenHit,e,n; n% chance to cause e state to the enemy when
|
||||
being hit by physical damage
|
||||
bonus2 bAddEffWhenHitShort,n,x; n% chance to cause x state to the enemy when
|
||||
bonus2 bAddEffWhenHitShort,e,n; n% chance to cause x state to the enemy when
|
||||
being hit by physical close range damage
|
||||
bonus2 bSkillAtk,n,x; Increase damage of skill n by x%
|
||||
bonus2 bAddDamageByClass,n,x; When being hit by monster of class n increase
|
||||
@ -208,3 +208,10 @@ bonus3 bAddMonsterDropItemGroup,n,x,y; y% chance to get an item of group type n
|
||||
0=Formless, 1=Undead, 2=Brute, 3=Plant, 4=Insect, 5=Fish, 6=Demon, 7=Demi-Human, 8=Angel, 9=Dragon, 10=Boss monster, 11=Other than (normal monster) boss monster
|
||||
if 'y' is negative value, then it's a part of formula
|
||||
chance = -y*(killed_mob_level/10)+1
|
||||
|
||||
bonus3 bAddEff,e,x,i; Adds a x/10000 chance to cause effect e on
|
||||
physical attack. i signals target:
|
||||
0: Self, 1: Target, 2: Both.
|
||||
bonus3 bAddEffWhenHit,e,x,i; Adds a x/10000 chance to cause effect e when
|
||||
physically attacked. i signals target:
|
||||
0: Self, 1: Target, 2: Both
|
||||
|
@ -255,6 +255,13 @@ enum {
|
||||
MAX_ITEMGROUP,
|
||||
} item_group_list;
|
||||
|
||||
enum {
|
||||
ATF_SELF=0x01,
|
||||
ATF_TARGET=0x02,
|
||||
ATF_SHORT=0x04,
|
||||
ATF_LONG=0x08
|
||||
} auto_trigger_flag;
|
||||
|
||||
struct block_list {
|
||||
struct block_list *next,*prev;
|
||||
int id;
|
||||
@ -610,8 +617,6 @@ struct map_session_data {
|
||||
int subrace[RC_MAX];
|
||||
int subrace2[RC_MAX];
|
||||
int subsize[3];
|
||||
int addeff[SC_COMMON_MAX-SC_COMMON_MIN+1];
|
||||
int addeff2[SC_COMMON_MAX-SC_COMMON_MIN+1];
|
||||
int reseff[SC_COMMON_MAX-SC_COMMON_MIN+1];
|
||||
int weapon_coma_ele[ELE_MAX];
|
||||
int weapon_coma_race[RC_MAX];
|
||||
@ -620,22 +625,22 @@ struct map_session_data {
|
||||
int arrow_addele[ELE_MAX];
|
||||
int arrow_addrace[RC_MAX];
|
||||
int arrow_addsize[3];
|
||||
int arrow_addeff[SC_COMMON_MAX-SC_COMMON_MIN+1];
|
||||
int arrow_addeff2[SC_COMMON_MAX-SC_COMMON_MIN+1];
|
||||
int magic_addele[ELE_MAX];
|
||||
int magic_addrace[RC_MAX];
|
||||
int magic_addsize[3];
|
||||
int critaddrace[RC_MAX];
|
||||
int expaddrace[RC_MAX];
|
||||
int itemhealrate[MAX_ITEMGROUP];
|
||||
int addeff3[SC_COMMON_MAX-SC_COMMON_MIN+1];
|
||||
short addeff3_type[SC_COMMON_MAX-SC_COMMON_MIN+1];
|
||||
short sp_gain_race[RC_MAX];
|
||||
// zeroed arrays end here.
|
||||
// zeroed structures start here
|
||||
struct s_autospell{
|
||||
short id, lv, rate, card_id;
|
||||
} autospell[MAX_PC_BONUS], autospell2[MAX_PC_BONUS];
|
||||
struct s_addeffect{
|
||||
short id, rate, arrow_rate;
|
||||
unsigned char flag;
|
||||
} addeff[MAX_PC_BONUS], addeff2[MAX_PC_BONUS];
|
||||
struct { //skillatk raises bonus dmg% of skills, skillblown increases bonus blewcount for some skills.
|
||||
short id, val;
|
||||
} skillatk[MAX_PC_BONUS], skillblown[MAX_PC_BONUS];
|
||||
|
79
src/map/pc.c
79
src/map/pc.c
@ -1171,6 +1171,29 @@ static int pc_bonus_autospell(struct s_autospell *spell, int max, short id, shor
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pc_bonus_addeff(struct s_addeffect *effect, int max, short id, short rate, short arrow_rate, unsigned char flag) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < max && effect[i].id; i++) {
|
||||
if (effect[i].id == id && effect[i].flag == flag)
|
||||
{
|
||||
effect[i].rate += rate;
|
||||
effect[i].arrow_rate += rate;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (i == max) {
|
||||
if (battle_config.error_log)
|
||||
ShowWarning("pc_bonus: Reached max (%d) number of add effects per character!\n", max);
|
||||
return 0;
|
||||
}
|
||||
effect[i].id = id;
|
||||
effect[i].rate = rate;
|
||||
effect[i].arrow_rate = arrow_rate;
|
||||
effect[i].flag = flag;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pc_bonus_item_drop(struct s_add_drop *drop, short *count, short id, short group, int race, int rate) {
|
||||
int i;
|
||||
//Apply config rate adjustment settings.
|
||||
@ -1815,24 +1838,22 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
|
||||
sd->subrace[type2]+=val;
|
||||
break;
|
||||
case SP_ADDEFF:
|
||||
if (type2 < SC_COMMON_MIN || type2 > SC_COMMON_MAX) {
|
||||
if (type2 > SC_MAX) {
|
||||
ShowWarning("pc_bonus2 (Add Effect): %d is not supported.\n", type2);
|
||||
break;
|
||||
}
|
||||
if(sd->state.lr_flag != 2)
|
||||
sd->addeff[type2-SC_COMMON_MIN]+=val;
|
||||
else
|
||||
sd->arrow_addeff[type2-SC_COMMON_MIN]+=val;
|
||||
pc_bonus_addeff(sd->addeff, MAX_PC_BONUS, type2,
|
||||
sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0,
|
||||
ATF_SHORT|ATF_LONG|ATF_TARGET);
|
||||
break;
|
||||
case SP_ADDEFF2:
|
||||
if (type2 < SC_COMMON_MIN || type2 > SC_COMMON_MAX) {
|
||||
if (type2 > SC_MAX) {
|
||||
ShowWarning("pc_bonus2 (Add Effect2): %d is not supported.\n", type2);
|
||||
break;
|
||||
}
|
||||
if(sd->state.lr_flag != 2)
|
||||
sd->addeff2[type2-SC_COMMON_MIN]+=val;
|
||||
else
|
||||
sd->arrow_addeff2[type2-SC_COMMON_MIN]+=val;
|
||||
pc_bonus_addeff(sd->addeff, MAX_PC_BONUS, type2,
|
||||
sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0,
|
||||
ATF_SHORT|ATF_LONG|ATF_SELF);
|
||||
break;
|
||||
case SP_RESEFF:
|
||||
if (type2 < SC_COMMON_MIN || type2 > SC_COMMON_MAX) {
|
||||
@ -2040,24 +2061,22 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
|
||||
sd->critaddrace[type2] += val*10;
|
||||
break;
|
||||
case SP_ADDEFF_WHENHIT:
|
||||
if (type2 < SC_COMMON_MIN || type2 > SC_COMMON_MAX) {
|
||||
if (type2 > SC_MAX) {
|
||||
ShowWarning("pc_bonus2 (Add Effect when hit): %d is not supported.\n", type2);
|
||||
break;
|
||||
}
|
||||
if(sd->state.lr_flag != 2) {
|
||||
sd->addeff3[type2-SC_COMMON_MIN]+=val;
|
||||
sd->addeff3_type[type2-SC_COMMON_MIN]=1;
|
||||
}
|
||||
if(sd->state.lr_flag != 2)
|
||||
pc_bonus_addeff(sd->addeff2, MAX_PC_BONUS, type2, val, 0,
|
||||
ATF_SHORT|ATF_LONG|ATF_TARGET);
|
||||
break;
|
||||
case SP_ADDEFF_WHENHIT_SHORT:
|
||||
if (type2 < SC_COMMON_MIN || type2 > SC_COMMON_MAX) {
|
||||
if (type2 > SC_MAX) {
|
||||
ShowWarning("pc_bonus2 (Add Effect when hit short): %d is not supported.\n", type2);
|
||||
break;
|
||||
}
|
||||
if(sd->state.lr_flag != 2) {
|
||||
sd->addeff3[type2-SC_COMMON_MIN]+=val;
|
||||
sd->addeff3_type[type2-SC_COMMON_MIN]=0;
|
||||
}
|
||||
if(sd->state.lr_flag != 2)
|
||||
pc_bonus_addeff(sd->addeff2, MAX_PC_BONUS, type2, val, 0,
|
||||
ATF_SHORT|ATF_TARGET);
|
||||
break;
|
||||
case SP_SKILL_ATK:
|
||||
for (i = 0; i < MAX_PC_BONUS && sd->skillatk[i].id != 0 && sd->skillatk[i].id != type2; i++);
|
||||
@ -2251,6 +2270,26 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
|
||||
pc_bonus_item_drop(sd->add_drop, &sd->add_drop_count, 0, type2, 1<<type3, val);
|
||||
break;
|
||||
|
||||
case SP_ADDEFF:
|
||||
if (type2 > SC_MAX) {
|
||||
ShowWarning("pc_bonus3 (Add Effect): %d is not supported.\n", type2);
|
||||
break;
|
||||
}
|
||||
pc_bonus_addeff(sd->addeff, MAX_PC_BONUS, type2,
|
||||
sd->state.lr_flag!=2?type3:0, sd->state.lr_flag==2?type3:0,
|
||||
ATF_SHORT|ATF_LONG|(val?ATF_TARGET:ATF_SELF)|(val==2?ATF_SELF:0));
|
||||
break;
|
||||
|
||||
case SP_ADDEFF_WHENHIT:
|
||||
if (type2 > SC_MAX) {
|
||||
ShowWarning("pc_bonus3 (Add Effect when hit): %d is not supported.\n", type2);
|
||||
break;
|
||||
}
|
||||
if(sd->state.lr_flag != 2)
|
||||
pc_bonus_addeff(sd->addeff2, MAX_PC_BONUS, type2, type3, 0,
|
||||
ATF_SHORT|ATF_LONG|(val?ATF_TARGET:ATF_SELF)|(val==2?ATF_SELF:0));
|
||||
break;
|
||||
|
||||
default:
|
||||
if(battle_config.error_log)
|
||||
ShowWarning("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val);
|
||||
|
@ -1324,14 +1324,34 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
|
||||
break;
|
||||
}
|
||||
|
||||
if(sd && skillid != MC_CARTREVOLUTION && skillid != AM_DEMONSTRATION && skillid != CR_REFLECTSHIELD && attack_type&BF_WEAPON){ /* カードによる追加効果 */
|
||||
if(sd && attack_type&BF_WEAPON &&
|
||||
skillid != MC_CARTREVOLUTION &&
|
||||
skillid != AM_DEMONSTRATION &&
|
||||
skillid != CR_REFLECTSHIELD
|
||||
){ //Trigger status effects
|
||||
int i, type;
|
||||
for(i=SC_COMMON_MIN;i<=SC_COMMON_MAX;i++){
|
||||
type=i-SC_COMMON_MIN;
|
||||
rate = sd->addeff[type]+(sd->state.arrow_atk?sd->arrow_addeff[type]:0);
|
||||
if (!rate)
|
||||
continue; //Code Speedup.
|
||||
status_change_start(bl,i,rate,7,0,0,0,skill_get_time2(StatusSkillChangeTable[type],7),0);
|
||||
for(i=0; i < MAX_PC_BONUS && sd->addeff[i].id; i++)
|
||||
{
|
||||
rate = sd->addeff[i].rate;
|
||||
type = sd->state.arrow_atk; //Ranged?
|
||||
if (type)
|
||||
rate += sd->addeff[i].arrow_rate;
|
||||
if (!rate) continue;
|
||||
|
||||
if (!(sd->addeff[i].flag&ATF_LONG && sd->addeff[i].flag&ATF_SHORT))
|
||||
{ //Trigger has range consideration.
|
||||
if ((sd->addeff[i].flag&ATF_LONG && !type) ||
|
||||
(sd->addeff[i].flag&ATF_SHORT && type))
|
||||
continue; //Range Failed.
|
||||
}
|
||||
type = sd->addeff[i].id;
|
||||
skill = skill_get_time2(StatusSkillChangeTable[type],7);
|
||||
|
||||
if (sd->addeff[i].flag&ATF_TARGET)
|
||||
status_change_start(bl,type,rate,7,0,0,0,skill,0);
|
||||
|
||||
if (sd->addeff[i].flag&ATF_SELF)
|
||||
status_change_start(src,type,rate,7,0,0,0,skill,0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1445,24 +1465,35 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
|
||||
clif_skill_nodamage(src,bl,HW_SOULDRAIN,rate,1);
|
||||
status_heal(src, 0, status_get_lv(bl)*(95+15*rate)/100, 2);
|
||||
}
|
||||
|
||||
if((sd||dstsd) && skillid != MC_CARTREVOLUTION && attack_type&BF_WEAPON){ /* カードによる追加効果 */
|
||||
int i, type;
|
||||
|
||||
for(i=SC_COMMON_MIN;i<=SC_COMMON_MAX;i++){
|
||||
type=i-SC_COMMON_MIN;
|
||||
if(dstsd && attack_type&BF_WEAPON)
|
||||
{ //Counter effects.
|
||||
int i, type, time;
|
||||
for(i=0; i < MAX_PC_BONUS && dstsd->addeff2[i].id; i++)
|
||||
{
|
||||
rate = dstsd->addeff2[i].rate;
|
||||
type = (sd && sd->state.arrow_atk) || (status_get_range(src)>2);
|
||||
if (type)
|
||||
rate+=dstsd->addeff2[i].arrow_rate;
|
||||
if (!rate) continue;
|
||||
|
||||
if (!(dstsd->addeff2[i].flag&ATF_LONG && dstsd->addeff2[i].flag&ATF_SHORT))
|
||||
{ //Trigger has range consideration.
|
||||
if ((dstsd->addeff2[i].flag&ATF_LONG && !type) ||
|
||||
(dstsd->addeff2[i].flag&ATF_SHORT && type))
|
||||
continue; //Range Failed.
|
||||
}
|
||||
type = dstsd->addeff2[i].id;
|
||||
time = skill_get_time2(StatusSkillChangeTable[type],7);
|
||||
|
||||
rate = sd?(sd->addeff2[type]+(sd->state.arrow_atk?sd->arrow_addeff2[type]:0)):0;
|
||||
if (rate) //Self inflicted status from attacking.
|
||||
status_change_start(src,i,rate,7,0,0,0,skill_get_time2(StatusSkillChangeTable[type],7),0);
|
||||
|
||||
rate = dstsd?dstsd->addeff3[type]:0;
|
||||
if (rate && (dstsd->addeff3_type[type] == 1 || ((sd && sd->state.arrow_atk) || (status_get_range(src)>2))))
|
||||
status_change_start(src,i,rate,7,0,0,0,skill_get_time2(StatusSkillChangeTable[type],7),0);
|
||||
if (dstsd->addeff2[i].flag&ATF_TARGET)
|
||||
status_change_start(src,type,rate,7,0,0,0,time,0);
|
||||
|
||||
if (dstsd->addeff2[i].flag&ATF_SELF && !status_isdead(bl))
|
||||
status_change_start(bl,type,rate,7,0,0,0,time,0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Trigger counter-spells to retaliate against damage causing skills. [Skotlex]
|
||||
if(dstsd && !status_isdead(bl) && src != bl && !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE))
|
||||
{
|
||||
|
@ -1504,8 +1504,6 @@ int status_calc_pc(struct map_session_data* sd,int first)
|
||||
+ sizeof(sd->subrace)
|
||||
+ sizeof(sd->subrace2)
|
||||
+ sizeof(sd->subsize)
|
||||
+ sizeof(sd->addeff)
|
||||
+ sizeof(sd->addeff2)
|
||||
+ sizeof(sd->reseff)
|
||||
+ sizeof(sd->weapon_coma_ele)
|
||||
+ sizeof(sd->weapon_coma_race)
|
||||
@ -1514,16 +1512,12 @@ int status_calc_pc(struct map_session_data* sd,int first)
|
||||
+ sizeof(sd->arrow_addele)
|
||||
+ sizeof(sd->arrow_addrace)
|
||||
+ sizeof(sd->arrow_addsize)
|
||||
+ sizeof(sd->arrow_addeff)
|
||||
+ sizeof(sd->arrow_addeff2)
|
||||
+ sizeof(sd->magic_addele)
|
||||
+ sizeof(sd->magic_addrace)
|
||||
+ sizeof(sd->magic_addsize)
|
||||
+ sizeof(sd->critaddrace)
|
||||
+ sizeof(sd->expaddrace)
|
||||
+ sizeof(sd->itemhealrate)
|
||||
+ sizeof(sd->addeff3)
|
||||
+ sizeof(sd->addeff3_type)
|
||||
+ sizeof(sd->sp_gain_race)
|
||||
);
|
||||
|
||||
@ -1552,6 +1546,8 @@ int status_calc_pc(struct map_session_data* sd,int first)
|
||||
//zero up structures...
|
||||
memset(&sd->autospell,0,sizeof(sd->autospell)
|
||||
+ sizeof(sd->autospell2)
|
||||
+ sizeof(sd->addeff)
|
||||
+ sizeof(sd->addeff2)
|
||||
+ sizeof(sd->skillatk)
|
||||
+ sizeof(sd->skillblown)
|
||||
+ sizeof(sd->add_def)
|
||||
|
Loading…
x
Reference in New Issue
Block a user