summaryrefslogtreecommitdiff
path: root/src/map/homunculus.c
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-09-30 23:32:36 +0300
committerAndrei Karas <akaras@inbox.ru>2015-12-04 18:50:06 +0300
commitadb8f7f6cc63a110c8583aaee0d9f7039fbbbe2c (patch)
treed65d546b295d6bc02bdee148e7472560a6849607 /src/map/homunculus.c
parent55ead23717432966098853438c7e29de32e369fe (diff)
downloadhercules-adb8f7f6cc63a110c8583aaee0d9f7039fbbbe2c.tar.gz
hercules-adb8f7f6cc63a110c8583aaee0d9f7039fbbbe2c.tar.bz2
hercules-adb8f7f6cc63a110c8583aaee0d9f7039fbbbe2c.tar.xz
hercules-adb8f7f6cc63a110c8583aaee0d9f7039fbbbe2c.zip
Add missing checks to homunculus.c
Diffstat (limited to 'src/map/homunculus.c')
-rw-r--r--src/map/homunculus.c55
1 files changed, 46 insertions, 9 deletions
diff --git a/src/map/homunculus.c b/src/map/homunculus.c
index 874d26fdb..2490bc659 100644
--- a/src/map/homunculus.c
+++ b/src/map/homunculus.c
@@ -49,6 +49,7 @@ struct homunculus_interface *homun;
//Returns the viewdata for homunculus
struct view_data* homunculus_get_viewdata(int class_) {
+ Assert_retr(NULL, class_ >= HM_CLASS_BASE && class_ - HM_CLASS_BASE < MAX_HOMUNCULUS_CLASS);
if (homdb_checkid(class_))
return &homun->dbs->viewdb[class_-HM_CLASS_BASE];
return NULL;
@@ -122,8 +123,11 @@ void homunculus_damaged(struct homun_data *hd) {
int homunculus_dead(struct homun_data *hd) {
//There's no intimacy penalties on death (from Tharis)
- struct map_session_data *sd = hd->master;
+ struct map_session_data *sd;
+ nullpo_retr(3, hd);
+ sd = hd->master;
+ nullpo_retr(3, sd);
clif->emotion(&hd->bl, E_WAH);
//Delete timers when dead.
@@ -195,6 +199,7 @@ int homunculus_calc_skilltree(struct homun_data *hd, int flag_evolve) {
/* load previous homunculus form skills first. */
if( hd->homunculus.prev_class != 0 ) {
c = hd->homunculus.prev_class - HM_CLASS_BASE;
+ Assert_ret(c >= 0 && c < MAX_HOMUNCULUS_CLASS);
for( i = 0; i < MAX_SKILL_TREE && ( id = homun->dbs->skill_tree[c][i].id ) > 0; i++ ) {
if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id )
@@ -216,6 +221,7 @@ int homunculus_calc_skilltree(struct homun_data *hd, int flag_evolve) {
}
c = hd->homunculus.class_ - HM_CLASS_BASE;
+ Assert_ret(c >= 0 && c < MAX_HOMUNCULUS_CLASS);
for( i = 0; i < MAX_SKILL_TREE && ( id = homun->dbs->skill_tree[c][i].id ) > 0; i++ ) {
if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id )
@@ -246,6 +252,7 @@ int homunculus_checkskill(struct homun_data *hd,uint16 skill_id) {
if(!hd)
return 0;
+ Assert_ret(i >= 0 && i < MAX_HOMUNSKILL);
if(hd->homunculus.hskill[i].id == skill_id)
return (hd->homunculus.hskill[i].lv);
@@ -255,6 +262,7 @@ int homunculus_checkskill(struct homun_data *hd,uint16 skill_id) {
int homunculus_skill_tree_get_max(int id, int b_class) {
int i, skill_id;
b_class -= HM_CLASS_BASE;
+ Assert_ret(b_class >= 0 && b_class < MAX_HOMUNCULUS_CLASS);
for(i=0;(skill_id=homun->dbs->skill_tree[b_class][i].id)>0;i++)
if (id == skill_id)
return homun->dbs->skill_tree[b_class][i].max;
@@ -269,6 +277,7 @@ void homunculus_skillup(struct homun_data *hd,uint16 skill_id) {
return;
i = skill_id - HM_SKILLBASE;
+ Assert_retv(i >= 0 && i < MAX_HOMUNSKILL);
if(hd->homunculus.skillpts > 0 &&
hd->homunculus.hskill[i].id &&
hd->homunculus.hskill[i].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
@@ -293,6 +302,7 @@ bool homunculus_levelup(struct homun_data *hd) {
int growth_max_hp, growth_max_sp;
enum homun_type htype;
+ nullpo_retr(false, hd);
if( (htype = homun->class2type(hd->homunculus.class_)) == HT_INVALID ) {
ShowError("homunculus_levelup: Invalid class %d. \n", hd->homunculus.class_);
return false;
@@ -365,8 +375,8 @@ bool homunculus_levelup(struct homun_data *hd) {
}
int homunculus_change_class(struct homun_data *hd, short class_) {
- int i;
- i = homun->db_search(class_,HOMUNCULUS_CLASS);
+ int i = homun->db_search(class_,HOMUNCULUS_CLASS);
+ nullpo_retr(0, hd);
if(i < 0)
return 0;
hd->homunculusDB = &homun->dbs->db[i];
@@ -477,6 +487,7 @@ bool homunculus_mutate(struct homun_data *hd, int homun_id) {
int homunculus_gainexp(struct homun_data *hd,unsigned int exp) {
enum homun_type htype;
+ nullpo_ret(hd);
if(hd->homunculus.vaporize != HOM_ST_ACTIVE)
return 1;
@@ -518,6 +529,7 @@ int homunculus_gainexp(struct homun_data *hd,unsigned int exp) {
// Return the new value
unsigned int homunculus_add_intimacy(struct homun_data *hd, unsigned int value) {
+ nullpo_ret(hd);
if (battle_config.homunculus_friendly_rate != 100)
value = (value * battle_config.homunculus_friendly_rate) / 100;
@@ -530,6 +542,7 @@ unsigned int homunculus_add_intimacy(struct homun_data *hd, unsigned int value)
// Return 0 if decrease fails or intimacy became 0 else the new value
unsigned int homunculus_consume_intimacy(struct homun_data *hd, unsigned int value) {
+ nullpo_ret(hd);
if (hd->homunculus.intimacy >= value)
hd->homunculus.intimacy -= value;
else
@@ -539,15 +552,19 @@ unsigned int homunculus_consume_intimacy(struct homun_data *hd, unsigned int val
}
void homunculus_healed (struct homun_data *hd) {
+ nullpo_retv(hd);
clif->hominfo(hd->master,hd,0);
}
void homunculus_save(struct homun_data *hd) {
// copy data that must be saved in homunculus struct ( hp / sp )
- TBL_PC * sd = hd->master;
+ TBL_PC * sd;
//Do not check for max_hp/max_sp caps as current could be higher to max due
//to status changes/skills (they will be capped as needed upon stat
//calculation on login)
+ nullpo_retv(hd);
+ sd = hd->master;
+ nullpo_retv(sd);
hd->homunculus.hp = hd->battle_status.hp;
hd->homunculus.sp = hd->battle_status.sp;
intif->homunculus_requestsave(sd->status.account_id, &hd->homunculus);
@@ -577,6 +594,8 @@ unsigned char homunculus_menu(struct map_session_data *sd,unsigned char menu_num
bool homunculus_feed(struct map_session_data *sd, struct homun_data *hd) {
int i, foodID, emotion;
+ nullpo_retr(false, hd);
+ nullpo_retr(false, sd);
if(hd->homunculus.vaporize == HOM_ST_REST)
return false;
@@ -617,7 +636,6 @@ bool homunculus_feed(struct map_session_data *sd, struct homun_data *hd) {
// Too much food :/
if(hd->homunculus.intimacy == 0)
return homun->delete(sd->hd, E_OMG);
-
return true;
}
@@ -669,6 +687,7 @@ int homunculus_change_name(struct map_session_data *sd,char *name) {
int i;
struct homun_data *hd;
nullpo_retr(1, sd);
+ nullpo_retr(1, name);
hd = sd->hd;
if (!homun_alive(hd))
@@ -685,7 +704,11 @@ int homunculus_change_name(struct map_session_data *sd,char *name) {
}
bool homunculus_change_name_ack(struct map_session_data *sd, char* name, int flag) {
- struct homun_data *hd = sd->hd;
+ struct homun_data *hd;
+ nullpo_retr(false, sd);
+ nullpo_retr(false, name);
+ hd = sd->hd;
+ nullpo_retr(false, hd);
if (!homun_alive(hd)) return false;
normalize_name(name," ");//bugreport:3032
@@ -730,6 +753,7 @@ bool homunculus_create(struct map_session_data *sd, struct s_homunculus *hom) {
int i = 0;
nullpo_retr(false, sd);
+ nullpo_retr(false, hom);
Assert_retr(false, sd->status.hom_id == 0 || sd->hd == 0 || sd->hd->master == sd);
@@ -772,6 +796,7 @@ bool homunculus_create(struct map_session_data *sd, struct s_homunculus *hom) {
}
void homunculus_init_timers(struct homun_data * hd) {
+ nullpo_retv(hd);
if (hd->hungry_timer == INVALID_TIMER)
hd->hungry_timer = timer->add(timer->gettick()+hd->homunculusDB->hungryDelay,homun->hunger_timer,hd->master->bl.id,0);
hd->regen.state.block = 0; //Restore HP/SP block.
@@ -780,6 +805,7 @@ void homunculus_init_timers(struct homun_data * hd) {
bool homunculus_call(struct map_session_data *sd) {
struct homun_data *hd;
+ nullpo_retr(false, sd);
if (!sd->status.hom_id) //Create a new homun.
return homun->creation_request(sd, HM_CLASS_BASE + rnd_value(0, 7));
@@ -818,6 +844,7 @@ bool homunculus_recv_data(int account_id, struct s_homunculus *sh, int flag) {
struct map_session_data *sd;
struct homun_data *hd;
+ nullpo_retr(false, sh);
sd = map->id2sd(account_id);
if(!sd)
return false;
@@ -916,6 +943,7 @@ bool homunculus_ressurect(struct map_session_data* sd, unsigned char per, short
hd = sd->hd;
+ nullpo_retr(false, hd);
if (hd->homunculus.vaporize != HOM_ST_ACTIVE)
return false; // vaporized homunculi need to be 'called'
@@ -937,7 +965,10 @@ bool homunculus_ressurect(struct map_session_data* sd, unsigned char per, short
}
void homunculus_revive(struct homun_data *hd, unsigned int hp, unsigned int sp) {
- struct map_session_data *sd = hd->master;
+ struct map_session_data *sd;
+
+ nullpo_retv(hd);
+ sd = hd->master;
hd->homunculus.hp = hd->battle_status.hp;
if (!sd)
return;
@@ -951,6 +982,7 @@ void homunculus_stat_reset(struct homun_data *hd) {
struct s_homunculus_db *db;
struct s_homunculus *hom;
struct h_stats *base;
+ nullpo_retv(hd);
hom = &hd->homunculus;
db = hd->homunculusDB;
base = &db->base;
@@ -976,6 +1008,7 @@ bool homunculus_shuffle(struct homun_data *hd) {
unsigned int exp;
struct s_skill b_skill[MAX_HOMUNSKILL];
+ nullpo_retr(false, hd);
if (!homun_alive(hd))
return false;
@@ -1022,6 +1055,7 @@ bool homunculus_read_db_sub(char* str[], int columns, int current) {
int classid;
struct s_homunculus_db *db;
+ nullpo_retr(false, str);
//Base Class,Evo Class
classid = atoi(str[0]);
if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX) {
@@ -1153,13 +1187,14 @@ bool homunculus_read_skill_db_sub(char* split[], int columns, int current) {
int j;
int minJobLevelPresent = 0;
+ nullpo_retr(false, split);
if( columns == 15 )
minJobLevelPresent = 1; // MinJobLvl has been added - FIXME: is this extra field even needed anymore?
// check for bounds [celest]
classid = atoi(split[0]) - HM_CLASS_BASE;
- if ( classid >= MAX_HOMUNCULUS_CLASS ) {
+ if ( classid < 0 || classid >= MAX_HOMUNCULUS_CLASS ) {
ShowWarning("homunculus_read_skill_db_sub: Invalid homunculus class %d.\n", atoi(split[0]));
return false;
}
@@ -1188,7 +1223,9 @@ bool homunculus_read_skill_db_sub(char* split[], int columns, int current) {
}
int8 homunculus_get_intimacy_grade(struct homun_data *hd) {
- unsigned int val = hd->homunculus.intimacy / 100;
+ unsigned int val;
+ nullpo_ret(hd);
+ val = hd->homunculus.intimacy / 100;
if( val > 100 ) {
if( val > 250 ) {
if( val > 750 ) {