Jump to content
  • 0
Sign in to follow this  
K4m4r40

[Help] Duvida C - Source [Basic hit max - mobs]

Question

Olá,

Editei recentemente os mvps do meu servidor High Rate e me deparei com um problema referente ao máx hit básic.
 

 

[Error]: mob_parse_dbrow: for class '1038', field value '211980' is higher than the maximum '65535'! capping...
[Error]: mob_parse_dbrow: for class '1038', field value '221503' is higher than the maximum '65535'! capping...


O monstro 1038 Osiris, possui 221.503 de dano de hit basico, e provavelmente na source esta configurado para no máx 65535.

Segue print:
2jg1chl.jpg

 

 

Gostaria de aumentar o hit basic max para não dar mais erro nas minhas edições.

 

---------------------------------------------------------

@EDIT

---------------------------------------------------------

 

mob.c no pastebin:
http://pastebin.com/MweEfdnU

 

Com ajuda cheguei no seguintes locais dentro da mob.c:

1º - Linha 3649 - Local aonde monstra o erro no log:

/**
 * Check if global item drop rate is overridden for given item
 * in db/mob_item_ratio.txt
 * @param nameid ID of the item
 * @param mob_id ID of the monster
 * @param rate_adjust pointer to store ratio if found
 */
void item_dropratio_adjust(int nameid, int mob_id, int *rate_adjust)
{
	if( item_drop_ratio_db[nameid] ) {
		if( item_drop_ratio_db[nameid]->mob_id[0] ) { // only for listed mobs
			int i;
			ARR_FIND(0, MAX_ITEMRATIO_MOBS, i, item_drop_ratio_db[nameid]->mob_id[i] == mob_id);
			if(i < MAX_ITEMRATIO_MOBS) // found
				*rate_adjust = item_drop_ratio_db[nameid]->drop_ratio;
		}
		else // for all mobs
			*rate_adjust = item_drop_ratio_db[nameid]->drop_ratio;
	}
}
/* (mob_parse_dbrow)_cap_value */
static inline int mob_parse_dbrow_cap_value(int class_, int min, int max, int value) {
	if( value > max ) {
------>		ShowError("mob_parse_dbrow: for class '%d', field value '%d' is higher than the maximum '%d'! capping...\n", class_, value, max);
		return max;
	} else if ( value < min ) {
		ShowError("mob_parse_dbrow: for class '%d', field value '%d' is lower than the minimum '%d'! capping...\n", class_, value, min);
		return min;
	}
	return value;
}

 

2º - Linha 3705 - local que acredito ser para editar do atk e atk2 dos monstros:

/*==========================================
 * processes one mobdb entry
 *------------------------------------------*/
bool mob_parse_dbrow(char** str) {
	struct mob_db *db, entry;
	struct status_data *mstatus;
	int class_, i, k;
	double exp, maxhp;
	struct mob_data data;

	class_ = atoi(str[0]);

	if (class_ <= 1000 || class_ > MAX_MOB_DB) {
		ShowError("mob_parse_dbrow: Invalid monster ID %d, must be in range %d-%d.\n", class_, 1000, MAX_MOB_DB);
		return false;
	}
	if (pcdb_checkid(class_)) {
		ShowError("mob_parse_dbrow: Invalid monster ID %d, reserved for player classes.\n", class_);
		return false;
	}

	if (class_ >= MOB_CLONE_START && class_ < MOB_CLONE_END) {
		ShowError("mob_parse_dbrow: Invalid monster ID %d. Range %d-%d is reserved for player clones. Please increase MAX_MOB_DB (%d).\n", class_, MOB_CLONE_START, MOB_CLONE_END-1, MAX_MOB_DB);
		return false;
	}

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

	db = &entry;
	mstatus = &db->status;

	db->vd.class_ = class_;
	safestrncpy(db->sprite, str[1], sizeof(db->sprite));
	safestrncpy(db->jname, str[2], sizeof(db->jname));
	safestrncpy(db->name, str[3], sizeof(db->name));
	db->lv = atoi(str[4]);
	db->lv = cap_value(db->lv, 1, USHRT_MAX);
	mstatus->max_hp = atoi(str[5]);
	mstatus->max_sp = atoi(str[6]);

	exp = (double)atoi(str[7]) * (double)battle_config.base_exp_rate / 100.;
	db->base_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);

	exp = (double)atoi(str[8]) * (double)battle_config.job_exp_rate / 100.;
	db->job_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);

	mstatus->rhw.range = atoi(str[9]);
	
