Exemple #1
0
int merc_delete(struct mercenary_data *md, int reply)
{
	struct map_session_data *sd = md->master;
	md->mercenary.life_time = 0;

	merc_contract_stop(md);

	if( !sd )
		return unit_free(&md->bl, CLR_OUTSIGHT);

	if( md->devotion_flag )
	{
		md->devotion_flag = 0;
		status_change_end(&sd->bl, SC_DEVOTION, INVALID_TIMER);
	}

	switch( reply )
	{
		case 0: mercenary_set_faith(md, 1); break; // +1 Loyalty on Contract ends.
		case 1: mercenary_set_faith(md, -1); break; // -1 Loyalty on Mercenary killed
	}

	clif->mercenary_message(sd, reply);
	return unit_remove_map(&md->bl, CLR_OUTSIGHT);
}
Exemple #2
0
/**
* Vaporize a character's homunculus
* @param sd
* @param flag 1: then HP needs to be 80% or above. 2: then set to morph state.
*/
int hom_vaporize(struct map_session_data *sd, int flag)
{
	struct homun_data *hd;

	nullpo_ret(sd);

	hd = sd->hd;
	if (!hd || hd->homunculus.vaporize)
		return 0;

	if (status_isdead(&hd->bl))
		return 0; //Can't vaporize a dead homun.

	if (flag == HOM_ST_REST && get_percentage(hd->battle_status.hp, hd->battle_status.max_hp) < 80)
		return 0;

	hd->regen.state.block = 3; //Block regen while vaporized.
	//Delete timers when vaporized.
	hom_hungry_timer_delete(hd);
	hd->homunculus.vaporize = flag ? flag : HOM_ST_REST;
	if (battle_config.hom_setting&HOMSET_RESET_REUSESKILL_VAPORIZED)
		memset(hd->blockskill, 0, sizeof(hd->blockskill));
	clif_hominfo(sd, sd->hd, 0);
	hom_save(hd);
	return unit_remove_map(&hd->bl, CLR_OUTSIGHT);
}
//Vaporize a character's homun. If flag, HP needs to be 80% or above.
int merc_hom_vaporize(struct map_session_data *sd, int flag)
{
	struct homun_data *hd;

	nullpo_retr(0, sd);

	hd = sd->hd;
	if (!hd || hd->homunculus.vaporize)
		return 0;
	
	if (status_isdead(&hd->bl))
		return 0; //Can't vaporize a dead homun.

	if (flag && status_calc_life(hd->battle_status.hp, hd->battle_status.max_hp)< 80)
		return 0;

	hd->regen.state.block = 3; //Block regen while vaporized.
	//Delete timers when vaporized.
	merc_hom_hungry_timer_delete(hd);
	hd->homunculus.vaporize = 1;
	if(battle_config.hom_setting&0x40)
		memset(hd->blockskill, 0, sizeof(hd->blockskill));
	clif_hominfo(sd, sd->hd, 0);
	merc_save(hd);
	return unit_remove_map(&hd->bl, 0);
}
Exemple #4
0
int merc_hom_mutation(struct homun_data *hd, int class_)
{
	struct s_homunculus *hom;
	struct map_session_data *sd;
	nullpo_ret(hd);
	
	//Only allows mutating level 99 evolved homunculus and also prevents mutating already mutated homunculus.
	if( hd->homunculus.level < 99 || !(hd->homunculus.class_ >= 6009 && hd->homunculus.class_ <= 6016) || 
		hd->homunculus.class_ >= MH_CLASS_BASE && hd->homunculus.class_ <= MH_CLASS_MAX)
	{
		clif_emotion(&hd->bl, E_SWT);
		return 0 ;
	}
	sd = hd->master;
	if (!sd)
		return 0;

	if (!merc_hom_change_class(hd, class_)) {
		ShowError("merc_hom_mutation: Can't mutate homunc from %d to %d", hd->homunculus.class_, class_);
		return 0;
	}

	// Its said the player can rename the homunculus again after mutation.
	// This might be true since the homunculus's form completely changes.
	hd->homunculus.rename_flag = 0;

	//Apply mutation bonuses.
	//Bonuses are the same for all mutations.
	hom = &hd->homunculus;
	hom->max_hp += rand(1000, 2000);
	hom->max_sp += rand(10, 200);
	hom->str += 10*rand(1, 10);
	hom->agi += 10*rand(1, 10);
	hom->vit += 10*rand(1, 10);
	hom->int_+= 10*rand(1, 10);
	hom->dex += 10*rand(1, 10);
	hom->luk += 10*rand(1, 10);

	unit_remove_map(&hd->bl, CLR_OUTSIGHT);
	map_addblock(&hd->bl);

	clif_spawn(&hd->bl);
	clif_emotion(&sd->bl, E_NO1);
	clif_specialeffect(&hd->bl,568,AREA);

	//status_Calc flag&1 will make current HP/SP be reloaded from hom structure
	hom->hp = hd->battle_status.hp;
	hom->sp = hd->battle_status.sp;
	status_calc_homunculus(hd,1);

	if (!(battle_config.hom_setting&0x2))
		skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately

	return 1 ;
}
Exemple #5
0
/**
 * Make an homonculus evolve, (changing in evolution class and apply bonus)
 * @param hd : homonculus datas
 * @return 0:failure, 1:success
 */
