diff options
-rw-r--r-- | src/map/battle.c | 127 | ||||
-rw-r--r-- | src/map/chat.c | 16 | ||||
-rw-r--r-- | src/map/clif.c | 13 | ||||
-rw-r--r-- | src/map/duel.c | 2 | ||||
-rw-r--r-- | src/map/elemental.c | 3 | ||||
-rw-r--r-- | src/map/guild.c | 2 | ||||
-rw-r--r-- | src/map/homunculus.c | 3 | ||||
-rw-r--r-- | src/map/intif.c | 2 | ||||
-rw-r--r-- | src/map/map.c | 38 | ||||
-rw-r--r-- | src/map/mercenary.c | 3 | ||||
-rw-r--r-- | src/map/mob.c | 37 | ||||
-rw-r--r-- | src/map/npc.c | 23 | ||||
-rw-r--r-- | src/map/party.c | 4 | ||||
-rw-r--r-- | src/map/pc.c | 11 | ||||
-rw-r--r-- | src/map/pet.c | 11 | ||||
-rw-r--r-- | src/map/script.c | 20 | ||||
-rw-r--r-- | src/map/skill.c | 101 | ||||
-rw-r--r-- | src/map/status.c | 96 | ||||
-rw-r--r-- | src/map/unit.c | 15 |
19 files changed, 276 insertions, 251 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index 273ea7fcb..3b3ea2047 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -242,55 +242,37 @@ int battle_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) { struct delay_damage *dat = (struct delay_damage *)data; if ( dat ) { - struct block_list* src = NULL; - struct block_list* target = map->id2bl(dat->target_id); - - if( !target || status->isdead(target) ) {/* nothing we can do */ - if (dat->src_type == BL_PC - && (src = map->id2bl(dat->src_id)) != NULL - && --((struct map_session_data *)src)->delayed_damage == 0 - && ((struct map_session_data *)src)->state.hold_recalc - ) { - ((struct map_session_data *)src)->state.hold_recalc = 0; - status_calc_pc((struct map_session_data *)src, SCO_FORCE); + struct block_list *src = map->id2bl(dat->src_id); + struct map_session_data *sd = BL_CAST(BL_PC, src); + struct block_list *target = map->id2bl(dat->target_id); + + if (target != NULL && !status->isdead(target)) { + //Check to see if you haven't teleported. [Skotlex] + if (src != NULL && ( + battle_config.fix_warp_hit_delay_abuse ? + (dat->skill_id == MO_EXTREMITYFIST || target->m != src->m || check_distance_bl(src, target, dat->distance)) + : + ((target->type != BL_PC || BL_UCAST(BL_PC, target)->invincible_timer == INVALID_TIMER) + && (dat->skill_id == MO_EXTREMITYFIST || (target->m == src->m && check_distance_bl(src, target, dat->distance)))) + )) { + map->freeblock_lock(); + status_fix_damage(src, target, dat->damage, dat->delay); + if (dat->attack_type && !status->isdead(target) && dat->additional_effects) + skill->additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,dat->dmg_lv,tick); + if (dat->dmg_lv > ATK_BLOCK && dat->attack_type) + skill->counter_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick); + map->freeblock_unlock(); + } else if (src == NULL && dat->skill_id == CR_REFLECTSHIELD) { + // it was monster reflected damage, and the monster died, we pass the damage to the character as expected + map->freeblock_lock(); + status_fix_damage(target, target, dat->damage, dat->delay); + map->freeblock_unlock(); } - ers_free(battle->delay_damage_ers, dat); - return 0; } - src = map->id2bl(dat->src_id); - - //Check to see if you haven't teleported. [Skotlex] - if (src && ( - battle_config.fix_warp_hit_delay_abuse ? - (dat->skill_id == MO_EXTREMITYFIST || target->m != src->m || check_distance_bl(src, target, dat->distance)) - : - ((target->type != BL_PC || ((struct map_session_data *)target)->invincible_timer == INVALID_TIMER) - && (dat->skill_id == MO_EXTREMITYFIST || (target->m == src->m && check_distance_bl(src, target, dat->distance)))) - )) { - map->freeblock_lock(); - status_fix_damage(src, target, dat->damage, dat->delay); - if( dat->attack_type && !status->isdead(target) && dat->additional_effects ) - skill->additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,dat->dmg_lv,tick); - if( dat->dmg_lv > ATK_BLOCK && dat->attack_type ) - skill->counter_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick); - map->freeblock_unlock(); - } else if( !src && dat->skill_id == CR_REFLECTSHIELD ) { - /** - * it was monster reflected damage, and the monster died, we pass the damage to the character as expected - **/ - map->freeblock_lock(); - status_fix_damage(target, target, dat->damage, dat->delay); - map->freeblock_unlock(); - } - - if (src != NULL - && src->type == BL_PC - && --((struct map_session_data *)src)->delayed_damage == 0 - && ((struct map_session_data*)src)->state.hold_recalc - ) { - ((struct map_session_data *)src)->state.hold_recalc = 0; - status_calc_pc((struct map_session_data *)src, SCO_FORCE); + if (sd != NULL && --sd->delayed_damage == 0 && sd->state.hold_recalc) { + sd->state.hold_recalc = 0; + status_calc_pc(sd, SCO_FORCE); } } ers_free(battle->delay_damage_ers, dat); @@ -546,17 +528,20 @@ int64 battle_calc_base_damage(struct block_list *src, struct block_list *bl, uin int64 damage; struct status_data *st = status->get_status_data(src); struct status_change *sc = status->get_sc(src); - + const struct map_session_data *sd = NULL; nullpo_retr(0, src); + + sd = BL_CCAST(BL_PC, src); + if ( !skill_id ) { s_ele = st->rhw.ele; s_ele_ = st->lhw.ele; - if ( src->type == BL_PC ) { - if (((struct map_session_data *)src)->charm_type != CHARM_TYPE_NONE && ((struct map_session_data *)src)->charm_count >= MAX_SPIRITCHARM) { - s_ele = s_ele_ = ((struct map_session_data*)src)->charm_type; + if (sd != NULL) { + if (sd->charm_type != CHARM_TYPE_NONE && sd->charm_count >= MAX_SPIRITCHARM) { + s_ele = s_ele_ = sd->charm_type; } - if (flag&2 && ((struct map_session_data *)src)->bonus.arrow_ele) - s_ele = ((struct map_session_data *)src)->bonus.arrow_ele; + if (flag&2 && sd->bonus.arrow_ele != 0) + s_ele = sd->bonus.arrow_ele; } } if (src->type == BL_PC) { @@ -570,8 +555,7 @@ int64 battle_calc_base_damage(struct block_list *src, struct block_list *bl, uin damage = batk + 3 * battle->calc_weapon_damage(src, bl, skill_id, skill_lv, &st->lhw, nk, n_ele, s_ele, s_ele_, status_get_size(bl), type, flag, flag2) / 4; else damage = (batk << 1) + battle->calc_weapon_damage(src, bl, skill_id, skill_lv, &st->rhw, nk, n_ele, s_ele, s_ele_, status_get_size(bl), type, flag, flag2); - } - else{ + } else { damage = st->batk + battle->calc_weapon_damage(src, bl, skill_id, skill_lv, &st->rhw, nk, n_ele, s_ele, s_ele_, status_get_size(bl), type, flag, flag2); } @@ -2740,6 +2724,8 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam nullpo_ret(bl); nullpo_ret(d); + + sd = BL_CAST(BL_PC, bl); div_ = d->div_; flag = d->flag; @@ -2749,8 +2735,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam return 0; if( battle_config.ksprotection && mob->ksprotected(src, bl) ) return 0; - if (bl->type == BL_PC) { - sd=(struct map_session_data *)bl; + if (sd != NULL) { //Special no damage states if(flag&BF_WEAPON && sd->special_state.no_weapon_damage) damage -= damage * sd->special_state.no_weapon_damage / 100; @@ -2881,9 +2866,11 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam // If the target is too far away from the devotion caster, autoguard has no effect // Autoguard will be disabled later on struct block_list *d_bl = map->id2bl(sce_d->val1); - if (d_bl && check_distance_bl(bl, d_bl, sce_d->val3) - && ((d_bl->type == BL_MER && ((struct mercenary_data *)d_bl)->master && ((struct mercenary_data *)d_bl)->master->bl.id == bl->id) - || (d_bl->type == BL_PC && ((struct map_session_data *)d_bl)->devotion[sce_d->val2] == bl->id)) + struct mercenary_data *d_md = BL_CAST(BL_MER, d_bl); + struct map_session_data *d_sd = BL_CAST(BL_PC, d_bl); + if (d_bl != NULL && check_distance_bl(bl, d_bl, sce_d->val3) + && ((d_bl->type == BL_MER && d_md->master != NULL && d_md->master->bl.id == bl->id) + || (d_bl->type == BL_PC && d_sd->devotion[sce_d->val2] == bl->id)) ) { // if player is target of devotion, show guard effect on the devotion caster rather than the target clif->skill_nodamage(d_bl, d_bl, CR_AUTOGUARD, sce->val1, 1); @@ -3325,8 +3312,9 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam if (!skill_id || (element = skill->get_ele(skill_id, skill_lv)) == -1) { // Take weapon's element struct status_data *sstatus = NULL; - if (src->type == BL_PC && ((struct map_session_data *)src)->bonus.arrow_ele) { - element = ((struct map_session_data *)src)->bonus.arrow_ele; + struct map_session_data *ssd = BL_CAST(BL_PC, src); + if (src->type == BL_PC && ssd->bonus.arrow_ele != 0) { + element = ssd->bonus.arrow_ele; } else if ((sstatus = status->get_status_data(src)) != NULL) { element = sstatus->rhw.ele; } @@ -3394,7 +3382,13 @@ int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64 } } if(src->type != BL_MOB) { - struct guild *g = src->type == BL_PC ? ((struct map_session_data *)src)->guild : guild->search(status->get_guild_id(src)); + struct guild *g = NULL; + if (src->type == BL_PC) { + struct map_session_data *sd = BL_UCAST(BL_PC, src); + g = sd->guild; + } else { + g = guild->search(status->get_guild_id(src)); + } if (class_ == MOBID_EMPELIUM && (!g || guild->checkskill(g,GD_APPROVAL) <= 0)) return 0; @@ -5632,8 +5626,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list } } //Reject Sword bugreport:4493 by Daegaladh - if (wd.damage != 0 - && tsc != NULL && tsc->data[SC_SWORDREJECT] != NULL + if (wd.damage != 0 && tsc != NULL && tsc->data[SC_SWORDREJECT] != NULL && (sd == NULL || sd->weapontype1 == W_DAGGER || sd->weapontype1 == W_1HSWORD || sd->status.weapon == W_2HSWORD) && rnd()%100 < tsc->data[SC_SWORDREJECT]->val2 ) { @@ -6227,10 +6220,12 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t if( tsc->data[SC_DEVOTION] ) { struct status_change_entry *sce = tsc->data[SC_DEVOTION]; struct block_list *d_bl = map->id2bl(sce->val1); + struct mercenary_data *d_md = BL_CAST(BL_MER, d_bl); + struct map_session_data *d_sd = BL_CAST(BL_PC, d_bl); if (d_bl != NULL - && ((d_bl->type == BL_MER && ((struct mercenary_data *)d_bl)->master && ((struct mercenary_data *)d_bl)->master->bl.id == target->id) - || (d_bl->type == BL_PC && ((struct map_session_data *)d_bl)->devotion[sce->val2] == target->id) + && ((d_bl->type == BL_MER && d_md->master != NULL && d_md->master->bl.id == target->id) + || (d_bl->type == BL_PC && d_sd->devotion[sce->val2] == target->id) ) && check_distance_bl(target, d_bl, sce->val3) ) { diff --git a/src/map/chat.c b/src/map/chat.c index 7b4894deb..d60b9bece 100644 --- a/src/map/chat.c +++ b/src/map/chat.c @@ -53,7 +53,7 @@ struct chat_data* chat_createchat(struct block_list* bl, const char* title, cons nullpo_retr(NULL, ev); /* Given the overhead and the numerous instances (npc allocated or otherwise) wouldn't it be beneficial to have it use ERS? [Ind] */ - cd = (struct chat_data *) aMalloc(sizeof(struct chat_data)); + CREATE(cd, struct chat_data, 1); safestrncpy(cd->title, title, sizeof(cd->title)); safestrncpy(cd->pass, pass, sizeof(cd->pass)); @@ -247,14 +247,14 @@ int chat_leavechat(struct map_session_data* sd, bool kicked) { if( leavechar == 0 && cd->owner->type == BL_PC ) { // Set and announce new owner - cd->owner = (struct block_list*) cd->usersd[0]; + cd->owner = &cd->usersd[0]->bl; clif->changechatowner(cd, cd->usersd[0]); clif->clearchat(cd, 0); //Adjust Chat location after owner has been changed. map->delblock( &cd->bl ); - cd->bl.x=cd->usersd[0]->bl.x; - cd->bl.y=cd->usersd[0]->bl.y; + cd->bl.x = cd->owner->x; + cd->bl.y = cd->owner->y; map->addblock( &cd->bl ); clif->dispchat(cd,0); @@ -280,7 +280,7 @@ bool chat_changechatowner(struct map_session_data* sd, const char* nextownername nullpo_ret(nextownername); cd = map->id2cd(sd->chatID); - if( cd == NULL || (struct block_list*) sd != cd->owner ) + if (cd == NULL || &sd->bl != cd->owner) return false; ARR_FIND( 1, cd->users, i, strncmp(cd->usersd[i]->status.name, nextownername, NAME_LENGTH) == 0 ); @@ -291,7 +291,7 @@ bool chat_changechatowner(struct map_session_data* sd, const char* nextownername clif->clearchat(cd,0); // set new owner - cd->owner = (struct block_list*) cd->usersd[i]; + cd->owner = &cd->usersd[i]->bl; clif->changechatowner(cd,cd->usersd[i]); // swap the old and new owners' positions @@ -325,7 +325,7 @@ bool chat_changechatstatus(struct map_session_data* sd, const char* title, const nullpo_ret(pass); cd = map->id2cd(sd->chatID); - if( cd==NULL || (struct block_list *)sd != cd->owner ) + if (cd == NULL || &sd->bl != cd->owner) return false; safestrncpy(cd->title, title, CHATROOM_TITLE_SIZE); @@ -354,7 +354,7 @@ bool chat_kickchat(struct map_session_data* sd, const char* kickusername) { cd = map->id2cd(sd->chatID); - if( cd==NULL || (struct block_list *)sd != cd->owner ) + if (cd == NULL || &sd->bl != cd->owner) return false; ARR_FIND( 0, cd->users, i, strncmp(cd->usersd[i]->status.name, kickusername, NAME_LENGTH) == 0 ); diff --git a/src/map/clif.c b/src/map/clif.c index dbfd71fea..827f57c45 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -192,7 +192,10 @@ static inline void RFIFOPOS2(int fd, unsigned short pos, short* x0, short* y0, s //To identify disguised characters. static inline bool disguised(struct block_list* bl) { - return (bool)(bl->type == BL_PC && ((struct map_session_data *)bl)->disguise != -1); + struct map_session_data *sd = BL_CAST(BL_PC, bl); + if (sd == NULL || sd->disguise == -1) + return false; + return true; } //Guarantees that the given string does not exceeds the allowed size, as well as making sure it's null terminated. [Skotlex] @@ -4532,8 +4535,10 @@ void clif_getareachar_skillunit(struct block_list *bl, struct skill_unit *su, en clif->send(&p,sizeof(p),bl,target); - if(su->group->skill_id == WZ_ICEWALL) - clif->changemapcell(bl->type == BL_PC ? ((struct map_session_data *)bl)->fd : 0, su->bl.m, su->bl.x, su->bl.y, 5, SELF); + if (su->group->skill_id == WZ_ICEWALL) { + struct map_session_data *sd = BL_CAST(BL_PC, bl); + clif->changemapcell(sd != NULL ? sd->fd : 0, su->bl.m, su->bl.x, su->bl.y, 5, SELF); + } } /*========================================== @@ -18654,7 +18659,7 @@ int clif_parse(int fd) { unsigned short (*parse_cmd_func)(int fd, struct map_session_data *sd); // begin main client packet processing loop - sd = (struct map_session_data *)sockt->session[fd]->session_data; + sd = sockt->session[fd]->session_data; if (sockt->session[fd]->flag.eof) { if (sd) { diff --git a/src/map/duel.c b/src/map/duel.c index 8f309abe4..c658ea3e3 100644 --- a/src/map/duel.c +++ b/src/map/duel.c @@ -134,7 +134,7 @@ void duel_invite(const unsigned int did, struct map_session_data* sd, struct map // "Blue -- Player %s invites you to PVP duel (@accept/@reject) --" sprintf(output, msg_sd(target_sd,374), sd->status.name); - clif->broadcast((struct block_list *)target_sd, output, strlen(output)+1, BC_BLUE, SELF); + clif->broadcast(&target_sd->bl, output, strlen(output)+1, BC_BLUE, SELF); } static int duel_leave_sub(struct map_session_data* sd, va_list va) diff --git a/src/map/elemental.c b/src/map/elemental.c index a6fe94ab2..a87deb7d7 100644 --- a/src/map/elemental.c +++ b/src/map/elemental.c @@ -273,9 +273,10 @@ int elemental_data_received(struct s_elemental *ele, bool flag) { db = &elemental->db[i]; if( !sd->ed ) { // Initialize it after first summon. - sd->ed = ed = (struct elemental_data*)aCalloc(1,sizeof(struct elemental_data)); + CREATE(ed, struct elemental_data, 1); ed->bl.type = BL_ELEM; ed->bl.id = npc->get_new_npc_id(); + sd->ed = ed; ed->master = sd; ed->db = db; memcpy(&ed->elemental, ele, sizeof(struct s_elemental)); diff --git a/src/map/guild.c b/src/map/guild.c index d7dcad58f..cba05638f 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -2208,7 +2208,7 @@ void guild_flag_remove(struct npc_data *nd) { continue; if( cursor != i ) { - memmove(&guild->flags[cursor], &guild->flags[i], sizeof(struct npc_data*)); + memmove(&guild->flags[cursor], &guild->flags[i], sizeof(guild->flags[0])); } cursor++; } diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 8ba8ba93b..b642c197f 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -786,9 +786,10 @@ bool homunculus_create(struct map_session_data *sd, struct s_homunculus *hom) { intif->homunculus_requestdelete(hom->hom_id); return false; } - sd->hd = hd = (struct homun_data*)aCalloc(1,sizeof(struct homun_data)); + CREATE(hd, struct homun_data, 1); hd->bl.type = BL_HOM; hd->bl.id = npc->get_new_npc_id(); + sd->hd = hd; hd->master = sd; hd->homunculusDB = &homun->dbs->db[i]; diff --git a/src/map/intif.c b/src/map/intif.c index ed5078088..1968ebe67 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -995,7 +995,7 @@ void intif_parse_WisEnd(int fd) { if (battle_config.etc_log) ShowInfo("intif_parse_wisend: player: %s, flag: %d\n", RFIFOP(fd,2), RFIFOB(fd,26)); // flag: 0: success to send whisper, 1: target character is not logged in?, 2: ignored by target - sd = (struct map_session_data *)map->nick2sd((char *) RFIFOP(fd,2)); + sd = map->nick2sd((char *)RFIFOP(fd,2)); if (sd != NULL) clif->wis_end(sd->fd, RFIFOB(fd,26)); diff --git a/src/map/map.c b/src/map/map.c index 79c314aae..ed171f4bd 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -348,16 +348,17 @@ int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) { #endif if (bl->type&BL_CHAR) { + struct map_session_data *sd = BL_CAST(BL_PC, bl); skill->unit_move(bl,tick,3); - if (bl->type == BL_PC && ((struct map_session_data *)bl)->shadowform_id != 0) { + if (sd != NULL && sd->shadowform_id != 0) { //Shadow Form Target Moving struct block_list *d_bl; - if ((d_bl = map->id2bl(((struct map_session_data *)bl)->shadowform_id)) == NULL || !check_distance_bl(bl,d_bl,10)) { + if ((d_bl = map->id2bl(sd->shadowform_id)) == NULL || !check_distance_bl(bl,d_bl,10)) { if( d_bl ) status_change_end(d_bl,SC__SHADOWFORM,INVALID_TIMER); - ((struct map_session_data *)bl)->shadowform_id = 0; + sd->shadowform_id = 0; } } @@ -393,7 +394,7 @@ int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) { } } /* Guild Aura Moving */ - if (bl->type == BL_PC && ((struct map_session_data *)bl)->state.gmaster_flag) { + if (sd != NULL && sd->state.gmaster_flag) { if (sc->data[SC_LEADERSHIP]) skill->unit_move_unit_group(skill->id2group(sc->data[SC_LEADERSHIP]->val4), bl->m, x1-x0, y1-y0); if (sc->data[SC_GLORYWOUNDS]) @@ -1373,10 +1374,12 @@ int map_get_new_object_id(void) * Timered function to clear the floor (remove remaining item) * Called each flooritem_lifetime ms *------------------------------------------*/ -int map_clearflooritem_timer(int tid, int64 tick, int id, intptr_t data) { - struct flooritem_data* fitem = (struct flooritem_data*)idb_get(map->id_db, id); +int map_clearflooritem_timer(int tid, int64 tick, int id, intptr_t data) +{ + struct block_list *bl = idb_get(map->id_db, id); + struct flooritem_data *fitem = BL_CAST(BL_ITEM, bl); - if (fitem == NULL || fitem->bl.type != BL_ITEM || (fitem->cleartimer != tid)) { + if (fitem == NULL || fitem->cleartimer != tid) { ShowError("map_clearflooritem_timer : error\n"); return 1; } @@ -1394,8 +1397,11 @@ int map_clearflooritem_timer(int tid, int64 tick, int id, intptr_t data) { /* * clears a single bl item out of the bazooonga. */ -void map_clearflooritem(struct block_list *bl) { - struct flooritem_data* fitem = (struct flooritem_data*)bl; +void map_clearflooritem(struct block_list *bl) +{ + struct flooritem_data *fitem = BL_CAST(BL_ITEM, bl); + + nullpo_retv(fitem); if( fitem->cleartimer != INVALID_TIMER ) timer->delete(fitem->cleartimer,map->clearflooritem_timer); @@ -2099,7 +2105,9 @@ const char *map_charid2nick(int charid) { /// Returns the struct map_session_data of the charid or NULL if the char is not online. struct map_session_data* map_charid2sd(int charid) { - return (struct map_session_data*)idb_get(map->charid_db, charid); + struct block_list *bl = idb_get(map->charid_db, charid); + Assert_retr(NULL, bl->type == BL_PC); + return BL_UCAST(BL_PC, bl); } /*========================================== @@ -2173,10 +2181,14 @@ struct mob_data * map_getmob_boss(int16 m) return (found)? md : NULL; } -struct mob_data * map_id2boss(int id) +struct mob_data *map_id2boss(int id) { - if (id <= 0) return NULL; - return (struct mob_data*)idb_get(map->bossid_db,id); + struct block_list *bl = NULL; + if (id <= 0) + return NULL; + bl = idb_get(map->bossid_db,id); + Assert_retr(NULL, bl->type == BL_MOB); + return BL_UCAST(BL_MOB, bl); } /** diff --git a/src/map/mercenary.c b/src/map/mercenary.c index fb801a8da..e6c911ef6 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -317,10 +317,11 @@ int merc_data_received(struct s_mercenary *merc, bool flag) { db = &mercenary->db[i]; if( !sd->md ) { - sd->md = md = (struct mercenary_data*)aCalloc(1,sizeof(struct mercenary_data)); + CREATE(md, struct mercenary_data, 1); md->bl.type = BL_MER; md->bl.id = npc->get_new_npc_id(); md->devotion_flag = 0; + sd->md = md; md->master = sd; md->db = db; diff --git a/src/map/mob.c b/src/map/mob.c index 708a2900b..37da81a15 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -274,7 +274,8 @@ int mob_parse_dataset(struct spawn_data *data) * Generates the basic mob data using the spawn_data provided. *------------------------------------------*/ struct mob_data* mob_spawn_dataset(struct spawn_data *data) { - struct mob_data *md = (struct mob_data*)aCalloc(1, sizeof(struct mob_data)); + struct mob_data *md = NULL; + CREATE(md, struct mob_data, 1); md->bl.id= npc->get_new_npc_id(); md->bl.type = BL_MOB; md->bl.m = data->m; @@ -591,12 +592,9 @@ int mob_spawn_guardian_sub(int tid, int64 tick, int id, intptr_t data) { if( bl == NULL ) //It is possible mob was already removed from map when the castle has no owner. [Skotlex] return 0; - if( bl->type != BL_MOB ) { - ShowError("mob_spawn_guardian_sub: Block error!\n"); - return 0; - } + Assert_ret(bl->type == BL_MOB); + md = BL_UCAST(BL_MOB, bl); - md = (struct mob_data*)bl; nullpo_ret(md->guardian_data); g = guild->search((int)data); @@ -684,11 +682,9 @@ int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobnam if( has_index && gc->guardian[guardian].id ) { //Check if guardian already exists, refuse to spawn if so. - struct mob_data *md2 = (struct mob_data *)map->id2bl(gc->guardian[guardian].id); - if (md2 && md2->bl.type == BL_MOB - && md2->guardian_data - && md2->guardian_data->number == guardian - ) { + struct block_list *bl2 = map->id2bl(gc->guardian[guardian].id); // TODO: Why does this not use map->id2md? + struct mob_data *md2 = BL_CAST(BL_MOB, bl2); + if (md2 != NULL && md2->guardian_data != NULL && md2->guardian_data->number == guardian) { ShowError("mob_spawn_guardian: Attempted to spawn guardian in position %d which already has a guardian (castle map %s)\n", guardian, map->list[m].name); return 0; } @@ -1436,14 +1432,13 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) { if (md->target_id) { //Check validity of current target. [Skotlex] + struct map_session_data *tsd = NULL; tbl = map->id2bl(md->target_id); - if (!tbl || tbl->m != md->bl.m + tsd = BL_CAST(BL_PC, tbl); + if (tbl == NULL || tbl->m != md->bl.m || (md->ud.attacktimer == INVALID_TIMER && !status->check_skilluse(&md->bl, tbl, 0, 0)) || (md->ud.walktimer != INVALID_TIMER && !(battle_config.mob_ai&0x1) && !check_distance_bl(&md->bl, tbl, md->min_chase)) - || (tbl->type == BL_PC - && ((((struct map_session_data *)tbl)->state.gangsterparadise && !(mode&MD_BOSS)) - || ((struct map_session_data *)tbl)->invincible_timer != INVALID_TIMER) - ) + || (tsd != NULL && ((tsd->state.gangsterparadise && !(mode&MD_BOSS)) || tsd->invincible_timer != INVALID_TIMER)) ) { //No valid target if (mob->warpchase(md, tbl)) @@ -2099,9 +2094,9 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage) { *------------------------------------------*/ int mob_dead(struct mob_data *md, struct block_list *src, int type) { struct status_data *mstatus; - struct map_session_data *sd = NULL; + struct map_session_data *sd = BL_CAST(BL_PC, src); struct map_session_data *tmpsd[DAMAGELOG_SIZE] = { NULL }; - struct map_session_data *mvp_sd = NULL, *second_sd = NULL, *third_sd = NULL; + struct map_session_data *mvp_sd = sd, *second_sd = NULL, *third_sd = NULL; struct { struct party_data *p; @@ -2116,12 +2111,6 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { mstatus = &md->status; - if( src && src->type == BL_PC ) - { - sd = (struct map_session_data *)src; - mvp_sd = sd; - } - if( md->guardian_data && md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS ) guild->castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0); diff --git a/src/map/npc.c b/src/map/npc.c index 6d495e531..411e52c29 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -277,9 +277,9 @@ int npc_enable(const char* name, int flag) /*========================================== * NPC lookup (get npc_data through npcname) *------------------------------------------*/ -struct npc_data* npc_name2id(const char* name) +struct npc_data *npc_name2id(const char *name) { - return (struct npc_data *) strdb_get(npc->name_db, name); + return strdb_get(npc->name_db, name); } /** * For the Secure NPC Timeout option (check config/Secure.h) [RR] @@ -1170,13 +1170,13 @@ int npc_check_areanpc(int flag, int16 m, int16 x, int16 y, int16 range) { *------------------------------------------*/ struct npc_data* npc_checknear(struct map_session_data* sd, struct block_list* bl) { - struct npc_data *nd; + struct npc_data *nd = BL_CAST(BL_NPC, bl); int distance = AREA_SIZE + 1; nullpo_retr(NULL, sd); - if (bl == NULL) return NULL; - if (bl->type != BL_NPC) return NULL; - nd = (struct npc_data *)bl; + + if (nd == NULL) + return NULL; if (sd->npc_id == bl->id) return nd; @@ -2288,10 +2288,11 @@ int npc_unload(struct npc_data* nd, bool single) if( single && nd->bl.m != -1 ) map->remove_questinfo(nd->bl.m,nd); - if( nd->src_id == 0 && ( nd->subtype == SHOP || nd->subtype == CASHSHOP ) ) //src check for duplicate shops [Orcao] + if (nd->src_id == 0 && ( nd->subtype == SHOP || nd->subtype == CASHSHOP)) { + //src check for duplicate shops [Orcao] aFree(nd->u.shop.shop_item); - else if( nd->subtype == SCRIPT ) { - struct s_mapiterator* iter; + } else if (nd->subtype == SCRIPT) { + struct s_mapiterator *iter; struct map_session_data *sd = NULL; if( single ) { @@ -2301,7 +2302,7 @@ int npc_unload(struct npc_data* nd, bool single) iter = mapit_geteachpc(); for (sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) { - if( sd && sd->npc_timer_id != INVALID_TIMER ) { + if (sd->npc_timer_id != INVALID_TIMER ) { const struct TimerData *td = timer->get(sd->npc_timer_id); if( td && td->id != nd->bl.id ) @@ -4889,7 +4890,7 @@ int do_init_npc(bool minimal) { } // Init dummy NPC - npc->fake_nd = (struct npc_data *)aCalloc(1,sizeof(struct npc_data)); + CREATE(npc->fake_nd, struct npc_data, 1); npc->fake_nd->bl.m = -1; npc->fake_nd->bl.id = npc->get_new_npc_id(); npc->fake_nd->class_ = FAKE_NPC; diff --git a/src/map/party.c b/src/map/party.c index 320370c33..a3e59c281 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -955,8 +955,8 @@ int party_exp_share(struct party_data* p, struct block_list* src, unsigned int b for (i = 0; i < c; i++) { #ifdef RENEWAL_EXP - if (!(src != NULL && src->type == BL_MOB && ((struct mob_data *)src)->db->mexp)) { - struct mob_data *md = (struct mob_data *)src; + struct mob_data *md = BL_CAST(BL_MOB, src); + if (md != NULL && md->db->mexp == 0) { int rate = pc->level_penalty_mod(md->level - (sd[i])->status.base_level, md->status.race, md->status.mode, 1); base_exp = (unsigned int)cap_value(base_exp_bonus * rate / 100, 1, UINT_MAX); diff --git a/src/map/pc.c b/src/map/pc.c index 960001d37..2dfd9519b 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5261,15 +5261,13 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil int i,itemid,flag; double rate; struct status_data *sd_status, *md_status; - struct mob_data *md; + struct mob_data *md = BL_CAST(BL_MOB, bl); struct item tmp_item; struct item_data *data = NULL; - if(!sd || !bl || bl->type!=BL_MOB) + if (sd == NULL || md == NULL) return 0; - md = (struct mob_data *)bl; - if(md->state.steal_flag == UCHAR_MAX || ( md->sc.opt1 && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE ) ) //already stolen from / status change check return 0; @@ -5341,12 +5339,11 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil **/ int pc_steal_coin(struct map_session_data *sd, struct block_list *target) { int rate, skill_lv; - struct mob_data *md; + struct mob_data *md = BL_CAST(BL_MOB, target); - if (!sd || !target || target->type != BL_MOB) + if (sd == NULL || md == NULL) return 0; - md = (struct mob_data *)target; if (md->state.steal_coin_flag || md->sc.data[SC_STONE] || md->sc.data[SC_FREEZE] || md->status.mode&MD_BOSS) return 0; diff --git a/src/map/pet.c b/src/map/pet.c index 501dc8c27..db8d0d1f1 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -359,9 +359,10 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *petinfo) sd->status.pet_id = 0; return 1; } - sd->pd = pd = (struct pet_data *)aCalloc(1,sizeof(struct pet_data)); + CREATE(pd, struct pet_data, 1); pd->bl.type = BL_PET; pd->bl.id = npc->get_new_npc_id(); + sd->pd = pd; pd->msd = sd; pd->petDB = &pet->db[i]; @@ -505,13 +506,15 @@ int pet_catch_process1(struct map_session_data *sd,int target_class) } int pet_catch_process2(struct map_session_data* sd, int target_id) { - struct mob_data* md; + struct mob_data *md = NULL; + struct block_list *bl = NULL; int i = 0, pet_catch_rate = 0; nullpo_retr(1, sd); - md = (struct mob_data*)map->id2bl(target_id); - if(!md || md->bl.type != BL_MOB || md->bl.prev == NULL) { + bl = map->id2bl(target_id); // TODO: Why does this not use map->id2md? + md = BL_CAST(BL_MOB, bl); + if (md == NULL || md->bl.prev == NULL) { // Invalid inputs/state, abort capture. clif->pet_roulette(sd,0); sd->catch_target_class = -1; diff --git a/src/map/script.c b/src/map/script.c index 7581531da..befb85304 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10395,7 +10395,15 @@ BUILDIN(announce) { if( flag&(BC_TARGET_MASK|BC_SOURCE_MASK) ) { // Broadcast source or broadcast region defined send_target target; - struct block_list *bl = (flag&BC_NPC) ? map->id2bl(st->oid) : (struct block_list *)script->rid2sd(st); // If bc_npc flag is set, use NPC as broadcast source + struct block_list *bl = NULL; + if (flag&BC_NPC) { + // If bc_npc flag is set, use NPC as broadcast source + bl = map->id2bl(st->oid); + } else { + struct map_session_data *sd = script->rid2sd(st); + if (sd != NULL) + bl = &sd->bl; + } if (bl == NULL) return true; @@ -17614,15 +17622,15 @@ BUILDIN(bg_monster) return true; } -BUILDIN(bg_monster_set_team) { - struct mob_data *md; - struct block_list *mbl; +BUILDIN(bg_monster_set_team) +{ int id = script_getnum(st,2), bg_id = script_getnum(st,3); + struct block_list *mbl = map->id2bl(id); // TODO: Why does this not use map->id2md? + struct mob_data *md = BL_CAST(BL_MOB, mbl); - if( (mbl = map->id2bl(id)) == NULL || mbl->type != BL_MOB ) + if (md == NULL) return true; - md = (struct mob_data *)mbl; md->bg_id = bg_id; mob_stop_attack(md); diff --git a/src/map/skill.c b/src/map/skill.c index 4632ca541..8414ac638 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -260,6 +260,7 @@ int skill_get_casttype2 (uint16 index) { //Returns actual skill range taking into account attack range and AC_OWL [Skotlex] int skill_get_range2 (struct block_list *bl, uint16 skill_id, uint16 skill_lv) { int range; + struct map_session_data *sd = BL_CAST(BL_PC, bl); if( bl->type == BL_MOB && battle_config.mob_ai&0x400 ) return 9; //Mobs have a range of 9 regardless of skill used. @@ -288,8 +289,8 @@ int skill_get_range2 (struct block_list *bl, uint16 skill_id, uint16 skill_lv) { case RA_ARROWSTORM: case RA_AIMEDBOLT: case RA_WUGBITE: - if (bl->type == BL_PC) - range += pc->checkskill((struct map_session_data *)bl, AC_VULTURE); + if (sd != NULL) + range += pc->checkskill(sd, AC_VULTURE); else range += 10; //Assume level 10? break; @@ -299,14 +300,14 @@ int skill_get_range2 (struct block_list *bl, uint16 skill_id, uint16 skill_lv) { case GS_FULLBUSTER: case GS_SPREADATTACK: case GS_GROUNDDRIFT: - if (bl->type == BL_PC) - range += pc->checkskill((struct map_session_data *)bl, GS_SNAKEEYE); + if (sd != NULL) + range += pc->checkskill(sd, GS_SNAKEEYE); else range += 10; //Assume level 10? break; case NJ_KIRIKAGE: - if (bl->type == BL_PC) - range = skill->get_range(NJ_SHADOWJUMP, pc->checkskill((struct map_session_data *)bl, NJ_SHADOWJUMP)); + if (sd != NULL) + range = skill->get_range(NJ_SHADOWJUMP, pc->checkskill(sd, NJ_SHADOWJUMP)); break; /** * Warlock @@ -323,8 +324,8 @@ int skill_get_range2 (struct block_list *bl, uint16 skill_id, uint16 skill_lv) { case WL_TETRAVORTEX: case WL_EARTHSTRAIN: case WL_RELEASE: - if (bl->type == BL_PC) - range += pc->checkskill((struct map_session_data *)bl, WL_RADIUS); + if (sd != NULL) + range += pc->checkskill(sd, WL_RADIUS); break; /** * Ranger Bonus @@ -336,8 +337,8 @@ int skill_get_range2 (struct block_list *bl, uint16 skill_id, uint16 skill_lv) { case RA_CLUSTERBOMB: case RA_FIRINGTRAP: case RA_ICEBOUNDTRAP: - if (bl->type == BL_PC) - range += (1 + pc->checkskill((struct map_session_data *)bl, RA_RESEARCHTRAP))/2; + if (sd != NULL) + range += (1 + pc->checkskill(sd, RA_RESEARCHTRAP))/2; } if( !range && bl->type != BL_PC ) @@ -2773,11 +2774,11 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr if( sc && sc->data[SC_DEVOTION] && skill_id != PA_PRESSURE ) { struct status_change_entry *sce = sc->data[SC_DEVOTION]; struct block_list *d_bl = map->id2bl(sce->val1); + struct mercenary_data *d_md = BL_CAST(BL_MER, d_bl); + struct map_session_data *d_sd = BL_CAST(BL_PC, d_bl); if (d_bl != NULL - && ((d_bl->type == BL_MER && ((struct mercenary_data *)d_bl)->master && ((struct mercenary_data *)d_bl)->master->bl.id == bl->id) - || (d_bl->type == BL_PC && ((struct map_session_data *)d_bl)->devotion[sce->val2] == bl->id) - ) + && ((d_md != NULL && d_md->master && d_md->master->bl.id == bl->id) || (d_sd != NULL && d_sd->devotion[sce->val2] == bl->id)) && check_distance_bl(bl, d_bl, sce->val3) ) { if(!rmdamage){ @@ -5581,24 +5582,24 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin abra_skill_lv = min(skill_lv, skill->get_max(abra_skill_id)); clif->skill_nodamage (src, bl, skill_id, skill_lv, 1); - if( sd ) - {// player-casted + if (sd) { + // player-casted sd->state.abra_flag = 1; sd->skillitem = abra_skill_id; sd->skillitemlv = abra_skill_lv; clif->item_skill(sd, abra_skill_id, abra_skill_lv); - } - else - {// mob-casted + } else { + // mob-casted struct unit_data *ud = unit->bl2ud(src); int inf = skill->get_inf(abra_skill_id); - if (!ud) break; + if (ud == NULL) + break; if (inf&INF_SELF_SKILL || inf&INF_SUPPORT_SKILL) { - if (src->type == BL_PET) - bl = (struct block_list *)((struct pet_data *)src)->msd; - if (bl == NULL) - bl = src; - unit->skilluse_id(src, bl->id, abra_skill_id, abra_skill_lv); + int id = src->id; + struct pet_data *pd = BL_CAST(BL_PET, src); + if (pd != NULL && pd->msd != NULL) + id = pd->msd->bl.id; + unit->skilluse_id(src, id, abra_skill_id, abra_skill_lv); } else { //Assume offensive skills int target_id = 0; if (ud->target) @@ -9273,7 +9274,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin improv_skill_lv = 4 + skill_lv; clif->skill_nodamage (src, bl, skill_id, skill_lv, 1); - if( sd ) { + if (sd == NULL) { sd->state.abra_flag = 2; sd->skillitem = improv_skill_id; sd->skillitemlv = improv_skill_lv; @@ -9281,13 +9282,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } else { struct unit_data *ud = unit->bl2ud(src); int inf = skill->get_inf(improv_skill_id); - if (!ud) break; + if (ud == NULL) + break; if (inf&INF_SELF_SKILL || inf&INF_SUPPORT_SKILL) { - if (src->type == BL_PET) - bl = (struct block_list *)((struct pet_data *)src)->msd; - if (bl == NULL) - bl = src; - unit->skilluse_id(src, bl->id, improv_skill_id, improv_skill_lv); + int id = src->id; + struct pet_data *pd = BL_CAST(BL_PET, src); + if (pd != NULL && pd->msd != NULL) + id = pd->msd->bl.id; + unit->skilluse_id(src, id, improv_skill_id, improv_skill_lv); } else { int target_id = 0; if (ud->target) { @@ -11170,10 +11172,13 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ limit=2000; } else { // previous implementation (not used anymore) //Warp Portal morphing to active mode, extract relevant data from src. [Skotlex] - if( src->type != BL_SKILL ) return NULL; - group = ((struct skill_unit *)src)->group; + struct skill_unit *su = BL_CAST(BL_SKILL, src); + if (su == NULL) + return NULL; + group = su->group; src = map->id2bl(group->src_id); - if( !src ) return NULL; + if (src == NULL) + return NULL; val2 = group->val2; //Copy the (x,y) position you warp to val3 = group->val3; //as well as the mapindex to warp to. } @@ -16036,6 +16041,7 @@ bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit) if (sc && sc->data[SC__SHADOWFORM] && damage) { struct block_list *src = map->id2bl(sc->data[SC__SHADOWFORM]->val2); + struct map_session_data *sd = BL_CAST(BL_PC, src); if( !src || src->m != bl->m ) { status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); @@ -16043,8 +16049,8 @@ bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit) } if( src && (status->isdead(src) || !battle->check_target(bl,src,BCT_ENEMY)) ){ - if( src->type == BL_PC ) - ((struct map_session_data *)src)->shadowform_id = 0; + if (sd != NULL) + sd->shadowform_id = 0; status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); return false; } @@ -16054,8 +16060,8 @@ bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit) /* because damage can cancel it */ if( sc->data[SC__SHADOWFORM] && (--sc->data[SC__SHADOWFORM]->val3) <= 0 ) { status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); - if( src->type == BL_PC ) - ((struct map_session_data *)src)->shadowform_id = 0; + if (sd != NULL) + sd->shadowform_id = 0; } return true; } @@ -16252,7 +16258,7 @@ struct skill_unit_group* skill_initunitgroup (struct block_list* src, int count, group->guild_id = status->get_guild_id(src); group->bg_id = bg->team_get_id(src); group->group_id = skill->get_new_group_id(); - group->unit.data = (struct skill_unit *)aCalloc(count,sizeof(struct skill_unit)); + CREATE(group->unit.data, struct skill_unit, 1); group->unit.count = count; group->alive_count = 0; group->val1 = 0; @@ -16279,24 +16285,27 @@ struct skill_unit_group* skill_initunitgroup (struct block_list* src, int count, /*========================================== * *------------------------------------------*/ -int skill_delunitgroup(struct skill_unit_group *group, const char* file, int line, const char* func) { +int skill_delunitgroup(struct skill_unit_group *group, const char *file, int line, const char *func) +{ struct block_list* src; struct unit_data *ud; int i,j; + struct map_session_data *sd = NULL; if( group == NULL ) { ShowDebug("skill_delunitgroup: group is NULL (source=%s:%d, %s)! Please report this! (#3504)\n", file, line, func); return 0; } - src=map->id2bl(group->src_id); + src = map->id2bl(group->src_id); ud = unit->bl2ud(src); - if(!src || !ud) { + sd = BL_CAST(BL_PC, src); + if (src == NULL || ud == NULL) { ShowError("skill_delunitgroup: Group's source not found! (src_id: %d skill_id: %d)\n", group->src_id, group->skill_id); return 0; } - if (src->type == BL_PC && !status->isdead(src) && ((struct map_session_data *)src)->state.warping && !((struct map_session_data *)src)->state.changemap) { + if (sd != NULL && !status->isdead(src) && sd->state.warping && !sd->state.changemap) { switch( group->skill_id ) { case BA_DISSONANCE: case BA_POEMBRAGI: @@ -16308,7 +16317,7 @@ int skill_delunitgroup(struct skill_unit_group *group, const char* file, int lin case DC_DONTFORGETME: case DC_FORTUNEKISS: case DC_SERVICEFORYOU: - skill->usave_add((struct map_session_data *)src, group->skill_id, group->skill_lv); + skill->usave_add(sd, group->skill_id, group->skill_lv); break; } } @@ -16373,8 +16382,8 @@ int skill_delunitgroup(struct skill_unit_group *group, const char* file, int lin break; } - if (src->type==BL_PC && group->state.ammo_consume) - battle->consume_ammo((struct map_session_data *)src, group->skill_id, group->skill_lv); + if (sd != NULL && group->state.ammo_consume) + battle->consume_ammo(sd, group->skill_id, group->skill_lv); group->alive_count=0; diff --git a/src/map/status.c b/src/map/status.c index a4cb85d66..c755d8eb0 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1350,11 +1350,12 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, #ifdef DEVOTION_REFLECT_DAMAGE if (src && (sce = sc->data[SC_DEVOTION]) != NULL) { struct block_list *d_bl = map->id2bl(sce->val1); + struct mercenary_data *d_md = BL_CAST(BL_MER, d_bl); + struct map_session_data *d_sd = BL_CAST(BL_PC, d_bl); if (d_bl != NULL - && ((d_bl->type == BL_MER && ((struct mercenary_data *)d_bl)->master && ((struct mercenary_data *)d_bl)->master->bl.id == target->id) - || (d_bl->type == BL_PC && ((struct map_session_data *)d_bl)->devotion[sce->val2] == target->id) - ) + && ((d_md != NULL && d_md->master != NULL && d_md->master->bl.id == target->id) + || (d_sd != NULL && d_sd->devotion[sce->val2] == target->id)) && check_distance_bl(target, d_bl, sce->val3) ) { clif->damage(d_bl, d_bl, 0, 0, hp, 0, BDT_NORMAL, 0); @@ -1739,10 +1740,11 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin struct status_data *st; struct status_change *sc=NULL, *tsc; int hide_flag; + struct map_session_data *sd = BL_CAST(BL_PC, src); st = src ? status->get_status_data(src) : &status->dummy; - if (src && src->type != BL_PC && status->isdead(src)) + if (src != NULL && src->type != BL_PC && status->isdead(src)) return 0; if (!skill_id) { //Normal attack checks. @@ -1757,15 +1759,14 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin } if( skill_id ) { - - if (src != NULL && !(src->type == BL_PC && ((struct map_session_data *)src)->skillitem)) { + if (src != NULL && (sd == NULL || sd->skillitem == 0)) { // Items that cast skills using 'itemskill' will not be handled by map_zone_db. int i; for(i = 0; i < map->list[src->m].zone->disabled_skills_count; i++) { if( skill_id == map->list[src->m].zone->disabled_skills[i]->nameid && (map->list[src->m].zone->disabled_skills[i]->type&src->type) ) { if (src->type == BL_PC) { - clif->msgtable((struct map_session_data *)src, MSG_SKILL_CANT_USE_AREA); // This skill cannot be used within this area + clif->msgtable(sd, MSG_SKILL_CANT_USE_AREA); // This skill cannot be used within this area } else if (src->type == BL_MOB && map->list[src->m].zone->disabled_skills[i]->subtype != MZS_NONE) { if( st->mode&MD_BOSS ) { /* is boss */ if( !( map->list[src->m].zone->disabled_skills[i]->subtype&MZS_BOSS ) ) @@ -1798,7 +1799,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin if (src != NULL && map->getcell(src->m, src, src->x, src->y, CELL_CHKLANDPROTECTOR) && !(st->mode&MD_BOSS) - && (src->type != BL_PC || ((struct map_session_data *)src)->skillitem != skill_id)) + && (src->type != BL_PC || sd->skillitem != skill_id)) return 0; break; default: @@ -1828,7 +1829,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin struct block_list *winkcharm_target = map->id2bl(sc->data[SC_DC_WINKCHARM]->val2); if (winkcharm_target != NULL) { if (unit->bl2ud(src) && (unit->bl2ud(src))->walktimer == INVALID_TIMER) - unit->walktobl(src, map->id2bl(sc->data[SC_DC_WINKCHARM]->val2), 3, 1); + unit->walktobl(src, winkcharm_target, 3, 1); clif->emotion(src, E_LV); return 0; } else { @@ -1850,7 +1851,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin if (sc->data[SC_DANCING] && flag!=2) { if (src->type == BL_PC && skill_id >= WA_SWING_DANCE && skill_id <= WM_UNLIMITED_HUMMING_VOICE) { // Lvl 5 Lesson or higher allow you use 3rd job skills while dancing.v - if (pc->checkskill((struct map_session_data *)src, WM_LESSON) < 5) + if (pc->checkskill(sd, WM_LESSON) < 5) return 0; } else if(sc->data[SC_LONGING]) { //Allow everything except dancing/re-dancing. [Skotlex] if (skill_id == BD_ENCORE || @@ -1872,48 +1873,45 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin return 0; //Can't amp out of Wand of Hermode :/ [Skotlex] } - if (skill_id != 0 //Do not block item-casted skills. - && (src->type != BL_PC || ((struct map_session_data *)src)->skillitem != skill_id) - ) { + if (skill_id != 0 /* Do not block item-casted skills.*/ && (src->type != BL_PC || sd->skillitem != skill_id)) { //Skills blocked through status changes... - if (!flag && ( //Blocked only from using the skill (stuff like autospell may still go through - sc->data[SC_SILENCE] || - sc->data[SC_STEELBODY] || - sc->data[SC_BERSERK] || - sc->data[SC_OBLIVIONCURSE] || - sc->data[SC_WHITEIMPRISON] || - sc->data[SC__INVISIBILITY] || - (sc->data[SC_COLD] && src->type != BL_MOB) || - sc->data[SC__IGNORANCE] || - sc->data[SC_DEEP_SLEEP] || - sc->data[SC_SATURDAY_NIGHT_FEVER] || - sc->data[SC_CURSEDCIRCLE_TARGET] || - (sc->data[SC_MARIONETTE_MASTER] && skill_id != CG_MARIONETTE) || //Only skill you can use is marionette again to cancel it - (sc->data[SC_MARIONETTE] && 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)) || - (sc->data[SC_KG_KAGEHUMI] && skill->block_check(src, SC_KG_KAGEHUMI, skill_id)) - )) - return 0; + if (!flag && ( //Blocked only from using the skill (stuff like autospell may still go through + sc->data[SC_SILENCE] || + sc->data[SC_STEELBODY] || + sc->data[SC_BERSERK] || + sc->data[SC_OBLIVIONCURSE] || + sc->data[SC_WHITEIMPRISON] || + sc->data[SC__INVISIBILITY] || + (sc->data[SC_COLD] && src->type != BL_MOB) || + sc->data[SC__IGNORANCE] || + sc->data[SC_DEEP_SLEEP] || + sc->data[SC_SATURDAY_NIGHT_FEVER] || + sc->data[SC_CURSEDCIRCLE_TARGET] || + (sc->data[SC_MARIONETTE_MASTER] && skill_id != CG_MARIONETTE) || //Only skill you can use is marionette again to cancel it + (sc->data[SC_MARIONETTE] && 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)) || + (sc->data[SC_KG_KAGEHUMI] && skill->block_check(src, SC_KG_KAGEHUMI, skill_id)) + )) + return 0; - //Skill blocking. - if ( - (sc->data[SC_VOLCANO] && skill_id == WZ_ICEWALL) || - (sc->data[SC_ROKISWEIL] && skill_id != BD_ADAPTATION) || - (sc->data[SC_HERMODE] && skill->get_inf(skill_id) & INF_SUPPORT_SKILL) || - pc_ismuted(sc, MANNER_NOSKILL) - ) - return 0; + //Skill blocking. + if ( + (sc->data[SC_VOLCANO] && skill_id == WZ_ICEWALL) || + (sc->data[SC_ROKISWEIL] && skill_id != BD_ADAPTATION) || + (sc->data[SC_HERMODE] && skill->get_inf(skill_id) & INF_SUPPORT_SKILL) || + pc_ismuted(sc, MANNER_NOSKILL) + ) + return 0; - if( sc->data[SC__MANHOLE] || ((tsc = status->get_sc(target)) && tsc->data[SC__MANHOLE]) ) { - switch(skill_id) {//##TODO## make this a flag in skill_db? - // Skills that can be used even under Man Hole effects. - case SC_SHADOWFORM: - break; - default: - return 0; - } + if( sc->data[SC__MANHOLE] || ((tsc = status->get_sc(target)) && tsc->data[SC__MANHOLE]) ) { + switch(skill_id) {//##TODO## make this a flag in skill_db? + // Skills that can be used even under Man Hole effects. + case SC_SHADOWFORM: + break; + default: + return 0; } - + } } } @@ -2065,7 +2063,7 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) { return 0; } if (!md->base_status) - md->base_status = (struct status_data*)aCalloc(1, sizeof(struct status_data)); + CREATE(md->base_status, struct status_data, 1); mstatus = md->base_status; memcpy(mstatus, &md->db->status, sizeof(struct status_data)); diff --git a/src/map/unit.c b/src/map/unit.c index 53d0a9bf4..03334f7f3 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -93,9 +93,10 @@ struct unit_data* unit_bl2ud(struct block_list *bl) * @param bl block_list to process * @return a pointer to the given object's unit_data */ -struct unit_data* unit_bl2ud2(struct block_list *bl) { - if( bl && bl->type == BL_NPC && ((struct npc_data*)bl)->ud == &npc->base_ud ) { - struct npc_data *nd = (struct npc_data *)bl; +struct unit_data *unit_bl2ud2(struct block_list *bl) +{ + struct npc_data *nd = BL_CAST(BL_NPC, bl); + if (nd != NULL && nd->ud == &npc->base_ud) { nd->ud = NULL; CREATE(nd->ud, struct unit_data, 1); unit->dataset(&nd->bl); @@ -1261,13 +1262,17 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui break; case WE_MALE: case WE_FEMALE: + { + struct map_session_data *p_sd = NULL; if (!sd->status.partner_id) return 0; - target = (struct block_list*)map->charid2sd(sd->status.partner_id); - if (!target) { + p_sd = map->charid2sd(sd->status.partner_id); + if (p_sd == NULL) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } + target = &p_sd->bl; + } break; case GC_WEAPONCRUSH: if( sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == GC_WEAPONBLOCKING ) { |