- Added bonusautoscript and bonusautoscript2. These are used to attach a script to a player which gets executed on attack (or when attacked). Required for several of the more recent items.
git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@11519 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
8d0ac1d316
commit
a1becae58f
@ -4,6 +4,12 @@ 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.
|
||||||
|
|
||||||
2007/10/19
|
2007/10/19
|
||||||
|
* Added bonusautoscript and bonusautoscript2. These are used to attach a
|
||||||
|
script to a player which gets executed on attack (or when attacked). This
|
||||||
|
is very similar to the autospell bonuses, except that a script is executed
|
||||||
|
instead of a spell. See doc/script_commands for indepth description and
|
||||||
|
usage. NOTE that I am unable to test ingame, and even though I proofread
|
||||||
|
the code it could have bugs. Feel free to test and report. [Skotlex]
|
||||||
* Applied some cleanups that should correct "Infinite Endure" ending
|
* Applied some cleanups that should correct "Infinite Endure" ending
|
||||||
sometimes. [Skotlex]
|
sometimes. [Skotlex]
|
||||||
2007/10/18
|
2007/10/18
|
||||||
|
@ -4285,6 +4285,45 @@ kind in 'doc/item_bonus.txt'.
|
|||||||
|
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
*bonusautoscript <script>,<rate>{,<flag>}
|
||||||
|
*bonusautoscript2 <script>,<rate>{,<flag>}
|
||||||
|
|
||||||
|
These commands are meant to be used in item scripts. They will probably work
|
||||||
|
outside item scripts, but the bonus will not persist for long. They, as
|
||||||
|
expected, refer only to an invoking character.
|
||||||
|
|
||||||
|
What these commands do is 'attach' a script to the player which will get
|
||||||
|
executed on attack (or when attacked in the case of bonusautoscript2). Rate is
|
||||||
|
the trigger rate of the script (1000 = 100%). The optional argument flag is
|
||||||
|
used to classify the type of attack where the script can trigger (it shares
|
||||||
|
the same flags as the bAutoSpell bonus script):
|
||||||
|
|
||||||
|
Range criteria:
|
||||||
|
BF_SHORT: Trigger on melee attack
|
||||||
|
BF_LONG: Trigger on ranged attack
|
||||||
|
Default: BF_SHORT+BF_LONG
|
||||||
|
Attack type criteria:
|
||||||
|
BF_WEAPON: Trigger on weapon skills
|
||||||
|
BF_MAGIC: Trigger on magic skills
|
||||||
|
BF_MISC: Trigger on misc skills
|
||||||
|
Default: BF_WEAPON
|
||||||
|
Skill criteria:
|
||||||
|
BF_NORMAL: Trigger on normal attacks
|
||||||
|
BF_SKILL: Trigger on skills
|
||||||
|
default: If the attack type is BF_WEAPON (only) BF_NORMAL is used, otherwise
|
||||||
|
BF_SKILL+BF_NORMAL is used.
|
||||||
|
|
||||||
|
In both cases, when the script triggers, the attached player will be the one
|
||||||
|
who holds the bonus. There is currently no way of knowing within this script
|
||||||
|
who was the other character (the attacker in autoscript2, or the target in
|
||||||
|
autoscript).
|
||||||
|
|
||||||
|
//Grants a 1% chance of starting the state "all stats +10" for 10 seconds when
|
||||||
|
//using weapon or misc attacks (both melee and ranged skills).
|
||||||
|
bonusautoscript "sc_start SC_INCALLSTATUS, 10, 10000;", 10, BF_WEAPON|BF_MISC;
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
*skill <skill id>,<level>{,<flag>};
|
*skill <skill id>,<level>{,<flag>};
|
||||||
*addtoskill <skill id>,<level>{,<flag>}
|
*addtoskill <skill id>,<level>{,<flag>}
|
||||||
|
|
||||||
|
@ -692,6 +692,12 @@ struct map_session_data {
|
|||||||
int rate;
|
int rate;
|
||||||
} itemhealrate[MAX_PC_BONUS];
|
} itemhealrate[MAX_PC_BONUS];
|
||||||
// zeroed structures end here
|
// zeroed structures end here
|
||||||
|
// manually zeroed structures start here.
|
||||||
|
struct s_autoscript {
|
||||||
|
unsigned short rate, flag;
|
||||||
|
struct script_code *script;
|
||||||
|
} autoscript[5], autoscript2[5]; //Auto script on attack, when attacked
|
||||||
|
// manually zeroed structures end here.
|
||||||
// zeroed vars start here.
|
// zeroed vars start here.
|
||||||
int arrow_atk,arrow_ele,arrow_cri,arrow_hit;
|
int arrow_atk,arrow_ele,arrow_cri,arrow_hit;
|
||||||
int nsshealhp,nsshealsp;
|
int nsshealhp,nsshealsp;
|
||||||
|
30
src/map/pc.c
30
src/map/pc.c
@ -1219,6 +1219,36 @@ int pc_disguise(struct map_session_data *sd, int class_)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pc_autoscript_add(struct s_autoscript *scripts, int max, short rate, short flag, struct script_code *script)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
ARR_FIND(0, max, i, scripts[i].script == NULL);
|
||||||
|
if (i == max) {
|
||||||
|
if (battle_config.error_log)
|
||||||
|
ShowWarning("pc_autoscript_bonus: Reached max (%d) number of autoscripts per character!\n", max);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
scripts[i].script = script;
|
||||||
|
scripts[i].rate = rate;
|
||||||
|
//Auto-update flag value.
|
||||||
|
if (!(flag&BF_RANGEMASK)) flag|=BF_SHORT|BF_LONG; //No range defined? Use both.
|
||||||
|
if (!(flag&BF_WEAPONMASK)) flag|=BF_WEAPON; //No attack type defined? Use weapon.
|
||||||
|
if (!(flag&BF_SKILLMASK)) {
|
||||||
|
if (flag&(BF_MAGIC|BF_MISC)) flag|=BF_SKILL; //These two would never trigger without BF_SKILL
|
||||||
|
if (flag&BF_WEAPON) flag|=BF_NORMAL;
|
||||||
|
}
|
||||||
|
scripts[i].flag = flag;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pc_autoscript_clear(struct s_autoscript *scripts, int max)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < max && scripts[i].script; i++)
|
||||||
|
script_free_code(scripts[i].script);
|
||||||
|
memset(scripts, 0, i*sizeof(struct s_autoscript));
|
||||||
|
}
|
||||||
|
|
||||||
static int pc_bonus_autospell_del(struct s_autospell *spell, int max, short id, short lv, short rate, short card_id)
|
static int pc_bonus_autospell_del(struct s_autospell *spell, int max, short id, short lv, short rate, short card_id)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
@ -167,6 +167,9 @@ int pc_dropitem(struct map_session_data*,int,int);
|
|||||||
|
|
||||||
int pc_updateweightstatus(struct map_session_data *sd);
|
int pc_updateweightstatus(struct map_session_data *sd);
|
||||||
|
|
||||||
|
int pc_autoscript_add(struct s_autoscript *scripts, int max, short rate, short flag, struct script_code *script);
|
||||||
|
void pc_autoscript_clear(struct s_autoscript *scripts, int max);
|
||||||
|
|
||||||
int pc_bonus(struct map_session_data*,int,int);
|
int pc_bonus(struct map_session_data*,int,int);
|
||||||
int pc_bonus2(struct map_session_data *sd,int,int,int);
|
int pc_bonus2(struct map_session_data *sd,int,int,int);
|
||||||
int pc_bonus3(struct map_session_data *sd,int,int,int,int);
|
int pc_bonus3(struct map_session_data *sd,int,int,int,int);
|
||||||
|
@ -3802,6 +3802,8 @@ BUILDIN_FUNC(bonus2);
|
|||||||
BUILDIN_FUNC(bonus3);
|
BUILDIN_FUNC(bonus3);
|
||||||
BUILDIN_FUNC(bonus4);
|
BUILDIN_FUNC(bonus4);
|
||||||
BUILDIN_FUNC(bonus5);
|
BUILDIN_FUNC(bonus5);
|
||||||
|
BUILDIN_FUNC(bonusautoscript);
|
||||||
|
BUILDIN_FUNC(bonusautoscript2);
|
||||||
BUILDIN_FUNC(skill);
|
BUILDIN_FUNC(skill);
|
||||||
BUILDIN_FUNC(addtoskill); // [Valaris]
|
BUILDIN_FUNC(addtoskill); // [Valaris]
|
||||||
BUILDIN_FUNC(guildskill);
|
BUILDIN_FUNC(guildskill);
|
||||||
@ -4134,6 +4136,8 @@ struct script_function buildin_func[] = {
|
|||||||
BUILDIN_DEF2(bonus,"bonus3","iiii"),
|
BUILDIN_DEF2(bonus,"bonus3","iiii"),
|
||||||
BUILDIN_DEF2(bonus,"bonus4","iiiii"),
|
BUILDIN_DEF2(bonus,"bonus4","iiiii"),
|
||||||
BUILDIN_DEF2(bonus,"bonus5","iiiiii"),
|
BUILDIN_DEF2(bonus,"bonus5","iiiiii"),
|
||||||
|
BUILDIN_DEF(bonusautoscript,"si?"),
|
||||||
|
BUILDIN_DEF(bonusautoscript2,"si?"),
|
||||||
BUILDIN_DEF(skill,"ii?"),
|
BUILDIN_DEF(skill,"ii?"),
|
||||||
BUILDIN_DEF(addtoskill,"ii?"), // [Valaris]
|
BUILDIN_DEF(addtoskill,"ii?"), // [Valaris]
|
||||||
BUILDIN_DEF(guildskill,"ii"),
|
BUILDIN_DEF(guildskill,"ii"),
|
||||||
@ -7192,6 +7196,59 @@ BUILDIN_FUNC(bonus)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Bonus script that has a chance of being executed on attack.
|
||||||
|
BUILDIN_FUNC(bonusautoscript)
|
||||||
|
{
|
||||||
|
int rate, flag = 0;
|
||||||
|
const char *str;
|
||||||
|
struct script_code *script;
|
||||||
|
TBL_PC* sd;
|
||||||
|
|
||||||
|
sd = script_rid2sd(st);
|
||||||
|
if( sd == NULL )
|
||||||
|
return 1;// no player attached, report source
|
||||||
|
|
||||||
|
str = script_getstr(st,2);
|
||||||
|
rate = script_getnum(st,3);
|
||||||
|
if( script_hasdata(st,4) )
|
||||||
|
flag = script_getnum(st,4);
|
||||||
|
script = parse_script(str, "autoscript bonus", 0, 0);
|
||||||
|
if (!script)
|
||||||
|
return 1;
|
||||||
|
if (!pc_autoscript_add(sd->autoscript, ARRAYLENGTH(sd->autoscript), rate, flag, script))
|
||||||
|
{
|
||||||
|
script_free_code(script);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/// Bonus script that has a chance of being executed when attacked.
|
||||||
|
BUILDIN_FUNC(bonusautoscript2)
|
||||||
|
{
|
||||||
|
int rate, flag = 0;
|
||||||
|
const char *str;
|
||||||
|
struct script_code *script;
|
||||||
|
TBL_PC* sd;
|
||||||
|
|
||||||
|
sd = script_rid2sd(st);
|
||||||
|
if( sd == NULL )
|
||||||
|
return 1;// no player attached, report source
|
||||||
|
|
||||||
|
str = script_getstr(st,2);
|
||||||
|
rate = script_getnum(st,3);
|
||||||
|
if( script_hasdata(st,4) )
|
||||||
|
flag = script_getnum(st,4);
|
||||||
|
script = parse_script(str, "autoscript2 bonus", 0, 0);
|
||||||
|
if (!script)
|
||||||
|
return 1;
|
||||||
|
if (!pc_autoscript_add(sd->autoscript2, ARRAYLENGTH(sd->autoscript2), rate, flag, script))
|
||||||
|
{
|
||||||
|
script_free_code(script);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// Changes the level of a player skill.
|
/// Changes the level of a player skill.
|
||||||
/// <flag> defaults to 1
|
/// <flag> defaults to 1
|
||||||
/// <flag>=0 : set the level of the skill
|
/// <flag>=0 : set the level of the skill
|
||||||
|
@ -1508,6 +1508,22 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Auto-script when attacking
|
||||||
|
if(sd && src != bl && sd->autoscript[0].script) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ARRAYLENGTH(sd->autoscript) && sd->autoscript[i].script; i++) {
|
||||||
|
|
||||||
|
if(!(sd->autoscript[i].flag&attack_type&BF_WEAPONMASK &&
|
||||||
|
sd->autoscript[i].flag&attack_type&BF_RANGEMASK &&
|
||||||
|
sd->autoscript[i].flag&attack_type&BF_SKILLMASK))
|
||||||
|
continue; // one or more trigger conditions were not fulfilled
|
||||||
|
if (rand()%1000 > sd->autoscript[i].rate)
|
||||||
|
continue;
|
||||||
|
run_script(sd->autoscript[i].script,0,sd->bl.id,0);
|
||||||
|
break; //Have only one script execute at a time.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Polymorph
|
//Polymorph
|
||||||
if(sd && sd->classchange && attack_type&BF_WEAPON &&
|
if(sd && sd->classchange && attack_type&BF_WEAPON &&
|
||||||
dstmd && !(tstatus->mode&MD_BOSS) &&
|
dstmd && !(tstatus->mode&MD_BOSS) &&
|
||||||
@ -1683,6 +1699,24 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
|
|||||||
break; //trigger only one auto-spell per hit.
|
break; //trigger only one auto-spell per hit.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//Auto-script when attacked
|
||||||
|
if(dstsd && !status_isdead(bl) && src != bl && dstsd->autoscript2[0].script &&
|
||||||
|
!(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE))
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ARRAYLENGTH(dstsd->autoscript2) && dstsd->autoscript2[i].script; i++) {
|
||||||
|
|
||||||
|
if(!(dstsd->autoscript2[i].flag&attack_type&BF_WEAPONMASK &&
|
||||||
|
dstsd->autoscript2[i].flag&attack_type&BF_RANGEMASK &&
|
||||||
|
dstsd->autoscript2[i].flag&attack_type&BF_SKILLMASK))
|
||||||
|
continue; // one or more trigger conditions were not fulfilled
|
||||||
|
if (rand()%1000 > dstsd->autoscript2[i].rate)
|
||||||
|
continue;
|
||||||
|
run_script(dstsd->autoscript2[i].script,0,dstsd->bl.id,0);
|
||||||
|
break; //Have only one script execute at a time.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*=========================================================================
|
/*=========================================================================
|
||||||
|
@ -1642,7 +1642,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
|
|||||||
sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
|
sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
|
||||||
sd->regen.state.block = 0;
|
sd->regen.state.block = 0;
|
||||||
|
|
||||||
// zeroed arays, order follows the order in map.h.
|
// zeroed arrays, order follows the order in map.h.
|
||||||
// add new arrays to the end of zeroed area in map.h (see comments) and size here. [zzo]
|
// add new arrays to the end of zeroed area in map.h (see comments) and size here. [zzo]
|
||||||
memset (sd->param_bonus, 0, sizeof(sd->param_bonus)
|
memset (sd->param_bonus, 0, sizeof(sd->param_bonus)
|
||||||
+ sizeof(sd->param_equip)
|
+ sizeof(sd->param_equip)
|
||||||
@ -1715,7 +1715,10 @@ int status_calc_pc(struct map_session_data* sd,int first)
|
|||||||
+ sizeof(sd->add_drop)
|
+ sizeof(sd->add_drop)
|
||||||
+ sizeof(sd->itemhealrate)
|
+ sizeof(sd->itemhealrate)
|
||||||
);
|
);
|
||||||
|
// clear autoscripts...
|
||||||
|
pc_autoscript_clear(sd->autoscript, ARRAYLENGTH(sd->autoscript));
|
||||||
|
pc_autoscript_clear(sd->autoscript2, ARRAYLENGTH(sd->autoscript2));
|
||||||
|
|
||||||
// vars zeroing. ints, shorts, chars. in that order.
|
// vars zeroing. ints, shorts, chars. in that order.
|
||||||
memset (&sd->arrow_atk, 0,sizeof(sd->arrow_atk)
|
memset (&sd->arrow_atk, 0,sizeof(sd->arrow_atk)
|
||||||
+ sizeof(sd->arrow_ele)
|
+ sizeof(sd->arrow_ele)
|
||||||
|
@ -1805,6 +1805,10 @@ int unit_free(struct block_list *bl, int clrtype)
|
|||||||
status_change_end(bl,SC_STEELBODY,-1);
|
status_change_end(bl,SC_STEELBODY,-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pc_autoscript_clear(sd->autoscript, ARRAYLENGTH(sd->autoscript));
|
||||||
|
pc_autoscript_clear(sd->autoscript2, ARRAYLENGTH(sd->autoscript2));
|
||||||
|
|
||||||
if (sd->followtimer != -1)
|
if (sd->followtimer != -1)
|
||||||
pc_stop_following(sd);
|
pc_stop_following(sd);
|
||||||
// Force exiting from duel and rejecting all duel invitations when player quit [LuzZza]
|
// Force exiting from duel and rejecting all duel invitations when player quit [LuzZza]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user