---->	mstatus->rhw.atk = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[10]));
---->	mstatus->rhw.atk2 = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[11]));
	
	mstatus->def  = mob_parse_dbrow_cap_value(class_,DEFTYPE_MIN,DEFTYPE_MAX,atoi(str[12]));
	mstatus->mdef = mob_parse_dbrow_cap_value(class_,DEFTYPE_MIN,DEFTYPE_MAX,atoi(str[13]));
	
	mstatus->str  = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[14]));
	mstatus->agi  = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[15]));
	mstatus->vit  = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[16]));
	mstatus->int_ = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[17]));
	mstatus->dex  = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[18]));
	mstatus->luk  = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[19]));

	/*
	* Disabled for renewal since difference of 0 and 1 still has an impact in the formulas
	* Just in case there is a mishandled division by zero please let us know. [malufett]
	*/
#ifndef RENEWAL
	//All status should be min 1 to prevent divisions by zero from some skills. [Skotlex]
	if (mstatus->str < 1) mstatus->str = 1;
	if (mstatus->agi < 1) mstatus->agi = 1;
	if (mstatus->vit < 1) mstatus->vit = 1;
	if (mstatus->int_< 1) mstatus->int_= 1;
	if (mstatus->dex < 1) mstatus->dex = 1;
	if (mstatus->luk < 1) mstatus->luk = 1;
