Skip to content

Commit

Permalink
Follow up 43068e1:
Browse files Browse the repository at this point in the history
* Eff_Crystalize on Sropho_Card (4522) has defined duration.
* Bonus added:
  * `bonus4 bAddEff,eff,n,y,t;`
    * Adds a n/100% chance to cause status eff for t milliseconds on the target when attacking
    * Just like `bonus3 bAddEff,eff,n,y;` but with user-defined duration;
  * `bonus4 bAddEffWhenHit,eff,n,y,t;`
    * Adds a n/100% chance to cause status eff for t milliseconds on the target when being hit by physical damage
    * Just like `bonus3 bAddEffWhenHit,eff,n,y;` but with user-defined duration;
  * bonus5 bAddEffOnSkill,sk,eff,n,y,t;
    * Adds a n/100% chance to cause status eff for t milliseconds on the target when using skill sk
    * Just like `bonus4 bAddEffOnSkill,sk,eff,n,y;` but with user-defined duration;

Signed-off-by: Cydh Ramdh <cydh@pservero.com>
  • Loading branch information
cydh committed Sep 5, 2015
1 parent 8701b9b commit 9978368
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 105 deletions.
2 changes: 1 addition & 1 deletion db/re/item_db.txt
Expand Up @@ -2626,7 +2626,7 @@
4519,Butoijo_Card,Butoijo Card,6,20,,10,,,,,,,,2,,,,,{ bonus2 bAddRace,RC_Angel,20; },{},{}
4520,Leak_Card,Leak Card,6,20,,10,,,,,,,,4,,,,,{ bonus bStr,3; bonus2 bAddEff,Eff_Confusion,5000; bonus3 bAddEff,Eff_Confusion,5000,ATF_SKILL; },{},{}
4521,Sedora_Card,Sedora Card,6,20,,10,,,,,,,,2,,,,,{ bonus bCritAtkRate,15; },{},{}
4522,Sropho_Card,Sropho Card,6,20,,10,,,,,,,,2,,,,,{ bonus3 bAddEff,Eff_Crystalize,500,ATF_SHORT; },{},{}
4522,Sropho_Card,Sropho Card,6,20,,10,,,,,,,,2,,,,,{ bonus4 bAddEff,Eff_Crystalize,500,ATF_SHORT,3000; },{},{}
4523,Pot_Dofle_Card,Pot Dofle Card,6,20,,10,,,,,,,,16,,,,,{ bonus bDefEle,Ele_Water; bonus2 bSubRace,RC_Fish,10; },{},{}
4524,King_Dramoh_Card,King Dramoh Card,6,20,,10,,,,,,,,769,,,,,{ bonus bStr,2; if(BaseClass==Job_Swordman){ bonus bStr,2+(getrefine()/3); } },{},{}
4525,Kraken_Card,Kraken Card,6,20,,10,,,,,,,,4,,,,,{ bonus bFlee,10; skill "TF_HIDING",1; skill "RG_RAID",1; bonus5 bAutoSpellOnSkill,"RG_RAID","NPC_WIDEBLEEDING",1,250,1; },{},{ sc_end SC_HIDING; }
Expand Down
20 changes: 15 additions & 5 deletions doc/item_bonus.txt
Expand Up @@ -14,7 +14,8 @@ This list contains all available constants referenced in the 'bonus' commands.

* Status effect (eff)
Eff_Stone, Eff_Freeze, Eff_Stun, Eff_Sleep, Eff_Poison, Eff_Curse, Eff_Silence,
Eff_Confusion, Eff_Blind, Eff_Bleeding, Eff_DPoison, Eff_Fear, Eff_Burning
Eff_Confusion, Eff_Blind, Eff_Bleeding, Eff_DPoison, Eff_Fear, Eff_Burning,
Eff_Crystalize

* Element (e)
Ele_Neutral, Ele_Water, Ele_Earth, Ele_Fire, Ele_Wind, Ele_Poison,
Expand Down Expand Up @@ -275,15 +276,24 @@ bonus2 bAddEffWhenHit,eff,n; Adds a n/100% chance to cause status eff on the en
bonus2 bResEff,eff,n; Adds a n/100% tolerance to status eff

