summaryrefslogtreecommitdiff
path: root/src/map/mob.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/mob.c')
-rw-r--r--src/map/mob.c160
1 files changed, 78 insertions, 82 deletions
diff --git a/src/map/mob.c b/src/map/mob.c
index 16b5417b9..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 = (TBL_MOB*)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;
}
@@ -794,17 +790,16 @@ int mob_can_reach(struct mob_data *md,struct block_list *bl,int range, int state
/*==========================================
* Links nearby mobs (supportive mobs)
*------------------------------------------*/
-int mob_linksearch(struct block_list *bl,va_list ap) {
- struct mob_data *md;
- int class_;
- struct block_list *target;
- int64 tick;
+int mob_linksearch(struct block_list *bl,va_list ap)
+{
+ struct mob_data *md = NULL;
+ int class_ = va_arg(ap, int);
+ struct block_list *target = va_arg(ap, struct block_list *);
+ int64 tick = va_arg(ap, int64);
nullpo_ret(bl);
- md=(struct mob_data *)bl;
- class_ = va_arg(ap, int);
- target = va_arg(ap, struct block_list *);
- tick = va_arg(ap, int64);
+ Assert_ret(bl->type == BL_MOB);
+ md = BL_UCAST(BL_MOB, bl);
if (md->class_ == class_ && DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME
&& !md->target_id)
@@ -825,7 +820,7 @@ int mob_linksearch(struct block_list *bl,va_list ap) {
* mob spawn with delay (timer function)
*------------------------------------------*/
int mob_delayspawn(int tid, int64 tick, int id, intptr_t data) {
- struct block_list* bl = map->id2bl(id);
+ struct block_list* bl = map->id2bl(id); // TODO: Why does this not use map->bl2md?
struct mob_data* md = BL_CAST(BL_MOB, bl);
if( md )
@@ -889,7 +884,7 @@ int mob_count_sub(struct block_list *bl, va_list ap) {
int mobid[10] = { 0 }, i;
ARR_FIND(0, 10, i, (mobid[i] = va_arg(ap, int)) == 0); //fetch till 0
if (mobid[0]) { //if there one let's check it otherwise go backward
- TBL_MOB *md = BL_CAST(BL_MOB, bl);
+ struct mob_data *md = BL_CAST(BL_MOB, bl);
nullpo_ret(md);
ARR_FIND(0, 10, i, md->class_ == mobid[i]);
return (i < 10) ? 1 : 0;
@@ -1073,8 +1068,7 @@ int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
switch (bl->type) {
case BL_PC:
- if (((TBL_PC*)bl)->state.gangsterparadise &&
- !(status_get_mode(&md->bl)&MD_BOSS))
+ if (BL_UCCAST(BL_PC, bl)->state.gangsterparadise && !(status_get_mode(&md->bl)&MD_BOSS))
return 0; //Gangster paradise protection.
default:
if (battle_config.hom_setting&0x4 &&
@@ -1174,17 +1168,15 @@ int mob_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap)
}
int mob_warpchase_sub(struct block_list *bl,va_list ap) {
- struct block_list *target;
- struct npc_data **target_nd;
- struct npc_data *nd;
- int *min_distance;
int cur_distance;
+ struct block_list *target = va_arg(ap, struct block_list *);
+ struct npc_data **target_nd = va_arg(ap, struct npc_data **);
+ int *min_distance = va_arg(ap, int *);
+ struct npc_data *nd = NULL;
- target= va_arg(ap, struct block_list*);
- target_nd= va_arg(ap, struct npc_data**);
- min_distance= va_arg(ap, int*);
-
- nd = (TBL_NPC*) bl;
+ nullpo_ret(bl);
+ Assert_ret(bl->type == BL_NPC);
+ nd = BL_UCAST(BL_NPC, bl);
if(nd->subtype != WARP)
return 0; //Not a warp
@@ -1440,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
- && ((((TBL_PC*)tbl)->state.gangsterparadise && !(mode&MD_BOSS))
- || ((TBL_PC*)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))
@@ -1580,7 +1571,7 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
//Target exists, attack or loot as applicable.
if (tbl->type == BL_ITEM) {
//Loot time.
- struct flooritem_data *fitem;
+ struct flooritem_data *fitem = BL_UCAST(BL_ITEM, tbl);
if (md->ud.target == tbl->id && md->ud.walktimer != INVALID_TIMER)
return true; //Already locked.
if (md->lootitem == NULL) {
@@ -1606,7 +1597,6 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
if (md->ud.attacktimer != INVALID_TIMER)
return true; //Busy attacking?
- fitem = (struct flooritem_data *)tbl;
//Logs items, taken by (L)ooter Mobs [Lupus]
logs->pick_mob(md, LOG_TYPE_LOOT, fitem->item_data.amount, &fitem->item_data, NULL);
@@ -1687,9 +1677,15 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
return true;
}
-int mob_ai_sub_hard_timer(struct block_list *bl, va_list ap) {
- struct mob_data *md = (struct mob_data*)bl;
+int mob_ai_sub_hard_timer(struct block_list *bl, va_list ap)
+{
+ struct mob_data *md = NULL;
int64 tick = va_arg(ap, int64);
+
+ nullpo_ret(bl);
+ Assert_ret(bl->type == BL_MOB);
+ md = BL_UCAST(BL_MOB, bl);
+
if (mob->ai_sub_hard(md, tick)) {
//Hard AI triggered.
if(!md->state.spotted)
@@ -1847,7 +1843,7 @@ int mob_delay_item_drop(int tid, int64 tick, int id, intptr_t data) {
*------------------------------------------*/
void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, struct item_drop *ditem, int loot, int drop_rate, unsigned short flag)
{
- TBL_PC* sd;
+ struct map_session_data *sd = NULL;
//Logs items, dropped by mobs [Lupus]
logs->pick_mob(md, loot?LOG_TYPE_LOOT:LOG_TYPE_PICKDROP_MONSTER, -ditem->item_data.amount, &ditem->item_data, NULL);
@@ -1878,7 +1874,7 @@ void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, struct ite
}
int mob_timer_delete(int tid, int64 tick, int id, intptr_t data) {
- struct block_list* bl = map->id2bl(id);
+ struct block_list* bl = map->id2bl(id); // TODO: Why does this not use map->id2md?
struct mob_data* md = BL_CAST(BL_MOB, bl);
if( md )
@@ -1900,13 +1896,13 @@ int mob_timer_delete(int tid, int64 tick, int id, intptr_t data) {
*------------------------------------------*/
int mob_deleteslave_sub(struct block_list *bl,va_list ap)
{
- struct mob_data *md;
- int id;
+ struct mob_data *md = NULL;
+ int id = va_arg(ap, int);
nullpo_ret(bl);
- nullpo_ret(md = (struct mob_data *)bl);
+ Assert_ret(bl->type == BL_MOB);
+ md = BL_UCAST(BL_MOB, bl);
- id=va_arg(ap,int);
if(md->master_id > 0 && md->master_id == id )
status_kill(bl);
return 0;
@@ -1945,7 +1941,7 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage)
{
case BL_PC:
{
- struct map_session_data *sd = (TBL_PC*)src;
+ const struct map_session_data *sd = BL_UCCAST(BL_PC, src);
char_id = sd->status.char_id;
if( damage )
md->attacked_id = src->id;
@@ -1953,7 +1949,7 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage)
}
case BL_HOM:
{
- struct homun_data *hd = (TBL_HOM*)src;
+ const struct homun_data *hd = BL_UCCAST(BL_HOM, src);
flag = MDLF_HOMUN;
if( hd->master )
char_id = hd->master->status.char_id;
@@ -1963,7 +1959,7 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage)
}
case BL_MER:
{
- struct mercenary_data *mer = (TBL_MER*)src;
+ const struct mercenary_data *mer = BL_UCCAST(BL_MER, src);
if( mer->master )
char_id = mer->master->status.char_id;
if( damage )
@@ -1972,7 +1968,7 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage)
}
case BL_PET:
{
- struct pet_data *pd = (TBL_PET*)src;
+ const struct pet_data *pd = BL_UCCAST(BL_PET, src);
flag = MDLF_PET;
if( pd->msd )
{
@@ -1984,7 +1980,7 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage)
}
case BL_MOB:
{
- struct mob_data* md2 = (TBL_MOB*)src;
+ const struct mob_data *md2 = BL_UCCAST(BL_MOB, src);
if (md2->special_state.ai != AI_NONE && md2->master_id) {
struct map_session_data* msd = map->id2sd(md2->master_id);
if( msd )
@@ -2001,7 +1997,7 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage)
}
case BL_ELEM:
{
- struct elemental_data *ele = (TBL_ELEM*)src;
+ const struct elemental_data *ele = BL_UCCAST(BL_ELEM, src);
if( ele->master )
char_id = ele->master->status.char_id;
if( damage )
@@ -2098,14 +2094,15 @@ 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, *tmpsd[DAMAGELOG_SIZE];
- struct map_session_data *mvp_sd = NULL, *second_sd = NULL, *third_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 = sd, *second_sd = NULL, *third_sd = NULL;
struct {
struct party_data *p;
int id,zeny;
unsigned int base_exp,job_exp;
- } pt[DAMAGELOG_SIZE];
+ } pt[DAMAGELOG_SIZE] = { { 0 } };
int i, temp, count, m = md->bl.m;
int dmgbltypes = 0; // bitfield of all bl types, that caused damage to the mob and are eligible for exp distribution
unsigned int mvp_damage;
@@ -2114,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);
@@ -2131,13 +2122,10 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) {
map->freeblock_lock();
- memset(pt,0,sizeof(pt));
-
- if(src && src->type == BL_MOB)
- mob->unlocktarget((struct mob_data *)src,tick);
+ if (src != NULL && src->type == BL_MOB)
+ mob->unlocktarget(BL_UCAST(BL_MOB, src), tick);
// filter out entries not eligible for exp distribution
- memset(tmpsd,0,sizeof(tmpsd));
for(i = 0, count = 0, mvp_damage = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++) {
struct map_session_data* tsd = map->charid2sd(md->dmglog[i].id);
@@ -2582,10 +2570,10 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) {
md->status.hp = 0; //So that npc_event invoked functions KNOW that mob is dead
if( src ) {
switch( src->type ) {
- case BL_PET: sd = ((TBL_PET*)src)->msd; break;
- case BL_HOM: sd = ((TBL_HOM*)src)->master; break;
- case BL_MER: sd = ((TBL_MER*)src)->master; break;
- case BL_ELEM: sd = ((TBL_ELEM*)src)->master; break;
+ case BL_PET: sd = BL_UCAST(BL_PET, src)->msd; break;
+ case BL_HOM: sd = BL_UCAST(BL_HOM, src)->master; break;
+ case BL_MER: sd = BL_UCAST(BL_MER, src)->master; break;
+ case BL_ELEM: sd = BL_UCAST(BL_ELEM, src)->master; break;
}
}
@@ -2843,13 +2831,18 @@ void mob_heal(struct mob_data *md, unsigned int heal)
/*==========================================
* Added by RoVeRT
*------------------------------------------*/
-int mob_warpslave_sub(struct block_list *bl,va_list ap) {
- struct mob_data *md=(struct mob_data *)bl;
+int mob_warpslave_sub(struct block_list *bl, va_list ap)
+{
+ struct mob_data *md = NULL;
struct block_list *master;
short x,y,range=0;
master = va_arg(ap, struct block_list*);
range = va_arg(ap, int);
+ nullpo_ret(bl);
+ Assert_ret(bl->type == BL_MOB);
+ md = BL_UCAST(BL_MOB, bl);
+
if(md->master_id!=master->id)
return 0;
@@ -2873,14 +2866,16 @@ int mob_warpslave(struct block_list *bl, int range) {
/*==========================================
* Counts slave sub, currently checking if mob master is the given ID.
*------------------------------------------*/
-int mob_countslave_sub(struct block_list *bl,va_list ap)
+int mob_countslave_sub(struct block_list *bl, va_list ap)
{
- int id;
- struct mob_data *md;
- id=va_arg(ap,int);
+ int id = va_arg(ap, int);
+ struct mob_data *md = NULL;
+
+ nullpo_ret(bl);
+ Assert_ret(bl->type == BL_MOB);
+ md = BL_UCAST(BL_MOB, bl);
- md = (struct mob_data *)bl;
- if( md->master_id==id )
+ if (md->master_id == id)
return 1;
return 0;
}
@@ -3064,11 +3059,12 @@ struct block_list *mob_getmasterhpltmaxrate(struct mob_data *md,int rate) {
int mob_getfriendstatus_sub(struct block_list *bl,va_list ap)
{
int cond1,cond2;
- struct mob_data **fr, *md, *mmd;
+ struct mob_data **fr = NULL, *md = NULL, *mmd = NULL;
int flag=0;
nullpo_ret(bl);
- nullpo_ret(md=(struct mob_data *)bl);
+ Assert_ret(bl->type == BL_MOB);
+ md = BL_UCAST(BL_MOB, bl);
nullpo_ret(mmd=va_arg(ap,struct mob_data *));
if( mmd->bl.id == bl->id && !(battle_config.mob_ai&0x10) )