int merc_hom_evolution(struct homun_data *hd)
{
	struct s_homunculus *hom;
	struct h_stats *max, *min;
	struct map_session_data *sd;
	nullpo_ret(hd);

	if(!hd->homunculusDB->evo_class || hd->homunculus.class_ == hd->homunculusDB->evo_class)
	{
		clif_emotion(&hd->bl, E_SWT);
		return 0 ;
	}
	sd = hd->master;
	if (!sd)
		return 0;

	if (!merc_hom_change_class(hd, hd->homunculusDB->evo_class)) {
		ShowError("merc_hom_evolution: Can't evolve homunc from %d to %d", hd->homunculus.class_, hd->homunculusDB->evo_class);
		return 0;
	}

	//Apply evolution bonuses
	hom = &hd->homunculus;
	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);
	hom->intimacy = 500;

	unit_remove_map(&hd->bl, CLR_OUTSIGHT);
	if(map_addblock(&hd->bl))
		return 0;

	clif_spawn(&hd->bl);
	clif_emotion(&sd->bl, E_NO1);
	clif_specialeffect(&hd->bl,568,AREA);

	//status_Calc flag&1 will make current HP/SP be reloaded from hom structure
	hom->hp = hd->battle_status.hp;
	hom->sp = hd->battle_status.sp;
	status_calc_homunculus(hd,1);

	if (!(battle_config.hom_setting&0x2))
		skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately

	return 1 ;
}
Exemple #6
0
/**
 * Begin the actual catching process of a monster.
 * @param sd : player requesting
 * @param target_id : monster ID of pet to catch
 * @return 0:success, 1:failure
 */
int pet_catch_process2(struct map_session_data* sd, int target_id)
{
	struct mob_data* md;
	int i = 0, pet_catch_rate = 0;

	nullpo_retr(1, sd);

	md = (struct mob_data*)map_id2bl(target_id);

	if(!md || md->bl.type != BL_MOB || md->bl.prev == NULL) { // Invalid inputs/state, abort capture.
		clif_pet_roulette(sd,0);
		sd->catch_target_class = -1;
		sd->itemid = sd->itemindex = -1;
		return 1;
	}

	//FIXME: delete taming item here, if this was an item-invoked capture and the item was flagged as delay-consume [ultramage]

	i = search_petDB_index(md->mob_id,PET_CLASS);

	//catch_target_class == 0 is used for universal lures (except bosses for now). [Skotlex]
	if (sd->catch_target_class == 0 && !status_has_mode(&md->status,MD_STATUS_IMMUNE))
		sd->catch_target_class = md->mob_id;

	if(i < 0 || sd->catch_target_class != md->mob_id) {
		clif_emotion(&md->bl, E_AG);	//mob will do /ag if wrong lure is used on them.
		clif_pet_roulette(sd,0);
		sd->catch_target_class = -1;

		return 1;
	}

	pet_catch_rate = (pet_db[i].capture + (sd->status.base_level - md->level)*30 + sd->battle_status.luk*20)*(200 - get_percentage(md->status.hp, md->status.max_hp))/100;

	if(pet_catch_rate < 1)
		pet_catch_rate = 1;

	if(battle_config.pet_catch_rate != 100)
		pet_catch_rate = (pet_catch_rate*battle_config.pet_catch_rate)/100;

	if(rnd()%10000 < pet_catch_rate) {
		unit_remove_map(&md->bl,CLR_OUTSIGHT);
		status_kill(&md->bl);
		clif_pet_roulette(sd,1);
		intif_create_pet(sd->status.account_id,sd->status.char_id,pet_db[i].class_,mob_db(pet_db[i].class_)->lv,
			pet_db[i].EggID,0,pet_db[i].intimate,100,0,1,pet_db[i].jname);
	} else {
		clif_pet_roulette(sd,0);
		sd->catch_target_class = -1;
	}

	return 0;
}
Exemple #7
0
int elemental_delete (struct elemental_data *ed, int reply)
{
	struct map_session_data *sd;
	nullpo_ret (ed);
	sd = ed->master;
	ed->elemental.life_time = 0;
	elemental_clean_effect (ed);
	elemental_summon_stop (ed);

	if (!sd)
		return unit_free (&ed->bl, 0);

	sd->ed = NULL;
	sd->status.ele_id = 0;
	return unit_remove_map (&ed->bl, 0);
}
Exemple #8
0
/**
 * Make an homonculus mutate in renewal homon
 * @param hd : homonculus datas
 * @param homun_id : id to make it transform into (must be a valid homon class)
 * @return 0:failure, 1:sucess
 */
