- 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.
|
||||
|
||||
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
|
||||
sometimes. [Skotlex]
|
||||
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>};
|
||||
*addtoskill <skill id>,<level>{,<flag>}
|
||||
|
||||
|
@ -692,6 +692,12 @@ struct map_session_data {
|
||||
int rate;
|
||||
} itemhealrate[MAX_PC_BONUS];
|
||||
// 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.
|
||||
int arrow_atk,arrow_ele,arrow_cri,arrow_hit;
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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_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_bonus2(struct map_session_data *sd,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(bonus4);
|
||||
BUILDIN_FUNC(bonus5);
|
||||
BUILDIN_FUNC(bonusautoscript);
|
||||
BUILDIN_FUNC(bonusautoscript2);
|
||||
BUILDIN_FUNC(skill);
|
||||
BUILDIN_FUNC(addtoskill); // [Valaris]
|
||||
BUILDIN_FUNC(guildskill);
|
||||
@ -4134,6 +4136,8 @@ struct script_function buildin_func[] = {
|
||||
BUILDIN_DEF2(bonus,"bonus3","iiii"),
|
||||
BUILDIN_DEF2(bonus,"bonus4","iiiii"),
|
||||
BUILDIN_DEF2(bonus,"bonus5","iiiiii"),
|
||||
BUILDIN_DEF(bonusautoscript,"si?"),
|
||||
BUILDIN_DEF(bonusautoscript2,"si?"),
|
||||
BUILDIN_DEF(skill,"ii?"),
|
||||
BUILDIN_DEF(addtoskill,"ii?"), // [Valaris]
|
||||
BUILDIN_DEF(guildskill,"ii"),
|
||||
@ -7192,6 +7196,59 @@ BUILDIN_FUNC(bonus)
|
||||
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.
|
||||
/// <flag> defaults to 1
|
||||
/// <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
|
||||
if(sd && sd->classchange && attack_type&BF_WEAPON &&
|
||||
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.
|
||||
}
|
||||
}
|
||||
//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;
|
||||
}
|
||||
/*=========================================================================
|
||||
|
@ -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->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]
|
||||
memset (sd->param_bonus, 0, sizeof(sd->param_bonus)
|
||||
+ 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->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.
|
||||
memset (&sd->arrow_atk, 0,sizeof(sd->arrow_atk)
|
||||
+ sizeof(sd->arrow_ele)
|
||||
|
@ -1805,6 +1805,10 @@ int unit_free(struct block_list *bl, int clrtype)
|
||||
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)
|
||||
pc_stop_following(sd);
|
||||
// Force exiting from duel and rejecting all duel invitations when player quit [LuzZza]
|
||||
|
Loading…
x
Reference in New Issue
Block a user