/** * Inter-serv has sent us the elemental data from sql, fill it in map-serv memory * @param ele : The elemental data received from char-serv * @param flag : 0:not created, 1:was saved/loaded * @return 0:failed, 1:sucess */ int elemental_data_received(struct s_elemental *ele, bool flag) { struct map_session_data *sd; struct elemental_data *ed; struct s_elemental_db *db; int i = elemental_search_index(ele->class_); if( (sd = map_charid2sd(ele->char_id)) == NULL ) return 0; if( !flag || i < 0 ) { // Not created - loaded - DB info sd->status.ele_id = 0; return 0; } db = &elemental_db[i]; if( !sd->ed ) { // Initialize it after first summon. sd->ed = ed = (struct elemental_data*)aCalloc(1,sizeof(struct elemental_data)); ed->bl.type = BL_ELEM; ed->bl.id = npc_get_new_npc_id(); ed->master = sd; ed->db = db; memcpy(&ed->elemental, ele, sizeof(struct s_elemental)); status_set_viewdata(&ed->bl, ed->elemental.class_); ed->vd->head_mid = 10; // Why? status_change_init(&ed->bl); unit_dataset(&ed->bl); ed->ud.dir = sd->ud.dir; ed->bl.m = sd->bl.m; ed->bl.x = sd->bl.x; ed->bl.y = sd->bl.y; unit_calc_pos(&ed->bl, sd->bl.x, sd->bl.y, sd->ud.dir); ed->bl.x = ed->ud.to_x; ed->bl.y = ed->ud.to_y; map_addiddb(&ed->bl); status_calc_elemental(ed,SCO_FIRST); ed->last_spdrain_time = ed->last_thinktime = gettick(); ed->summon_timer = INVALID_TIMER; ed->masterteleport_timer = INVALID_TIMER; elemental_summon_init(ed); } else { memcpy(&sd->ed->elemental, ele, sizeof(struct s_elemental)); ed = sd->ed; } sd->status.ele_id = ele->elemental_id; if( ed->bl.prev == NULL && sd->bl.prev != NULL ) { if(map_addblock(&ed->bl)) return 0; clif_spawn(&ed->bl); clif_elemental_info(sd); clif_elemental_updatestatus(sd,SP_HP); clif_hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.max_hp); clif_elemental_updatestatus(sd,SP_SP); } return 1; }
/** * Received mercenary data from char-serv * @param merc : mercenary datas * @param flag : if inter-serv request was sucessfull * @return false:failure, true:sucess */ bool mercenary_recv_data(struct s_mercenary *merc, bool flag) { struct map_session_data *sd; struct mercenary_data *md; struct s_mercenary_db *db; int i = mercenary_search_index(merc->class_); if( (sd = map_charid2sd(merc->char_id)) == NULL ) return false; if( !flag || i < 0 ) { // Not created - loaded - DB info sd->status.mer_id = 0; return false; } db = &mercenary_db[i]; if( !sd->md ) { sd->md = md = (struct mercenary_data*)aCalloc(1,sizeof(struct mercenary_data)); md->bl.type = BL_MER; md->bl.id = npc_get_new_npc_id(); md->devotion_flag = 0; md->master = sd; md->db = db; memcpy(&md->mercenary, merc, sizeof(struct s_mercenary)); status_set_viewdata(&md->bl, md->mercenary.class_); status_change_init(&md->bl); unit_dataset(&md->bl); md->ud.dir = sd->ud.dir; md->bl.m = sd->bl.m; md->bl.x = sd->bl.x; md->bl.y = sd->bl.y; unit_calc_pos(&md->bl, sd->bl.x, sd->bl.y, sd->ud.dir); md->bl.x = md->ud.to_x; md->bl.y = md->ud.to_y; map_addiddb(&md->bl); status_calc_mercenary(md, SCO_FIRST); md->contract_timer = INVALID_TIMER; md->masterteleport_timer = INVALID_TIMER; merc_contract_init(md); } else { memcpy(&sd->md->mercenary, merc, sizeof(struct s_mercenary)); md = sd->md; } if( sd->status.mer_id == 0 ) mercenary_set_calls(md, 1); sd->status.mer_id = merc->mercenary_id; if( md && md->bl.prev == NULL && sd->bl.prev != NULL ) { if(map_addblock(&md->bl)) return false; clif_spawn(&md->bl); clif_mercenary_info(sd); clif_mercenary_skillblock(sd); } return true; }
/** * Changes homunculus class * @param hd * @param class_ old class * @reutrn Fals if the class cannot be changed, True if otherwise */ static bool hom_change_class(struct homun_data *hd, short class_) { int i; i = hom_search(class_,HOMUNCULUS_CLASS); if (i < 0) return false; hd->homunculusDB = &homunculus_db[i]; hd->homunculus.class_ = class_; status_set_viewdata(&hd->bl, class_); hom_calc_skilltree(hd, 1); return true; }
int merc_hom_change_class(struct homun_data *hd, short class_) { int i; i = search_homunculusDB_index(class_,HOMUNCULUS_CLASS); if(i < 0) return 0; hd->homunculusDB = &homunculus_db[i]; hd->homunculus.class_ = class_; status_set_viewdata(&hd->bl, class_); merc_hom_calc_skilltree(hd); return 1; }
// Create homunc structure int merc_hom_alloc(struct map_session_data *sd, struct s_homunculus *hom) { struct homun_data *hd; int i = 0; short x,y; nullpo_retr(1, sd); Assert((sd->status.hom_id == 0 || sd->hd == 0) || sd->hd->master == sd); i = search_homunculusDB_index(hom->class_,HOMUNCULUS_CLASS); if(i < 0) { ShowError("merc_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 1; } sd->hd = hd = 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; x = sd->bl.x + 1; y = sd->bl.y + 1; map_random_dir(&hd->bl, &x, &y); hd->bl.x = x; hd->bl.y = y; map_addiddb(&hd->bl); status_calc_homunculus(hd,1); hd->hungry_timer = -1; return 0; }
/** * 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; }
/** * Remove a pet's equipment. * @param sd : player requesting * @param pd : pet requesting * @return 0:success, 1:failure */ static int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd) { struct item tmp_item; unsigned short nameid; unsigned char flag = 0; if(pd->pet.equip == 0) return 1; nameid = pd->pet.equip; pd->pet.equip = 0; status_set_viewdata(&pd->bl, pd->pet.class_); clif_pet_equip_area(pd); memset(&tmp_item,0,sizeof(tmp_item)); tmp_item.nameid = nameid; tmp_item.identify = 1; if((flag = pc_additem(sd,&tmp_item,1,LOG_TYPE_OTHER))) { clif_additem(sd,0,0,flag); map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0); } if( battle_config.pet_equip_required ) { // Skotlex: halt support timers if needed if( pd->state.skillbonus ) { pd->state.skillbonus = 0; status_calc_pc(sd,SCO_NONE); } if( pd->s_skill && pd->s_skill->timer != INVALID_TIMER ) { if( pd->s_skill->id ) delete_timer(pd->s_skill->timer, pet_skill_support_timer); else delete_timer(pd->s_skill->timer, pet_heal_timer); pd->s_skill->timer = INVALID_TIMER; } if( pd->bonus && pd->bonus->timer != INVALID_TIMER ) { delete_timer(pd->bonus->timer, pet_skill_bonus_timer); pd->bonus->timer = INVALID_TIMER; } } return 0; }
static int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd) { struct item tmp_item; int nameid,flag; if(pd->pet.equip == 0) return 1; nameid = pd->pet.equip; pd->pet.equip = 0; status_set_viewdata(&pd->bl, pd->pet.class_); clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom); memset(&tmp_item,0,sizeof(tmp_item)); tmp_item.nameid = nameid; tmp_item.identify = 1; if((flag = pc->additem(sd,&tmp_item,1,LOG_TYPE_OTHER))) { clif->additem(sd,0,0,flag); iMap->addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } if( battle_config.pet_equip_required ) { // Skotlex: halt support timers if needed if( pd->state.skillbonus ) { pd->state.skillbonus = 0; status_calc_pc(sd,0); } if( pd->s_skill && pd->s_skill->timer != INVALID_TIMER ) { if( pd->s_skill->id ) iTimer->delete_timer(pd->s_skill->timer, pet_skill_support_timer); else iTimer->delete_timer(pd->s_skill->timer, pet_heal_timer); pd->s_skill->timer = INVALID_TIMER; } if( pd->bonus && pd->bonus->timer != INVALID_TIMER ) { iTimer->delete_timer(pd->bonus->timer, pet_skill_bonus_timer); pd->bonus->timer = INVALID_TIMER; } } return 0; }
/** * Apply a pet's equipment. * @param sd : player requesting * @param index : index value of item * @return 0:success, 1:failure */ int pet_equipitem(struct map_session_data *sd,int index) { struct pet_data *pd; unsigned short nameid; nullpo_retr(1, sd); pd = sd->pd; if (!pd) return 1; nameid = sd->status.inventory[index].nameid; if(pd->petDB->AcceID == 0 || nameid != pd->petDB->AcceID || pd->pet.equip != 0) { clif_equipitemack(sd,0,0,0); return 1; } pc_delitem(sd,index,1,0,0,LOG_TYPE_OTHER); pd->pet.equip = nameid; status_set_viewdata(&pd->bl, pd->pet.class_); //Updates view_data. clif_pet_equip_area(pd); if (battle_config.pet_equip_required) { // Skotlex: start support timers if need unsigned int tick = gettick(); if (pd->s_skill && pd->s_skill->timer == INVALID_TIMER) { if (pd->s_skill->id) pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000, pet_skill_support_timer, sd->bl.id, 0); else pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000, pet_heal_timer, sd->bl.id, 0); } if (pd->bonus && pd->bonus->timer == INVALID_TIMER) pd->bonus->timer=add_timer(tick+pd->bonus->delay*1000, pet_skill_bonus_timer, sd->bl.id, 0); } return 0; }
int merc_hom_change_class (struct homun_data *hd, short class_) { int i; i = search_homunculusDB_index (class_, HOMUNCULUS_CLASS); if (i < 0) return 0; if(hd->homunculus.class_ == 2633 && class_ != 2634 || hd->homunculus.class_ == 2633 && class_ != 2635 || hd->homunculus.class_ == 2633 && class_ != 2636){ i = rand(0, 99); if(i < 34) class_ = 2634; else if(i <= 66 && i >= 34) class_ = 2635; else if(i > 66) class_ = 2636; } hd->homunculusDB = &homunculus_db[i]; hd->homunculus.class_ = class_; status_set_viewdata (&hd->bl, class_); merc_hom_calc_skilltree (hd); return 1; }
int pet_data_init(struct map_session_data *sd, struct s_pet *pet) { struct pet_data *pd; int i = 0, interval = 0; nullpo_retr(1,sd); Assert((sd->status.pet_id == 0 || sd->pd == NULL) || sd->pd->master == sd); if(sd->status.account_id != pet->account_id || sd->status.char_id != pet->char_id) { sd->status.pet_id = 0; return 1; } if(sd->status.pet_id != pet->pet_id) { if(sd->status.pet_id) { //Wrong pet?? Set incubate to no and send it back for saving pet->incubate = 1; intif_save_petdata(sd->status.account_id,pet); sd->status.pet_id = 0; return 1; } //The pet_id value was lost? Odd, restore it sd->status.pet_id = pet->pet_id; } i = search_petDB_index(pet->class_,PET_CLASS); if(i < 0) { sd->status.pet_id = 0; return 1; } sd->pd = pd = (struct pet_data *)aCalloc(1,sizeof(struct pet_data)); pd->bl.type = BL_PET; pd->bl.id = npc_get_new_npc_id(); pd->master = sd; pd->petDB = &pet_db[i]; pd->db = mob_db(pet->class_); memcpy(&pd->pet,pet,sizeof(struct s_pet)); status_set_viewdata(&pd->bl,pet->class_); unit_dataset(&pd->bl); pd->ud.dir = sd->ud.dir; pd->bl.m = sd->bl.m; pd->bl.x = sd->bl.x; pd->bl.y = sd->bl.y; unit_calc_pos(&pd->bl,sd->bl.x,sd->bl.y,sd->ud.dir); pd->bl.x = pd->ud.to_x; pd->bl.y = pd->ud.to_y; map_addiddb(&pd->bl); status_calc_pet(pd,SCO_FIRST); pd->last_thinktime = gettick(); pd->state.skillbonus = 0; if(battle_config.pet_status_support) run_script(pet_db[i].pet_script,0,sd->bl.id,0); if(pd->petDB) { if(pd->petDB->pet_friendly_script) status_calc_pc(sd,SCO_NONE); if(battle_config.pet_hungry_delay_rate != 100) interval = pd->petDB->hungry_delay * battle_config.pet_hungry_delay_rate / 100; else interval = pd->petDB->hungry_delay; } if(interval <= 0) interval = 1; pd->pet_hungry_timer = add_timer(gettick() + interval,pet_hungry,sd->bl.id,0); pd->masterteleport_timer = INVALID_TIMER; return 0; }