Exemplo n.º 1
0
//---------------------------------------------------------
int inter_pet_tosql (int pet_id, struct s_pet *p)
{
	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
	char esc_name[NAME_LENGTH * 2 + 1]; // escaped pet name
	Sql_EscapeStringLen (sql_handle, esc_name, p->name, strnlen (p->name, NAME_LENGTH));
	p->hungry = cap_value (p->hungry, 0, 100);
	p->intimate = cap_value (p->intimate, 0, 1000);

	if (pet_id == -1) {
		// New pet.
		if (SQL_ERROR == Sql_Query (sql_handle, "INSERT INTO `%s` "
									"(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`) "
									"VALUES ('%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
									pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
									p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate)) {
			Sql_ShowDebug (sql_handle);
			return 0;
		}

		p->pet_id = (int) Sql_LastInsertId (sql_handle);
	} else {
		// Update pet.
		if (SQL_ERROR == Sql_Query (sql_handle, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incuvate`='%d' WHERE `pet_id`='%d'",
									pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
									p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate, p->pet_id)) {
			Sql_ShowDebug (sql_handle);
			return 0;
		}
	}

	if (save_log)
		ShowInfo ("Pet salvo %d - %s.\n", pet_id, p->name);

	return 1;
}
Exemplo n.º 2
0
//Exp share and added zeny share [Valaris]
int party_exp_share(struct party_data *p, struct block_list *src, unsigned int base_exp, unsigned int job_exp, int zeny)
{
	struct map_session_data *sd[MAX_PARTY];
	unsigned int i, c;
#ifdef RENEWAL_EXP
	uint32 base_exp_bonus, job_exp_bonus;
#endif
	nullpo_ret(p);

	//Count the number of players eligible for exp sharing
	for (i = c = 0; i < MAX_PARTY; i++) {
		if ((sd[c] = p->data[i].sd) == NULL || sd[c]->bl.m != src->m || pc_isdead(sd[c]) || (battle_config.idle_no_share && pc_isidle(sd[c])))
			continue;
		c++;
	}
	if (c < 1)
		return 0;

	base_exp /= c;
	job_exp /= c;
	zeny /= c;

	if (battle_config.party_even_share_bonus && c > 1) {
		double bonus = 100 + battle_config.party_even_share_bonus * (c - 1);

		if (base_exp)
			base_exp = (unsigned int)cap_value(base_exp * bonus / 100, 0, UINT_MAX);
		if (job_exp)
			job_exp = (unsigned int)cap_value(job_exp * bonus / 100, 0, UINT_MAX);
		if (zeny)
			zeny = (unsigned int)cap_value(zeny * bonus / 100, INT_MIN, INT_MAX);
	}

#ifdef RENEWAL_EXP
	base_exp_bonus = base_exp;
	job_exp_bonus = job_exp;
#endif

	for (i = 0; i < c; i++) {
#ifdef RENEWAL_EXP
		if (!(src && src->type == BL_MOB && ((TBL_MOB *)src)->db->mexp)) {
			TBL_MOB *md = BL_CAST(BL_MOB, src);
			int rate = 0;

			if (!md)
				return 0;

			rate = pc_level_penalty_mod(sd[i], md->db->lv, md->db->status.class_, 1);
			base_exp = (unsigned int)cap_value(base_exp_bonus * rate / 100, 1, UINT_MAX);
			job_exp = (unsigned int)cap_value(job_exp_bonus * rate / 100, 1, UINT_MAX);
		}
#endif
		pc_gainexp(sd[i], src, base_exp, job_exp, false);

		if (zeny) //Zeny from mobs [Valaris]
			pc_getzeny(sd[i],zeny,LOG_TYPE_PICKDROP_MONSTER,NULL);
	}
	return 0;
}
Exemplo n.º 3
0
/** Party EXP and Zeny sharing
 * @param p Party data
 * @param src EXP source (for renewal level penalty)
 * @param base_exp Base EXP gained from killed mob
 * @param job_exp Job EXP gained from killed mob
 * @param zeny Zeny gained from killed mob
 * @author Valaris
 **/
void party_exp_share(struct party_data* p, struct block_list* src, unsigned int base_exp, unsigned int job_exp, int zeny)
{
	struct map_session_data* sd[MAX_PARTY];
	unsigned int i, c;
#ifdef RENEWAL_EXP
	TBL_MOB *md = BL_CAST(BL_MOB, src);

	if (!md)
		return;
#endif

	nullpo_retv(p);

	// count the number of players eligible for exp sharing
	for (i = c = 0; i < MAX_PARTY; i++) {
		if( (sd[c] = p->data[i].sd) == NULL || sd[c]->bl.m != src->m || pc_isdead(sd[c]) || (battle_config.idle_no_share && pc_isidle(sd[c])) )
			continue;
		c++;
	}
	if (c < 1)
		return;

	base_exp/=c;
	job_exp/=c;
	zeny/=c;

	if (battle_config.party_even_share_bonus && c > 1) {
		double bonus = 100 + battle_config.party_even_share_bonus*(c-1);

		if (base_exp)
			base_exp = (unsigned int) cap_value(base_exp * bonus/100, 0, UINT_MAX);
		if (job_exp)
			job_exp = (unsigned int) cap_value(job_exp * bonus/100, 0, UINT_MAX);
		if (zeny)
			zeny = (unsigned int) cap_value(zeny * bonus/100, INT_MIN, INT_MAX);
	}

	for (i = 0; i < c; i++) {
#ifdef RENEWAL_EXP
		uint32 base_gained = base_exp, job_gained = job_exp;
		if (base_exp || job_exp) {
			int rate = pc_level_penalty_mod(md->level - sd[i]->status.base_level, md->db->status.class_, md->db->status.mode, 1);
			if (rate != 100) {
				if (base_exp)
					base_gained = (unsigned int)cap_value(apply_rate(base_exp, rate), 1, UINT_MAX);
				if (job_exp)
					job_gained = (unsigned int)cap_value(apply_rate(job_exp, rate), 1, UINT_MAX);
			}
		}
		pc_gainexp(sd[i], src, base_gained, job_gained, 0);
#else
		pc_gainexp(sd[i], src, base_exp, job_exp, 0);
#endif

		if (zeny) // zeny from mobs [Valaris]
			pc_getzeny(sd[i],zeny,LOG_TYPE_PICKDROP_MONSTER,NULL);
	}
}
Exemplo n.º 4
0
int inter_pet_fromsql(int pet_id, struct s_pet* p)
{
    char* data;
    size_t len;

#ifdef NOISY
    ShowInfo("Loading pet (%d)...\n",pet_id);
#endif
    memset(p, 0, sizeof(struct s_pet));

    //`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)

    if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate` FROM `%s` WHERE `pet_id`='%d'", pet_db, pet_id) )
    {
        Sql_ShowDebug(sql_handle);
        return 0;
    }

    if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
    {
        p->pet_id = pet_id;
        Sql_GetData(sql_handle,  1, &data, NULL);
        p->class_ = atoi(data);
        Sql_GetData(sql_handle,  2, &data, &len);
        memcpy(p->name, data, min(len, NAME_LENGTH));
        Sql_GetData(sql_handle,  3, &data, NULL);
        p->account_id = atoi(data);
        Sql_GetData(sql_handle,  4, &data, NULL);
        p->char_id = atoi(data);
        Sql_GetData(sql_handle,  5, &data, NULL);
        p->level = atoi(data);
        Sql_GetData(sql_handle,  6, &data, NULL);
        p->egg_id = atoi(data);
        Sql_GetData(sql_handle,  7, &data, NULL);
        p->equip = atoi(data);
        Sql_GetData(sql_handle,  8, &data, NULL);
        p->intimate = atoi(data);
        Sql_GetData(sql_handle,  9, &data, NULL);
        p->hungry = atoi(data);
        Sql_GetData(sql_handle, 10, &data, NULL);
        p->rename_flag = atoi(data);
        Sql_GetData(sql_handle, 11, &data, NULL);
        p->incuvate = atoi(data);

        Sql_FreeResult(sql_handle);

        p->hungry = cap_value(p->hungry, 0, 100);
        p->intimate = cap_value(p->intimate, 0, 1000);

        if( save_log )
            ShowInfo("Pet loaded (%d - %s).\n", pet_id, p->name);
    }
    return 0;
}
Exemplo n.º 5
0
// exp share and added zeny share [Valaris]
int party_exp_share(struct party_data* p, struct block_list* src, unsigned int base_exp, unsigned int job_exp, int zeny)
{
	struct map_session_data* sd[MAX_PARTY];
	unsigned int i, c;

	nullpo_retr(0, p);

	// count the number of players eligible for exp sharing
	for( i = c = 0; i < MAX_PARTY; i++ )
	{
		if( (sd[c] = p->data[i].sd) == NULL || sd[c]->bl.m != src->m || pc_isdead(sd[c]) || (battle_config.idle_no_share && pc_isidle(sd[c])) )
			continue;
		c++;
	}
	if( c < 1 )
		return 0;

	base_exp /= c;	
	job_exp /= c;
	zeny /= c;

	if( battle_config.renewal_system_enable && c > 2 )
	{
		int rbonus = 100 + (10 * (c - 2)); // 10% ~ 100%
		if( base_exp )
			base_exp = (unsigned int) cap_value(base_exp * rbonus/100, 0, UINT_MAX);
		if( job_exp )
			job_exp = (unsigned int) cap_value(job_exp * rbonus/100, 0, UINT_MAX);
	}

	if( battle_config.party_even_share_bonus && c > 1 )
	{
		double bonus = 100 + battle_config.party_even_share_bonus*(c-1);
		if (base_exp)
			base_exp = (unsigned int) cap_value(base_exp * bonus/100, 0, UINT_MAX);
		if (job_exp)
			job_exp = (unsigned int) cap_value(job_exp * bonus/100, 0, UINT_MAX);
		if (zeny)
			zeny = (unsigned int) cap_value(zeny * bonus/100, INT_MIN, INT_MAX);
	}

	for( i = 0; i < c; i++ )
	{
		pc_gainexp(sd[i],src,base_exp,job_exp,false);
		if( zeny ) // zeny from mobs [Valaris]
			pc_getzeny(sd[i],zeny);
	}

	return 0;
}
Exemplo n.º 6
0
int mercenary_set_faith(struct mercenary_data *md, int value)
{
	struct map_session_data *sd;
	int class_, *faith;

	if( md == NULL || md->db == NULL || (sd = md->master) == NULL )
		return 0;

	class_ = md->db->class_;

	if( class_ >= 6017 && class_ <= 6026 )
		faith = &sd->status.arch_faith;
	else if( class_ >= 6027 && class_ <= 6036 )
		faith = &sd->status.spear_faith;
	else if( class_ >= 6037 && class_ <= 6046 )
		faith = &sd->status.sword_faith;
	else
		return 0;

	*faith += value;
	*faith = cap_value(*faith, 0, SHRT_MAX);
	clif->mercenary_updatestatus(sd, SP_MERCFAITH);

	return 0;
}
Exemplo n.º 7
0
CBazaarItemPacket::CBazaarItemPacket(CItem* PItem, uint8 slotID, uint8 tax) 
{
	this->type = 0x05;	// 0x105
	this->size = 0x17;

	WBUFL(data,(0x04)-4) = PItem->getCharPrice();
	WBUFL(data,(0x08)-4) = PItem->getQuantity();
	WBUFW(data,(0x0C)-4) = tax;
	WBUFW(data,(0x0E)-4) = PItem->getID();

	WBUFB(data,(0x10)-4) = slotID;

	if (PItem->getSubType() & ITEM_CHARGED)
	{
		uint32 currentTime = CVanaTime::getInstance()->getSysTime() - 1009810800;
		uint32 nextUseTime = ((CItemUsable*)PItem)->getLastUseTime() + ((CItemUsable*)PItem)->getReuseDelay();

		WBUFB(data,(0x11)-4) = 0x01;													// флаг ITEM_CHARGED
		WBUFB(data,(0x12)-4) = ((CItemUsable*)PItem)->getCurrentCharges(); 
		WBUFB(data,(0x14)-4) = (nextUseTime > currentTime ? 0x90 : 0xD0); 

	    WBUFL(data,(0x15)-4) = nextUseTime;												// таймер следующего использования
		WBUFL(data,(0x19)-4) = ((CItemUsable*)PItem)->getUseDelay() + currentTime;		// таймер задержки использования
	}

	memcpy(data+(0x1D)-4, PItem->getSignature(), cap_value(strlen(PItem->getSignature()), 0, 12));
}
Exemplo n.º 8
0
bool channel_create(struct map_session_data *sd, const char* name, const char* pass, short type, short color, int op)
{
	struct channel_data *cd;
	int i = 0;

	if( !name || strlen(name) < 2 || strlen(name) >= NAME_LENGTH || name[0] != '#' )
	{
		if( sd ) clif_displaymessage(sd->fd, msg_txt(801));
		return false;
	}
	if( type == CHN_USER && !sd )
		return false; // Operator required for user channels
	if( sd && type == CHN_USER && (i = channel_slot_free(sd)) < 0 )
	{
		clif_displaymessage(sd->fd, msg_txt(800));
		return false;
	}
	if( (cd = (struct channel_data *)strdb_get(channel_db, name)) != NULL )
	{
		if( sd ) clif_displaymessage(sd->fd, msg_txt(802));
		return false; // Already exists
	}

	CREATE(cd, struct channel_data, 1);
	cd->channel_id = ++channel_counter;
	safestrncpy(cd->name, name, sizeof(cd->name));
	safestrncpy(cd->pass, pass, sizeof(cd->pass));
	cd->type = type;
	cd->color = channel_color[cap_value(color,0,38)];
	cd->users = 0;
	cd->op = 0;
	cd->users_db = idb_alloc(DB_OPT_BASE);

	if( type == CHN_USER )
	{
		char output[128];
		sprintf(output, msg_txt(803), cd->name, sd->status.name);
		
		sd->cd[i] = cd;
		cd->op = sd->bl.id;
		idb_put(cd->users_db, sd->bl.id, sd);
		cd->users++;
		clif_channel_message(cd, output, -1);
	}
	else if( type < CHN_USER )
	{
		server_channel[type] = cd; // Quick access to main channels
		ShowInfo("Channel System : New channel %s created.\n", cd->name);
	}
	else
		cd->op = op; // Server Channel

	strdb_put(channel_db, cd->name, cd);
	return true;
}
Exemplo n.º 9
0
void vsx_widget_controller_slider::command_process_back_queue(vsx_command_s *t)
{
  if (owned && t->cmd == "si") { vsx_widget::command_process_back_queue(t); }
  else
  if (t->cmd == "u") {
    target_value = vsx_string_helper::s2f(t->cmd_data);
    cap_value();
    send_to_server();
    k_focus = this;
  } else vsx_widget_controller_base::command_process_back_queue(t);
}
Exemplo n.º 10
0
void vsx_widget_controller_slider::event_mouse_move(vsx_widget_distance distance,vsx_widget_coords coords)
{
  VSX_UNUSED(coords);

  if (controlling)
  {
    target_value = (-(((distance.corner.y-handlesize/2)/(size.y-handlesize))-1) * (amp))+ofs; //amp-ofs
    cap_value();
  }
  send_to_server();
  ++mouse_moves;
}
Exemplo n.º 11
0
// ギルド役職変更
int guild_change_position(int guild_id,int idx,
	int mode,int exp_mode,const char *name)
{
	struct guild_position p;

	exp_mode = cap_value(exp_mode, 0, battle_config.guild_exp_limit);
	//Mode 0x01 <- Invite
	//Mode 0x10 <- Expel.
	p.mode=mode&0x11;
	p.exp_mode=exp_mode;
	safestrncpy(p.name,name,NAME_LENGTH);
	return intif_guild_position(guild_id,idx,&p);
}
Exemplo n.º 12
0
// ギルド役職変更
int guild_change_position(int guild_id,int idx,
	int mode,int exp_mode,const char *name)
{
	struct guild_position p;

	exp_mode = cap_value(exp_mode, 0, battle_config.guild_exp_limit);
	//Mode 0x01 <- Invite
	//Mode 0x10 <- Expel.
	p.mode=mode&0x11;
	p.exp_mode=exp_mode;
	memcpy(p.name,name,NAME_LENGTH-1);
	p.name[NAME_LENGTH-1] = '\0'; //Security check... [Skotlex]
	return intif_guild_position(guild_id,idx,&p);
}
Exemplo n.º 13
0
int mercenary_kills(struct mercenary_data *md)
{
    md->mercenary.kill_count++;
    md->mercenary.kill_count = cap_value(md->mercenary.kill_count, 0, INT_MAX);

    if((md->mercenary.kill_count % 50) == 0) {
        mercenary_set_faith(md, 1);
        mercenary_killbonus(md);
    }

    if(md->master)
        clif_mercenary_updatestatus(md->master, SP_MERCKILLS);

    return 0;
}
Exemplo n.º 14
0
struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv){
	struct skill_condition req;
	uint16 idx = skill_get_index(skill_id);

	memset(&req,0,sizeof(req));

	if( idx == 0 ) // invalid skill id
		return req;

	skill_lv = cap_value(skill_lv, 1, MAX_SKILL_LEVEL);

	req.hp = skill_db[idx]->require.hp[skill_lv-1];
	req.sp = skill_db[idx]->require.sp[skill_lv-1];

	return req;
}
Exemplo n.º 15
0
/**
* Set Mercenary's calls
* @param md Mercenary
* @param value
**/
void mercenary_set_calls(struct mercenary_data *md, int value) {
	struct map_session_data *sd;
	uint16 class_;
	int *calls;

	if( md == NULL || md->db == NULL || (sd = md->master) == NULL )
		return;

	class_ = md->db->class_;

	if( class_ >= 6017 && class_ <= 6026 )
		calls = &sd->status.arch_calls;
	else if( class_ >= 6027 && class_ <= 6036 )
		calls = &sd->status.spear_calls;
	else if( class_ >= 6037 && class_ <= 6046 )
		calls = &sd->status.sword_calls;
	else
		return;

	*calls += value;
	*calls = cap_value(*calls, 0, INT_MAX);
}
Exemplo n.º 16
0
/*==========================================
 * Open shop
 * data := {<index>.w <amount>.w <value>.l}[count]
 *------------------------------------------*/
void vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count) {
	int i, j;
	int vending_skill_lvl;
	nullpo_retv(sd);

	if ( pc_isdead(sd) || !sd->state.prevend || pc_istrading(sd))
		return; // can't open vendings lying dead || didn't use via the skill (wpe/hack) || can't have 2 shops at once

	vending_skill_lvl = pc->checkskill(sd, MC_VENDING);
	// skill level and cart check
	if( !vending_skill_lvl || !pc_iscarton(sd) ) {
		clif->skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
		return;
	}

	// check number of items in shop
	if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl ) {
		// invalid item count
		clif->skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
		return;
	}
    
	// filter out invalid items
	i = 0;
	for( j = 0; j < count; j++ ) {
		short index        = *(uint16*)(data + 8*j + 0);
		short amount       = *(uint16*)(data + 8*j + 2);
		unsigned int value = *(uint32*)(data + 8*j + 4);

		index -= 2; // offset adjustment (client says that the first cart position is 2)

		if( index < 0 || index >= MAX_CART // invalid position
		||  pc->cartitem_amount(sd, index, amount) < 0 // invalid item or insufficient quantity
		//NOTE: official server does not do any of the following checks!
		||  !sd->status.cart[index].identify // unidentified item
		||  sd->status.cart[index].attribute == 1 // broken item
		||  sd->status.cart[index].expire_time // It should not be in the cart but just in case
		||  !itemdb_cantrade(&sd->status.cart[index], pc->get_group_level(sd), pc->get_group_level(sd)) ) // untradeable item
			continue;

		sd->vending[i].index = index;
		sd->vending[i].amount = amount;
		sd->vending[i].value = cap_value(value, 0, (unsigned int)battle_config.vending_max_value);

		i++; // item successfully added
	}

	if( i != j )
		clif->message (sd->fd, msg_txt(266)); //"Some of your items cannot be vended and were removed from the shop."

	if( i == 0 ) { // no valid item found
		clif->skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
		return;
	}
	sd->state.prevend = sd->state.workinprogress = 0;
	sd->state.vending = true;
	sd->vender_id = getid();
	sd->vend_num = i;
	safestrncpy(sd->message, message, MESSAGE_SIZE);

	clif->openvending(sd,sd->bl.id,sd->vending);
	clif->showvendingboard(&sd->bl,message,0);
	
	idb_put(vending->db, sd->status.char_id, sd);
}
Exemplo n.º 17
0
/* ==============================================================
   bg_arena (0 EoS | 1 Boss | 2 TI | 3 CTF | 4 TD | 5 SC | 6 CON | 7 RUSH | 8 DOM)
   bg_result (0 Won | 1 Tie | 2 Lost)
   ============================================================== */
void bg_team_rewards(int bg_id, int nameid, int amount, int kafrapoints, int quest_id, const char *var, int add_value, int bg_arena, int bg_result)
{
	struct battleground_data *bg;
	struct map_session_data *sd;
	struct item_data *id;
	struct item it;
	int i, j, flag, fame, get_amount, rank = 0, type;

	if( amount < 1 || (bg = bg_team_search(bg_id)) == NULL || (id = itemdb_exists(nameid)) == NULL )
		return;

	if( battle_config.bg_reward_rates != 100 )
	{ // BG Reward Rates
		amount = amount * battle_config.bg_reward_rates / 100;
		kafrapoints = kafrapoints * battle_config.bg_reward_rates / 100;
	}

	bg_result = cap_value(bg_result,0,2);
	memset(&it,0,sizeof(it));
	if( nameid == 7828 || nameid == 7829 || nameid == 7773 )
	{
		it.nameid = nameid;
		it.identify = 1;
	}
	else nameid = 0;

	for( j = 0; j < MAX_BG_MEMBERS; j++ )
	{
		if( (sd = bg->members[j].sd) == NULL )
			continue;

		if( battle_config.bg_ranking_bonus )
		{
			rank = 0;
			ARR_FIND(0,MAX_FAME_LIST,i,bgrank_fame_list[i].id == sd->status.char_id);
			if( i < MAX_FAME_LIST )
				rank = 1;
			else
			{
				ARR_FIND(0,MAX_FAME_LIST,i,bg_fame_list[i].id == sd->status.char_id);
				if( i < MAX_FAME_LIST )
					rank = 1;
			}
		}

		if( quest_id ) quest_add(sd,quest_id);
		pc_setglobalreg(sd,var,pc_readglobalreg(sd,var) + add_value);

		if( kafrapoints > 0 )
		{
			get_amount = kafrapoints;
			if( rank ) get_amount += battle_config.bg_ranking_bonus * get_amount / 100;
			pc_getcash(sd,0,get_amount);
		}

		if( nameid && amount > 0 )
		{
			get_amount = amount;
			if( rank ) get_amount += battle_config.bg_ranking_bonus * get_amount / 100;

			if( (flag = pc_additem(sd,&it,get_amount,LOG_TYPE_SCRIPT)) )
				clif_additem(sd,0,0,flag);
		}

		type = bg->members[j].ranked ? 2 : 3; // Where to Add Fame

		switch( bg_result )
		{
		case 0: // Won
			add2limit(sd->status.bgstats.win,1,USHRT_MAX);
			achievement_validate_bg(sd,ATB_VICTORY,1);
			fame = 100;
			if( sd->bmaster_flag )
			{
				add2limit(sd->status.bgstats.leader_win,1,USHRT_MAX);
				achievement_validate_bg(sd,ATB_LEADER_VICTORY,1);
				fame += 25;
			}
			pc_addfame(sd,fame,type);
			switch( bg_arena )
			{
			case 0:
				add2limit(sd->status.bgstats.eos_wins,1,USHRT_MAX);
				achievement_validate_bg(sd,ATB_EOS_VICTORY,1);
				break;
			case 1:
				add2limit(sd->status.bgstats.boss_wins,1,USHRT_MAX);
				achievement_validate_bg(sd,ATB_BOSS_VICTORY,1);
				break;
			case 2:
				add2limit(sd->status.bgstats.ti_wins,1,USHRT_MAX);
				achievement_validate_bg(sd,ATB_TI_VICTORY,1);
				break;
			case 3:
				add2limit(sd->status.bgstats.ctf_wins,1,USHRT_MAX);
				achievement_validate_bg(sd,ATB_CTF_VICTORY,1);
				break;
			case 4:
				add2limit(sd->status.bgstats.td_wins,1,USHRT_MAX);
				achievement_validate_bg(sd,ATB_TDM_VICTORY,1);
				break;
			case 5:
				add2limit(sd->status.bgstats.sc_wins,1,USHRT_MAX);
				achievement_validate_bg(sd,ATB_SC_VICTORY,1);
				break;
			case 6:
				add2limit(sd->status.bgstats.cq_wins,1,USHRT_MAX);
				achievement_validate_bg(sd,ATB_CON_VICTORY,1);
				break;
			case 7:
				add2limit(sd->status.bgstats.ru_wins,1,USHRT_MAX);
				achievement_validate_bg(sd,ATB_RU_VICTORY,1);
				break;
			case 8:
				add2limit(sd->status.bgstats.dom_wins,1,USHRT_MAX);
				achievement_validate_bg(sd,ATB_DOM_VICTORY,1);
				break;
			}
			break;
		case 1: // Tie
			add2limit(sd->status.bgstats.tie,1,USHRT_MAX);
			fame = 75;
			if( sd->bmaster_flag )
			{
				add2limit(sd->status.bgstats.leader_tie,1,USHRT_MAX);
				fame += 10;
			}
			pc_addfame(sd,fame,type);
			switch( bg_arena )
			{
			case 0: add2limit(sd->status.bgstats.eos_tie,1,USHRT_MAX); break;
			case 1: add2limit(sd->status.bgstats.boss_tie,1,USHRT_MAX); break;
			case 2: add2limit(sd->status.bgstats.ti_tie,1,USHRT_MAX); break;
			case 3: add2limit(sd->status.bgstats.ctf_tie,1,USHRT_MAX); break;
			case 4: add2limit(sd->status.bgstats.td_tie,1,USHRT_MAX); break;
			case 5: add2limit(sd->status.bgstats.sc_tie,1,USHRT_MAX); break;
			// No Tie for Conquest or Rush
			case 8: add2limit(sd->status.bgstats.dom_tie,1,USHRT_MAX); break;
			}
			break;
		case 2: // Lost
			add2limit(sd->status.bgstats.lost,1,USHRT_MAX);
			achievement_validate_bg(sd,ATB_DEFEAT,1);
			fame = 50;
			if( sd->bmaster_flag )
			{
				add2limit(sd->status.bgstats.leader_lost,1,USHRT_MAX);
				achievement_validate_bg(sd,ATB_LEADER_DEFEAT,1);
			}
			pc_addfame(sd,fame,type);
			switch( bg_arena )
			{
			case 0: add2limit(sd->status.bgstats.eos_lost,1,USHRT_MAX); break;
			case 1: add2limit(sd->status.bgstats.boss_lost,1,USHRT_MAX); break;
			case 2: add2limit(sd->status.bgstats.ti_lost,1,USHRT_MAX); break;
			case 3: add2limit(sd->status.bgstats.ctf_lost,1,USHRT_MAX); break;
			case 4: add2limit(sd->status.bgstats.td_lost,1,USHRT_MAX); break;
			case 5: add2limit(sd->status.bgstats.sc_lost,1,USHRT_MAX); break;
			case 6: add2limit(sd->status.bgstats.cq_lost,1,USHRT_MAX); break;
			case 7: add2limit(sd->status.bgstats.ru_lost,1,USHRT_MAX); break;
			case 8: add2limit(sd->status.bgstats.dom_lost,1,USHRT_MAX); break;
			}
			break;
		}
	}
}
Exemplo n.º 18
0
/*==========================================
 * Abrir loja
 * data := {<index>.w <amount>.w <value>.l}[count]
 *------------------------------------------*/
void vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count) {
	int i, j;
	int vending_skill_lvl;
	nullpo_retv(sd);

	if ( pc_isdead(sd) || !sd->state.prevend || pc_istrading(sd))
		return; // nao pode abrir vendas deitado morto || não usou via habilidade (wpe/hack) || não pode ter 2 lojas ao mesmo tempo

	vending_skill_lvl = pc->checkskill(sd, MC_VENDING);
	// check de nivel de habilidade e carrinho
	if( !vending_skill_lvl || !pc_iscarton(sd) ) {
		clif->skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
		return;
	}

	// checka numero de itens na loja
	if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl ) {
		// contagem de item invalida
		clif->skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
		return;
	}

	// filtrar itens invalidos
	i = 0;
	for( j = 0; j < count; j++ ) {
		short index        = *(uint16*)(data + 8*j + 0);
		short amount       = *(uint16*)(data + 8*j + 2);
		unsigned int value = *(uint32*)(data + 8*j + 4);

		index -= 2; // ajuste de equilibrio (cliente diz que a posição do primeiro carrinho é 2)

		if( index < 0 || index >= MAX_CART // posição inválida
		 || pc->cartitem_amount(sd, index, amount) < 0 // item invalido ou quantidade insuficiente
		//NOT: servidores oficiais não fazem nenhum dos checks abaixo!
		 || !sd->status.cart[index].identify // item não-identficado
		 || sd->status.cart[index].attribute == 1 // item quebrado
		 || sd->status.cart[index].expire_time // Isso não deveria estar no carrinho mas apenas no caso de estar
		 || (sd->status.cart[index].bound && !pc_can_give_bound_items(sd)) // não pode trocar itens de recompensa, permissão w/o
		 || !itemdb_cantrade(&sd->status.cart[index], pc_get_group_level(sd), pc_get_group_level(sd)) ) // Itens não-trocaveis
			continue;

		sd->vending[i].index = index;
		sd->vending[i].amount = amount;
		sd->vending[i].value = cap_value(value, 0, (unsigned int)battle_config.vending_max_value);

		i++; // item adicionado com sucesso
	}

	if( i != j )
		clif->message (sd->fd, msg_txt(266)); //"Alguns dos seus itens não pode ser vendido e foram removidos da loja."

	if( i == 0 ) { // nenhum item válido encontrado
		clif->skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // packet de resposta personalizada
		return;
	}
	sd->state.prevend = sd->state.workinprogress = 0;
	sd->state.vending = true;
	sd->vender_id = getid();
	sd->vend_num = i;
	safestrncpy(sd->message, message, MESSAGE_SIZE);

	clif->openvending(sd,sd->bl.id,sd->vending);
	clif->showvendingboard(&sd->bl,message,0);

	idb_put(vending->db, sd->status.char_id, sd);
}
Exemplo n.º 19
0
/*==========================================
 * Open shop
 * data := {<index>.w <amount>.w <value>.l}[count]
 *------------------------------------------*/
void vending_openvending(struct map_session_data* sd, const char* message, bool flag, const uint8* data, int count)
{
	int i, j, char_id;
	int vending_skill_lvl;
	nullpo_retv(sd);

	if( !flag ) // cancelled
		return; // nothing to do

	if (pc_istrading(sd))
		return; // can't have 2 shops at once

	vending_skill_lvl = pc_checkskill(sd, MC_VENDING);
	// skill level and cart check
	if( !vending_skill_lvl || !pc_iscarton(sd) )
	{
		clif_skill_fail(sd, MC_VENDING, 0, 0);
		return;
	}

	// check number of items in shop
	if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl )
	{	// invalid item count
		clif_skill_fail(sd, MC_VENDING, 0, 0);
		return;
	}

	if((sd->bl.m == map_mapname2mapid("mercadores") 
 	 && (
	((sd->bl.x != 65) && (sd->bl.x != 74) && (sd->bl.x != 85) && (sd->bl.x != 94)
	&& (sd->bl.x != 34) && (sd->bl.x != 25) && (sd->bl.x != 14) && (sd->bl.x != 5)
	&& (sd->bl.x != 44) && (sd->bl.x != 55))
 	))) {
	clif_displaymessage(sd->fd,"Você não pode abrir lojas no meio da Sala."); 
	return; 
	}

	// filter out invalid items
	i = 0;
	for( j = 0; j < count; j++ )
	{
		short index        = *(uint16*)(data + 8*j + 0);
		short amount       = *(uint16*)(data + 8*j + 2);
		unsigned int value = *(uint32*)(data + 8*j + 4);

		index -= 2; // offset adjustment (client says that the first cart position is 2)

		if( index < 0 || index >= MAX_CART // invalid position
		||  pc_cartitem_amount(sd, index, amount) < 0 // invalid item or insufficient quantity
		//NOTE: official server does not do any of the following checks!
		||  !sd->status.cart[index].identify // unidentified item
		||  sd->status.cart[index].attribute == 1 // broken item
		||  sd->status.cart[index].expire_time // It should not be in the cart but just in case
		||  sd->status.cart[index].bound // Can't Trade Account bound items
		||  ( sd->status.cart[index].card[0] == CARD0_CREATE && (char_id = MakeDWord(sd->status.cart[index].card[2],sd->status.cart[index].card[3])) > 0 && ((battle_config.bg_reserved_char_id && char_id == battle_config.bg_reserved_char_id) || (battle_config.ancient_reserved_char_id && char_id == battle_config.ancient_reserved_char_id)) )
		||  !itemdb_cantrade(&sd->status.cart[index], pc_isGM(sd), pc_isGM(sd)) ) // untradeable item
			continue;

		sd->vending[i].index = index;
		sd->vending[i].amount = amount;
		sd->vending[i].value = cap_value(value, 0, (unsigned int)battle_config.vending_max_value);

		i++; // item successfully added
	}

	if( i != j )
		clif_displaymessage (sd->fd, msg_txt(266)); //"Some of your items cannot be vended and were removed from the shop."

	if( i == 0 )
	{	// no valid item found
		clif_skill_fail(sd, MC_VENDING, 0, 0); // custom reply packet
		return;
	}

	sd->state.vending = true;
	sd->vender_id = vending_getuid();
	sd->vend_num = i;
	safestrncpy(sd->message, message, MESSAGE_SIZE);

	pc_stop_walking(sd,1);
	clif_openvending(sd,sd->bl.id,sd->vending);
	clif_showvendingboard(&sd->bl,message,0);

	if( battle_config.channel_announces&0x10 )
	{
		char chat_message[256];
		sprintf(chat_message, msg_txt(820), vending_chat_nick, sd->status.name, sd->message, map[sd->bl.m].name, sd->bl.x, sd->bl.y);
		clif_channel_message(server_channel[CHN_VENDING], chat_message, 27);
	}

	if( map[sd->bl.m].flag.vending_cell )
		map_setcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_NOBOARDS, false);
}
Exemplo n.º 20
0
// exp share and added zeny share [Valaris]
int party_exp_share(struct party_data* p, struct block_list* src, unsigned int base_exp, unsigned int job_exp, int zeny)
{
	struct map_session_data* sd[MAX_PARTY];
	unsigned int i, c;

	nullpo_ret(p);

	// count the number of players eligible for exp sharing
	for( i = c = 0; i < MAX_PARTY; i++ )
	{
		if( (sd[c] = p->data[i].sd) == NULL || sd[c]->bl.m != src->m || pc_isdead(sd[c]) || (battle_config.idle_no_share && pc_isidle(sd[c])) )
			continue;
		c++;
	}
	
	if(c < 1)
		return 0;
	
	if (battle_config.renewal_party_exp_nerf)
	{
		int nerf;

		if (c == 2)
		{
			nerf = 50;
		}
		else if (c == 3)
		{
			nerf = 37;
		}
		else if (c == 4)
		{
			nerf = 30;
		}
		else if (c == 5)
		{
			nerf = 26;
		}
		else if (c == 6)
		{
			nerf = 23;
		}
		else if (c == 7)
		{
			nerf = 21;
		}
		else if (c == 8)
		{
			nerf = 20;
		}
		else if (c == 9)
		{
			nerf = 19;
		}
		else if (c == 10)
		{
			nerf = 18;
		}
		else if (c == 11)
		{
			nerf = 17;
		}
		else if (c == 12)
		{
			nerf = 17;
		}
		else
		{
			nerf = 0;
		}

		if (nerf)
		{
			base_exp = base_exp * nerf / 100;
			job_exp = job_exp * nerf / 100;
			zeny = zeny * nerf / 100;
		}
	}
	else
	{
		base_exp /= c;	
		job_exp /= c;
		zeny /= c;
	}

	if( battle_config.party_even_share_bonus && c > 1 )
	{
		double bonus = 100 + battle_config.party_even_share_bonus*(c-1);
		if (base_exp)
			base_exp = (unsigned int) cap_value(base_exp * bonus/100, 0, UINT_MAX);
		if (job_exp)
			job_exp = (unsigned int) cap_value(job_exp * bonus/100, 0, UINT_MAX);
		if (zeny)
			zeny = (unsigned int) cap_value(zeny * bonus/100, INT_MIN, INT_MAX);
	}

	for( i = 0; i < c; i++ )
	{
		pc_gainexp(sd[i], src, base_exp, job_exp, false);
		if( zeny ) // zeny from mobs [Valaris]
			pc_getzeny(sd[i],zeny);
	}
	return 0;
}
Exemplo n.º 21
0
CCheckPacket::CCheckPacket(CCharEntity* PChar, CCharEntity* PTarget) 
{
	this->type = 0xC9;
	this->size = 0x06;

	WBUFL(data,(0x04)-4) = PTarget->id;
	WBUFW(data,(0x08)-4) = PTarget->targid;

	WBUFB(data,(0x0A)-4) = 0x03;

	uint8 count = 0;

	for (int32 i = 0; i < 16; ++i) 
	{
		if (PTarget->equip[i] != 0) 
		{
			CItem* PItem = PTarget->getStorage(LOC_INVENTORY)->GetItem(PTarget->equip[i]);

			if (PItem != NULL) 
			{
				WBUFW(data,(size*2+0x00)-4) = PItem->getID();
				WBUFB(data,(size*2+0x02)-4) = i;

				if (PItem->getSubType() & ITEM_CHARGED)
				{
					uint32 currentTime = CVanaTime::getInstance()->getSysTime() - 1009810800;
					uint32 nextUseTime = ((CItemUsable*)PItem)->getLastUseTime() + ((CItemUsable*)PItem)->getReuseDelay();

					WBUFB(data,(size*2+0x04)-4) = 0x01;													
					WBUFB(data,(size*2+0x05)-4) = ((CItemUsable*)PItem)->getCurrentCharges(); 
					WBUFB(data,(size*2+0x07)-4) = (nextUseTime > currentTime ? 0x90 : 0xD0); 

					WBUFL(data,(size*2+0x08)-4) = nextUseTime;												
					WBUFL(data,(size*2+0x0C)-4) = ((CItemUsable*)PItem)->getUseDelay() + currentTime;		
				}

				memcpy(data+(size*2+0x10)-4, PItem->getSignature(), cap_value(strlen(PItem->getSignature()), 0, 12));

				this->size += 0x0E;
				count++;

				if (count == 8)
				{
					WBUFB(data,(0x0B)-4) = count;

					PChar->pushPacket(new CBasicPacket(*this));

					this->size = 0x06;
					memset(data+(0x0B)-4, 0, sizeof(data)-7);
				}
			}
		}
	}

	if (count == 0)
	{
		this->size = 0x14;
		PChar->pushPacket(new CBasicPacket(*this));
	}
	else if (count != 8) 
	{
		WBUFB(data,(0x0B)-4) = (count > 8 ? count - 8 : count);
		PChar->pushPacket(new CBasicPacket(*this));
	}

	this->size = 0x28;
	memset(data+(0x0B)-4, 0, sizeof(data)-7);

	WBUFB(data,(0x0A)-4) = 0x01;

	if ( (PChar->nameflags.flags & FLAG_GM) ||
		!(PTarget->nameflags.flags & FLAG_ANON)) 
	{
		WBUFB(data,(0x12)-4) = PTarget->GetMJob();
		WBUFB(data,(0x13)-4) = PTarget->GetSJob();
		WBUFB(data,(0x23)-4) = PTarget->GetMLevel();
		WBUFB(data,(0x24)-4) = PTarget->GetSLevel();
	}

	//Chevron 32 bit Big Endean, starting at 0x2B
	//WBUFB(data,(0x2C)-4) = 0x00;	//Ballista Star next to Chevron count
}
Exemplo n.º 22
0
// Load an homunculus
bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd)
{
	int i;
	char* data;
	size_t len;

	memset(hd, 0, sizeof(*hd));

	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `homun_id`,`char_id`,`class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize` FROM `%s` WHERE `homun_id`='%u'", homunculus_db, homun_id) )
	{
		Sql_ShowDebug(sql_handle);
		return false;
	}

	if( !Sql_NumRows(sql_handle) )
	{	//No homunculus found.
		Sql_FreeResult(sql_handle);
		return false;
	}
	if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
	{
		Sql_ShowDebug(sql_handle);
		Sql_FreeResult(sql_handle);
		return false;
	}

	hd->hom_id = homun_id;
	Sql_GetData(sql_handle,  1, &data, NULL); hd->char_id = atoi(data);
	Sql_GetData(sql_handle,  2, &data, NULL); hd->class_ = atoi(data);
	Sql_GetData(sql_handle,  3, &data, NULL); hd->prev_class = atoi(data);
	Sql_GetData(sql_handle,  4, &data, &len); safestrncpy(hd->name, data, sizeof(hd->name));
	Sql_GetData(sql_handle,  5, &data, NULL); hd->level = atoi(data);
	Sql_GetData(sql_handle,  6, &data, NULL); hd->exp = atoi(data);
	Sql_GetData(sql_handle,  7, &data, NULL); hd->intimacy = (unsigned int)strtoul(data, NULL, 10);
	Sql_GetData(sql_handle,  8, &data, NULL); hd->hunger = atoi(data);
	Sql_GetData(sql_handle,  9, &data, NULL); hd->str = atoi(data);
	Sql_GetData(sql_handle, 10, &data, NULL); hd->agi = atoi(data);
	Sql_GetData(sql_handle, 11, &data, NULL); hd->vit = atoi(data);
	Sql_GetData(sql_handle, 12, &data, NULL); hd->int_ = atoi(data);
	Sql_GetData(sql_handle, 13, &data, NULL); hd->dex = atoi(data);
	Sql_GetData(sql_handle, 14, &data, NULL); hd->luk = atoi(data);
	Sql_GetData(sql_handle, 15, &data, NULL); hd->hp = atoi(data);
	Sql_GetData(sql_handle, 16, &data, NULL); hd->max_hp = atoi(data);
	Sql_GetData(sql_handle, 17, &data, NULL); hd->sp = atoi(data);
	Sql_GetData(sql_handle, 18, &data, NULL); hd->max_sp = atoi(data);
	Sql_GetData(sql_handle, 19, &data, NULL); hd->skillpts = atoi(data);
	Sql_GetData(sql_handle, 20, &data, NULL); hd->rename_flag = atoi(data);
	Sql_GetData(sql_handle, 21, &data, NULL); hd->vaporize = atoi(data);
	Sql_FreeResult(sql_handle);

	hd->intimacy = cap_value(hd->intimacy, 0, 100000);
	hd->hunger = cap_value(hd->hunger, 0, 100);

	// Load Homunculus Skill
	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `%s` WHERE `homun_id`=%d", skill_homunculus_db, homun_id) )
	{
		Sql_ShowDebug(sql_handle);
		return false;
	}
	while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
	{
		// id
		Sql_GetData(sql_handle, 0, &data, NULL);
		i = atoi(data);
		if( i < HM_SKILLBASE || i >= HM_SKILLBASE + MAX_HOMUNSKILL )
			continue;// invalid skill id
		i = i - HM_SKILLBASE;
		hd->hskill[i].id = (unsigned short)atoi(data);

		// lv
		Sql_GetData(sql_handle, 1, &data, NULL);
		hd->hskill[i].lv = (unsigned char)atoi(data);
	}
	Sql_FreeResult(sql_handle);

	if( save_log )
		ShowInfo("Homúnculus carregado (%d - %s).\n", hd->hom_id, hd->name);

	return true;
}
Exemplo n.º 23
0
/** Read item group data
 * Structure: GroupID,ItemID,Rate{,Amount,isMust,isAnnounced,Duration,isNamed,isBound}
 */
static void itemdb_read_itemgroup_sub(const char* filename)
{
	FILE *fp;
	int ln = 0, entries = 0;
	char line[1024];

	if( (fp = fopen(filename, "r")) == NULL ) {
		ShowError("Can't read %s\n", filename);
		return;
	}

	while( fgets(line, sizeof(line), fp) ) {
		uint16 nameid;
		int j, group_id, prob = 1, amt = 1, rand_group = 1, announced = 0, dur = 0, named = 0, bound = 0;
		char *str[3], *p, w1[1024], w2[1024];
		bool found = false;
		struct s_item_group_random *random;

		ln++;
		if( line[0] == '/' && line[1] == '/' )
			continue;
		if( strstr(line, "import") ) {
			if( sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2 && strcmpi(w1, "import") == 0 ) {
				itemdb_read_itemgroup_sub(w2);
				continue;
			}
		}
		memset(str, 0, sizeof(str));
		for( j = 0, p = line; j < 3 && p; j++ ) {
			str[j] = p;
			if( j == 2 )
				sscanf(str[j], "%d,%d,%d,%d,%d,%d,%d", &prob, &amt, &rand_group, &announced, &dur, &named, &bound);
			p = strchr(p, ',');
			if( p ) *p++ = 0;
		}
		if( str[0] == NULL )
			continue;
		if( j < 3 ) {
			if( j > 1 ) //Or else it barks on blank lines...
				ShowWarning("itemdb_read_itemgroup: Insufficient fields for entry at %s:%d\n", filename, ln);
			continue;
		}

		//Checking group_id
		trim(str[0]);
		if( ISDIGIT(str[0][0]) )
			group_id = atoi(str[0]);
		else //Try reads group id by const
			script_get_constant(trim(str[0]), &group_id);
		if( group_id < 1 || group_id >= MAX_ITEMGROUP ) {
			ShowWarning("itemdb_read_itemgroup: Cannot save '%s' because invalid group id or group db is overflow in %s:%d\n", str[0], filename, ln);
			continue;
		}

		//Checking sub group
		if( rand_group < 0 || rand_group > MAX_ITEMGROUP_RANDGROUP ) {
			ShowWarning("itemdb_read_itemgroup: Invalid sub group %d for group '%s' in %s:%d\n", rand_group, str[0], filename, ln);
			continue;
		}

		if( rand_group && prob < 1 ) {
			ShowWarning("itemdb_read_itemgroup: Invalid probaility for group '%s' sub: %d in %s:%d\n", str[0], rand_group, filename, ln);
			continue;
		}

		//Checking item
		trim(str[1]);
		if( ISDIGIT(str[1][0]) && itemdb_exists((nameid = atoi(str[1]))) )
			found = true;
		else if( itemdb_searchname(str[1]) ) {
			found = true;
			nameid = itemdb_searchname(str[1])->nameid;
		}
		if( !found ) {
			ShowWarning("itemdb_read_itemgroup: Non-existant item '%s' in %s:%d\n", str[1], filename, ln);
			continue;
		}

		amt = cap_value(amt, 1, MAX_AMOUNT);
		dur = cap_value(dur, 0, UINT16_MAX);
		bound = cap_value(bound, 0, 4);

		//Must item (rand_group == 0), place it here
		if( !rand_group ) {
			uint16 idx = itemgroup_db[group_id].must_qty;

			if( !idx )
				CREATE(itemgroup_db[group_id].must, struct s_item_group, 1);
			else
				RECREATE(itemgroup_db[group_id].must, struct s_item_group, idx + 1);

			itemgroup_db[group_id].must[idx].nameid = nameid;
			itemgroup_db[group_id].must[idx].amount = amt;
			itemgroup_db[group_id].must[idx].isAnnounced = announced;
			itemgroup_db[group_id].must[idx].duration = dur;
			itemgroup_db[group_id].must[idx].isNamed = named;
			itemgroup_db[group_id].must[idx].bound = bound;
			itemgroup_db[group_id].must_qty++;

			//If 'must' item isn't set as random item, skip the next process
			if( !prob ) {
				entries++;
				continue;
			}
			rand_group = 0;
		} else
Exemplo n.º 24
0
/*==========================================
 * Open shop
 * data := {<index>.w <amount>.w <value>.l}[count]
 *------------------------------------------*/
void vending_openvending(struct map_session_data* sd, const char* message, bool flag, const uint8* data, int count)
{
	int i, j;
	int vending_skill_lvl;
	nullpo_retv(sd);

	if( !flag ) // cancelled
		return; // nothing to do

	if (pc_istrading(sd))
		return; // can't have 2 shops at once

	vending_skill_lvl = pc_checkskill(sd, MC_VENDING);
	// skill level and cart check
	if( !vending_skill_lvl || !pc_iscarton(sd) )
	{
		clif_skill_fail(sd, MC_VENDING, 0, 0);
		return;
	}

	// check number of items in shop
	if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl )
	{	// invalid item count
		clif_skill_fail(sd, MC_VENDING, 0, 0);
		return;
	}

	// filter out invalid items
	i = 0;
	for( j = 0; j < count; j++ )
	{
		short index        = *(uint16*)(data + 8*j + 0);
		short amount       = *(uint16*)(data + 8*j + 2);
		unsigned int value = *(uint32*)(data + 8*j + 4);

		index -= 2; // offset adjustment (client says that the first cart position is 2)

		if( index < 0 || index >= MAX_CART // invalid position
		||  pc_cartitem_amount(sd, index, amount) < 0 // invalid item or insufficient quantity
		//NOTE: official server does not do any of the following checks!
		||  !sd->status.cart[index].identify // unidentified item
		||  sd->status.cart[index].attribute == 1 // broken item
		||  !itemdb_cantrade(&sd->status.cart[index], pc_isGM(sd), pc_isGM(sd)) ) // untradeable item
			continue;

		sd->vending[i].index = index;
		sd->vending[i].amount = amount;
		sd->vending[i].value = cap_value(value, 1, (unsigned int)battle_config.vending_max_value);

		i++; // item successfully added
	}

	if( i != j )
		clif_displaymessage (sd->fd, msg_txt(266)); //"Some of your items cannot be vended and were removed from the shop."

	if( i == 0 )
	{	// no valid item found
		clif_skill_fail(sd, MC_VENDING, 0, 0); // custom reply packet
		return;
	}

	sd->vender_id = sd->bl.id;
	sd->vend_num = i;
	safestrncpy(sd->message, message, MESSAGE_SIZE);

	pc_stop_walking(sd,1);
	clif_openvending(sd,sd->vender_id,sd->vending);
	clif_showvendingboard(&sd->bl,message,0);
}
Exemplo n.º 25
0
/*==========================================
 * processes one itemdb entry
 *------------------------------------------*/
static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt, char *comboScript)
{
	/*
		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
		| 00 |      01      |       02      |  03  |     04    |     05     |   06   |   07   |    08   |   09  |   10  |     11     |      12     |       13      |        14       |      15      |      16     |     17     |  18  |   19   |      20      |        21      |
		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
		| id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_upper | equip_genders | equip_locations | weapon_level | equip_level | refineable | view | script | equip_script | unequip_script |
		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
	*/
	int nameid;
	struct item_data* id;
	
	nameid = atoi(str[0]);
	if( nameid <= 0 )
	{
		ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source);
		return false;
	}

	//ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
	id = itemdb_load(nameid);
	safestrncpy(id->name, str[1], sizeof(id->name));
	safestrncpy(id->jname, str[2], sizeof(id->jname));

	id->type = atoi(str[3]);

	if( id->type < 0 || id->type == IT_UNKNOWN || id->type == IT_UNKNOWN2 || ( id->type > IT_DELAYCONSUME && id->type < IT_CASH ) || id->type >= IT_MAX )
	{// catch invalid item types
		ShowWarning("itemdb_parse_dbrow: Invalid item type %d for item %d. IT_ETC will be used.\n", id->type, nameid);
		id->type = IT_ETC;
	}

	if (id->type == IT_DELAYCONSUME)
	{	//Items that are consumed only after target confirmation
		id->type = IT_USABLE;
		id->flag.delay_consume = 1;
	} else //In case of an itemdb reload and the item type changed.
		id->flag.delay_consume = 0;

	//When a particular price is not given, we should base it off the other one
	//(it is important to make a distinction between 'no price' and 0z)
	if ( str[4][0] )
		id->value_buy = atoi(str[4]);
	else
		id->value_buy = atoi(str[5]) * 2;

	if ( str[5][0] )
		id->value_sell = atoi(str[5]);
	else
		id->value_sell = id->value_buy / 2;
	/* 
	if ( !str[4][0] && !str[5][0])
	{  
		ShowWarning("itemdb_parse_dbrow: No buying/selling price defined for item %d (%s), using 20/10z\n",       nameid, id->jname);
		id->value_buy = 20;
		id->value_sell = 10;
	} else
	*/
	if (id->value_buy/124. < id->value_sell/75.)
		ShowWarning("itemdb_parse_dbrow: Buying/Selling [%d/%d] price of item %d (%s) allows Zeny making exploit  through buying/selling at discounted/overcharged prices!\n",
			id->value_buy, id->value_sell, nameid, id->jname);

	id->weight = atoi(str[6]);
#ifdef RENEWAL
	itemdb_re_split_atoi(str[7],&id->atk,&id->matk);
#else
	id->atk = atoi(str[7]);
#endif
	id->def = atoi(str[8]);
	id->range = atoi(str[9]);
	id->slot = atoi(str[10]);

	if (id->slot > MAX_SLOTS)
	{
		ShowWarning("itemdb_parse_dbrow: Item %d (%s) specifies %d slots, but the server only supports up to %d. Using %d slots.\n", nameid, id->jname, id->slot, MAX_SLOTS, MAX_SLOTS);
		id->slot = MAX_SLOTS;
	}

	itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0));
	id->class_upper = atoi(str[12]);
	id->sex	= atoi(str[13]);
	id->equip = atoi(str[14]);

	if (!id->equip && itemdb_isequip2(id))
	{
		ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
		id->type = IT_ETC;
	}

	id->wlv = cap_value(atoi(str[15]), REFINE_TYPE_ARMOR, REFINE_TYPE_MAX);
	id->elv = atoi(str[16]);
	id->flag.no_refine = atoi(str[17]) ? 0 : 1; //FIXME: verify this
	id->look = atoi(str[18]);

	id->flag.available = 1;
	id->view_id = 0;
	id->sex = itemdb_gendercheck(id); //Apply gender filtering.

	if (id->script)
	{
		script_free_code(id->script);
		id->script = NULL;
	}
	if (id->equip_script)
	{
		script_free_code(id->equip_script);
		id->equip_script = NULL;
	}
	if (id->unequip_script)
	{
		script_free_code(id->unequip_script);
		id->unequip_script = NULL;
	}

	if (*str[19]) {
		char *scriptCode = str[19];

		if ( comboScript ) {
			char *script1 = str[19];

			while (*script1++ != '{');

			scriptCode = (char *)aMalloc(strlen(script1) + strlen(comboScript) + 2); // +2 = {\0
			sprintf(scriptCode, "{%s%s", comboScript, script1);
		}

		id->script = parse_script(scriptCode, source, line, scriptopt);
		
		if( comboScript )
			aFree(scriptCode);

	} else if ( comboScript )
		id->script = parse_script(comboScript, source, line, scriptopt);
	
	if (*str[20])
		id->equip_script = parse_script(str[20], source, line, scriptopt);
	if (*str[21])
		id->unequip_script = parse_script(str[21], source, line, scriptopt);

	return true;
}
Exemplo n.º 26
0
/** Read item group data
* Structure: GroupID,ItemID,Rate{,Amount,isMust,isAnnounced,Duration,GUID,isBound,isNamed}
*/
static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
{
	FILE *fp;
	int ln = 0, entries = 0;
	char line[1024];

	if ((fp=fopen(filename,"r")) == NULL) {
		if(silent == 0) ShowError("Can't read %s\n", filename);
		return;
	}
	
	while (fgets(line,sizeof(line),fp)) {
		DBData data;
		int group_id = -1;
		unsigned int j, prob = 1;
		uint8 rand_group = 1;
		char *str[10], *p;
		struct s_item_group_random *random = NULL;
		struct s_item_group_db *group = NULL;
		struct s_item_group_entry entry;
		bool found = false;

		ln++;
		if (line[0] == '/' && line[1] == '/')
			continue;
		if (strstr(line,"import")) {
			char w1[16], w2[64];

			if (sscanf(line,"%15[^:]: %63[^\r\n]",w1,w2) == 2 &&
				strcmpi(w1,"import") == 0)
			{
				itemdb_read_itemgroup_sub(w2, 0);
				continue;
			}
		}
		memset(str,0,sizeof(str));
		for (j = 0, p = line; j < 9 && p;j++) {
			str[j] = p;
			p = strchr(p,',');
			if (p) *p++=0;
		}
		if (str[0] == NULL) //Empty Group ID
			continue;
		if (j < 3) {
			if (j > 1) // Or else it barks on blank lines...
				ShowWarning("itemdb_read_itemgroup: Insufficient fields for entry at %s:%d\n", filename, ln);
			continue;
		}

		memset(&entry, 0, sizeof(entry));
		entry.amount = 1;
		entry.bound = BOUND_NONE;

		// Checking group_id
		trim(str[0]);
		if (ISDIGIT(str[0][0]))
			group_id = atoi(str[0]);
		else // Try reads group id by const
			script_get_constant(trim(str[0]), &group_id);

		if (group_id < 0) {
			ShowWarning("itemdb_read_itemgroup: Invalid Group ID '%s' (%s:%d)\n", str[0], filename, ln);
			continue;
		}

		// Remove from DB
		if (strcmpi(str[1], "clear") == 0 && itemdb_group->remove(itemdb_group, db_ui2key(group_id), &data)) {
			itemdb_group_free(db_ui2key(group_id), &data, 0);
			ShowNotice("Item Group '%s' has been cleared.\n", str[0]);
			continue;
		}

		// Checking sub group
		prob = atoi(str[2]);
		if (str[4] != NULL)
			rand_group = atoi(str[4]);
		if (rand_group < 0 || rand_group > MAX_ITEMGROUP_RANDGROUP) {
			ShowWarning("itemdb_read_itemgroup: Invalid sub group '%d' for group '%s' in %s:%d\n", rand_group, str[0], filename, ln);
			continue;
		}

		if (rand_group != 0 && prob < 1) {
			ShowWarning("itemdb_read_itemgroup: Random item must has probability. Group '%s' in %s:%d\n", str[0], filename, ln);
			continue;
		}

		// Checking item
		trim(str[1]);
		if (ISDIGIT(str[1][0]) && ISDIGIT(str[1][1]) && itemdb_exists((entry.nameid = atoi(str[1]))))
			found = true;
		else {
			struct item_data *id = itemdb_searchname(str[1]);
			if (id) {
				entry.nameid = id->nameid;
				found = true;
			}
		}

		if (!found) {
			ShowWarning("itemdb_read_itemgroup: Non-existant item '%s' in %s:%d\n", str[1], filename, ln);
			continue;
		}

		if (str[3] != NULL) entry.amount = cap_value(atoi(str[3]),1,MAX_AMOUNT);
		if (str[5] != NULL) entry.isAnnounced= atoi(str[5]);
		if (str[6] != NULL) entry.duration = cap_value(atoi(str[6]),0,UINT16_MAX);
#ifdef ENABLE_ITEM_GUID
		if (str[7] != NULL) entry.GUID = atoi(str[7]);
#endif
		if (str[8] != NULL) entry.bound = cap_value(atoi(str[8]),BOUND_NONE,BOUND_MAX-1);
		if (str[9] != NULL) entry.isNamed = atoi(str[9]);

		if (!(group = (struct s_item_group_db *) uidb_get(itemdb_group, group_id))) {
			CREATE(group, struct s_item_group_db, 1);
			group->id = group_id;
			uidb_put(itemdb_group, group->id, group);
		}

		// Must item (rand_group == 0), place it here
		if (!rand_group) {
			RECREATE(group->must, struct s_item_group_entry, group->must_qty+1);
			group->must[group->must_qty++] = entry;

			// If 'must' item isn't set as random item, skip the next process
			if (!prob) {
				entries++;
				continue;
			}
			rand_group = 0;
		}