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.c95
1 files changed, 88 insertions, 7 deletions
diff --git a/src/map/mob.c b/src/map/mob.c
index 53ad87912..c765e7d63 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -114,6 +114,8 @@ struct mob_chat *mob_chat(short id) {
int mobdb_searchname(const char *str)
{
int i;
+
+ nullpo_ret(str);
for(i=0;i<=MAX_MOB_DB;i++){
struct mob_db *monster = mob->db(i);
if(monster == mob->dummy) //Skip dummy mobs.
@@ -129,10 +131,13 @@ int mobdb_searchname(const char *str)
return 0;
}
int mobdb_searchname_array_sub(struct mob_db* monster, const char *str, int flag) {
+
+ nullpo_ret(monster);
if (monster == mob->dummy)
return 1;
if(!monster->base_exp && !monster->job_exp && monster->spawn[0].qty < 1)
return 1; // Monsters with no base/job exp and no spawn point are, by this criteria, considered "slave mobs" and excluded from search results
+ nullpo_ret(str);
if( !flag ) {
if(stristr(monster->jname,str))
return 0;
@@ -156,6 +161,7 @@ void mvptomb_create(struct mob_data *md, char *killer, time_t time)
{
struct npc_data *nd;
+ nullpo_retv(md);
if ( md->tomb_nid )
mob->mvptomb_destroy(md);
@@ -181,6 +187,7 @@ void mvptomb_create(struct mob_data *md, char *killer, time_t time)
void mvptomb_destroy(struct mob_data *md) {
struct npc_data *nd;
+ nullpo_retv(md);
if ( (nd = map->id2nd(md->tomb_nid)) ) {
int16 m, i;
@@ -212,6 +219,7 @@ int mobdb_searchname_array(struct mob_db** data, int size, const char *str, int
{
int count = 0, i;
struct mob_db* monster;
+ nullpo_ret(data);
for(i=0;i<=MAX_MOB_DB;i++){
monster = mob->db(i);
if (monster == mob->dummy || mob->is_clone(i) ) //keep clones out (or you leak player stats)
@@ -253,6 +261,7 @@ int mob_parse_dataset(struct spawn_data *data)
{
size_t len;
+ nullpo_ret(data);
if ((!mob->db_checkid(data->class_) && !mob->is_clone(data->class_)) || !data->num)
return 0;
@@ -276,6 +285,7 @@ int mob_parse_dataset(struct spawn_data *data)
*------------------------------------------*/
struct mob_data* mob_spawn_dataset(struct spawn_data *data) {
struct mob_data *md = NULL;
+ nullpo_retr(NULL, data);
CREATE(md, struct mob_data, 1);
md->bl.id= npc->get_new_npc_id();
md->bl.type = BL_MOB;
@@ -328,6 +338,7 @@ int mob_get_random_id(int type, int flag, int lv)
ShowError("mob_get_random_id: Invalid type (%d) of random monster.\n", type);
return 0;
}
+ Assert_ret(type >= 0 && type < MAX_RANDOMMONSTER);
do {
if (type)
class_ = summon[type].class_[rnd()%summon[type].qty];
@@ -634,6 +645,11 @@ int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobnam
struct guild *g=NULL;
struct guild_castle *gc;
int16 m;
+
+ nullpo_ret(mapname);
+ nullpo_ret(mobname);
+ nullpo_ret(event);
+
memset(&data, 0, sizeof(struct spawn_data));
data.num = 1;
@@ -728,6 +744,10 @@ int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int
struct spawn_data data;
int16 m;
+ nullpo_ret(mapname);
+ nullpo_ret(mobname);
+ nullpo_ret(event);
+
if( (m = map->mapname2mapid(mapname)) < 0 ) {
ShowWarning("mob_spawn_bg: Map [%s] not found.\n", mapname);
return 0;
@@ -846,6 +866,8 @@ int mob_setdelayspawn(struct mob_data *md)
uint32 mode;
struct mob_db *db;
+ nullpo_ret(md);
+
if (!md->spawn) //Doesn't has respawn data!
return unit->free(&md->bl,CLR_DEAD);
@@ -903,6 +925,7 @@ int mob_spawn (struct mob_data *md)
int64 tick = timer->gettick();
int64 c = 0;
+ nullpo_retr(1, md);
md->last_thinktime = tick;
if (md->bl.prev != NULL)
unit->remove_map(&md->bl,CLR_RESPAWN,ALC_MARK);
@@ -992,6 +1015,8 @@ int mob_spawn (struct mob_data *md)
*------------------------------------------*/
int mob_can_changetarget(const struct mob_data *md, const struct block_list *target, uint32 mode)
{
+ nullpo_ret(md);
+ nullpo_ret(target);
// if the monster was provoked ignore the above rule [celest]
if(md->state.provoke_flag)
{
@@ -1057,6 +1082,8 @@ int mob_ai_sub_hard_activesearch(struct block_list *bl, va_list ap)
md=va_arg(ap,struct mob_data *);
target= va_arg(ap,struct block_list**);
mode = va_arg(ap, uint32);
+ nullpo_ret(md);
+ nullpo_ret(target);
//If can't seek yet, not an enemy, or you can't attack it, skip.
if (md->bl.id == bl->id || (*target) == bl || !status->check_skilluse(&md->bl, bl, 0, 0))
@@ -1111,8 +1138,10 @@ int mob_ai_sub_hard_changechase(struct block_list *bl,va_list ap) {
struct block_list **target;
nullpo_ret(bl);
- md=va_arg(ap,struct mob_data *);
- target= va_arg(ap,struct block_list**);
+ md = va_arg(ap,struct mob_data *);
+ target = va_arg(ap,struct block_list**);
+ nullpo_ret(md);
+ nullpo_ret(target);
//If can't seek yet, not an enemy, or you can't attack it, skip.
if( md->bl.id == bl->id || *target == bl
@@ -1139,6 +1168,8 @@ int mob_ai_sub_hard_bg_ally(struct block_list *bl,va_list ap) {
nullpo_ret(bl);
md=va_arg(ap,struct mob_data *);
target= va_arg(ap,struct block_list**);
+ nullpo_retr(1, md);
+ nullpo_retr(1, target);
if( status->check_skilluse(&md->bl, bl, 0, 0) && battle->check_target(&md->bl,bl,BCT_ENEMY)<=0 ) {
(*target) = bl;
@@ -1157,6 +1188,8 @@ int mob_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap)
md=va_arg(ap,struct mob_data *);
target= va_arg(ap,struct block_list**);
+ nullpo_ret(md);
+ nullpo_ret(target);
dist=distance_bl(&md->bl, bl);
if(mob->can_reach(md,bl,dist+1, MSS_LOOT) &&
@@ -1177,6 +1210,9 @@ int mob_warpchase_sub(struct block_list *bl,va_list ap) {
struct npc_data *nd = NULL;
nullpo_ret(bl);
+ nullpo_ret(target);
+ nullpo_ret(target_nd);
+ nullpo_ret(min_distance);
Assert_ret(bl->type == BL_NPC);
nd = BL_UCAST(BL_NPC, bl);
@@ -1201,6 +1237,7 @@ int mob_warpchase_sub(struct block_list *bl,va_list ap) {
int mob_ai_sub_hard_slavemob(struct mob_data *md, int64 tick) {
struct block_list *bl;
+ nullpo_ret(md);
bl=map->id2bl(md->master_id);
if (!bl || status->isdead(bl)) {
@@ -1378,6 +1415,7 @@ int mob_warpchase(struct mob_data *md, struct block_list *target)
{
struct npc_data *warp = NULL;
int distance = AREA_SIZE;
+ nullpo_ret(md);
if (!(target && battle_config.mob_ai&0x40 && battle_config.mob_warp&1))
return 0; //Can't warp chase.
@@ -1405,6 +1443,7 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
uint32 mode;
int view_range, can_move;
+ nullpo_retr(false, md);
if(md->bl.prev == NULL || md->status.hp <= 0)
return false;
@@ -1702,6 +1741,7 @@ int mob_ai_sub_hard_timer(struct block_list *bl, va_list ap)
*------------------------------------------*/
int mob_ai_sub_foreachclient(struct map_session_data *sd, va_list ap) {
int64 tick;
+ nullpo_ret(sd);
tick=va_arg(ap, int64);
map->foreachinrange(mob->ai_sub_hard_timer,&sd->bl, AREA_SIZE+ACTIVE_AI_RANGE, BL_MOB,tick);
@@ -1810,7 +1850,10 @@ struct item_drop* mob_setdropitem(int nameid, int qty, struct item_data *data) {
*------------------------------------------*/
struct item_drop* mob_setlootitem(struct item* item)
{
- struct item_drop *drop = ers_alloc(item_drop_ers, struct item_drop);
+ struct item_drop *drop ;
+
+ nullpo_retr(NULL, item);
+ drop = ers_alloc(item_drop_ers, struct item_drop);
memcpy(&drop->item_data, item, sizeof(struct item));
drop->next = NULL;
return drop;
@@ -1847,6 +1890,9 @@ void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, struct ite
{
struct map_session_data *sd = NULL;
+ nullpo_retv(md);
+ nullpo_retv(dlist);
+ nullpo_retv(ditem);
//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);
@@ -1932,6 +1978,9 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage)
{
int char_id = 0, flag = MDLF_NORMAL;
+ nullpo_retv(md);
+ nullpo_retv(src);
+
if( damage < 0 )
return; //Do nothing for absorbed damage.
if( !damage && !(src->type&DEFAULT_ENEMY_TYPE(md)) )
@@ -2042,6 +2091,7 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage)
}
//Call when a mob has received damage.
void mob_damage(struct mob_data *md, struct block_list *src, int damage) {
+ nullpo_retv(md);
if (damage > 0) { //Store total damage...
if (UINT_MAX - (unsigned int)damage > md->tdmg)
md->tdmg+=damage;
@@ -2105,12 +2155,14 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) {
int id,zeny;
unsigned int base_exp,job_exp;
} pt[DAMAGELOG_SIZE] = { { 0 } };
- int i, temp, count, m = md->bl.m;
+ int i, temp, count, 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;
int64 tick = timer->gettick();
bool rebirth, homkillonly;
+ nullpo_retr(3, md);
+ m = md->bl.m;
mstatus = &md->status;
if( md->guardian_data && md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS )
@@ -2663,6 +2715,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) {
void mob_revive(struct mob_data *md, unsigned int hp)
{
int64 tick = timer->gettick();
+
+ nullpo_retv(md);
md->state.skillstate = MSS_IDLE;
md->last_thinktime = tick;
md->next_walktime = tick+rnd()%1000+MIN_RANDOMWALKTIME;
@@ -2810,6 +2864,7 @@ int mob_class_change (struct mob_data *md, int class_) {
*------------------------------------------*/
void mob_heal(struct mob_data *md, unsigned int heal)
{
+ nullpo_retv(md);
if (battle_config.show_mob_info&3)
clif->charnameack (0, &md->bl);
#if PACKETVER >= 20131223
@@ -2844,6 +2899,7 @@ int mob_warpslave_sub(struct block_list *bl, va_list ap)
range = va_arg(ap, int);
nullpo_ret(bl);
+ nullpo_ret(master);
Assert_ret(bl->type == BL_MOB);
md = BL_UCAST(BL_MOB, bl);
@@ -2861,6 +2917,7 @@ int mob_warpslave_sub(struct block_list *bl, va_list ap)
* appear in randomly.
*------------------------------------------*/
int mob_warpslave(struct block_list *bl, int range) {
+ nullpo_ret(bl);
if (range < 1)
range = 1; //Min range needed to avoid crashes and stuff. [Skotlex]
@@ -2888,6 +2945,7 @@ int mob_countslave_sub(struct block_list *bl, va_list ap)
* Counts the number of slaves a mob has on the map.
*------------------------------------------*/
int mob_countslave(struct block_list *bl) {
+ nullpo_ret(bl);
return map->foreachinmap(mob->countslave_sub, bl->m, BL_MOB,bl->id);
}
@@ -3016,6 +3074,8 @@ int mob_getfriendhprate_sub(struct block_list *bl,va_list ap)
struct mob_data *md;
md = va_arg(ap,struct mob_data *);
+ nullpo_ret(bl);
+ nullpo_ret(md);
min_rate=va_arg(ap,int);
max_rate=va_arg(ap,int);
fr=va_arg(ap,struct block_list **);
@@ -3326,6 +3386,8 @@ int mobskill_use(struct mob_data *md, int64 tick, int event) {
int mobskill_event(struct mob_data *md, struct block_list *src, int64 tick, int flag) {
int target_id, res = 0;
+ nullpo_ret(md);
+ nullpo_ret(src);
if(md->bl.prev == NULL || md->status.hp <= 0)
return 0;
@@ -3387,7 +3449,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
return 0;
ARR_FIND( MOB_CLONE_START, MOB_CLONE_END, class_, mob->db_data[class_] == NULL );
- if(class_ >= MOB_CLONE_END)
+ if(class_ < 0 || class_ >= MOB_CLONE_END)
return 0;
db = mob->db_data[class_]=(struct mob_db*)aCalloc(1, sizeof(struct mob_db));
@@ -3577,7 +3639,10 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
int mob_clone_delete(struct mob_data *md)
{
- const int class_ = md->class_;
+ int class_;
+
+ nullpo_ret(md);
+ class_ = md->class_;
if (class_ >= MOB_CLONE_START && class_ < MOB_CLONE_END
&& mob->db_data[class_]!=NULL) {
mob->destroy_mob_db(class_);
@@ -3667,6 +3732,7 @@ unsigned int mob_drop_adjust(int baserate, int rate_adjust, unsigned short rate_
*/
void item_dropratio_adjust(int nameid, int mob_id, int *rate_adjust)
{
+ nullpo_retv(rate_adjust);
if( item_drop_ratio_db[nameid] ) {
if( item_drop_ratio_db[nameid]->mob_id[0] ) { // only for listed mobs
int i;
@@ -3701,6 +3767,7 @@ static inline int mob_parse_dbrow_cap_value(int class_, int min, int max, int va
void mob_read_db_stats_sub(struct mob_db *entry, struct config_setting_t *t)
{
int i32;
+ nullpo_retv(entry);
if (mob->lookup_const(t, "Str", &i32) && i32 >= 0) {
entry->status.str = mob_parse_dbrow_cap_value(entry->mob_id, UINT16_MIN, UINT16_MAX, i32);
}
@@ -3784,6 +3851,7 @@ void mob_read_db_mvpdrops_sub(struct mob_db *entry, struct config_setting_t *t)
int idx = 0;
int i32;
+ nullpo_retv(entry);
while (idx < MAX_MVP_DROP && (drop = libconfig->setting_get_elem(t, i))) {
const char *name = config_setting_name(drop);
int rate_adjust = battle_config.item_rate_mvp;
@@ -3841,6 +3909,7 @@ void mob_read_db_drops_sub(struct mob_db *entry, struct config_setting_t *t)
int i32;
int k;
+ nullpo_retv(entry);
while (idx < MAX_MOB_DROP && (drop = libconfig->setting_get_elem(t, i))) {
const char *name = config_setting_name(drop);
int rate_adjust, type;
@@ -3962,6 +4031,7 @@ int mob_db_validate_entry(struct mob_db *entry, int n, const char *source)
{
struct mob_data data;
+ nullpo_ret(entry);
if (entry->mob_id <= 1000 || entry->mob_id > MAX_MOB_DB) {
ShowError("mob_db_validate_entry: Invalid monster ID %d, must be in range %d-%d.\n", entry->mob_id, 1000, MAX_MOB_DB);
return 0;
@@ -4395,6 +4465,8 @@ bool mob_lookup_const(const struct config_setting_t *it, const char *name, int *
bool mob_get_const(const struct config_setting_t *it, int *value)
{
const char *str = config_setting_get_string(it);
+
+ nullpo_retr(false, value);
if (str && *str && script->get_constant(str, value))
return true;
@@ -4491,6 +4563,7 @@ bool mob_readdb_mobavail(char* str[], int columns, int current)
{
int class_, k;
+ nullpo_retr(false, str);
class_=atoi(str[0]);
if(mob->db(class_) == mob->dummy) {
@@ -4602,6 +4675,8 @@ bool mob_parse_row_chatdb(char** str, const char* source, int line, int* last_ms
int msg_id;
size_t len;
+ nullpo_retr(false, str);
+ nullpo_retr(false, last_msg_id);
msg_id = atoi(str[0]);
if (msg_id <= 0 || msg_id > MAX_MOB_CHAT)
@@ -4786,6 +4861,7 @@ bool mob_parse_row_mobskilldb(char** str, int columns, int current)
int i =0, j, tmp;
uint16 sidx = 0;
+ nullpo_retr(false, str);
mob_id = atoi(str[0]);
if (mob_id > 0 && mob->db(mob_id) == mob->dummy)
@@ -5001,6 +5077,7 @@ bool mob_readdb_race2(char* fields[], int columns, int current)
{
int race, i;
+ nullpo_retr(false, fields);
race = atoi(fields[0]);
if (race < RC2_NONE || race >= RC2_MAX) {
@@ -5025,6 +5102,8 @@ bool mob_readdb_race2(char* fields[], int columns, int current)
bool mob_readdb_itemratio(char* str[], int columns, int current)
{
int nameid, ratio, i;
+
+ nullpo_retr(false, str);
nameid = atoi(str[0]);
if( itemdb->exists(nameid) == NULL )
@@ -5126,7 +5205,9 @@ int do_init_mob(bool minimal) {
void mob_destroy_mob_db(int index)
{
- struct mob_db *data = mob->db_data[index];
+ struct mob_db *data;
+ Assert_retv(index >= 0 && index <= MAX_MOB_DB);
+ data = mob->db_data[index];
HPM->data_store_destroy(&data->hdata);
aFree(data);
mob->db_data[index] = NULL;