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.
Olá,
Editei recentemente os mvps do meu servidor High Rate e me deparei com um problema referente ao máx hit básic.
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:
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:
2º - Linha 3705 - local que acredito ser para editar do atk e atk2 dos monstros:
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
Se alguém puder colaborar agradeço, Finalmente poderemos colocar danos maior do que 65535 para monstros no jogo.
Ajudem por favor.
---------------------------------------------------------
Edited by K4m4r40Créditos evilpuncker
Share this post
Link to post
Share on other sites