* Fixed bugreport:9211. Basilica causes map-server crashed when caster changing map

* Some source docs for skill.c/h

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
Cydh Ramdh 2014-08-17 00:00:19 +07:00
parent adabedba23
commit d270047312
8 changed files with 393 additions and 254 deletions

View File

@ -507,7 +507,7 @@
//****
// High Priest
361,9,6,16,0,0x1,1,5,1,yes,0,0,0,magic,0,0x0, HP_ASSUMPTIO,Assumptio
362,4,6,4,0,0x1,0,5,1,yes,0,0,0,magic,2,0x0, HP_BASILICA,Basilica
362,4,6,4,0,0x1,0,5,1,yes,0,0,1,magic,2,0x0, HP_BASILICA,Basilica
363,0,0,0,0,0,0,10,0,no,0,0,0,magic,0,0x0, HP_MEDITATIO,Meditatio
//****

View File

@ -83,7 +83,7 @@
330,0xaf, , 3, 0, -1,all, 0x140 //DC_SERVICEFORYOU
336,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLPARTNER
339,0x86, , -1, 0, 300,enemy, 0x000 //NPC_DARKGRANDCROSS
362,0xb4, , 0, 2, 300,all, 0x000 //HP_BASILICA
362,0xb4, , 2, 0, 300,all, 0x2000 //HP_BASILICA
369,0xb3, , -1, 0,10000,all, 0x008 //PA_GOSPEL
395,0xb5, , 4, 0, -1,all, 0x200 //CG_MOONLIT
404,0xb6, , -1, 0, -1,all, 0x8000 //PF_FOGWALL

View File

@ -507,7 +507,7 @@
//****
// High Priest
361,9,6,16,0,0x1,1,5,1,yes,0,0,0,magic,0,0x0, HP_ASSUMPTIO,Assumptio
362,4,6,4,0,0x1,0,5,1,yes,0,0,0,magic,2,0x0, HP_BASILICA,Basilica
362,4,6,4,0,0x1,0,5,1,yes,0,0,1,magic,2,0x0, HP_BASILICA,Basilica
363,0,0,0,0,0,0,10,0,no,0,0,0,magic,0,0x0, HP_MEDITATIO,Meditatio
//****

View File

@ -83,7 +83,7 @@
330,0xaf, , 3, 0, -1,all, 0x140 //DC_SERVICEFORYOU
336,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLPARTNER
339,0x86, , -1, 0, 300,enemy, 0x000 //NPC_DARKGRANDCROSS
362,0xb4, , 0, 2, 300,all, 0x000 //HP_BASILICA
362,0xb4, , 2, 0, 300,all, 0x2000 //HP_BASILICA
369,0xb3, , -1, 0,10000,all, 0x008 //PA_GOSPEL
395,0xb5, , 4, 0, -1,all, 0x200 //CG_MOONLIT
404,0xb6, , -1, 0, -1,all, 0x8000 //PF_FOGWALL

View File