bonus3 bAddEff,eff,n,y; Adds a n/100% chance to cause status eff on the target when attacking
bonus3 bAddEffWhenHit,eff,n,y; Adds a n/100% chance to cause status eff on the enemy when being hit by physical damage
bonus4 bAddEff,eff,n,y,t; Adds a n/100% chance to cause status eff for t milliseconds on the target when attacking
bonus3 bAddEffWhenHit,eff,n,y; Adds a n/100% chance to cause status eff on the target when being hit by physical damage
bonus4 bAddEffWhenHit,eff,n,y,t; Adds a n/100% chance to cause status eff for t milliseconds on the target when being hit by physical damage
y is the trigger criteria:
Effect target: (Default: Attacked target)
ATF_SELF = trigger effect on self
ATF_TARGET = trigger effect on target (default)
ATF_TARGET = trigger effect on target
Attack range criteria: (Default: All attacks)
ATF_SHORT = trigger on melee attacks
ATF_LONG = trigger on ranged attacks (default: trigger on all attacks)
ATF_LONG = trigger on ranged attacks
Skill/attack type criteria: (Default: Physical/weapon)
ATF_WEAPON = trigger on weapon skill / physical attacks
ATF_MAGIC = trigger on magic skills
ATF_MISC = trigger on misc skills