#endif

	//Tests showed that chase range is effectively 2 cells larger than expected [Playtester]
	if (db->range3 > 0)
		db->range3 += 2;

	db->range2 = atoi(str[20]);
	db->range3 = atoi(str[21]);
	if (battle_config.view_range_rate != 100) {
		db->range2 = db->range2 * battle_config.view_range_rate / 100;
		if (db->range2 < 1)
			db->range2 = 1;
	}
	if (battle_config.chase_range_rate != 100) {
		db->range3 = db->range3 * battle_config.chase_range_rate / 100;
		if (db->range3 < db->range2)
			db->range3 = db->range2;
	}

	mstatus->size = atoi(str[22]);
	mstatus->race = atoi(str[23]);

	i = atoi(str[24]); //Element
	mstatus->def_ele = i%10;
	mstatus->ele_lv = i/20;
	if (mstatus->def_ele >= ELE_MAX) {
		ShowError("mob_parse_dbrow: Invalid element type %d for monster ID %d (max=%d).\n", mstatus->def_ele, class_, ELE_MAX-1);
		return false;
	}
	if (mstatus->ele_lv < 1 || mstatus->ele_lv > 4) {
		ShowError("mob_parse_dbrow: Invalid element level %d for monster ID %d, must be in range 1-4.\n", mstatus->ele_lv, class_);
		return false;
	}

	mstatus->mode = (int)strtol(str[25], NULL, 0);
	if (!battle_config.monster_active_enable)
		mstatus->mode &= ~MD_AGGRESSIVE;

	mstatus->speed = atoi(str[26]);
	mstatus->aspd_rate = 1000;
	i = atoi(str[27]);
	mstatus->adelay = cap_value(i, battle_config.monster_max_aspd*2, 4000);
	i = atoi(str[28]);
	mstatus->amotion = cap_value(i, battle_config.monster_max_aspd, 2000);
	//If the attack animation is longer than the delay, the client crops the attack animation!
	//On aegis there is no real visible effect of having a recharge-time less than amotion anyway.
	if (mstatus->adelay < mstatus->amotion)
		mstatus->adelay = mstatus->amotion;
	mstatus->dmotion = atoi(str[29]);
	if(battle_config.monster_damage_delay_rate != 100)
		mstatus->dmotion = mstatus->dmotion * battle_config.monster_damage_delay_rate / 100;

	// Fill in remaining status data by using a dummy monster.
	data.bl.type = BL_MOB;
	data.level = db->lv;
	memcpy(&data.status, mstatus, sizeof(struct status_data));
	status->calc_misc(&data.bl, mstatus, db->lv);

	// MVP EXP Bonus: MEXP
	// Some new MVP's MEXP multiple by high exp-rate cause overflow. [LuzZza]
	exp = (double)atoi(str[30]) * (double)battle_config.mvp_exp_rate / 100.;
	db->mexp = (unsigned int)cap_value(exp, 0, UINT_MAX);

	//Now that we know if it is an mvp or not, apply battle_config modifiers [Skotlex]
	maxhp = (double)mstatus->max_hp;
	if (db->mexp > 0) { //Mvp
		if (battle_config.mvp_hp_rate != 100)
			maxhp = maxhp * (double)battle_config.mvp_hp_rate / 100.;
	} else //Normal mob
		if (battle_config.monster_hp_rate != 100)
			maxhp = maxhp * (double)battle_config.monster_hp_rate / 100.;

	mstatus->max_hp = (unsigned int)cap_value(maxhp, 1, UINT_MAX);
	if(mstatus->max_sp < 1) mstatus->max_sp = 1;

	//Since mobs always respawn with full life...
	mstatus->hp = mstatus->max_hp;
	mstatus->sp = mstatus->max_sp;

	// MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per
	for(i = 0; i < MAX_MVP_DROP; i++) {
		int rate_adjust = battle_config.item_rate_mvp;;
		db->mvpitem[i].nameid = atoi(str[31+i*2]);
		if (!db->mvpitem[i].nameid) {
			db->mvpitem[i].p = 0; //No item....
			continue;
		}
		mob->item_dropratio_adjust(db->mvpitem[i].nameid, class_, &rate_adjust);
		db->mvpitem[i].p = mob->drop_adjust(atoi(str[32+i*2]), rate_adjust, battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);

		//calculate and store Max available drop chance of the MVP item
		if (db->mvpitem[i].p) {
			struct item_data *id;
			id = itemdb->search(db->mvpitem[i].nameid);
			if (id->maxchance == -1 || (id->maxchance < db->mvpitem[i].p/10 + 1) ) {
				//item has bigger drop chance or sold in shops
				id->maxchance = db->mvpitem[i].p/10 + 1; //reduce MVP drop info to not spoil common drop rate
			}
		}
	}

	for(i = 0; i < MAX_MOB_DROP; i++) {
		int rate = 0, rate_adjust, type;
		unsigned short ratemin, ratemax;
		struct item_data *id;
		k = 31 + MAX_MVP_DROP*2 + i*2;
		db->dropitem[i].nameid = atoi(str[k]);
		if (!db->dropitem[i].nameid) {
			db->dropitem[i].p = 0; //No drop.
			continue;
		}
		id = itemdb->search(db->dropitem[i].nameid);
		type = id->type;
		rate = atoi(str[k+1]);
		if( (class_ >= 1324 && class_ <= 1363) || (class_ >= 1938 && class_ <= 1946) ) {
			//Treasure box drop rates [Skotlex]
			rate_adjust = battle_config.item_rate_treasure;
			ratemin = battle_config.item_drop_treasure_min;
			ratemax = battle_config.item_drop_treasure_max;
		}
		else switch (type)
		{ // Added support to restrict normal drops of MVP's [Reddozen]
		case IT_HEALING:
			rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_heal_boss : battle_config.item_rate_heal;
			ratemin = battle_config.item_drop_heal_min;
			ratemax = battle_config.item_drop_heal_max;
			break;
		case IT_USABLE:
		case IT_CASH:
			rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_use_boss : battle_config.item_rate_use;
			ratemin = battle_config.item_drop_use_min;
			ratemax = battle_config.item_drop_use_max;
			break;
		case IT_WEAPON:
		case IT_ARMOR:
		case IT_PETARMOR:
			rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_equip_boss : battle_config.item_rate_equip;
			ratemin = battle_config.item_drop_equip_min;
			ratemax = battle_config.item_drop_equip_max;
			break;
		case IT_CARD:
			rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_card_boss : battle_config.item_rate_card;
			ratemin = battle_config.item_drop_card_min;
			ratemax = battle_config.item_drop_card_max;
			break;
		default:
			rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_common_boss : battle_config.item_rate_common;
			ratemin = battle_config.item_drop_common_min;
			ratemax = battle_config.item_drop_common_max;
			break;
		}
		mob->item_dropratio_adjust(id->nameid, class_, &rate_adjust);
		db->dropitem[i].p = mob->drop_adjust(rate, rate_adjust, ratemin, ratemax);

		//calculate and store Max available drop chance of the item
		if( db->dropitem[i].p && (class_ < 1324 || class_ > 1363) && (class_ < 1938 || class_ > 1946) )
		{ //Skip treasure chests.
			if (id->maxchance == -1 || (id->maxchance < db->dropitem[i].p) ) {
				id->maxchance = db->dropitem[i].p; //item has bigger drop chance or sold in shops
			}
			for (k = 0; k< MAX_SEARCH; k++) {
				if (id->mob[k].chance <= db->dropitem[i].p)
					break;
			}
			if (k == MAX_SEARCH)
				continue;

			if (id->mob[k].id != class_)
				memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
			id->mob[k].chance = db->dropitem[i].p;
			id->mob[k].id = class_;
		}
	}
	// Finally insert monster's data into the database.
	if (mob->db_data[class_] == NULL)
		mob->db_data[class_] = (struct mob_db*)aMalloc(sizeof(struct mob_db));
	else
		//Copy over spawn data
		memcpy(&db->spawn, mob->db_data[class_]->spawn, sizeof(db->spawn));

	memcpy(mob->db_data[class_], db, sizeof(struct mob_db));
	return true;
} 

