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

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

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