- Added battle_get_master which returns the master bl of a given object.

- Recoded battle_check_target to use battle_get_master, the src/target switch has been split into two, so that actual target and master target are seperately treated (same for source).


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@7897 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
skotlex 2006-07-26 18:22:24 +00:00
parent 7cd47130d0
commit cfe71d744a
2 changed files with 135 additions and 116 deletions

View File

@ -4,6 +4,11 @@ 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/26
* Added battle_get_master which returns the master bl of a given object.
[Skotlex]
* Recoded battle_check_target to use battle_get_master, the src/target
switch has been split into two, so that actual target and master target are
seperately treated (same for source). [Skotlex]
* Added support for "sc_end -1" which will clear all status changes. Added
the constant SC_ALL so you can use in scripts "sc_end SC_ALL;" instead.
[Skotlex]

View File

@ -2985,6 +2985,46 @@ int battle_check_undead(int race,int element)
return 0;
}
//Returns the upmost level master starting with the given object
static struct block_list* battle_get_master(struct block_list *src)
{
do {
switch (src->type) {
case BL_PET:
if (((TBL_PET*)src)->msd)
src = (struct block_list*)((TBL_PET*)src)->msd;
else
return src;
break;
case BL_MOB:
if (((TBL_MOB*)src)->master_id)
src = map_id2bl(((TBL_MOB*)src)->master_id);
else
return src;
break;
case BL_HOMUNCULUS:
if (((TBL_HOMUNCULUS*)src)->master)
src = (struct block_list*)((TBL_HOMUNCULUS*)src)->master;
else
return src;
break;
case BL_SKILL:
if (((TBL_SKILL*)src)->group && ((TBL_SKILL*)src)->group->src_id)
src = map_id2bl(((TBL_SKILL*)src)->group->src_id);
else
return src;
break;
default:
return src;
}
#ifdef RECURSIVE_MASTER_CHECK
} while (src);
#else
} while (0); //Single pass check.
#endif
return src;
}
/*==========================================
* Checks the state between two targets (rewritten by Skotlex)
* (enemy, friend, party, guild, etc)
@ -3013,9 +3053,30 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
return -1;
}
if (target->type == BL_SKILL) //Needed out of the switch in case the ownership needs to be passed skill->mob->master
//t_bl/s_bl hold the 'master' of the attack, while src/target are the actual
//objects involved.
if ((t_bl = battle_get_master(target)) == NULL)
t_bl = target;
if ((s_bl = battle_get_master(src)) == NULL)
s_bl = src;
switch (target->type)
{ //Checks on actual target
case BL_PC:
if (((TBL_PC*)target)->invincible_timer != -1 || pc_isinvisible((TBL_PC*)target))
return -1; //Cannot be targeted yet.
break;
case BL_MOB:
if (((TBL_MOB*)target)->special_state.ai == 2)
{ //Mines are sort of universal enemies.
state |= BCT_ENEMY;
strip_enemy = 0;
}
break;
case BL_SKILL:
{
struct skill_unit *su = (struct skill_unit *)target;
TBL_SKILL *su = (TBL_SKILL*)target;
if (!su->group)
return 0;
if (skill_get_inf2(su->group->skill_id)&INF2_TRAP)
@ -3039,17 +3100,20 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
strip_enemy = 0;
} else //Excepting traps and icewall, you should not be able to target skills.
return 0;
if ((t_bl = map_id2bl(su->group->src_id)) == NULL)
t_bl = target; //Fallback on the trap itself, otherwise consider this a "versus caster" scenario.
}
//Valid targets with no special checks here.
case BL_HOMUNCULUS:
break;
//All else not specified is an invalid target.
default:
return 0;
}
switch (t_bl->type)
{
{ //Checks on target master
case BL_PC:
{
TBL_PC *sd = (TBL_PC*)t_bl;
if (sd->invincible_timer != -1 || pc_isinvisible(sd))
return -1; //Cannot be targeted yet.
if (sd->state.monster_ignore && t_bl != s_bl && flag&BCT_ENEMY)
return 0; //Global inmunity to attacks.
if (sd->special_state.killable && t_bl != s_bl)
@ -3067,42 +3131,32 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
if (!agit_flag && md->guardian_data && md->guardian_data->guild_id)
return 0; //Disable guardians/emperiums owned by Guilds on non-woe times.
if (md->special_state.ai == 2)
{ //Mines are sort of universal enemies.
state |= BCT_ENEMY;
strip_enemy = 0;
}
if (md->master_id && (t_bl = map_id2bl(md->master_id)) == NULL)
t_bl = &md->bl; //Fallback on the mob itself, otherwise consider this a "versus master" scenario.
break;
}
case BL_PET:
{
return 0; //Pets cannot be targetted.
}
case BL_HOMUNCULUS:
{
//For some mysterious reason ground-skills can't target homun.
if (src->type == BL_SKILL)
return 0;
//Just fallback on master.
t_bl=(struct block_list *)((TBL_HOMUNCULUS*)target)->master;
if (((TBL_PC*)t_bl)->state.monster_ignore && t_bl != s_bl && flag&BCT_ENEMY)
return 0;
break;
}
case BL_SKILL: //Skill with no owner? Kinda odd... but.. let it through.
break;
default: //Invalid target
return 0;
}
if (src->type == BL_SKILL)
switch(src->type)
{ //Checks on actual src type
case BL_MOB:
if (!agit_flag && ((TBL_MOB*)src)->guardian_data && ((TBL_MOB*)src)->guardian_data->guild_id)
return 0; //Disable guardians/emperium owned by Guilds on non-woe times.
break;
case BL_PET:
if (t_bl->type != BL_MOB && flag&BCT_ENEMY)
return 0; //Pet may not attack non-mobs.
if (t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->guardian_data && flag&BCT_ENEMY)
return 0; //pet may not attack Guardians/Emperium
break;
case BL_SKILL:
{
struct skill_unit *su = (struct skill_unit *)src;
if (!su->group)
return 0;
//For some mysterious reason ground-skills can't target homun.
if (target->type == BL_HOMUNCULUS)
return 0;
if (su->group->src_id == target->id)
{
int inf2;
@ -3112,12 +3166,12 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
if (inf2&INF2_TARGET_SELF)
return 1;
}
if ((s_bl = map_id2bl(su->group->src_id)) == NULL)
s_bl = src; //Fallback on the trap itself, otherwise consider this a "caster versus enemy" scenario.
break;
}
}
switch (s_bl->type)
{
{ //Checks on source master
case BL_PC:
{
TBL_PC *sd = (TBL_PC*) s_bl;
@ -3149,24 +3203,8 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
case BL_MOB:
{
TBL_MOB*md = (TBL_MOB*)s_bl;
#ifdef RECURSIVE_MASTER_CHECK
struct block_list *tmp_bl = NULL;
TBL_MOB *tmp_md = NULL;
#endif
if (!agit_flag && md->guardian_data && md->guardian_data->guild_id)
return 0; //Disable guardians/emperium owned by Guilds on non-woe times.
#ifdef RECURSIVE_MASTER_CHECK
tmp_md = md;
while(tmp_md->master_id && (tmp_bl = map_id2bl(tmp_md->master_id))){
if(t_bl->id == tmp_bl->id){
state |= BCT_PARTY;
break;
}
if(tmp_bl->type != BL_MOB)
break;
tmp_md = (TBL_MOB *)tmp_bl;
}
#endif
if(md->state.killer) // Is on a rampage too :D
state |= BCT_ENEMY;
else if (!md->special_state.ai) { //Normal mobs.
@ -3178,46 +3216,22 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
if (t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai)
state |= BCT_ENEMY; //Natural enemy for AI mobs are normal mobs.
}
if (md->master_id && (s_bl = map_id2bl(md->master_id)) == NULL)
s_bl = &md->bl; //Fallback on the mob itself, otherwise consider this a "from master" scenario.
break;
}
case BL_HOMUNCULUS:
{
//[blackhole89] -- check homunculus' targeting by their masters.
if (t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai)
state |= BCT_ENEMY; //Default enemy. Normal mobs.
//Pass on to master.
s_bl=(struct block_list *)((struct homun_data*)src)->master;
default:
//Need some sort of default behaviour for unhandled types.
if (t_bl->type != s_bl->type)
state |= BCT_ENEMY;
break;
}
case BL_PET:
{
TBL_PET *pd = (TBL_PET*)s_bl;
if (t_bl->type != BL_MOB && flag&BCT_ENEMY)
return 0; //Pet may not attack non-mobs.
if (t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->guardian_data && flag&BCT_ENEMY)
return 0; //pet may not attack Guardians/Emperium
if (t_bl->type != BL_PC)
state |= BCT_ENEMY; //Stock enemy type.
if (pd->msd)
s_bl = &pd->msd->bl; //"My master's enemies are my enemies..."
break;
}
case BL_SKILL: //Skill with no owner? Fishy, but let it through.
break;
case BL_NPC: // allows NPC-set skill units to proceed [blackhole89]
break;
default: //Invalid source of attack?
return 0;
}
if ((flag&BCT_ALL) == BCT_ALL) { //All actually stands for all attackable chars
if (target->type&BL_CHAR)
return 1;
else
return -1;
} else if (flag == BCT_NOONE) //Why would someone use this? no clue.
} else
if (flag == BCT_NOONE) //Why would someone use this? no clue.
return -1;
if (t_bl == s_bl)