int merc_hom_gainexp(struct homun_data *hd,int exp) { if(hd->homunculus.vaporize) return 1; if( hd->exp_next == 0 ) { hd->homunculus.exp = 0 ; return 0; } hd->homunculus.exp += exp; if(hd->homunculus.exp < hd->exp_next) { clif_hominfo(hd->master,hd,0); return 0; } //levelup do { merc_hom_levelup(hd) ; } while(hd->homunculus.exp > hd->exp_next && hd->exp_next != 0 ); if( hd->exp_next == 0 ) hd->homunculus.exp = 0 ; clif_specialeffect(&hd->bl,568,AREA); status_calc_homunculus(hd,0); status_percent_heal(&hd->bl, 100, 100); return 0; }
/** * Shuffle homunculus status * @param hd */ int hom_shuffle(struct homun_data *hd) { struct map_session_data *sd; int lv, i, skillpts; unsigned int exp; struct s_skill b_skill[MAX_HOMUNSKILL]; if (!hom_is_active(hd)) return 0; sd = hd->master; lv = hd->homunculus.level; exp = hd->homunculus.exp; memcpy(&b_skill, &hd->homunculus.hskill, sizeof(b_skill)); skillpts = hd->homunculus.skillpts; //Reset values to level 1. hom_reset_stats(hd); //Level it back up for (i = 1; i < lv && hd->exp_next; i++){ hd->homunculus.exp += hd->exp_next; // Should never happen, but who knows if( !hom_levelup(hd) ) { break; } } if(hd->homunculus.class_ == hd->homunculusDB->evo_class) { //Evolved bonuses struct s_homunculus *hom = &hd->homunculus; struct h_stats *max = &hd->homunculusDB->emax, *min = &hd->homunculusDB->emin; hom->max_hp += rnd_value(min->HP, max->HP); hom->max_sp += rnd_value(min->SP, max->SP); hom->str += 10*rnd_value(min->str, max->str); hom->agi += 10*rnd_value(min->agi, max->agi); hom->vit += 10*rnd_value(min->vit, max->vit); hom->int_+= 10*rnd_value(min->int_,max->int_); hom->dex += 10*rnd_value(min->dex, max->dex); hom->luk += 10*rnd_value(min->luk, max->luk); } hd->homunculus.exp = exp; memcpy(&hd->homunculus.hskill, &b_skill, sizeof(b_skill)); hd->homunculus.skillpts = skillpts; clif_homskillinfoblock(sd); status_calc_homunculus(hd, SCO_NONE); status_percent_heal(&hd->bl, 100, 100); clif_specialeffect(&hd->bl,568,AREA); return 1; }
/** * Receive homunculus data from char server * @param account_id : owner account_id of the homon * @param sh : homonculus data from char-serv * @param flag : does the creation in inter-serv was a success (0:no,1:yes) * @return 0:failure, 1:sucess */ int hom_recv_data(uint32 account_id, struct s_homunculus *sh, int flag) { struct map_session_data *sd; struct homun_data *hd; bool created = false; sd = map_id2sd(account_id); if(!sd) return 0; if (sd->status.char_id != sh->char_id) { if (sd->status.hom_id == sh->hom_id) sh->char_id = sd->status.char_id; //Correct char id. else return 0; } if(!flag) { // Failed to load sd->status.hom_id = 0; return 0; } if (!sd->status.hom_id) { //Hom just created. sd->status.hom_id = sh->hom_id; created = true; } if (sd->hd) //uh? Overwrite the data. memcpy(&sd->hd->homunculus, sh, sizeof(struct s_homunculus)); else hom_alloc(sd, sh); hd = sd->hd; if (created) status_percent_heal(&hd->bl, 100, 100); if(hd && hd->homunculus.hp && !hd->homunculus.vaporize && hd->bl.prev == NULL && sd->bl.prev != NULL) { if(map_addblock(&hd->bl)) return 0; clif_spawn(&hd->bl); clif_send_homdata(sd,SP_ACK,0); clif_hominfo(sd,hd,1); clif_hominfo(sd,hd,0); // send this x2. dunno why, but kRO does that [blackhole89] clif_homskillinfoblock(sd); hom_init_timers(hd); } return 1; }
/** * Create homunc structure * @param sd * @param hom */ void hom_alloc(struct map_session_data *sd, struct s_homunculus *hom) { struct homun_data *hd; int i = 0; nullpo_retv(sd); Assert((sd->status.hom_id == 0 || sd->hd == 0) || sd->hd->master == sd); i = hom_search(hom->class_,HOMUNCULUS_CLASS); if(i < 0) { ShowError("hom_alloc: unknown class [%d] for homunculus '%s', requesting deletion.\n", hom->class_, hom->name); sd->status.hom_id = 0; intif_homunculus_requestdelete(hom->hom_id); return; } sd->hd = hd = (struct homun_data*)aCalloc(1,sizeof(struct homun_data)); hd->bl.type = BL_HOM; hd->bl.id = npc_get_new_npc_id(); hd->master = sd; hd->homunculusDB = &homunculus_db[i]; memcpy(&hd->homunculus, hom, sizeof(struct s_homunculus)); hd->exp_next = hexptbl[hd->homunculus.level - 1]; status_set_viewdata(&hd->bl, hd->homunculus.class_); status_change_init(&hd->bl); unit_dataset(&hd->bl); hd->ud.dir = sd->ud.dir; // Find a random valid pos around the player hd->bl.m = sd->bl.m; hd->bl.x = sd->bl.x; hd->bl.y = sd->bl.y; unit_calc_pos(&hd->bl, sd->bl.x, sd->bl.y, sd->ud.dir); hd->bl.x = hd->ud.to_x; hd->bl.y = hd->ud.to_y; map_addiddb(&hd->bl); status_calc_homunculus(hd, SCO_FIRST); status_percent_heal(&hd->bl, 100, 100); hd->hungry_timer = INVALID_TIMER; hd->masterteleport_timer = INVALID_TIMER; }
/** * Add homunculus exp * @param hd * @param exp Added EXP */ void hom_gainexp(struct homun_data *hd,int exp) { int m_class; nullpo_retv(hd); if(hd->homunculus.vaporize) return; if((m_class = hom_class2mapid(hd->homunculus.class_)) == -1) { ShowError("hom_gainexp: Invalid class %d. \n", hd->homunculus.class_); return; } if( hd->exp_next == 0 || ((m_class&HOM_REG) && hd->homunculus.level >= battle_config.hom_max_level) || ((m_class&HOM_S) && hd->homunculus.level >= battle_config.hom_S_max_level) ) { hd->homunculus.exp = 0; return; } hd->homunculus.exp += exp; if (hd->homunculus.exp < hd->exp_next) { clif_hominfo(hd->master,hd,0); return; } // Do the levelup(s) while( hd->homunculus.exp > hd->exp_next ){ // Max level reached or error if( !hom_levelup(hd) ){ break; } } if( hd->exp_next == 0 ) hd->homunculus.exp = 0 ; clif_specialeffect(&hd->bl,568,AREA); status_calc_homunculus(hd, SCO_NONE); status_percent_heal(&hd->bl, 100, 100); }
int merc_hom_gainexp(struct homun_data *hd,int exp) { struct map_session_data *sd; struct s_homunculus *hom; hom = &hd->homunculus; sd = hd->master; if(hd->homunculus.vaporize) return 1; if( hd->exp_next == 0 ) { hd->homunculus.exp = 0 ; return 0; } if (sd->sc.data[SC_EXPBOOST]) exp += exp*((sd->sc.data[SC_EXPBOOST]->val1)/100); hd->homunculus.exp += exp; if(hd->homunculus.exp < hd->exp_next) { clif_hominfo(hd->master,hd,0); return 0; } //levelup do { merc_hom_levelup(hd) ; } while(hd->homunculus.exp > hd->exp_next && hd->exp_next != 0 && hom->evomoment == 0 ); if( hd->exp_next == 0 ) hd->homunculus.exp = 0 ; clif_specialeffect(&hd->bl,705,AREA); status_calc_homunculus(hd,0); status_percent_heal(&hd->bl, 100, 100); return 0; }
int merc_hom_gainexp(struct homun_data *hd,int exp) { int m_class; if(hd->homunculus.vaporize) return 1; if((m_class = hom_class2mapid(hd->homunculus.class_)) == -1) { ShowError("merc_hom_gainexp: Invalid class %d. \n", hd->homunculus.class_); return 0; } if( hd->exp_next == 0 || ((m_class&HOM_REG) && hd->homunculus.level >= battle_config.hom_max_level) || ((m_class&HOM_S) && hd->homunculus.level >= battle_config.hom_S_max_level) ) { hd->homunculus.exp = 0; return 0; } hd->homunculus.exp += exp; if(hd->homunculus.exp < hd->exp_next) { clif_hominfo(hd->master,hd,0); return 0; } //levelup do { merc_hom_levelup(hd) ; } while(hd->homunculus.exp > hd->exp_next && hd->exp_next != 0 ); if( hd->exp_next == 0 ) hd->homunculus.exp = 0 ; clif_specialeffect(&hd->bl,568,AREA); status_calc_homunculus(hd,0); status_percent_heal(&hd->bl, 100, 100); return 0; }