@ -8418,6 +8418,9 @@ bool pc_candrop(struct map_session_data *sd, struct item *item)
bool pc_can_attack( struct map_session_data *sd, int target_id ) {
nullpo_retr(false, sd);
if (!&sd->sc)
return true;
if( sd->sc.data[SC_BASILICA] ||
sd->sc.data[SC__SHADOWFORM] ||
sd->sc.data[SC__MANHOLE] ||
@ -9394,7 +9397,7 @@ bool pc_unequipitem(struct map_session_data *sd,int n,int flag) {
if((sd->status.inventory[n].equip & EQP_ARMS) &&
sd->weapontype1 == 0 && sd->weapontype2 == 0 && (!sd->sc.data[SC_SEVENWIND] || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!)
skill_enchant_elemental_end(&sd->bl,-1);
skill_enchant_elemental_end(&sd->bl,SC_NONE);
if(sd->status.inventory[n].equip & EQP_ARMOR) {
// On Armor Change...

File diff suppressed because it is too large Load Diff

View File

@ -211,38 +211,43 @@ struct skill_timerskill {
int flag;
};
#define MAX_SKILLUNITGROUP 25
#define MAX_SKILLUNITGROUP 25 /// Maximum skill unit group (for same skill each source)
/// Skill unit group
struct skill_unit_group {
int src_id;
int party_id;
int guild_id;
int bg_id;
int map;
int target_flag; //Holds BCT_* flag for battle_check_target
int bl_flag; //Holds BL_* flag for map_foreachin* functions
unsigned int tick;
int limit,interval;
uint16 skill_id,skill_lv;
int val1,val2,val3;
char *valstr;
int unit_id;
int group_id;
int unit_count,alive_count;
int item_id; //store item used.
struct skill_unit *unit;
int src_id; /// Caster ID/RID, if player is account_id
int party_id; /// Party ID
int guild_id; /// Guild ID
int bg_id; /// Battleground ID
int map; /// Map
int target_flag; /// Holds BCT_* flag for battle_check_target
int bl_flag; /// Holds BL_* flag for map_foreachin* functions
unsigned int tick; /// Tick when skill unit initialized
int limit, /// Life time
interval; /// Timer interval
uint16 skill_id, /// Skill ID
skill_lv; /// Skill level
int val1, val2, val3; /// Values
char *valstr; /// String value, used for HT_TALKIEBOX & RG_GRAFFITI
int unit_id; /// Unit ID (for client effect)
int group_id; /// Skill Group ID
int unit_count, /// Number of unit at this group
alive_count; /// Number of alive unit
int item_id; /// Store item used.
struct skill_unit *unit; /// Skill Unit
struct {
unsigned ammo_consume : 1;
unsigned ammo_consume : 1; // Need to consume ammo
unsigned song_dance : 2; //0x1 Song/Dance, 0x2 Ensemble
unsigned guildaura : 1;
unsigned guildaura : 1; // Guild Aura
} state;
};
/// Skill unit
struct skill_unit {
struct block_list bl;
struct skill_unit_group *group;
struct skill_unit_group *group; /// Skill group reference
int limit;
int val1,val2;
short alive,range;
int val1, val2;
short alive, range;
};
#define MAX_SKILLUNITGROUPTICKSET 25
@ -358,7 +363,7 @@ int skill_get_itemqty( uint16 skill_id, int idx );
int skill_name2id(const char* name);
int skill_isammotype(struct map_session_data *sd, int skill);
int skill_isammotype(struct map_session_data *sd, unsigned short skill_id);
int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data);
int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data);
int skill_castend_map( struct map_session_data *sd,uint16 skill_id, const char *map);
@ -380,10 +385,10 @@ int skill_delunit(struct skill_unit *unit);
struct skill_unit_group *skill_initunitgroup(struct block_list* src, int count, uint16 skill_id, uint16 skill_lv, int unit_id, int limit, int interval);
int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int line, const char* func);
#define skill_delunitgroup(group) skill_delunitgroup_(group,__FILE__,__LINE__,__func__)
int skill_clear_unitgroup(struct block_list *src);
void skill_clear_unitgroup(struct block_list *src);
int skill_clear_group(struct block_list *bl, int flag);
void ext_skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, unsigned int tick);
int64 skill_unit_ondamaged(struct skill_unit *unit,struct block_list *bl,int64 damage,unsigned int tick);
int64 skill_unit_ondamaged(struct skill_unit *unit,struct block_list *bl,int64 damage);
int skill_castfix( struct block_list *bl, uint16 skill_id, uint16 skill_lv);
int skill_castfix_sc( struct block_list *bl, int time);
@ -425,7 +430,7 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce);
// Abnormal status
int skill_enchant_elemental_end(struct block_list *bl, int type);
void skill_enchant_elemental_end(struct block_list *bl, int type);
bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd);
bool skill_isNotOk_hom(uint16 skill_id, struct homun_data *hd);
bool skill_isNotOk_mercenary(uint16 skill_id, struct mercenary_data *md);

View File

@ -1196,7 +1196,6 @@ void initChangeTables(void)
/* StatusChangeState (SCS_) NOCAST (skills) */
StatusChangeStateTable[SC_SILENCE] |= SCS_NOCAST;
StatusChangeStateTable[SC_STEELBODY] |= SCS_NOCAST;
StatusChangeStateTable[SC_BASILICA] |= SCS_NOCAST;
StatusChangeStateTable[SC_BERSERK] |= SCS_NOCAST;
StatusChangeStateTable[SC__BLOODYLUST] |= SCS_NOCAST;
StatusChangeStateTable[SC_DEATHBOUND] |= SCS_NOCAST;
@ -1353,7 +1352,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 dhp, in
}
if (target->type == BL_SKILL)
return (int)skill_unit_ondamaged((struct skill_unit *)target, src, hp, gettick());
return (int)skill_unit_ondamaged((struct skill_unit *)target, src, hp);
status = status_get_status_data(target);
if(!status || status == &dummy_status )
@ -1866,6 +1865,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
) { // Skills blocked through status changes...
if (!flag && ( // Blocked only from using the skill (stuff like autospell may still go through
sc->cant.cast ||
(sc->data[SC_BASILICA] && (sc->data[SC_BASILICA]->val4 != src->id || skill_id != HP_BASILICA)) || // Only Basilica caster that can cast, and only Basilica to cancel it
(sc->data[SC_MARIONETTE] && skill_id != CG_MARIONETTE) || // Only skill you can use is marionette again to cancel it
(sc->data[SC_MARIONETTE2] && skill_id == CG_MARIONETTE) || // Cannot use marionette if you are being buffed by another
(sc->data[SC_STASIS] && skill_block_check(src, SC_STASIS, skill_id)) ||
@ -10729,7 +10729,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if (sce->val3) { // Clear the group.
struct skill_unit_group* group = skill_id2group(sce->val3);
sce->val3 = 0;
skill_delunitgroup(group);
if (group)
skill_delunitgroup(group);
}
break;
case SC_HERMODE:
@ -10737,7 +10738,12 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
skill_clear_unitgroup(bl);
break;
case SC_BASILICA: // Clear the skill area. [Skotlex]
skill_clear_unitgroup(bl);
if (sce->val3 && sce->val4 == bl->id) {
struct skill_unit_group* group = skill_id2group(sce->val3);
sce->val3 = 0;
if (group)
skill_delunitgroup(group);
}
break;
case SC_TRICKDEAD:
if (vd) vd->dead_sit = 0;