bonus3 bAddEffOnSkill,sk,eff,n; Adds a n/100% chance to cause status eff on enemy when using skill sk
bonus4 bAddEffOnSkill,sk,eff,n,y; Adds a n/100% chance to cause status eff when using skill sk
bonus4 bAddEffOnSkill,sk,eff,n,y; Adds a n/100% chance to cause status eff on the target when using skill sk
bonus5 bAddEffOnSkill,sk,eff,n,y,t; Adds a n/100% chance to cause status eff for t milliseconds on the target when using skill sk
y is the trigger criteria:
ATF_SELF = trigger effect on self
ATF_TARGET = trigger effect on target
Expand Down
2 changes: 1 addition & 1 deletion sql-files/item_db_re.sql
Expand Up @@ -2657,7 +2657,7 @@ REPLACE INTO `item_db_re` VALUES (4518,'Banaspaty_Card','Banaspaty Card',6,20,NU
REPLACE INTO `item_db_re` VALUES (4519,'Butoijo_Card','Butoijo Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'bonus2 bAddRace,RC_Angel,20;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (4520,'Leak_Card','Leak Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bStr,3; bonus2 bAddEff,Eff_Confusion,5000; bonus3 bAddEff,Eff_Confusion,5000,ATF_SKILL;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (4521,'Sedora_Card','Sedora Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'bonus bCritAtkRate,15;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (4522,'Sropho_Card','Sropho Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'bonus3 bAddEff,Eff_Crystalize,500,ATF_SHORT;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (4522,'Sropho_Card','Sropho Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2,NULL,NULL,NULL,NULL,'bonus4 bAddEff,Eff_Crystalize,500,ATF_SHORT,3000;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (4523,'Pot_Dofle_Card','Pot Dofle Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16,NULL,NULL,NULL,NULL,'bonus bDefEle,Ele_Water; bonus2 bSubRace,RC_Fish,10;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (4524,'King_Dramoh_Card','King Dramoh Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,769,NULL,NULL,NULL,NULL,'bonus bStr,2; if(BaseClass==Job_Swordman){ bonus bStr,2+(getrefine()/3); }',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (4525,'Kraken_Card','Kraken Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bFlee,10; skill "TF_HIDING",1; skill "RG_RAID",1; bonus5 bAutoSpellOnSkill,"RG_RAID","NPC_WIDEBLEEDING",1,250,1;',NULL,'sc_end SC_HIDING;');
Expand Down
14 changes: 7 additions & 7 deletions src/map/map.h
Expand Up @@ -394,13 +394,13 @@ enum mob_ai {
};

enum auto_trigger_flag {
ATF_SELF=0x01,
ATF_TARGET=0x02,
ATF_SHORT=0x04,
ATF_LONG=0x08,
ATF_WEAPON=0x10,
ATF_MAGIC=0x20,
ATF_MISC=0x40,
ATF_SELF = 0x01,
ATF_TARGET = 0x02,
ATF_SHORT = 0x04,
ATF_LONG = 0x08,
ATF_WEAPON = 0x10,
ATF_MAGIC = 0x20,
ATF_MISC = 0x40,
};

struct block_list {
Expand Down
125 changes: 76 additions & 49 deletions src/map/pc.c
Expand Up @@ -1984,6 +1984,8 @@ int pc_disguise(struct map_session_data *sd, int class_)
#define PC_BONUS_CHK_CLASS(cl,bonus) { if (!CHK_CLASS((cl))) { PC_BONUS_SHOW_ERROR((bonus),Class,(cl)); }}
/// Check for valid Size, break & show error message if invalid Size
#define PC_BONUS_CHK_SIZE(sz,bonus) { if (!CHK_MOBSIZE((sz))) { PC_BONUS_SHOW_ERROR((bonus),Size,(sz)); }}
/// Check for valid SC, break & show error message if invalid SC
#define PC_BONUS_CHK_SC(sc,bonus) { if ((sc) <= SC_NONE || (sc) >= SC_MAX) { PC_BONUS_SHOW_ERROR((bonus),Effect,(sc)); }}

static void pc_bonus_autospell(struct s_autospell *spell, int max, short id, short lv, short rate, short flag, unsigned short card_id)
{
Expand Down Expand Up @@ -2046,53 +2048,81 @@ static void pc_bonus_autospell_onskill(struct s_autospell *spell, int max, short
return;
}

static void pc_bonus_addeff(struct s_addeffect* effect, int max, enum sc_type id, short rate, short arrow_rate, unsigned char flag)
/**
* Add inflict effect bonus for player while attacking/atatcked

This comment has been minimized.

Copy link
@nanakiwurtz

nanakiwurtz Sep 5, 2015

Contributor

"atatcked"

This comment has been minimized.

Copy link
@cydh

cydh Sep 5, 2015

Author Contributor

darn, my common typo.

* @param effect Effect array
* @param max Max array
* @param sc SC/Effect type
* @param rate Success chance
* @param arrow_rate success chance if bonus comes from arrow-type item
* @param flag Target flag
* @param duration Duration. If 0 use default duration lookup for associated skill with level 7
**/
static void pc_bonus_addeff(struct s_addeffect* effect, int max, enum sc_type sc, short rate, short arrow_rate, unsigned char flag, unsigned int duration)
{
uint16 i;

if (!(flag&(ATF_SHORT|ATF_LONG)))
flag|=ATF_SHORT|ATF_LONG; //Default range: both
flag |= ATF_SHORT|ATF_LONG; //Default range: both
if (!(flag&(ATF_TARGET|ATF_SELF)))
flag|=ATF_TARGET; //Default target: enemy.
flag |= ATF_TARGET; //Default target: enemy.
if (!(flag&(ATF_WEAPON|ATF_MAGIC|ATF_MISC)))
flag|=ATF_WEAPON; //Default type: weapon.
flag |= ATF_WEAPON; //Default type: weapon.

if (!duration)
duration = skill_get_time2(status_sc2skill(sc),7);

for (i = 0; i < max && effect[i].flag; i++) {
if (effect[i].id == id && effect[i].flag == flag)
{
if (effect[i].sc == sc && effect[i].flag == flag) {
effect[i].rate += rate;
effect[i].arrow_rate += arrow_rate;
effect[i].duration = max(effect[i].duration, duration);
return;
}
}
if (i == max) {
ShowWarning("pc_bonus_addeff: Reached max (%d) number of add effects per character!\n", max);
return;
}
effect[i].id = id;
effect[i].sc = sc;
effect[i].rate = rate;
effect[i].arrow_rate = arrow_rate;
effect[i].flag = flag;
effect[i].duration = duration;
}

static void pc_bonus_addeff_onskill(struct s_addeffectonskill* effect, int max, enum sc_type id, short rate, short skill, unsigned char target)
/**
* Add inflict effect bonus for player while attacking using skill
* @param effect Effect array
* @param max Max array
* @param sc SC/Effect type
* @param rate Success chance
* @param flag Target flag
* @param duration Duration. If 0 use default duration lookup for associated skill with level 7
**/
static void pc_bonus_addeff_onskill(struct s_addeffectonskill* effect, int max, enum sc_type sc, short rate, short skill_id, unsigned char target, unsigned int duration)
{
uint8 i;
for( i = 0; i < max && effect[i].skill; i++ )
{
if( effect[i].id == id && effect[i].skill == skill && effect[i].target == target )
{

if (!duration)
duration = skill_get_time2(status_sc2skill(sc),7);

for( i = 0; i < max && effect[i].skill_id; i++ ) {
if( effect[i].sc == sc && effect[i].skill_id == skill_id && effect[i].target == target ) {
effect[i].rate += rate;
effect[i].duration = max(effect[i].duration, duration);
return;
}
}
if( i == max ) {
ShowWarning("pc_bonus_addeff_onskill: Reached max (%d) number of add effects on skill per character!\n", max);
return;
}
effect[i].id = id;
effect[i].sc = sc;
effect[i].rate = rate;
effect[i].skill = skill;
effect[i].skill_id = skill_id;
effect[i].target = target;
effect[i].duration = duration;
}

/** Adjust/add drop rate modifier for player
Expand Down Expand Up @@ -3071,20 +3101,14 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
sd->subclass[type2]+=val;
break;
case SP_ADDEFF: // bonus2 bAddEff,eff,n;
if (type2 <= SC_NONE || type2 >= SC_MAX) {
ShowError("pc_bonus2: SP_ADDEFF: %d invalid effect.\n", type2);
break;
}
PC_BONUS_CHK_SC(type2,SP_ADDEFF);
pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, 0);
sd->state.lr_flag != 2 ? val : 0, sd->state.lr_flag == 2 ? val : 0, 0, 0);
break;
case SP_ADDEFF2: // bonus2 bAddEff2,eff,n;
if (type2 <= SC_NONE || type2 >= SC_MAX) {
ShowError("pc_bonus2: SP_ADDEFF2: %d is invalid effect.\n", type2);
break;
}
PC_BONUS_CHK_SC(type2,SP_ADDEFF2);
pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, ATF_SELF);
sd->state.lr_flag != 2 ? val : 0, sd->state.lr_flag == 2 ? val : 0, ATF_SELF, 0);
break;
case SP_RESEFF: // bonus2 bResEff,eff,n;
if (type2 < SC_COMMON_MIN || type2 > SC_COMMON_MAX) {
Expand Down Expand Up @@ -3270,12 +3294,9 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
sd->critaddrace[type2] += val*10;
break;
case SP_ADDEFF_WHENHIT: // bonus2 bAddEffWhenHit,eff,n;
if (type2 <= SC_NONE || type2 >= SC_MAX) {
ShowError("pc_bonus2: SP_ADDEFF_WHENHIT: %d is invalid effect.\n", type2);
break;
}
PC_BONUS_CHK_SC(type2,SP_ADDEFF_WHENHIT);
if(sd->state.lr_flag != 2)
pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, val, 0, 0);
pc_bonus_addeff(sd->addeff_atked, ARRAYLENGTH(sd->addeff_atked), (sc_type)type2, val, 0, 0, 0);
break;
case SP_SKILL_ATK: // bonus2 bSkillAtk,sk,n;
if(sd->state.lr_flag == 2)
Expand Down Expand Up @@ -3702,30 +3723,21 @@ void pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
break;

case SP_ADDEFF: // bonus3 bAddEff,eff,n,y;
if (type2 <= SC_NONE || type2 >= SC_MAX) {
ShowError("pc_bonus3: SP_ADDEFF: %d is not supported.\n", type2);
break;
}
PC_BONUS_CHK_SC(type2,SP_ADDEFF);
pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
sd->state.lr_flag!=2?type3:0, sd->state.lr_flag==2?type3:0, val);
sd->state.lr_flag != 2 ? type3 : 0, sd->state.lr_flag == 2 ? type3 : 0, val, 0);
break;

case SP_ADDEFF_WHENHIT: // bonus3 bAddEffWhenHit,eff,n,y;
if (type2 <= SC_NONE || type2 >= SC_MAX) {
ShowError("pc_bonus3: SP_ADDEFF_WHENHIT: %d is not supported.\n", type2);
break;
}
PC_BONUS_CHK_SC(type2,SP_ADDEFF_WHENHIT);
if(sd->state.lr_flag != 2)
pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, type3, 0, val);
pc_bonus_addeff(sd->addeff_atked, ARRAYLENGTH(sd->addeff_atked), (sc_type)type2, type3, 0, val, 0);
break;

case SP_ADDEFF_ONSKILL: // bonus3 bAddEffOnSkill,sk,eff,n;
if (type3 <= SC_NONE || type3 >= SC_MAX) {
ShowError("pc_bonus3: SP_ADDEFF_ONSKILL: %d is not supported.\n", type3);
break;
}
PC_BONUS_CHK_SC(type2,SP_ADDEFF_ONSKILL);
if( sd->state.lr_flag != 2 )
pc_bonus_addeff_onskill(sd->addeff3, ARRAYLENGTH(sd->addeff3), (sc_type)type3, val, type2, ATF_TARGET);
pc_bonus_addeff_onskill(sd->addeff_onskill, ARRAYLENGTH(sd->addeff_onskill), (sc_type)type3, val, type2, ATF_TARGET, 0);
break;

case SP_ADDELE: // bonus3 bAddEle,e,x,bf;
Expand Down Expand Up @@ -3795,13 +3807,22 @@ void pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type
}
break;

case SP_ADDEFF: // bonus4 bAddEff,eff,n,y,t;
PC_BONUS_CHK_SC(type3,SP_ADDEFF);
pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
sd->state.lr_flag != 2 ? type3 : 0, sd->state.lr_flag == 2 ? type3 : 0, type4, val);
break;

case SP_ADDEFF_WHENHIT: // bonus4 bAddEffWhenHit,eff,n,y,t;
PC_BONUS_CHK_SC(type3,SP_ADDEFF_WHENHIT);
if (sd->state.lr_flag != 2)
pc_bonus_addeff(sd->addeff_atked, ARRAYLENGTH(sd->addeff_atked), (sc_type)type2, type3, 0, 0, val);
break;

case SP_ADDEFF_ONSKILL: // bonus4 bAddEffOnSkill,sk,eff,n,y;
if (type2 <= SC_NONE || type2 >= SC_MAX) {
ShowError("pc_bonus4: SP_ADDEFF_ONSKILL: %d is not supported.\n", type2);
break;
}
PC_BONUS_CHK_SC(type3,SP_ADDEFF_ONSKILL);
if( sd->state.lr_flag != 2 )
pc_bonus_addeff_onskill(sd->addeff3, ARRAYLENGTH(sd->addeff3), (sc_type)type3, type4, type2, val);
pc_bonus_addeff_onskill(sd->addeff_onskill, ARRAYLENGTH(sd->addeff_onskill), (sc_type)type3, type4, type2, val, 0);
break;

case SP_SET_DEF_RACE: // bonus4 bSetDefRace,r,n,t,y;
Expand Down Expand Up @@ -3856,6 +3877,12 @@ void pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type
if(sd->state.lr_flag != 2)
pc_bonus_autospell_onskill(sd->autospell3, ARRAYLENGTH(sd->autospell3), type2, (val&1?-type3:type3), (val&2?-type4:type4), type5, current_equip_card_id);
break;

case SP_ADDEFF_ONSKILL: // bonus5 bAddEffOnSkill,sk,eff,n,y,t;
PC_BONUS_CHK_SC(type3,SP_ADDEFF_ONSKILL);
if( sd->state.lr_flag != 2 )
pc_bonus_addeff_onskill(sd->addeff_onskill, ARRAYLENGTH(sd->addeff_onskill), (sc_type)type3, type4, type2, type5, val);
break;

default:
ShowWarning("pc_bonus5: unknown type %d %d %d %d %d %d!\n",type,type2,type3,type4,type5,val);
Expand Down
22 changes: 14 additions & 8 deletions src/map/pc.h
Expand Up @@ -112,16 +112,22 @@ struct s_autospell {
bool lock; // bAutoSpellOnSkill: blocks autospell from triggering again, while being executed
};

/// AddEff and AddEff2 bonus struct
struct s_addeffect {
enum sc_type id;
short rate, arrow_rate;
unsigned char flag;
enum sc_type sc; /// SC type/effect
short rate, /// Rate
arrow_rate; /// Arrow rate
unsigned char flag; /// Flag
unsigned int duration; /// Duration the effect applied
};

/// AddEffOnSkill bonus struct
struct s_addeffectonskill {
enum sc_type id;
short rate, skill;
unsigned char target;
enum sc_type sc; /// SC type/effect
short rate, /// Rate
skill_id; /// Skill ID
unsigned char target; /// Target
unsigned int duration; /// Duration the effect applied
};

///Struct of add drop item/group rate
Expand Down Expand Up @@ -358,8 +364,8 @@ struct map_session_data {

// zeroed structures start here
struct s_autospell autospell[MAX_PC_BONUS], autospell2[MAX_PC_BONUS], autospell3[MAX_PC_BONUS];
struct s_addeffect addeff[MAX_PC_BONUS], addeff2[MAX_PC_BONUS];
struct s_addeffectonskill addeff3[MAX_PC_BONUS];
struct s_addeffect addeff[MAX_PC_BONUS], addeff_atked[MAX_PC_BONUS];
struct s_addeffectonskill addeff_onskill[MAX_PC_BONUS];

struct s_skill_bonus { //skillatk raises bonus dmg% of skills, skillheal increases heal%, skillblown increases bonus blewcount for some skills.
unsigned short id;
Expand Down

0 comments on commit 9978368

Please sign in to comment.