Tentei modificar o UNIT16 para UNIT32, porém ao fazer a edição e compilar o valor de 65535(UNIT16) se torna -1(UNIT32).

 

 

Não sou especialista em C, gostaria muito da ajuda de alguém para entender o por que de
o UNIT32 não se tornar 4294967296 conforme explica neste site sobre unit.
https://www.badprog....-t-and-uint64-t
 

3º - Linha 151 - Encontrei no arquivo Hercules/src/common/cbasetypes.h as seguintes informações que talvéz ajude

a desvendar o motivo pelo qual o unit32 não está funcionando corretamente.

https://github.com/H...on/cbasetypes.h

#undef UINT8_MIN
#undef UINT16_MIN
#undef UINT32_MIN
#undef UINT64_MIN
#define UINT8_MIN  ((uint8) UINT8_C(0x00))
#define UINT16_MIN ((uint16)UINT16_C(0x0000))
#define UINT32_MIN ((uint32)UINT32_C(0x00000000))
#define UINT64_MIN ((uint64)UINT64_C(0x0000000000000000))

#undef UINT8_MAX
#undef UINT16_MAX
#undef UINT32_MAX
#undef UINT64_MAX
#define UINT8_MAX  ((uint8) UINT8_C(0xFF))
#define UINT16_MAX ((uint16)UINT16_C(0xFFFF))
#define UINT32_MAX ((uint32)UINT32_C(0xFFFFFFFF))
#define UINT64_MAX ((uint64)UINT64_C(0xFFFFFFFFFFFFFFFF))

 

Se alguém puder colaborar agradeço, Finalmente poderemos colocar danos maior do que 65535 para monstros no jogo.
Ajudem por favor.
 

---------------------------------------------------------
Créditos evilpuncker

Edited by K4m4r40

Share this post


Link to post
Share on other sites

0 answers to this question

Recommended Posts

There have been no answers to this question yet

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.