示例#1
0
void itemdb_reload(void)
{
	struct s_mapiterator* iter;
	struct map_session_data* sd;

	int i,d,k;
	
	// clear the previous itemdb data
	for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
		if( itemdb_array[i] )
			destroy_item_data(itemdb_array[i], 1);

	itemdb_other->clear(itemdb_other, itemdb_final_sub);

	memset(itemdb_array, 0, sizeof(itemdb_array));
	
	// read new data
	itemdb_read();
	
	//Epoque's awesome @reloaditemdb fix - thanks! [Ind]
	//- Fixes the need of a @reloadmobdb after a @reloaditemdb to re-link monster drop data
	for( i = 0; i < MAX_MOB_DB; i++ ) {
		struct mob_db *entry;
		if( !((i < 1324 || i > 1363) && (i < 1938 || i > 1946)) )
			continue;
		entry = mob_db(i);
		for(d = 0; d < MAX_MOB_DROP; d++) {
			struct item_data *id;
			if( !entry->dropitem[d].nameid )
				continue;
			id = itemdb_search(entry->dropitem[d].nameid);

			for (k = 0; k < MAX_SEARCH; k++) {
				if (id->mob[k].chance <= entry->dropitem[d].p)
					break;
			}

			if (k == MAX_SEARCH)
				continue;
			
			if (id->mob[k].id != i)
				memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
			id->mob[k].chance = entry->dropitem[d].p;
			id->mob[k].id = i;
		}
	}

	// readjust itemdb pointer cache for each player
	iter = mapit_geteachpc();
	for( sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter); sd = (struct map_session_data*)mapit_next(iter) )
	{
		memset(sd->item_delay, 0, sizeof(sd->item_delay));  // reset item delays
		pc_setinventorydata(sd);
	}
	mapit_free(iter);
}
示例#2
0
文件: pet.c 项目: 544a/rathena
/**
 * 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;
}
示例#3
0
文件: pet.c 项目: ChowZenki/Cronus
int pet_create_egg(struct map_session_data *sd, int item_id)
{
	int pet_id = search_petDB_index(item_id, PET_EGG);
	if (pet_id < 0) return 0; //No pet egg here.
	sd->catch_target_class = pet_db[pet_id].class_;
	intif_create_pet(sd->status.account_id, sd->status.char_id,
		(short)pet_db[pet_id].class_,
		(short)mob_db(pet_db[pet_id].class_)->lv,
		(short)pet_db[pet_id].EggID, 0,
		(short)pet_db[pet_id].intimate,
		100, 0, 1, pet_db[pet_id].jname);
	return 1;
}
示例#4
0
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;
}
示例#5
0
bool AchievementCheck_KillMob(struct map_session_data *Player, struct AchievementObject *Achieve, va_list Args) {
    int j, MobID;
    struct mob_db *db;
    bool canUpdate = false, isComplete = true;
    struct AchievementRequireMobObject r;

    MobID = va_arg(Args, int);
    if ((db = mob_db(MobID)) == NULL) {
        return 0;
    }

    for (j = 0; j < MAX_ACHIEVE_PARAMS; j++) {
        // no Count, end of Data
        r = Achieve->RequireMob[j];
        if (r.Count == 0) {
            break;
        }

        // check for valid killed Mob
        if (r.ID > 0) {
            if (r.ID != MobID) {
                isComplete = false;
                continue;
            }
            canUpdate = true;
        }
        if (r.Mode > 0) { // we need to kill a special mode
            if (!(db->status.mode & r.Mode) ) {
                isComplete = false;
                continue;
            }
            // Special check for MvPs, check MvP EXP
            if ((r.Mode & MD_BOSS) && db->mexp == 0) {
                isComplete = false;
                continue;
            }
            canUpdate = true;
        }
        if (r.Race > 0) { // need a special race
            if (db->status.race != r.Race) {
                isComplete = false;
                continue;
            }
            canUpdate = true;
        }

        if (canUpdate == true) {
            // increment counter & set as updateable
            achieve_Update(Player, Achieve, j, 1);
        }
    }


    // Finished all these requirements?
    if (isComplete == false) {
        return 0;
    }

    // Notify caller that the required mobs are complete
    return achieve_isComplete(Player, Achieve);
}
示例#6
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;
}
示例#7
0
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 == 0) || sd->pd->msd == 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 incuvate to no and send it back for saving.
			pet->incuvate = 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->msd = sd;
	pd->petDB = &pet_db[i];
	pd->db = mob_db(pet->class_);
	memcpy(&pd->pet, pet, sizeof(struct s_pet));
	iStatus->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;

	iMap->addiddb(&pd->bl);
	status_calc_pet(pd,1);

	pd->last_thinktime = iTimer->gettick();
	pd->state.skillbonus = 0;
	if( battle_config.pet_status_support )
		script->run(pet_db[i].pet_script,0,sd->bl.id,0);
	if( pd->petDB && pd->petDB->equip_script )
		status_calc_pc(sd,0);

	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 = iTimer->add_timer(iTimer->gettick() + interval, pet_hungry, sd->bl.id, 0);
	return 0;
}