int hom_mutate(struct homun_data *hd, int homun_id)
{
	struct s_homunculus *hom;
	struct map_session_data *sd;
	int m_class, m_id, prev_class = 0;
	nullpo_ret(hd);

	m_class = hom_class2mapid(hd->homunculus.class_);
	m_id    = hom_class2mapid(homun_id);

	if( m_class == -1 || m_id == -1 || !(m_class&HOM_EVO) || !(m_id&HOM_S) ) {
		clif_emotion(&hd->bl, E_SWT);
		return 0;
	}

	sd = hd->master;
	if (!sd)
		return 0;

	prev_class = hd->homunculus.class_;

	if (!hom_change_class(hd, homun_id)) {
		ShowError("hom_mutate: Can't evolve homunc from %d to %d", hd->homunculus.class_, homun_id);
		return 0;
	}

	unit_remove_map(&hd->bl, CLR_OUTSIGHT);
	if(map_addblock(&hd->bl))
		return 0;

	clif_spawn(&hd->bl);
	clif_emotion(&sd->bl, E_NO1);
	clif_specialeffect(&hd->bl,568,AREA);


	//status_Calc flag&1 will make current HP/SP be reloaded from hom structure
	hom = &hd->homunculus;
	hom->hp = hd->battle_status.hp;
	hom->sp = hd->battle_status.sp;
	hom->prev_class = prev_class;
	status_calc_homunculus(hd, SCO_FIRST);

	if (!(battle_config.hom_setting&0x2))
		skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately

	return 1;
}
Exemple #9
0
/**
* Delete a homunculus, completely "killing it".
* Emote is the emotion the master should use, send negative to disable.
* @param hd
* @param emote
*/
int hom_delete(struct homun_data *hd, int emote)
{
	struct map_session_data *sd;
	nullpo_ret(hd);
	sd = hd->master;

	if (!sd)
		return unit_free(&hd->bl,CLR_DEAD);

	if (emote >= 0)
		clif_emotion(&sd->bl, emote);

	//This makes it be deleted right away.
	hd->homunculus.intimacy = 0;
	// Send homunculus_dead to client
	hd->homunculus.hp = 0;
	clif_hominfo(sd, hd, 0);
	return unit_remove_map(&hd->bl,CLR_OUTSIGHT);
}
//Vaporize a character's homun. If flag, HP needs to be 80% or above.
int merc_hom_vaporize(struct map_session_data *sd, int flag)
{
	struct item tmp_item;
	struct s_homunculus *hom;
	struct homun_data *hd;
	int rate;

	hd = sd->hd;
	hom = &hd->homunculus;
	sd->status.lock = 0;
	
	if(hom->ditto == 1){
		//hd->homunculus.class_ = 2502;
		//status_set_viewdata(&hd->bl, 2502);
		//merc_hom_calc_skilltree(hd);
		rate = 8162;
	}else{
	rate =(hd->homunculus.class_) + 5530;
	}
	merc_save(hd);

	hom->char_id = sd->status.char_id;

	memset(&tmp_item,0,sizeof(tmp_item));
	tmp_item.nameid = rate;
	tmp_item.identify = 1;
	tmp_item.card[0] = CARD0_HUN;
	tmp_item.card[1] = GetWord(hd->homunculus.hom_id,0);
	tmp_item.card[2] = GetWord(hd->homunculus.hom_id,1);
	tmp_item.card[3] = 0;
	if((flag = pc_additem(sd,&tmp_item,1))) {
		clif_additem(sd,0,0,flag);
		map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
}
	sd = hd->master;
	hd->homunculus.intimacy = 0;
	return unit_remove_map(&hd->bl,CLR_OUTSIGHT);
	
}
int merc_hom_dead(struct homun_data *hd, int flag)
{   
	struct map_session_data *sd = hd->master;
	struct s_homunculus *hom;
	struct item tmp_item;
	int rate;
	sd = hd->master;
	hd = sd->hd;
	hom = &hd->homunculus;
	rate =(hd->homunculus.class_) + 5530;
	merc_save(hd);
	sd = hd->master;
	pc_delitem(sd, pc_search_inventory(sd,690), 1, 0, 0);
	//sd->status.hom_id = 0;
	
	sd->status.lock = 0;
	merc_hom_hungry_timer_delete(hd);
	hd->homunculus.hp = 0;

	hom->char_id = sd->status.char_id;
	
	memset(&tmp_item,0,sizeof(tmp_item));
	tmp_item.nameid = rate;
	tmp_item.identify = 1;
	tmp_item.card[0] = CARD0_HUN;
	tmp_item.card[1] = GetWord(hd->homunculus.hom_id,0);
	tmp_item.card[2] = GetWord(hd->homunculus.hom_id,1);
	tmp_item.card[3] = 1;
	if((flag = pc_additem(sd,&tmp_item,1))) {
		clif_additem(sd,0,0,flag);
		map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
}
	hd->homunculus.hp = 0;
	hd->homunculus.intimacy = 0;
	return unit_remove_map(&hd->bl,CLR_OUTSIGHT);
}
Exemple #12
0
int pet_catch_process2(struct map_session_data *sd,int target_id)
{
	struct mob_data *md;
	int i=0,pet_catch_rate=0;

	nullpo_retr(1, sd);

	md=(struct mob_data*)map_id2bl(target_id);
	if(!md || md->bl.type != BL_MOB || md->bl.prev == NULL){
		//Abort capture.
		sd->catch_target_class = -1;
		sd->itemid = sd->itemindex = -1;
		return 1;
	}
	
	if (sd->menuskill_id != SA_TAMINGMONSTER) 
	{	//Exploit?
		clif_pet_rulet(sd,0);
		sd->catch_target_class = -1;
		return 1;
	}
	
	if (sd->menuskill_lv > 0)
	{	//Consume the pet lure [Skotlex]
		i=pc_search_inventory(sd,sd->menuskill_lv);
		if (i < 0)
		{	//they tried an exploit?
			clif_pet_rulet(sd,0);
			sd->catch_target_class = -1;
			return 1;
		}
		//Delete the item
		if (sd->itemid == sd->menuskill_lv)
			sd->itemid = sd->itemindex = -1;
		sd->menuskill_id = sd->menuskill_lv = 0;
		pc_delitem(sd,i,1,0);
	}

	i = search_petDB_index(md->class_,PET_CLASS);
	//catch_target_class == 0 is used for universal lures. [Skotlex]
	//for now universal lures do not include bosses.
	if (sd->catch_target_class == 0 && !(md->status.mode&MD_BOSS))
		sd->catch_target_class = md->class_;
	if(i < 0 || sd->catch_target_class != md->class_) {
		clif_emotion(&md->bl, 7);	//mob will do /ag if wrong lure is used on them.
		clif_pet_rulet(sd,0);
		sd->catch_target_class = -1;
		return 1;
	}

	pet_catch_rate = (pet_db[i].capture + (sd->status.base_level - md->level)*30 + sd->battle_status.luk*20)*(200 - md->status.hp*100/md->status.max_hp)/100;
	if(pet_catch_rate < 1) pet_catch_rate = 1;
	if(battle_config.pet_catch_rate != 100)
		pet_catch_rate = (pet_catch_rate*battle_config.pet_catch_rate)/100;

	if(rand()%10000 < pet_catch_rate) {
		unit_remove_map(&md->bl,0);
		status_kill(&md->bl);
		clif_pet_rulet(sd,1);
//		if(battle_config.etc_log)
//			printf("rulet success %d\n",target_id);
		intif_create_pet(sd->status.account_id,sd->status.char_id,pet_db[i].class_,mob_db(pet_db[i].class_)->lv,
			pet_db[i].EggID,0,pet_db[i].intimate,100,0,1,pet_db[i].jname);
	}
	else
	{
		sd->catch_target_class = -1;
		clif_pet_rulet(sd,0);
	}

	return 0;
}