add more item detail in inventory. Create some place holder for pet item so that those item can be shown

This commit is contained in:
Chomper9981
2026-01-20 16:31:57 +07:00
parent 093c257f74
commit 273f353ddc
19 changed files with 1959 additions and 584 deletions
@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System;
using BrewMonster.abase;
using CSNetwork.GPDataType;
public static class generate_item_temp
{
public static int generate_weapon<RAND_CLASS>(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls,
@@ -705,7 +706,6 @@ public static class generate_item_temp
return 0;
}
public static int generate_material<RAND_CLASS>(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls)
{
DATA_TYPE datatype = DATA_TYPE.DT_INVALID;
@@ -742,6 +742,214 @@ public static class generate_item_temp
itemdataman.set_to_classid(DATA_TYPE.DT_MATERIAL_ESSENCE, data, -1);
return 0;
}
public static int generate_skilltome<RAND_CLASS>(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls)
{
DATA_TYPE datatype = DATA_TYPE.DT_INVALID;
data = new byte[0];
size = 0;
object obj = itemdataman._edm.get_data_ptr(id, idspace, ref datatype);
if(obj == null || datatype != DATA_TYPE.DT_SKILLTOME_ESSENCE)
{
return -1;
}
SKILLTOME_ESSENCE ess = (SKILLTOME_ESSENCE)obj;
size = (uint)(Marshal.SizeOf(typeof(item_data)) + Marshal.SizeOf(typeof(SKILLTOME_ESSENCE)));
data = new byte[size];
int offset = 0;
WriteUInt(data, ref offset, id);
WriteUInt(data, ref offset, 1);
WriteUInt(data, ref offset, (uint)ess.pile_num_max); //ƷĶѵ
WriteInt(data, ref offset, 0); //ƷĿװ־
WriteInt(data, ref offset, (int)ess.proc_type); //ƷĴʽ
WriteInt(data, ref offset, (int)DATA_TYPE.DT_SKILLTOME_ESSENCE); //ƷӦID
if(ess.has_guid == 1){
int g1,g2;
itemdataman.get_item_guid(id,out g1,out g2);
WriteInt(data, ref offset, g1); //ƷӦID guid
WriteInt(data, ref offset, g2); //ƷӦID guid
}
else{
WriteInt(data, ref offset, 0); //ƷӦID guid
WriteInt(data, ref offset, 0); //ƷӦID guid
}
WriteInt(data, ref offset, ess.price); //Ʒļ۸
WriteInt(data, ref offset, 0); //ʱ
int content_length = 0;
int content_length_ptr = offset;
WriteInt(data, ref offset, 0);
int item_content = offset;
WriteInt(data, ref offset, 0);
content_length = (int)(size - offset);
WriteInt(data, ref content_length_ptr, content_length);
WriteInt(data, ref item_content, offset);
itemdataman.set_to_classid(DATA_TYPE.DT_SKILLTOME_ESSENCE, data, -1);
return 0;
}
public struct PetSkill {
public int skill;
public int level;
}
public static int generate_pet_egg<RAND_CLASS>(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls)
{
DATA_TYPE datatype = DATA_TYPE.DT_INVALID;
data = new byte[0];
size = 0;
object obj = itemdataman._edm.get_data_ptr(id, idspace, ref datatype);
if(obj == null || datatype != DATA_TYPE.DT_PET_EGG_ESSENCE)
return -1;
PET_EGG_ESSENCE ess = (PET_EGG_ESSENCE)obj;
object petessobj = itemdataman._edm.get_data_ptr((uint)ess.id_pet, idspace, ref datatype);
if(petessobj == null || datatype != DATA_TYPE.DT_PET_ESSENCE)
return -1;
PET_ESSENCE petess = (PET_ESSENCE)petessobj;
size = (uint)(Marshal.SizeOf(typeof(item_data)) + Marshal.SizeOf(typeof(PET_EGG_ESSENCE)));
//ܵı䳤
PetSkill[] skills = new PetSkill[32];
int skill_count = 0;
int i;
for(i = 0; i < 32; i ++)
{
if(ess.skills[i].id_skill <= 0
|| ess.skills[i].level <= 0 ) continue;
skills[skill_count].skill = ess.skills[i].id_skill;
skills[skill_count].level = ess.skills[i].level;
skill_count ++;
}
size += (uint)(Marshal.SizeOf(typeof(int))*2 * skill_count);
// allocate the buffer with exact length
data = new byte[size];
int offset = 0;
WriteUInt(data, ref offset, id); //ƷģID
WriteUInt(data, ref offset, 1); //Ʒ
WriteUInt(data, ref offset, (uint)ess.pile_num_max); //ƷĶѵ
WriteInt(data, ref offset, 0); //ƷĿװ־
WriteInt(data, ref offset, (int)ess.proc_type); //ƷĴʽ
WriteInt(data, ref offset, (int)DATA_TYPE.DT_PET_EGG_ESSENCE); //ƷӦID
if(ess.has_guid == 1){
int g1,g2;
itemdataman.get_item_guid(id,out g1,out g2);
WriteInt(data, ref offset, g1); //ƷӦID guid
WriteInt(data, ref offset, g2); //ƷӦID guid
}
else{
WriteInt(data, ref offset, 0); //ƷӦID guid
WriteInt(data, ref offset, 0); //ƷӦID guid
}
WriteInt(data, ref offset, petess.level_require);
WriteInt(data, ref offset, (int)(petess.character_combo_id&0xFFFF));
WriteInt(data, ref offset, ess.honor_point);
WriteInt(data, ref offset, (int)ess.id_pet);
WriteInt(data, ref offset, 0);
WriteInt(data, ref offset, (int)ess.id);
int pet_class;
switch(petess.id_type)
{
case 8781: //
pet_class = 0;
break;
case 8782: // ս
pet_class = 1;
break;
case 8783: // ͳ
pet_class = 2;
break;
case 28752: // ٻ
pet_class = 3;
break;
case 28913: // ֲ
pet_class = 4;
break;
default:
pet_class = 4;
break;
}
WriteInt(data, ref offset, pet_class);
WriteShort(data, ref offset, (short)ess.level);
WriteShort(data, ref offset, 0);
WriteInt(data, ref offset, ess.exp);
WriteInt(data, ref offset, ess.skill_point);
WriteShort(data, ref offset, 0);
WriteShort(data, ref offset, (short)skill_count);
Array.Clear(data, offset, 16);
offset += 16;
for(i = 0; i < skill_count; i ++)
{
WriteInt(data, ref offset, skills[i].skill);
WriteInt(data, ref offset, skills[i].level);
}
if(pet_class == 5)
{
Array.Clear(data, offset, Marshal.SizeOf(typeof(_evo_prop)));
}
//ASSERT( (buf - (char*)*data) == (int)size);
itemdataman.set_to_classid(DATA_TYPE.DT_PET_EGG_ESSENCE, data, -1);
return 0;
}
public static int generate_pet_food<RAND_CLASS>(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls)
{
DATA_TYPE datatype = DATA_TYPE.DT_INVALID;
data = new byte[0];
size = 0;
object obj = itemdataman._edm.get_data_ptr(id, idspace, ref datatype);
if(obj == null || datatype != DATA_TYPE.DT_PET_FOOD_ESSENCE)
return -1;
PET_FOOD_ESSENCE ess = (PET_FOOD_ESSENCE)obj;
size = (uint)(Marshal.SizeOf(typeof(item_data)) + Marshal.SizeOf(typeof(PET_FOOD_ESSENCE)));
data = new byte[size];
int offset = 0;
WriteUInt(data, ref offset, id); //ƷģID
WriteUInt(data, ref offset, 1); //Ʒ
WriteUInt(data, ref offset, (uint)ess.pile_num_max); //ƷĶѵ
WriteInt(data, ref offset, 0); //ƷĿװ־
WriteInt(data, ref offset, (int)ess.proc_type); //ƷĴʽ
WriteInt(data, ref offset, (int)DATA_TYPE.DT_PET_EGG_ESSENCE); //ƷӦID
if(ess.has_guid == 1){
int g1,g2;
itemdataman.get_item_guid(id,out g1,out g2);
WriteInt(data, ref offset, g1); //ƷӦID guid
WriteInt(data, ref offset, g2); //ƷӦID guid
}
else{
WriteInt(data, ref offset, 0); //ƷӦID guid
WriteInt(data, ref offset, 0); //ƷӦID guid
}
WriteInt(data, ref offset, ess.price); //Ʒļ۸
WriteInt(data, ref offset, 0); //ʱ
int content_length = 0;
int content_length_ptr = offset;
WriteInt(data, ref offset, 0);
int item_content = offset;
WriteInt(data, ref offset, 0);
content_length = (int)(size - offset);
WriteInt(data, ref content_length_ptr, content_length);
WriteInt(data, ref item_content, offset);
WriteInt(data, ref offset, ess.food_type); //ƷĿװ־
WriteInt(data, ref offset, ess.hornor); //ƷӦID guid
//ASSERT( (buf - (char*)*data) == (int)size);
itemdataman.set_to_classid(DATA_TYPE.DT_PET_FOOD_ESSENCE, data, -1);
return 0;
}
#region Write Functions
private static void WriteUInt(byte[] buf, ref int offset, uint value)
{
@@ -851,517 +1059,3 @@ public static class generate_item_temp
}
}
#region unimplemented
// template <typename RAND_CLASS>
// int generate_projectile(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls)
// {
// DATA_TYPE datatype;
// PROJECTILE_ESSENCE * ess = (PROJECTILE_ESSENCE *)get_data_ptr(id, idspace, datatype);
// if(ess == NULL || datatype != DT_PROJECTILE_ESSENCE) return -1;
// size = sizeof(item_data) + sizeof(_item_content) + sizeof(_projectile_essence);
// // ޿׶
// // ̶addons 4
// char addon_buf[ELEMENTDATAMAN_MAX_NUM_ADDONS*sizeof(_addon)];
// unsigned int addon_num = 4; //ԱĿĿ̶ 4
// size_t addon_size = generate_equipment_addon_buffer_2(DT_PROJECTILE_ESSENCE, (int*)&(ess->id_addon0),sizeof(int), 4, addon_buf,addon_num);
// size += addon_size;
// //tag size
// size += sizeof(short);
// // allocate the buffer with exact length
// *data = (char *)abase::fastalloc(size);
// char * buf = *data;
// *(unsigned int*)buf = id; buf += sizeof(unsigned int); //ƷģID
// *(size_t*)buf = 1; buf += sizeof(size_t); //Ʒ
// *(size_t*)buf = ess->pile_num_max; buf += sizeof(size_t); //ƷĶѵ
// *(int*)buf = ELEMENTDATAMAN_EQUIP_MASK_PROJECTILE|(addon_num?0x40000000:0); buf += sizeof(int); //ƷĿװ־
// *(int*)buf = ess->proc_type; buf += sizeof(int); //ƷĴʽ
// *(int*)buf = DT_PROJECTILE_ESSENCE; buf += sizeof(int); //ƷӦID
// if(ess->has_guid == 1){
// int g1,g2;
// get_item_guid(id,g1,g2);
// *(int*)buf = g1; buf += sizeof(int); //ƷӦID guid
// *(int*)buf = g2; buf += sizeof(int); //ƷӦID guid
// }
// else{
// *(int*)buf = 0; buf += sizeof(int); //ƷӦID guid
// *(int*)buf = 0; buf += sizeof(int); //ƷӦID guid
// }
// *(int*)buf = ess->price; buf += sizeof(int); //Ʒļ۸
// *(int*)buf = 0; buf += sizeof(int); //ʱ
// size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //סbufָԺ
// char ** item_content = (char **)buf; buf += sizeof(char *); //סbufָԺ
// *content_length = (char*)(*data)+size-buf;
// *item_content = buf;
// // prerequisition
// char * require_ptr = buf;
// //int6
// *(short*)buf = 0; buf += sizeof(short); //prerequisition level
// *(short*)buf = (short)0xFFFF; buf += sizeof(short);
// *(short*)buf = 0; buf += sizeof(short); //prerequisition strength
// *(short*)buf = 0; buf += sizeof(short);
// *(short*)buf = 0; buf += sizeof(short); //prerequisition agility
// *(short*)buf = 0; buf += sizeof(short);
// *(int*)buf = 1; buf += sizeof(int); //prerequisition durability
// *(int*)buf = 1; buf += sizeof(int); //prerequisition max_durability
// *(short*)buf = sizeof(_projectile_essence); buf += sizeof(short); //װСֽڣ
// *(char*)buf = element_data::IMT_NULL;buf += sizeof(char);
// *(char*)buf = 0; buf += sizeof(char);
// // projectile_essence
// char * essence_ptr = buf;
// *(int*)buf = ess->type; buf += sizeof(int); //ҩ
// *(int*)buf = ess->damage_enhance; buf += sizeof(int); //Ĺ
// *(int*)buf = ess->damage_scale_enhance; buf += sizeof(int); //ձӹ
// *(int*)buf = ess->require_weapon_level_min; buf += sizeof(int); //Ҫȼ
// *(int*)buf = ess->require_weapon_level_max; buf += sizeof(int); //Ҫȼ
// // ׶
// *(short*)buf = 0; buf += sizeof(short);
// *(short*)buf = 0; buf += sizeof(short);
// // addon
// *(int*)buf = addon_num; buf += sizeof(int);
// char * addon_sld = addon_buf;
// for(size_t i=0; i<addon_num; i++)
// {
// int id = *(int*)addon_sld;
// addon_update_ess_data(*(addon_data*)addon_sld, essence_ptr, sizeof(_projectile_essence), (prerequisition*)require_ptr);
// addon_sld += ((id & 0x6000)>>13)*sizeof(int)+sizeof(int);
// }
// update_require_data((prerequisition*)require_ptr);
// memcpy(buf, addon_buf, addon_size);
// set_to_classid(DT_PROJECTILE_ESSENCE, (item_data*)(*data), -1);
// return 0;
// }
// template <typename RAND_CLASS>
// int generate_quiver(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls)
// {
// DATA_TYPE datatype;
// QUIVER_ESSENCE * ess = (QUIVER_ESSENCE *)get_data_ptr(id, ID_SPACE_ESSENCE, datatype);
// if(ess == NULL || datatype != DT_QUIVER_ESSENCE) return -1;
// datatype = DT_PROJECTILE_ESSENCE;
// //dupʽ
// // if(generate_projectile(ess->id_projectile, ID_SPACE_ESSENCE, (char **)data, size, cls) == 0)
// int ret = duplicate_static_item(id, data,size);
// if(ret == 0)
// {
// ASSERT(ess->num_max < (int)((item_data*)(*data))->pile_limit);
// ((item_data*)(*data))->count = element_data::RandNormal(ess->num_min,ess->num_max,cls,element_data::LOWER_TREND);
// return 0;
// }
// else
// return -1;
// /* {
// ASSERT(ess->num_max < (int)((item_data*)(*data))->pile_limit);
// ((item_data*)(*data))->count = element_data::RandNormal<RAND_CLASS,element_data::LOWER>(ess->num_min,ess->num_max,cls);
// return 0;
// }
// else
// return -1;
// */
// }
// template <typename RAND_CLASS>
// int generate_quiver_for_sell(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls)
// {
// DATA_TYPE datatype;
// QUIVER_ESSENCE * ess = (QUIVER_ESSENCE *)get_data_ptr(id, ID_SPACE_ESSENCE, datatype);
// if(ess == NULL || datatype != DT_QUIVER_ESSENCE) return -1;
// datatype = DT_PROJECTILE_ESSENCE;
// //޷dupΪ
// if(generate_projectile(ess->id_projectile, ID_SPACE_ESSENCE, (char **)data, size, cls) == 0)
// {
// ASSERT(ess->num_max < (int)((item_data*)(*data))->pile_limit);
// ((item_data*)(*data))->count = element_data::RandNormal(ess->num_min,ess->num_max,cls,element_data::LOWER_TREND);
// return 0;
// }
// else
// return -1;
// }
// template <typename RAND_CLASS>
// int generate_decoration(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls,element_data::GEN_ADDON_MODE normal_addon,const void * tag,size_t tag_size, int * sa_list = NULL)
// {
// DATA_TYPE datatype;
// size_t i=0;
// DECORATION_ESSENCE * ess = (DECORATION_ESSENCE *)get_data_ptr(id, idspace, datatype);
// if(ess == NULL || datatype != DT_DECORATION_ESSENCE) return -1;
// size = sizeof(item_data) + sizeof(_item_content) + sizeof(_decoration_essence);
// // ׶
// unsigned int hole_num = 0; //׶Ŀ
// // addons
// char addon_buf[ELEMENTDATAMAN_MAX_NUM_ADDONS*sizeof(_addon)];
// unsigned int addon_num = element_data::RandSelect(&(ess->probability_addon_num0),sizeof(float), 5,cls,element_data::LOWER_TREND); //ԱĿĿ
// size_t addon_size = 0;
// if(ess->fixed_props)
// {
// addon_size = generate_equipment_addon_buffer_2(DT_DECORATION_ESSENCE, (int*)&(ess->addons[0]), sizeof(int)+sizeof(float),32, addon_buf,addon_num);
// }
// else
// {
// if(normal_addon == element_data::ADDON_LIST_DROP)
// addon_size = generate_equipment_addon_buffer(DT_DECORATION_ESSENCE, (char*)&(ess->addons[0]), 32, addon_buf,addon_num);
// else if(normal_addon == element_data::ADDON_LIST_PRODUCE)
// addon_size = generate_equipment_addon_buffer(DT_DECORATION_ESSENCE, (char*)&(ess->rands[0]), 32, addon_buf,addon_num);
// else if (normal_addon == element_data::ADDON_LIST_SPEC)
// {
// addon_size = generate_spec_addon_buffer(DT_DECORATION_ESSENCE,addon_buf,ELEMENTDATAMAN_MAX_NUM_ADDONS,addon_num,sa_list);
// }
// else
// {
// addon_size = 0;
// addon_num = 0;
// }
// }
// size += addon_size;
// //tag size
// ASSERT(tag_size >= sizeof(short));
// size += tag_size;
// // allocate the buffer with exact length
// *data = (char *)abase::fastalloc(size);
// char * buf = (*data);
// *(unsigned int*)buf = id; buf += sizeof(unsigned int); //ƷģID
// *(size_t*)buf = 1; buf += sizeof(size_t); //Ʒ
// *(size_t*)buf = ess->pile_num_max; buf += sizeof(size_t); //ƷĶѵ
// DECORATION_SUB_TYPE* sub_type = (DECORATION_SUB_TYPE*)get_data_ptr(ess->id_sub_type, ID_SPACE_ESSENCE, datatype);
// if(sub_type == NULL || datatype != DT_DECORATION_SUB_TYPE) // error
// return -1;
// *(int*)buf = sub_type->equip_mask|(addon_num?ELEMENTDATAMAN_EQUIP_MASK_HAS_ADDON:0); buf += sizeof(int); //ƷĿװ־
// *(int*)buf = ess->proc_type; buf += sizeof(int); //ƷĴʽ
// *(int*)buf = DT_DECORATION_ESSENCE; buf += sizeof(int); //ƷӦID
// if(ess->has_guid == 1){
// int g1,g2;
// get_item_guid(id,g1,g2);
// *(int*)buf = g1; buf += sizeof(int); //ƷӦID guid
// *(int*)buf = g2; buf += sizeof(int); //ƷӦID guid
// }
// else{
// *(int*)buf = 0; buf += sizeof(int); //ƷӦID guid
// *(int*)buf = 0; buf += sizeof(int); //ƷӦID guid
// }
// *(int*)buf = ess->price; buf += sizeof(int); //Ʒļ۸
// *(int*)buf = 0; buf += sizeof(int); //ʱ
// size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //סbufָԺ
// char ** item_content = (char **)buf; buf += sizeof(char *); //סbufָԺ
// *content_length = (char*)(*data)+size-buf;
// *item_content = buf;
// // prerequisition
// char * require_ptr = buf;
// *(short*)buf = ess->require_level; buf += sizeof(short); //prerequisition level
// *(short*)buf = ess->character_combo_id&0xFFFF; buf += sizeof(short); //prerequisition race
// *(short*)buf = ess->require_strength; buf += sizeof(short); //prerequisition strength
// *(short*)buf = ess->require_tili; buf += sizeof(short); //prerequisition val
// *(short*)buf = ess->require_agility; buf += sizeof(short); //prerequisition agility
// *(short*)buf = ess->require_energy; buf += sizeof(short); //prerequisition energy
// int temp2 = element_data::RandNormal(ess->durability_min, ess->durability_max, cls,element_data::LOWER_TREND);
// int temp;
// if(normal_addon != element_data::ADDON_LIST_DROP || ess->proc_type & 0x1000)
// {
// temp = temp2;
// }
// else
// {
// temp = element_data::RandNormal(ess->durability_drop_min, ess->durability_drop_max, cls,element_data::UPPER_TREND);
// if(temp > temp2) temp = temp2;
// }
// *(int*)buf = temp; buf += sizeof(int); //prerequisition durability
// *(int*)buf = temp2; buf += sizeof(int); //prerequisition max_durability
// //߱ǩעǩڱСͱ֮
// *(short*)buf = sizeof(_decoration_essence); buf += sizeof(short); //װСֽڣ
// memcpy(buf,tag,tag_size);
// buf += tag_size;
// //
// char * essence_ptr = buf;
// *(int*)buf = element_data::RandNormal(ess->damage_low, ess->damage_high, cls,element_data::LOWER_TREND); buf += sizeof(int); //int damage;
// *(int*)buf = element_data::RandNormal(ess->magic_damage_low, ess->magic_damage_high, cls,element_data::LOWER_TREND); buf += sizeof(int); //int magic_damage;
// *(int*)buf = element_data::RandNormal(ess->defence_low, ess->defence_high, cls,element_data::LOWER_TREND); buf += sizeof(int); //int defense;
// *(int*)buf = element_data::RandNormal(ess->armor_enhance_low, ess->armor_enhance_high, cls,element_data::LOWER_TREND); buf += sizeof(int); //int armor;
// //
// int res[5] = {0,0,0,0,0};
// generate_magic_defense(res,(int*)(ess->magic_defences),cls,ess->fixed_props!=0);
// *(int*)buf = res[0]; buf += sizeof(int);
// *(int*)buf = res[1]; buf += sizeof(int);
// *(int*)buf = res[2]; buf += sizeof(int);
// *(int*)buf = res[3]; buf += sizeof(int);
// *(int*)buf = res[4]; buf += sizeof(int);
// // ׶
// *(short*)buf = hole_num; buf += sizeof(short); //׶Ŀ
// *(short*)buf = 0; buf += sizeof(short); //׶
// // addon
// *(int*)buf = addon_num; buf += sizeof(int);
// char * addon_sld = addon_buf;
// for(i=0; i<addon_num; i++)
// {
// int id = *(int*)addon_sld;
// addon_update_ess_data(*(addon_data*)addon_sld, essence_ptr, sizeof(_decoration_essence), (prerequisition*)require_ptr);
// addon_sld += ((id & 0x6000)>>13)*sizeof(int)+sizeof(int);
// }
// update_require_data((prerequisition*)require_ptr);
// memcpy(buf, addon_buf, addon_size);
// set_to_classid(DT_DECORATION_ESSENCE, (item_data*)(*data), -1);
// return 0;
// }
// template <typename RAND_CLASS>
// int generate_stone(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls)
// {
// DATA_TYPE datatype;
// STONE_ESSENCE * ess = (STONE_ESSENCE *)get_data_ptr(id, idspace, datatype);
// if(ess == NULL || datatype != DT_STONE_ESSENCE) return -1;
// char addon_buf[ELEMENTDATAMAN_MAX_NUM_ADDONS*sizeof(_addon)];
// int *pBuf = (int*)addon_buf;
// *pBuf = 1; //only one weapon addon now
// size_t addon_size = generate_addon_buffer(datatype,ess->id_addon_damage, (char*)(pBuf + 1));
// if(addon_size)
// {
// pBuf = (int*)(((char*)(pBuf+1)) + addon_size);
// }
// else
// {
// ASSERT(false);
// return -1;
// }
// *pBuf = 1; //only one armor addon now
// addon_size = generate_addon_buffer(datatype,ess->id_addon_defence, (char*)(pBuf + 1));
// if(addon_size)
// {
// pBuf = (int*)(((char*)(pBuf+1)) + addon_size);
// }
// else
// {
// ASSERT(false);
// return -1;
// }
// size_t ess_size = ((char*)pBuf) - addon_buf;
// size = sizeof(item_data) + ess_size;
// // allocate the buffer with exact length
// *data = (char *)abase::fastalloc(size);
// char *buf = *data;
// *(unsigned int*)buf = id; buf += sizeof(unsigned int); //ƷģID
// *(size_t*)buf = 1; buf += sizeof(size_t); //Ʒ
// *(size_t*)buf = ess->pile_num_max;buf += sizeof(size_t); //ƷĶѵ
// *(int*)buf = 0; buf += sizeof(int); //ƷĿװ־
// *(int*)buf = ess->proc_type; buf += sizeof(int); //ƷĴʽ
// *(int*)buf = DT_STONE_ESSENCE; buf += sizeof(int); //ƷӦID
// *(int*)buf = 0; buf += sizeof(int); //ƷӦID guid
// *(int*)buf = 0; buf += sizeof(int); //ƷӦID guid
// *(int*)buf = ess->price; buf += sizeof(int); //Ʒļ۸
// *(int*)buf = 0; buf += sizeof(int); //ʱ
// size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //סbufָԺ
// char ** item_content = (char **)buf; buf += sizeof(char *); //סbufָԺ
// *content_length = size - (buf - (char*)(*data));
// *item_content = buf;
// memcpy(buf, addon_buf, ess_size);
// set_to_classid(DT_STONE_ESSENCE, (item_data*)(*data), -1);
// return 0;
// }
// template <typename RAND_CLASS>
// int generate_medicine(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls)
// {
// DATA_TYPE datatype;
// MEDICINE_ESSENCE * ess = (MEDICINE_ESSENCE *)get_data_ptr(id, idspace, datatype);
// if(ess == NULL || datatype != DT_MEDICINE_ESSENCE) return -1;
// size = sizeof(item_data);
// switch(ess->id_major_type)
// {
// case 1794: // Ѫ
// case 1802: // ħ
// case 1810: // Ѫħ
// size += sizeof(size_t) + sizeof(int) + sizeof(int) + sizeof(int);
// break;
// case 1815: // ⶾҩ
// case 2038: // ˲ⶾҩ
// size += sizeof(int) + sizeof(int);
// break;
// default:
// return -1;
// }
// // allocate the buffer with exact length
// *data = (char *)abase::fastalloc(size);
// char * buf = (*data);
// *(unsigned int*)buf = id; buf += sizeof(unsigned int); //ƷģID
// *(size_t*)buf = 1; buf += sizeof(size_t); //Ʒ
// *(size_t*)buf = ess->pile_num_max; buf += sizeof(size_t); //ƷĶѵ
// *(int*)buf = 0; buf += sizeof(int); //ƷĿװ־
// *(int*)buf = ess->proc_type; buf += sizeof(int); //ƷĴʽ
// *(int*)buf = DT_MEDICINE_ESSENCE; buf += sizeof(int); //ƷӦID
// if(ess->has_guid == 1){
// int g1,g2;
// get_item_guid(id,g1,g2);
// *(int*)buf = g1; buf += sizeof(int); //ƷӦID guid
// *(int*)buf = g2; buf += sizeof(int); //ƷӦID guid
// }
// else{
// *(int*)buf = 0; buf += sizeof(int); //ƷӦID guid
// *(int*)buf = 0; buf += sizeof(int); //ƷӦID guid
// }
// *(int*)buf = ess->price; buf += sizeof(int); //Ʒļ۸
// *(int*)buf = 0; buf += sizeof(int); //ʱ
// size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //סbufָԺ
// char ** item_content = (char **)buf; buf += sizeof(char *); //סbufָԺ
// *content_length = (char*)(*data)+size-buf;
// *item_content = buf;
// switch(ess->id_major_type)
// {
// case 1794: // Ѫ
// if(ess->cool_time < 1000) ess->cool_time *= 100;
// *(int*)buf = ess->hp_add_total; buf += sizeof(int);
// *(int*)buf = ess->hp_add_time; buf += sizeof(int);
// *(int*)buf = ess->cool_time; buf += sizeof(int);
// *(int*)buf = ess->require_level; buf += sizeof(int);
// ASSERT(ess->hp_add_time && ess->hp_add_total);
// ASSERT(ess->hp_add_total/ess->hp_add_time);
// break;
// case 1802: // ħ
// if(ess->cool_time < 1000) ess->cool_time *= 100;
// *(int*)buf = ess->mp_add_total; buf += sizeof(int);
// *(int*)buf = ess->mp_add_time; buf += sizeof(int);
// *(int*)buf = ess->cool_time; buf += sizeof(int);
// *(int*)buf = ess->require_level; buf += sizeof(int);
// ASSERT(ess->mp_add_time && ess->mp_add_total);
// ASSERT(ess->mp_add_total/ess->mp_add_time);
// break;
// case 1810: // Ѫħ
// if(ess->cool_time < 1000) ess->cool_time *= 100;
// *(int*)buf = ess->mp_add_total; buf += sizeof(int);
// *(int*)buf = ess->hp_add_total; buf += sizeof(int);
// *(int*)buf = ess->cool_time; buf += sizeof(int);
// *(int*)buf = ess->require_level; buf += sizeof(int);
// ASSERT(ess->hp_add_time || ess->mp_add_total);
// break;
// case 1815: // ⶾҩ
// case 2038: // ˲ⶾҩ
// if(ess->cool_time < 1000) ess->cool_time *= 100;
// *(int*)buf = ess->cool_time; buf += sizeof(int);
// *(int*)buf = ess->require_level; buf += sizeof(int);
// break;
// default:
// return -1;
// }
// set_to_classid(DT_MEDICINE_ESSENCE, (item_data*)(*data), ess->id_major_type);
// return 0;
// }
// template <typename ESSENCE >
// int generate_material(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, ESSENCE * p, DATA_TYPE DTYPE)
// {
// DATA_TYPE datatype;
// ESSENCE * ess = (ESSENCE *)get_data_ptr(id, idspace, datatype);
// if(ess == NULL || datatype != DTYPE) return -1;
// size = sizeof(item_data) ;
// // allocate the buffer with exact length
// *data = (char *)abase::fastalloc(size);
// char * buf = (*data);
// *(unsigned int*)buf = id; buf += sizeof(unsigned int); //ƷģID
// *(size_t*)buf = 1; buf += sizeof(size_t); //Ʒ
// *(size_t*)buf = ess->pile_num_max; buf += sizeof(size_t); //ƷĶѵ
// *(int*)buf = 0; buf += sizeof(int); //ƷĿװ־
// *(int*)buf = ess->proc_type; buf += sizeof(int); //ƷĴʽ
// *(int*)buf = DTYPE; buf += sizeof(int); //ƷӦID
// if(ess->has_guid == 1){
// int g1,g2;
// get_item_guid(id,g1,g2);
// *(int*)buf = g1; buf += sizeof(int); //ƷӦID guid
// *(int*)buf = g2; buf += sizeof(int); //ƷӦID guid
// }
// else{
// *(int*)buf = 0; buf += sizeof(int); //ƷӦID guid
// *(int*)buf = 0; buf += sizeof(int); //ƷӦID guid
// }
// *(int*)buf = ess->price; buf += sizeof(int); //Ʒļ۸
// *(int*)buf = 0; buf += sizeof(int); //ʱ
// size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //סbufָԺ
// char ** item_content = (char **)buf; buf += sizeof(char *); //סbufָԺ
// *content_length = (char*)(*data)+size-buf;
// *item_content = buf;
// set_to_classid(DTYPE, (item_data*)(*data), -1);
// return 0;
// }
// template <typename RAND_CLASS>
// int generate_skilltome(unsigned int id, ID_SPACE idspace, char ** data, size_t& size, RAND_CLASS cls)
// {
// DATA_TYPE datatype;
// SKILLTOME_ESSENCE * ess = (SKILLTOME_ESSENCE *)get_data_ptr(id, idspace, datatype);
// if(ess == NULL || datatype != DT_SKILLTOME_ESSENCE) return -1;
// size = sizeof(item_data);
// // allocate the buffer with exact length
// *data = (char *)abase::fastalloc(size);
// char * buf = (*data);
// *(unsigned int*)buf = id; buf += sizeof(unsigned int); //ƷģID
// *(size_t*)buf = 1; buf += sizeof(size_t); //Ʒ
// *(size_t*)buf = ess->pile_num_max; buf += sizeof(size_t); //ƷĶѵ
// *(int*)buf = 0; buf += sizeof(int); //ƷĿװ־
// *(int*)buf = ess->proc_type; buf += sizeof(int); //ƷĴʽ
// *(int*)buf = DT_SKILLTOME_ESSENCE; buf += sizeof(int); //ƷӦID
// if(ess->has_guid == 1){
// int g1,g2;
// get_item_guid(id,g1,g2);
// *(int*)buf = g1; buf += sizeof(int); //ƷӦID guid
// *(int*)buf = g2; buf += sizeof(int); //ƷӦID guid
// }
// else{
// *(int*)buf = 0; buf += sizeof(int); //ƷӦID guid
// *(int*)buf = 0; buf += sizeof(int); //ƷӦID guid
// }
// *(int*)buf = ess->price; buf += sizeof(int); //Ʒļ۸
// *(int*)buf = 0; buf += sizeof(int); //ʱ
// size_t* content_length = (size_t*)buf; buf += sizeof(size_t); //סbufָԺ
// char ** item_content = (char **)buf; buf += sizeof(char *); //סbufָԺ
// *content_length = (char*)(*data)+size-buf;
// *item_content = buf;
// set_to_classid(DT_SKILLTOME_ESSENCE, (item_data*)(*data), -1);
// return 0;
// }
#endregion
@@ -468,6 +468,15 @@ namespace BrewMonster
case DATA_TYPE.DT_MATERIAL_ESSENCE:
ret = generate_item_temp.generate_material(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND);
break;
case DATA_TYPE.DT_SKILLTOME_ESSENCE:
ret = generate_item_temp.generate_skilltome(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND);
break;
case DATA_TYPE.DT_PET_EGG_ESSENCE:
ret = generate_item_temp.generate_pet_egg(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND);
break;
case DATA_TYPE.DT_PET_FOOD_ESSENCE:
ret = generate_item_temp.generate_pet_food(id, ID_SPACE.ID_SPACE_ESSENCE, out item, out size, SPECIFIC.SPECIFIC_RAND);
break;
default:
ret = -1;
break;
@@ -62,7 +62,7 @@ namespace BrewMonster
public string FileHitGfx => ByteToStringUtils.ByteArrayToCP936String(file_hitgfx);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_hitsfx; // Hit sound effect file path
public byte[] file_hitsfx; // Hit sound effect file pathpublic string FileHitSfx => ByteToStringUtils.ByteArrayToCP936String(file_hitsfx);
public string FileHitSfx => ByteToStringUtils.ByteArrayToCP936String(file_hitsfx);
public float probability_fastest; // Attack frequency probability: Fastest -0.1
public float probability_fast; // Attack frequency probability: Fast -0.05
@@ -260,8 +260,8 @@ namespace BrewMonster
public uint id; // Armor major type ID
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Armor major type name
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
public ushort[] name; // Armor major type name public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -459,9 +459,7 @@ namespace BrewMonster
// Display information
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model; // Model file path
public string FileModel => ByteToStringUtils.ByteArrayToCP936String(file_model);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Matter model file path
@@ -766,12 +764,10 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Fashion name, max 15 characters
public string Name => ByteToStringUtils.UshortArrayToCP936String(name);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] realname; // Real fashion name
public string RealName => ByteToStringUtils.ByteArrayToUnicodeString(realname);
// Display information
@@ -808,7 +804,6 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] wear_action; // Wear action
public string WearAction => ByteToStringUtils.ByteArrayToUnicodeString(wear_action);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
@@ -842,7 +837,7 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Medicine major type name
public string Name => ByteToStringUtils.UshortArrayToCP936String(name);
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -1070,7 +1065,7 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Material major type name
public string Name => ByteToStringUtils.UshortArrayToCP936String(name);
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -1080,7 +1075,7 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // Material sub-type name
public string Name => ByteToStringUtils.UshortArrayToCP936String(name);
public string Name => ByteToStringUtils.UshortArrayToUnicodeString(name);
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -1340,10 +1335,10 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // Matter model file path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // Icon file path
public string FileIcon => ByteToStringUtils.ByteArrayToCP936String(file_icon);
public int price; // Base price
public int shop_price; // Shop price
@@ -2120,6 +2115,7 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // icon file path
public string FileIcon { get { return ByteToStringUtils.ByteArrayToCP936String(file_icon); } }
public int id_pet; // pet ID
@@ -2158,9 +2154,11 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // matter file path
public string FileMatter { get { return ByteToStringUtils.ByteArrayToCP936String(file_matter); } }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon; // icon file path
public string FileIcon { get { return ByteToStringUtils.ByteArrayToCP936String(file_icon); } }
public int level; // level
@@ -2999,31 +2997,27 @@ namespace BrewMonster
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public ushort[] name; // name, max 15 characters
public string Name => ByteToStringUtils.UshortArrayToCP936String(name);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model1; // state 1 model file
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model2; // state 2 model file
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model3; // state 3 model file
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_model4; // state 4 model file
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_matter; // matter model path
public string FileMatter => ByteToStringUtils.ByteArrayToCP936String(file_matter);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon1; // state 1 icon path
public string FileIcon1 => ByteToStringUtils.ByteArrayToCP936String(file_icon1);
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon2; // state 2 icon path
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon3; // state 3 icon path
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] file_icon4; // state 4 icon path
@@ -80,4 +80,14 @@ namespace BrewMonster.Scripts
SIZE_FASHIONSCSET = 240,
};
// Pet food type
enum PetFoodType
{
PET_FOOD_GRASS = 0,
PET_FOOD_MEAT,
PET_FOOD_VEGETABLE,
PET_FOOD_FRUIT,
PET_FOOD_WATER,
MAX_PET_FOOD,
};
}
@@ -393,18 +393,13 @@ namespace PerfectWorld.Scripts.Managers
m_strDesc += "\\r";
AddIDDescText();
AddBindDescText();
BMLogger.Log("AddBindDescText: " + m_strDesc);
// Is destroying?
AddDestroyingDesc((int)m_pDBEssence.id_drop_after_damaged, m_pDBEssence.num_drop_after_damaged);
BMLogger.Log("AddDestroyingDesc: " + m_strDesc);
AddExpireTimeDesc();
BMLogger.Log("AddExpireTimeDesc: " + m_strDesc);
// Sub class name
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_CLASSNAME), m_pDBSubType.Name);
BMLogger.Log("AddDescText: " + m_strDesc);
// Weapon level
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVEL), m_pDBEssence.level);
BMLogger.Log("AddDescText: " + m_strDesc);
// Physical defence
if (m_Essence.defense - aPEEVals[PEEI_PHYDEF] + aRefines[REFINE_PHYDEF] != 0)
{
@@ -1,20 +1,763 @@
using BrewMonster.Scripts.Managers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.IO;
using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Skills;
namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrGoblin : EC_IvtrItem
/// <summary>
/// The goblin item class (cac loai tinh linh).(not completed, need generate class).
/// This feature is skip for now.
/// </summary>
public class EC_IvtrGoblin : EC_IvtrEquip
{
#region const, enum and struct
const int MAX_ELF_REFINE_LEVEL = 36;
const int INITIAL_MAX_VIGOR = 1000;
enum ElfSkillNum
{
MAX_SKILLNUM = 8, // Max skill num
SKILL_LEARN_PT = 40, // ÿSKILL_LEARN_PTܶѧһ (ѹʱ 2009-08-24)
INIT_SKILL_NUM = 4, // ʼ
};
public struct GOBLINSKILL
{
public ushort skill;
public short level;
}
#endregion
#region Array and List declaration
// Refine effect of goblin
int[,] m_iRefineEffect = new int[MAX_ELF_REFINE_LEVEL, 3] {
{45,0,0},
{100,0,0},
{165,0,0},
{240,0,0},
{325,0,0},
{420,0,0},
{420,1,0},
{420,2,0},
{420,2,1},
{420,2,2}, // 10
{420,3,3},
{420,4,4},
{420,6,5},
{420,9,6},
{420,12,7},
{420,16,8},
{420,20,9},
{420,24,11},
{420,28,13},
{420,32,15}, // 20
{420,36,17},
{420,41,19},
{420,46,21},
{420,51,24},
{420,56,27},
{420,61,30},
{420,66,33},
{420,72,36},
{420,78,39},
{420,84,42}, // 30
{420,90,45},
{420,96,48},
{420,102,51},
{420,108,54},
{420,114,57},
{420,120,60}
};
int[] m_iRefineMaterial = new int[MAX_ELF_REFINE_LEVEL] {
1, 2, 7, 20, 50, 110, 220, 390, 500, 550, // 10
600, 650, 700, 750, 800, 850, 900, 950, 1000, 1050, // 20
1100, 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500, 1550, // 30
1600, 1650, 1700, 1750, 1800, 1850,
};
static int[] elf_exp_loss_constant = new int[151] {0, //no use
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
100, 100, 100, 100, 100, //105
// ΪڷԳȼ150
100, 100, 100, 100, 100, //110
100, 100, 100, 100, 100,
100, 100, 100, 100, 100, //120
100, 100, 100, 100, 100,
100, 100, 100, 100, 100, //130
100, 100, 100, 100, 100,
100, 100, 100, 100, 100, //140
100, 100, 100, 100, 100,
100, 100, 100, 100, 100, //150
};
//ʹrmbĿȼӦijɹ
float[] elf_refine_succ_prob_ticket0 = new float[MAX_ELF_REFINE_LEVEL+1] {
1.0f, 0.4f, 0.315789474f, 0.338983051f, 0.377358491f, 0.417754569f, 0.463208685f, 0.510769231f, 0.55f, 0.55f,
0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f,
0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f,
0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f,
0.0f}; // [36]: cannot refine any more
//ʹ絤(߳ɹʣʧܵȼ0)ĿȼӦijɹ
static float[] elf_refine_succ_prob_ticket1 = new float[MAX_ELF_REFINE_LEVEL+1]{
1.0f, 0.6f, 0.368421053f, 0.355932203f, 0.383647799f, 0.420365535f, 0.464414958f, 0.511384615f, 0.557001027f, 0.60032861f,
0.640836732f, 0.678052261f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f,
0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f,
0.7f, 0.7f, 0.7f, 0.7f, 0.7f, 0.7f,
0.0f
};
//ʹϵ(ɹʣʧܵȼ1)ĿȼӦijɹ
static float[] elf_refine_succ_prob_ticket2 = new float[MAX_ELF_REFINE_LEVEL+1]{
1.0f, 0.6f, 0.333333333f, 0.296296296f, 0.3f, 0.314814815f, 0.337313433f, 0.360708535f, 0.381453155f, 0.4f,
0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f,
0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f,
0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f,
0.0f
};
//ʹλõ(ɹʹøиޣʧܵȼ)ĿȼӦʹɹ=/Էŵ
static int[] elf_refine_max_use_ticket3 = new int[MAX_ELF_REFINE_LEVEL+1]{
1 , 2 , 7 , 20 , 50 , 112 , 223 , 398 , 648 , 974 ,
1366 , 1806 , 2271 , 2739 , 3191 , 3612 , 3993 , 4331 , 4623 , 4873 ,
5084 , 5260 , 5405 , 5525 , 5623 , 5702 , 5767 , 5819 , 5861 , 5895 ,
5923 , 5945 , 5962 , 5977 , 5988 , 5997,
100000000
};
#endregion
List<GOBLINSKILL> m_aSkills;
List<uint> m_aEquipID;
IVTR_ESSENCE_GOBLIN m_Essence; // Goblin essence data
// Data in database
GOBLIN_ESSENCE m_pDBEssence;
/// <summary>
/// Not create logic yet (add summary later)
/// Create goblin item (cac loai tinh linh).
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrGoblin(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_GOBLIN;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (GOBLIN_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
Price = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_bNeedUpdate = false;
m_i64EquipMask = (long)EC_IvtrType.EQUIP_MASK64_GOBLIN;
CurEndurance = 1;
MaxEndurance = 1;
}
public EC_IvtrGoblin(EC_IvtrGoblin other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
m_Essence = other.m_Essence; // Copy essence
// Copy skills
int i, iNumSkill = other.m_aSkills.Count;
m_aSkills = new List<GOBLINSKILL>(iNumSkill);
for (i=0; i < iNumSkill; i++)
m_aSkills[i] = other.m_aSkills[i];
// Copy equipments
int iNumEquip = other.m_aEquipID.Count;
m_aEquipID = new List<uint>(iNumEquip);
for(i=0; i< iNumEquip; i++)
m_aEquipID[i] = other.m_aEquipID[i];
}
public IVTR_ESSENCE_GOBLIN GetEssence() { return m_Essence; }
// Get database data
public GOBLIN_ESSENCE GetDBEssence() { return m_pDBEssence; }
// Get skill number
public int GetSkillNum() { return m_aSkills.Count; }
public GOBLINSKILL GetSkill(int id) { if(id>=0 && id<m_aSkills.Count) return m_aSkills[id]; else throw new Exception("id is out of range"); }
// Set Goblin inventory stamina
void SetStamina(int iStamina) { m_Essence.data.stamina = iStamina; }
// Set Goblin Exp
public void SetExp(int iExp) { m_Essence.data.exp = (uint)iExp; }
float GetRefineSuccProb0(int iLevel)
{
return elf_refine_succ_prob_ticket0[iLevel];
}
float GetRefineSuccProb1(int iLevel)
{
if (iLevel < 0 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
return elf_refine_succ_prob_ticket1[iLevel];
}
float GetRefineSuccProb2(int iLevel)
{
if (iLevel < 0 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
return elf_refine_succ_prob_ticket2[iLevel];
}
float GetRefineSuccProb3(int iLevel, int iNum)
{
if (iLevel < 0 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
if (iNum >= elf_refine_max_use_ticket3[iLevel])
{
return 1.0f;
}
if (iLevel == MAX_ELF_REFINE_LEVEL)
{
return 0.0f;
}
return (float)iNum / (float)elf_refine_max_use_ticket3[iLevel];
}
int GetRefineLife(int iLevel)
{
if (iLevel < 1 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
return m_iRefineEffect[iLevel-1, 0];
}
int GetRefineAtkLvl(int iLevel)
{
if (iLevel < 1 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
return m_iRefineEffect[iLevel-1, 1];
}
int GetRefineDfsLvl(int iLevel)
{
if (iLevel < 1 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
return m_iRefineEffect[iLevel-1, 2];
}
int GetRefineMaterial(int iLevel)
{
if (iLevel < 1 || iLevel > MAX_ELF_REFINE_LEVEL)
{
throw new Exception("iLevel is out of range");
}
return m_iRefineMaterial[iLevel-1];
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
if (pInfoData == null || iDataLen == 0)
return true;
try
{
CECDataReader dr = new CECDataReader(pInfoData, iDataLen);
// Set _GOBLIN_DATA info
// Calculate size manually: uint(4) + 7*short(14) + short[5](10) + short(2) + 2*int(8) = 40 bytes
const int GOBLIN_DATA_SIZE = 40;
m_Essence.data = new IVTR_ESSENCE_GOBLIN._GOBLIN_DATA(dr.ReadData(GOBLIN_DATA_SIZE));
// Change proc type
if(m_Essence.data.status_value < 0)
{
m_iProcType |= (int)ProcType.PROC_SELLABLE;
m_iProcType |= (int)ProcType.PROC_TRADEABLE;
}
else
{
m_iProcType &= ~(int)ProcType.PROC_SELLABLE;
m_iProcType &= ~(int)ProcType.PROC_TRADEABLE;
}
// Set equipment info
int i, iEquipCnt = dr.ReadInt();
m_Essence.equip_cnt = iEquipCnt;
m_aEquipID = new List<uint>(iEquipCnt);
for(i=0; i< iEquipCnt; i++)
{
m_aEquipID[i] = (uint)dr.ReadInt();
}
// Set skill info
int iSkillCnt = dr.ReadInt();
m_Essence.skill_cnt = iSkillCnt;
m_aSkills = new List<GOBLINSKILL>(iSkillCnt);
for(i=0; i< iSkillCnt; i++)
{
GOBLINSKILL s = m_aSkills[i];
s.skill = (ushort)dr.ReadShort();
s.level = (short)dr.ReadShort();
}
}
catch (Exception e)
{
Debug.LogError("CECIvtrGoblin::SetItemInfo, data read error (" + e.GetType() + ")");
return false;
}
return true;
}
public override void DefaultInfo()
{
base.DefaultInfo();
}
public override string GetIconFile()
{
return m_pDBEssence.FileIcon1;
}
public override string GetName()
{
return m_pDBEssence.Name;
}
protected override string GetNormalDesc(bool bRepair)
{
if (m_bNeedUpdate)
{
return string.Empty;
}
m_strDesc = "";
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int yellow = (int)DescriptipionMsg.ITEMDESC_COL_YELLOW;
int green = (int)DescriptipionMsg.ITEMDESC_COL_GREEN;
int color = white;
int i;
int namecol = DecideNameCol();
// Item name: always use the name in template
if(m_Essence.data.refine_level != 0)
{
AddDescText(namecol, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), m_pDBEssence.Name);
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_REFINE_LEVEL), m_Essence.data.refine_level);
}
else
{
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), m_pDBEssence.Name);
}
AddIDDescText();
// Goblin level
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_LEVEL), m_Essence.data.level);
// Strength, Agility, Vitality, Energy + gained from equipment
int iEquipStrength = 0;
int iEquipAgility = 0;
int iEquipTili = 0;
int iEquipEnergy = 0;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
GOBLIN_EQUIP_ESSENCE pDBEssence;
for(i=0; i< m_aEquipID.Count; i++)
{
pDBEssence = (GOBLIN_EQUIP_ESSENCE)pDB.get_data_ptr(m_aEquipID[i], ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
iEquipStrength += pDBEssence.strength;
iEquipAgility += pDBEssence.agility;
iEquipTili += pDBEssence.tili;
iEquipEnergy += pDBEssence.energy;
}
color = (iEquipStrength == 0) ? white : green;
AddDescText(color, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_STRENGTH), iEquipStrength + m_Essence.data.strength + m_pDBEssence.init_strength);
color = (iEquipAgility == 0) ? white : green;
AddDescText(color, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_AGILITY), iEquipAgility + m_Essence.data.agility + m_pDBEssence.init_agility);
color = (iEquipTili == 0) ? white : green;
AddDescText(color, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_VITALITY), iEquipTili + m_Essence.data.vitality + m_pDBEssence.init_tili);
color = (iEquipEnergy == 0) ? white : green;
AddDescText(color, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ENERGY), iEquipEnergy + m_Essence.data.energy + m_pDBEssence.init_energy);
// Grow degree
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_GROW_DEGREE), GetGrowDegree());
// Random status point
int iMaxRandPt = GetMaxRandomStatusPt();
if(iMaxRandPt != 0)
{
int iRandPt = GetRandomStatusPt();
int iGrowDegree = GetGrowDegree();
int iRandomPt = GetRandomStatusPt();
int iMaxPt= GetMaxStautsPt();
if(iRandomPt <= iGrowDegree*0.8)
color = (int)DescriptipionMsg.ITEMDESC_COL_GREEN;
else if(iRandomPt <= iGrowDegree)
color = (int)DescriptipionMsg.ITEMDESC_COL_LIGHTBLUE;
else if(iRandomPt <= (iMaxPt - iGrowDegree)*0.2 + iGrowDegree)
color = (int)DescriptipionMsg.ITEMDESC_COL_PURPLE;
else if(iRandomPt < iMaxPt)
color = (int)DescriptipionMsg.ITEMDESC_COL_YELLOW;
else if(iRandomPt == iMaxPt)
color = (int)DescriptipionMsg.ITEMDESC_COL_DARKGOLD;
AddDescText(color, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_RANDPT), iRandPt, iMaxRandPt);
}
// Energy
int iEnergy = INITIAL_MAX_VIGOR + GetBasicProp(2);
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_ENERGY), iEnergy);
// Energy restore speed
float fRestoreSpeed = 1.0f + GetBasicProp(3)*0.02f;
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_ENERGY_RESTORE), fRestoreSpeed);
// Current stamina
int iCurrStamina = m_Essence.data.stamina;
if(iCurrStamina > 999999)
iCurrStamina = 999999;
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_STAMINA), iCurrStamina);
// Current refine effect
if(m_Essence.data.refine_level != 0)
{
int iAttackLevel, iDefenceLevel, iLife;
iLife = GetRefineLife(m_Essence.data.refine_level);
iAttackLevel = GetRefineAtkLvl(m_Essence.data.refine_level);
iDefenceLevel = GetRefineDfsLvl(m_Essence.data.refine_level);
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_REFINE_EFFECT), iLife, iAttackLevel, iDefenceLevel);
}
// Trade state
int iTradeState = m_Essence.data.status_value;
if(iTradeState == 0)
AddDescText(white,true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_TRADE_PROTECT));
else if(iTradeState > 0)
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_TRADE_UNPROTECT));
else if(iTradeState < 0)
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLIN_CANTRADE));
// Price
AddPriceDesc(white, bRepair);
// Equipment info
if(m_aEquipID.Count != 0)
m_strDesc += "\\r";
for(i=0; i< m_aEquipID.Count; i++)
{
pDBEssence = (GOBLIN_EQUIP_ESSENCE)pDB.get_data_ptr(m_aEquipID[i], ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_GOBLINEQUIP_POS_1 + pDBEssence.equip_type));
AddDescText(white, true, " %s", pDBEssence.name);
}
// Skill list
if(m_aSkills.Count != 0 && m_aEquipID.Count == 0)
m_strDesc += "\\r";
for (i=0; i < m_aSkills.Count; i++)
{
GOBLINSKILL gSkill = m_aSkills[i];
string szName = EC_Game.GetSkillDesc().GetWideString(gSkill.skill * 10);
if(i==m_aSkills.Count-1)
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_YELLOW, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PETSKILL), szName != null ? szName : "", gSkill.level);
else
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_YELLOW, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PETSKILL), szName != null ? szName : "", gSkill.level);
}
AddExtDescText();
return m_strDesc;
}
// Get grow degree
int GetGrowDegree()
{
float fGrowDegree = 0.0f;
for(int i=0;i<10;i++)
{
fGrowDegree += m_pDBEssence.rand_prop[i].rand_num * m_pDBEssence.rand_prop[i].rand_rate;
}
return (int)(fGrowDegree*10 + 0.5f);
}
// Max random status points that this goblin can get, depending on player's RP value
int GetMaxRandomStatusPt()
{
return (GetMaxStautsPt()/10) * (m_Essence.data.level/10);
}
// Max status points that this goblin can get
int GetMaxStautsPt()
{
int iMaxPt = 0;
for(int i= 0;i<10;i++)
{
if(iMaxPt < m_pDBEssence.rand_prop[i].rand_num)
iMaxPt = m_pDBEssence.rand_prop[i].rand_num;
}
return iMaxPt * 10;
}
// Current random status point
int GetRandomStatusPt()
{
return m_Essence.data.total_attribute - (m_Essence.data.level-1);
}
// Get basic property
int GetBasicProp(int iIndex)
{
if(iIndex < 0 || iIndex >= 4)
{
throw new Exception("iIndex is out of range");
}
int i, iRet = 0;
// Strength, Agility, Vitality, Energy + gained from equipment
int iEquipStrength = 0;
int iEquipAgility = 0;
int iEquipTili = 0;
int iEquipEnergy = 0;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
GOBLIN_EQUIP_ESSENCE pDBEssence;
for(i=0; i< m_aEquipID.Count; i++)
{
pDBEssence = (GOBLIN_EQUIP_ESSENCE)pDB.get_data_ptr(m_aEquipID[i], ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
iEquipStrength += pDBEssence.strength;
iEquipAgility += pDBEssence.agility;
iEquipTili += pDBEssence.tili;
iEquipEnergy += pDBEssence.energy;
}
if(iIndex == 0)
iRet = iEquipStrength + m_Essence.data.strength + m_pDBEssence.init_strength;
else if(iIndex == 1)
iRet = iEquipAgility + m_Essence.data.agility + m_pDBEssence.init_agility;
else if(iIndex == 2)
iRet = iEquipTili + m_Essence.data.vitality + m_pDBEssence.init_tili;
else if(iIndex == 3)
iRet = iEquipEnergy + m_Essence.data.energy + m_pDBEssence.init_energy;
return iRet;
}
uint GetDestroyExp()
{
double dRetExp = 0;
int iLevel = m_Essence.data.level;
uint iCurrExp = m_Essence.data.exp;
double factor = 0.0f;
for(int i=1;i<iLevel;i++)
{
uint iPlayerLvlUpExp = (uint)(EC_Game.GetGameRun().GetHostPlayer().GetLevelUpExp(i) * m_pDBEssence.exp_factor);
factor = (double)elf_exp_loss_constant[i]/(double)elf_exp_loss_constant[m_Essence.data.level];
dRetExp += (((double)iPlayerLvlUpExp * 0.1) / factor);
}
dRetExp += ((double)iCurrExp * 0.1);
return (dRetExp>4200000000.0) ? 4200000000 : (uint)dRetExp;
}
// Check whether goblin can trade
public override bool IsTradeable()
{
return (m_iProcType & (int)ProcType.PROC_TRADEABLE) != 0;
}
// Get drop model for shown
public override string GetDropModel() => m_pDBEssence.FileMatter;
// Get Equipment id
public uint GetEquip(int id)
{
if(id<0 || id>=4)
throw new Exception("id is out of range");
int iEquipPos = (int)m_aEquipID[id];
if(iEquipPos == id)
return m_aEquipID[id];
return 0;
}
// Check whether goblin can learn specified skill
// 0:ɹ 1:SP 2:
// 3: 4:ܸ 5:ID
// 6:Ǯ 7:С 8:ûм
// 9:ȼ 10:޲ 11:ְҵƥ
// 12:޲ְҵƥ
int CheckSkillLearnCondition(int idSkill, bool bCheckBook)
{
int iLevel = 1, i;
for(i=0;i<m_aSkills.Count;i++)
{
if(m_aSkills[i].skill == idSkill)
{
iLevel = m_aSkills[i].level + 1;
break;
}
}
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
if (iLevel == 1 && bCheckBook)
{
// Do we have the skill book ?
int idBook = ElementSkill.GetRequiredBook((uint)idSkill, iLevel);
if ((idBook != 0) && (pHost.GetPack().FindItem(idBook) == -1))
return 8;
}
// Build player information
GoblinRequirement Info;
Info = new GoblinRequirement();
for(i=0;i<5;i++)
{
Info.genius[i] = GetGenius(i);
}
Info.profession = pHost.GetProfession();
Info.sp = pHost.GetBasicProps().iSP;
Info.money = (int)pHost.GetMoneyAmount();
Info.level = m_Essence.data.level;
Info.mp = INITIAL_MAX_VIGOR + GetBasicProp(2);
int iRet = ElementSkill.GoblinLearn((uint)idSkill, Info, iLevel);
if(iRet == 0) // success
{
if((GetSkillNum() > GetCurrMaxSkillNum()) ||
(GetSkillNum() == GetCurrMaxSkillNum() && iLevel == 1))
return 4;
}
return iRet;
}
// Get genius point
int GetGenius(int iIndex)
{
if(iIndex < 0 || iIndex >= 5)
{
throw new Exception("iIndex is out of range");
}
int i, iRet = m_Essence.data.genius[iIndex];
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
GOBLIN_EQUIP_ESSENCE pDBEssence;
for(i=0; i< m_aEquipID.Count; i++)
{
pDBEssence = (GOBLIN_EQUIP_ESSENCE)pDB.get_data_ptr(m_aEquipID[i], ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
iRet += pDBEssence.magic[iIndex];
}
return (iRet > 8) ? 8 : iRet;
}
int GetCurrMaxSkillNum()
{
int iRandPt = GetRandomStatusPt();
if(iRandPt > 90)
return 8;
else if(iRandPt > 80)
return 7;
else if(iRandPt > 70)
return 6;
else if(iRandPt > 50)
return 5;
return (int)ElfSkillNum.INIT_SKILL_NUM;
}
//Check whether goblin can cast specified skill
/// <summary>
/// implement later
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
bool CheckSkillCastCondition(int index)
{
return true;
// if(index<0 || index >= m_aSkills.Count)
// {
// throw new Exception("index is out of range");
// return false;
// }
// if (EC_Game.GetGameRun().GetHostPlayer().GetBattleInfo().IsChariotWar())
// return false; // սս ֹ
// GNET::GoblinUseRequirement Info;
// memset(&Info, 0, sizeof(Info));
// for(int i=0;i<5;i++)
// {
// Info.genius[i] = GetGenius(i);
// }
// Info.level = m_Essence.data.level;
// Info.move_env = g_pGame->GetGameRun()->GetHostPlayer()->GetMoveEnv();
// GOBLINSKILL pSkill = GetSkill(index);
// int ret = GNET::ElementSkill::GoblinCondition(pSkill.skill, Info, pSkill.level);
// if(ret == 4)
// return false;
// return true;
}
int GetModelLevel()
{
int iGrowDegree = GetGrowDegree();
int iRandomPt = GetRandomStatusPt();
int iMaxPt= GetMaxStautsPt();
int iModelLvl = 0;
// ɳȡģ͵Ĺϵ֪ͬ
if(iRandomPt <= iGrowDegree*0.8)
iModelLvl = 1;
else if(iRandomPt <= iGrowDegree)
iModelLvl = 2;
else if(iRandomPt <= (iMaxPt - iGrowDegree)*0.2 + iGrowDegree)
iModelLvl = 3;
else
iModelLvl = 4;
return iModelLvl;
}
}
}
// Get current max skill number
@@ -1503,6 +1503,13 @@ namespace BrewMonster.Scripts.Managers
protected virtual void AddDescText(int iCol, bool bRet, string szText, params object[] args)
{
// Add color prefix if color is specified
if (iCol >= 0)
{
string colorStr = GetColorString((DescriptipionMsg)iCol);
m_strDesc += colorStr;
}
string line;
if (args != null && args.Length > 0)
{
@@ -1525,6 +1532,26 @@ namespace BrewMonster.Scripts.Managers
m_strDesc += "\n";
}
/// <summary>
/// Get color string for color ID
/// Returns color codes in ^RRGGBB format (6 hex digits) for text formatting
/// </summary>
protected virtual string GetColorString(DescriptipionMsg colorId)
{
switch (colorId)
{
case DescriptipionMsg.ITEMDESC_COL_WHITE: return "^FFFFFF"; // White
case DescriptipionMsg.ITEMDESC_COL_GREEN: return "^00FF00"; // Green
case DescriptipionMsg.ITEMDESC_COL_YELLOW: return "^FFFF00"; // Yellow
case DescriptipionMsg.ITEMDESC_COL_DARKGOLD: return "^FF8C00"; // Dark Gold / Orange
case DescriptipionMsg.ITEMDESC_COL_LIGHTBLUE: return "^5998FF"; // Light Blue
case DescriptipionMsg.ITEMDESC_COL_CYANINE: return "^00FFFF"; // Cyan
case DescriptipionMsg.ITEMDESC_COL_RED: return "^FF0000"; // Red
case DescriptipionMsg.ITEMDESC_COL_GRAY: return "^808080"; // Gray
default: return "^FFFFFF"; // Default to white
}
}
/// <summary>
/// Format string using printf-style format specifiers (%d, %+d, %.2f, %s, etc.)
/// Converts printf-style formats to C# string formatting
@@ -1662,7 +1689,6 @@ namespace BrewMonster.Scripts.Managers
if (!string.IsNullOrEmpty(desc))
m_strDesc += desc;
}
Debug.Log("m_strDesc: " + m_strDesc);
}
if ((m_iProcType & (int)ProcType.PROC_SELLABLE) != 0)
{
@@ -1,20 +1,360 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
{
public struct PETSKILL
{
public int idSkill;
public int iLevel;
};
/// <summary>
/// Class for Pet Egg(cac loai trung pet(thu cuoi, chien dau, di theo, p2w pet)). This is a part of IvtrPetItem(C++)
/// </summary>
public class EC_IvtrPetEgg : EC_IvtrItem
{
List<PETSKILL> m_aSkills;
IVTR_ESSENCE_PETEGG m_Essence;
string m_strName;
// Data in database
PET_EGG_ESSENCE m_pDBEssence;
PET_ESSENCE m_pPetEssence;
PET_ESSENCE m_pEvoPetEssence;
PET_EVOLVED_SKILL_CONFIG m_pEvoNatureConfig;
_evo_prop m_EvoProp; // ̳
/// <summary>
/// Not create logic yet (add summary later)
/// Constructor for Pet Egg(cac loai trung pet(thu cuoi, chien dau, di theo, p2w pet))
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrPetEgg(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_PETEGG;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (PET_EGG_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_pPetEssence = (PET_ESSENCE)pDB.get_data_ptr((uint)m_pDBEssence.id_pet, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
// ASSERT(m_pPetEssence);
//struct can't be null
//m_pEvoPetEssence = null;
m_pEvoPetEssence = new PET_ESSENCE();
if (m_pPetEssence.id >=0)
{
object pTempDBEssenceObj = pDB.get_data_ptr((uint)m_pPetEssence.id_pet_egg_evolved, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
if (pTempDBEssenceObj != null)
{
PET_EGG_ESSENCE pTempDBEssence = (PET_EGG_ESSENCE)pTempDBEssenceObj;
if (pTempDBEssence.id >=0)
{
object pEvoPetEssenceObj = pDB.get_data_ptr((uint)pTempDBEssence.id_pet, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
if (pEvoPetEssenceObj != null)
m_pEvoPetEssence = (PET_ESSENCE)pEvoPetEssenceObj;
}
}
}
m_iPileLimit = m_pDBEssence.pile_num_max;
m_iPrice = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = 0;
// m_bUseable = true;
// m_dwUseFlags = USE_PERSIST;
m_Essence = new IVTR_ESSENCE_PETEGG();
m_EvoProp = new _evo_prop{
r_attack = 0,
r_defense = 0,
r_hp = 0,
r_atk_lvl = 0,
r_def_lvl = 0,
nature = 0
};
m_pEvoNatureConfig = new PET_EVOLVED_SKILL_CONFIG();
}
public EC_IvtrPetEgg(EC_IvtrPetEgg other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
m_pPetEssence = other.m_pPetEssence;
m_Essence = other.m_Essence;
m_strName = other.m_strName;
// Copy skills
int i, iNumSkill = other.m_aSkills.Count;
m_aSkills = new List<PETSKILL>(iNumSkill);
for (i=0; i < iNumSkill; i++)
m_aSkills[i] = other.m_aSkills[i];
m_EvoProp = other.m_EvoProp;
m_pEvoNatureConfig = other.m_pEvoNatureConfig;
m_pEvoPetEssence = other.m_pEvoPetEssence;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
if (pInfoData == null || iDataLen == 0)
return true;
try {
CECDataReader dr = new CECDataReader(pInfoData, iDataLen);
m_Essence = new IVTR_ESSENCE_PETEGG(dr.ReadData(Marshal.SizeOf<IVTR_ESSENCE_PETEGG>()));
if (m_Essence.name_len != 0)
{
m_strName = ByteToStringUtils.UshortArrayToUnicodeString(m_Essence.name);
EC_Game.GetGameRun().GetUIManager().FilterBadWords(m_strName);
}
m_aSkills = new List<PETSKILL>(m_Essence.skill_count);
for (int i=0; i < m_Essence.skill_count; i++)
{
PETSKILL s = new PETSKILL();
s.idSkill = dr.ReadInt();
s.iLevel = dr.ReadInt();
m_aSkills.Add(s);
}
if (m_Essence.pet_class == (int)GP_PET_TYPE.GP_PET_CLASS_EVOLUTION)
{
m_EvoProp.r_attack = dr.ReadInt();
m_EvoProp.r_defense = dr.ReadInt();
m_EvoProp.r_hp = dr.ReadInt();
m_EvoProp.r_atk_lvl = dr.ReadInt();
m_EvoProp.r_def_lvl = dr.ReadInt();
m_EvoProp.nature = dr.ReadInt();
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
object pDBData = pDB.get_data_ptr((uint)m_EvoProp.nature, ID_SPACE.ID_SPACE_CONFIG, ref DataType);
if (pDBData != null && DataType == DATA_TYPE.DT_PET_EVOLVED_SKILL_CONFIG)
m_pEvoNatureConfig = (PET_EVOLVED_SKILL_CONFIG)pDBData;
}
}
catch (Exception e)
{
Debug.LogError("EC_IvtrPetEgg::SetItemInfo, data read error (" + e.GetType() + e.StackTrace + ")");
return false;
}
return true;
}
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
public override string GetName()
{
// Try Unicode first (for Vietnamese/wide char names), then fallback to CP936
if (m_pDBEssence.name != null && m_pDBEssence.name.Length > 0)
{
string s = ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return s;
// Fallback to legacy CP936 if Unicode was empty
s = ByteToStringUtils.UshortArrayToCP936String(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s))
return s;
}
return base.GetName(); // Fallback to base class method
}
protected override string GetNormalDesc(bool bRepair)
{
string szDesc = "";
switch (m_Essence.pet_class)
{
case (int)GP_PET_TYPE.GP_PET_CLASS_MOUNT: szDesc = GetRidingPetDesc(bRepair); break;
case (int)GP_PET_TYPE.GP_PET_CLASS_COMBAT: szDesc = GetCombatPetDesc(bRepair); break;
case (int)GP_PET_TYPE.GP_PET_CLASS_FOLLOW: szDesc = GetFollowPetDesc(bRepair); break;
case (int)GP_PET_TYPE.GP_PET_CLASS_EVOLUTION:szDesc = GetEvolutionPetDesc(bRepair); break;
}
return szDesc;
}
private string GetRidingPetDesc(bool bRepair)
{
Debug.Log("GetRidingPetDesc. This is not implemented yet.");
return "";
}
private string GetCombatPetDesc(bool bRepair)
{
if (m_bNeedUpdate)
return "";
m_strDesc = "";
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int red = (int)DescriptipionMsg.ITEMDESC_COL_RED;
int namecol = DecideNameCol();
// Item name: always use the name in template
if (m_iCount > 1)
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddBindDescText();
AddExpireTimeDesc();
// Food type requirement
AddFoodTypeDesc();
if (m_pPetEssence.id != 0)
{
// Pet level
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PETLEVEL), m_Essence.level);
// Physical damage
int iVal = (int)(((PET_ESSENCE)m_pPetEssence).damage_a * (((PET_ESSENCE)m_pPetEssence).damage_b * m_Essence.level * m_Essence.level + ((PET_ESSENCE)m_pPetEssence).damage_c * m_Essence.level + ((PET_ESSENCE)m_pPetEssence).damage_d));
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_DAMAGE), iVal);
// Attack speed
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ATKSPEED));
AddDescText(-1, true, " %.2f", 1.0f / ((PET_ESSENCE)m_pPetEssence).attack_speed);
//Attack rating
iVal = (int)(((PET_ESSENCE)m_pPetEssence).attack_a * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).attack_b * ((PET_ESSENCE)m_pPetEssence).level_require + ((PET_ESSENCE)m_pPetEssence).attack_c));
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ATTACKRATE), iVal);
// Physical defence
iVal = (int)(((PET_ESSENCE)m_pPetEssence).physic_defence_a * (((PET_ESSENCE)m_pPetEssence).physic_defence_b * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).physic_defence_c * ((PET_ESSENCE)m_pPetEssence).level_require) + ((PET_ESSENCE)m_pPetEssence).physic_defence_d));
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PHYDEFENCE));
AddDescText(-1, true, " %d", iVal);
// Magic defence
iVal = (int)(((PET_ESSENCE)m_pPetEssence).magic_defence_a * (((PET_ESSENCE)m_pPetEssence).magic_defence_b * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).magic_defence_c * ((PET_ESSENCE)m_pPetEssence).level_require) + ((PET_ESSENCE)m_pPetEssence).magic_defence_d));
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ALLMAGICDEF));
AddDescText(-1, true, " %d", iVal);
// Dodge
iVal = (int)(((PET_ESSENCE)m_pPetEssence).armor_a * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).armor_b * ((PET_ESSENCE)m_pPetEssence).level_require + ((PET_ESSENCE)m_pPetEssence).armor_c));
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_DODGE));
AddDescText(-1, true, " %d", iVal);
// hp
iVal = (int)(((PET_ESSENCE)m_pPetEssence).hp_a * (m_Essence.level - ((PET_ESSENCE)m_pPetEssence).hp_b * ((PET_ESSENCE)m_pPetEssence).level_require + ((PET_ESSENCE)m_pPetEssence).hp_c));
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_ADDHP));
AddDescText(-1, true, " %d", iVal);
// Profession requirement
AddProfReqDesc(((PET_ESSENCE)m_pPetEssence).character_combo_id);
}
// Level requirement
int iLevelReq = Mathf.Max((int)m_Essence.level, m_Essence.req_level);
if (iLevelReq > 0)
{
int col = pHost.GetMaxLevelSofar() >= iLevelReq ? white : red;
AddDescText(col, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_LEVELREQ), iLevelReq);
}
// Skill list
for (int i=0; i < m_aSkills.Count; i++)
{
PETSKILL skill = m_aSkills[i];
string szName = EC_Game.GetSkillDesc().GetWideString(skill.idSkill * 10);
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_YELLOW, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PETSKILL), szName != null ? szName : "", skill.iLevel);
}
// ɽ
if (m_pEvoPetEssence.id != 0)
{
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_PET_EVO_NAME), ByteToStringUtils.UshortArrayToUnicodeString(((PET_ESSENCE)m_pEvoPetEssence).name));
}
// Price
AddPriceDesc(white, bRepair);
// Extend description
AddExtDescText();
return m_strDesc;
}
private string GetFollowPetDesc(bool bRepair)
{
Debug.Log("[THN]GetFollowPetDesc. This is not implemented yet.");
return "";
}
private string GetEvolutionPetDesc(bool bRepair)
{
Debug.Log("[THN]GetEvolutionPetDesc. This is not implemented yet.");
return "";
}
private void AddFoodTypeDesc()
{
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
object pPetEssence = pDB.get_data_ptr((uint)m_Essence.pet_tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
if (pPetEssence == null)
return;
CECStringTab pDescTab = EC_Game.GetItemDesc();
AddDescText((int)DescriptipionMsg.ITEMDESC_COL_WHITE, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FOODTYPE));
for (int i=0; i < (int)PetFoodType.MAX_PET_FOOD; i++)
{
if ((((PET_ESSENCE)pPetEssence).food_mask & (1 << i)) != 0)
{
m_strDesc += " ";
AddDescText(-1, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FOOD_GRASS+i));
}
}
m_strDesc += "\\r";
}
// Get item description for booth buying
protected override string GetBoothBuyDesc()
{
m_strDesc = "";
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
// Item name
AddDescText(white, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name));
// Price
AddPriceDesc(white, false);
return m_strDesc;
}
// Get drop model for shown
public override string GetDropModel()
{
return ByteToStringUtils.ByteArrayToCP936String(m_pDBEssence.file_matter);
}
}
}
@@ -1,8 +1,23 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
{
public class EC_IvtrPetFood : EC_IvtrItem
{
protected PET_FOOD_ESSENCE m_pDBEssence;
/// <summary>
/// Not create logic yet (add summary later)
/// </summary>
@@ -10,11 +25,128 @@ namespace PerfectWorld.Scripts.Managers
/// <param name="expire_date">Expire date</param>
public EC_IvtrPetFood(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_PETFOOD;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (PET_FOOD_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
m_iPrice = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = 0;
m_bUseable = true;
m_bNeedUpdate = false;
}
public EC_IvtrPetFood(EC_IvtrPetFood other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
return true;
}
// Get item icon file name
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
// Get item name
public override string GetName()
{
// Try Unicode first (for Vietnamese/wide char names), then fallback to CP936
if (m_pDBEssence.name != null && m_pDBEssence.name.Length > 0)
{
string s = ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return s;
// Fallback to legacy CP936 if Unicode was empty
s = ByteToStringUtils.UshortArrayToCP936String(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s))
return s;
}
return base.GetName(); // Fallback to base class method
}
// Get item cool time
public int GetCoolTime(ref int piMax)
{
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
if (!pHost)
return 0;
int iTime = pHost.GetCoolTime((int)CoolTimeIndex.GP_CT_FEED_PET, ref piMax);
return iTime;
}
// Check item use condition
public override bool CheckUseCondition()
{
CECPetData pPet = EC_Game.GetGameRun().GetHostPlayer().GetPetCorral().GetActivePet();
if (pPet == null)
return false;
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
object temp = ElementDataManProvider.GetElementDataMan().get_data_ptr((uint)pPet.GetTemplateID(), ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
if (temp == null)
return false;
PET_ESSENCE pPetEssence = (PET_ESSENCE)temp;
return ((m_pDBEssence.food_type & pPetEssence.food_mask) != 0) ? true : false;
}
// Get item description text
protected override string GetNormalDesc(bool bRepair)
{
m_strDesc = "";
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int namecol = DecideNameCol();
// Item name
if (m_iCount > 1)
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddExpireTimeDesc();
// Food type
for (int i=0; i < (int)PetFoodType.MAX_PET_FOOD; i++)
{
if ((m_pDBEssence.food_type & (1 << i)) != 0)
{
AddDescText(white, false, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FOODTYPE));
m_strDesc += " ";
AddDescText(-1, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_FOOD_GRASS+i));
break;
}
}
// Price
AddPriceDesc(white, bRepair);
// Extend description
AddExtDescText();
return m_strDesc;
}
// Get drop model for shown
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
}
}
@@ -1,20 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.IO;
using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
namespace PerfectWorld.Scripts.Managers
{
/// <summary>
/// Skill tome item class(sach ky nang). This is a part of CEC_IvtrScroll(C++)
/// </summary>
public class EC_IvtrSkilltome : EC_IvtrItem
{
protected SKILLTOME_ESSENCE m_pDBEssence;
protected SKILLTOME_SUB_TYPE m_pDBSubType;
/// <summary>
/// Not create logic yet (add summary later)
/// Create skill tome item(sach ky nang)
/// </summary>
/// <param name="tid">Template id</param>
/// <param name="expire_date">Expire date</param>
public EC_IvtrSkilltome(int tid, int expire_date) : base(tid, expire_date)
{
m_iCID = (int)InventoryClassId.ICID_SKILLTOME;
// Get database data
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
m_pDBEssence = (SKILLTOME_ESSENCE)pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_pDBSubType = (SKILLTOME_SUB_TYPE)pDB.get_data_ptr(m_pDBEssence.id_sub_type, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
m_iPileLimit = m_pDBEssence.pile_num_max;
m_iPrice = m_pDBEssence.price;
m_iShopPrice = m_pDBEssence.shop_price;
m_iProcType = (int)m_pDBEssence.proc_type;
m_i64EquipMask = 0;
m_bNeedUpdate = false;
}
/// <summary>
/// Copy constructor for skill tome item(sach ky nang)
/// </summary>
/// <param name="other">Other skill tome item</param>
public EC_IvtrSkilltome(EC_IvtrSkilltome other) : base(other)
{
m_pDBEssence = other.m_pDBEssence;
m_pDBSubType = other.m_pDBSubType;
}
public override bool SetItemInfo(byte[] pInfoData, int iDataLen)
{
base.SetItemInfo(pInfoData, iDataLen);
return true;
}
public override string GetIconFile()
{
return m_pDBEssence.FileIcon;
}
// Get item name
public override string GetName()
{
// Try Unicode first (for Vietnamese/wide char names), then fallback to CP936
if (m_pDBEssence.name != null && m_pDBEssence.name.Length > 0)
{
string s = ByteToStringUtils.UshortArrayToUnicodeString(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return s;
// Fallback to legacy CP936 if Unicode was empty
s = ByteToStringUtils.UshortArrayToCP936String(m_pDBEssence.name);
if (!string.IsNullOrEmpty(s))
return s;
}
return base.GetName(); // Fallback to base class method
}
protected override string GetNormalDesc(bool bRepair)
{
m_strDesc = "";
// Try to build item description
CECStringTab pDescTab = EC_Game.GetItemDesc();
int white = (int)DescriptipionMsg.ITEMDESC_COL_WHITE;
int namecol = DecideNameCol();
if (m_iCount > 1)
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAMENUMBER), GetName(), m_iCount);
else
AddDescText(namecol, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_NAME), GetName());
AddIDDescText();
AddExpireTimeDesc();
// Price
AddPriceDesc(white, bRepair);
// Extend description
AddExtDescText();
return m_strDesc;
}
public override string GetDropModel()
{
return m_pDBEssence.FileMatter;
}
}
}
}
@@ -1,4 +1,5 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine;
using ModelRenderer.Scripts.GameData;
using BrewMonster;
@@ -190,21 +191,43 @@ namespace BrewMonster.Scripts.Managers
};
public struct IVTR_ESSENCE_PETEGG
{
// TODO : implement data later
// int req_level;
// int req_class;
// int honor_point;
// int pet_tid;
// int pet_vis_tid;
// int pet_egg_tid;
// int pet_class;
// short level;
// unsigned short color;
// int exp;
// int skill_point;
// unsigned short name_len;
// unsigned short skill_count;
// wchar_t name[8];
public int req_level;
public int req_class;
public int honor_point;
public int pet_tid;
public int pet_vis_tid;
public int pet_egg_tid;
public int pet_class;
public short level;
public ushort color;
public int exp;
public int skill_point;
public ushort name_len;
public ushort skill_count;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public ushort[] name;
public IVTR_ESSENCE_PETEGG(byte[] data)
{
CECDataReader dr = new (data, data.Length);
req_level = dr.ReadInt();
req_class = dr.ReadInt();
honor_point = dr.ReadInt();
pet_tid = dr.ReadInt();
pet_vis_tid = dr.ReadInt();
pet_egg_tid = dr.ReadInt();
pet_class = dr.ReadInt();
level = dr.ReadShort();
color = dr.ReadUShort();
exp = dr.ReadInt();
skill_point = dr.ReadInt();
name_len = dr.ReadUShort();
skill_count = dr.ReadUShort();
name = new ushort[8];
for(int i = 0; i < 8; i++)
{
name[i] = dr.ReadUShort();
}
}
};
public struct IVTR_ESSENCE_DESTROYING
{
@@ -213,22 +236,54 @@ namespace BrewMonster.Scripts.Managers
};
public struct IVTR_ESSENCE_GOBLIN
{
struct _GOBLIN_DATA
public struct _GOBLIN_DATA
{
// TODO : implement data later
// unsigned int exp;
// short level;
// short total_attribute;
// short strength;
// short agility;
// short vitality;
// short energy;
// short total_genius;
// short genius[5];
// short refine_level;
// int stamina;
// int status_value;
};
public uint exp;
public short level;
public short total_attribute;
public short strength;
public short agility;
public short vitality;
public short energy;
public short total_genius;
public short[] genius ;
public short refine_level;
public int stamina;
public int status_value;
public _GOBLIN_DATA(byte[] data)
{
CECDataReader dr = new (data, data.Length);
exp = dr.ReadUInt();
level = dr.ReadShort();
total_attribute = dr.ReadShort();
strength = dr.ReadShort();
agility = dr.ReadShort();
vitality = dr.ReadShort();
energy = dr.ReadShort();
total_genius = dr.ReadShort();
genius = new short[5];
for(int i = 0; i < 5; i++)
{
genius[i] = dr.ReadShort();
}
refine_level = dr.ReadShort();
stamina = dr.ReadInt();
status_value = dr.ReadInt();
}
}
public _GOBLIN_DATA data;
public int equip_cnt;
public int skill_cnt;
public IVTR_ESSENCE_GOBLIN(byte[] data)
{
CECDataReader dr = new (data, data.Length);
// Calculate size manually: uint(4) + 7*short(14) + short[5](10) + short(2) + 2*int(8) = 40 bytes
const int GOBLIN_DATA_SIZE = 40;
this.data = new _GOBLIN_DATA(dr.ReadData(GOBLIN_DATA_SIZE));
equip_cnt = dr.ReadInt();
skill_cnt = dr.ReadInt();
}
// TODO : implement data later
// _GOBLIN_DATA data;
@@ -385,17 +385,11 @@ namespace PerfectWorld.Scripts.Managers
AddDescText((int)DescriptipionMsg.ITEMDESC_COL2_BRIGHTBLUE, true, pDescTab.GetWideString((int)DescriptipionMsg.ITEMDESC_HASRANDOM_PROP));
// Price
AddPriceDesc(white, bRepair);
BMLogger.Log("AddPriceDesc: " + m_strDesc);
AddSharpenerDesc();
BMLogger.Log("AddSharpenerDesc: " + m_strDesc);
AddEngravedDesc();
BMLogger.Log("AddEngravedDesc: " + m_strDesc);
AddMakerDesc();
BMLogger.Log("AddMakerDesc: " + m_strDesc);
AddSuiteDesc();
BMLogger.Log("AddSuiteDesc: " + m_strDesc);
AddExtDescText();
BMLogger.Log("AddExtDescText: " + m_strDesc);
return m_strDesc;
}
// Get weapon attack speed index
@@ -0,0 +1,121 @@
using CSNetwork.GPDataType;
using PerfectWorld.Scripts;
using BrewMonster;
using BrewMonster.Scripts;
public struct PETSKILL
{
public int idSkill;
public int iLevel;
public int iCoolCnt;
public int iCoolMax;
};
public enum SkillType
{
EM_SKILL_DEFAULT = 0, // Ը
EM_SKILL_NORMAL, // ͨ
EM_SKILL_NATURE, // Ը
EM_SKILL_SPECIAL, // ר
}
public class EC_PetCorral
{
public enum MaxSlotNum
{
MAX_SLOTNUM = 20, // ͨ
MAX_SLOTNUM2 = 21, // г
};
// Moving mode
public enum MoveMode
{
MOVE_FOLLOW = 0,
MOVE_STAND,
};
// Attacking mode
public enum AttackMode
{
ATK_DEFENSE = 0,
ATK_POSITIVE,
ATK_PASSIVE,
};
protected int m_iIntimacy; // øж
protected int m_iHunger; //
protected int m_tid; // ģID
protected int m_tidVis; // ģIDΪ0ʾɼID
protected int m_idEgg; // ID
protected int m_iClass; // սͳ
protected float m_fHPFactor; // Ѫջʱʹã 0Ϊ
protected float m_fMPFactor; // MPջʱʹã 0Ϊ
protected int m_iLevel; //
protected bool m_isBind; // Ƿ˺һ
protected bool m_canWebTrade; // ǷѰɽ
protected ushort m_color; // ȾɫɫλΪ1ʱЧ
protected int m_iExp; // ﵱǰ
protected int m_iSkillPt; // ʣܵ
protected string m_strName;
protected int m_iHP; // Only fight pets have this
protected int m_iMP;
protected PETSKILL[] m_aSkills = new PETSKILL[(int)GP_PET_SKILL_NUM.GP_PET_SKILL_NUM];
protected int[] m_vecNorSkillIndex; // ֹԸܺͨ˳ҵ m_aSkills
protected int[] m_vecDynSkillIndex;
protected int m_iSpecialSkillIndex; // רm_aSkillsţֻнһ˼
protected CECCounter m_cntAutoSkill;
protected int[] m_aAutoSkills;
protected ROLEEXTPROP m_ExtProps;
protected PET_ESSENCE m_pDBEssence = new PET_ESSENCE();
protected int m_iAtkRation;
protected int m_iDefRation;
protected int m_iHpRation;
protected int m_iAtkLvlRation;
protected int m_iDefLvlRation;
protected int m_iNature;
public CECPetData GetActivePet()
{
//Place holder for ivtrPetFood
return null;
}
}
public class CECPetData
{
#region enum
public enum HungerLevel
{
HUNGER_LEVEL_0, // ʳ
HUNGER_LEVEL_1, //
HUNGER_LEVEL_2, // ̶һ
HUNGER_LEVEL_3,
HUNGER_LEVEL_4, // ̶ȶ
HUNGER_LEVEL_5,
HUNGER_LEVEL_6,
HUNGER_LEVEL_7, // ̶
HUNGER_LEVEL_8,
HUNGER_LEVEL_9,
HUNGER_LEVEL_10,
HUNGER_LEVEL_11, // ̶ļ
HUNGER_LEVEL_COUNT,
};
// Intimacy level
public enum IntimacyLevel
{
INTIMACY_LEVEL_0, // Ұѱ, 0-50
INTIMACY_LEVEL_1, // ޳, 51-150
INTIMACY_LEVEL_2, // , 151-500
INTIMACY_LEVEL_3, // Ĺ, 501-999
INTIMACY_LEVEL_COUNT,
INTIMACY_POINT_MAX = 999,
};
#endregion
public int GetTemplateID()
{
//Place holder for ivtrPetFood
return -1;
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c41c880dbc2344f819944899348d5124
@@ -2195,5 +2195,89 @@ namespace CSNetwork.GPDataType
return buf_size >= sz;
}
};
// Pet type
public enum GP_PET_TYPE
{
GP_PET_CLASS_INVALID = -1,
GP_PET_CLASS_MOUNT = 0, //
GP_PET_CLASS_COMBAT, // ս
GP_PET_CLASS_FOLLOW, //
GP_PET_CLASS_SUMMON, // ٻ
GP_PET_CLASS_PLANT, // ֲֻΪ˺ͷֵһ£ͻûõ
GP_PET_CLASS_EVOLUTION, //
GP_PET_CLASS_MAX,
};
public struct PetSkill
{
public int skill;
public int level;
}
public struct _evo_prop
{
public int r_attack;
public int r_defense;
public int r_hp;
public int r_atk_lvl;
public int r_def_lvl;
public int nature;
}
public enum GP_PET_SKILL_NUM
{
GP_PET_SKILL_NUM = 8
};
public struct info_pet
{
public int honor_point; // øж
public int hunger; //
public int feed_time; // ϴιڵʱ
public int pet_tid; // ģID
public int pet_vis_tid; // ĿɼIDΪ0ʾɼID
public int pet_egg_tid; // ID
public int pet_class; // սͳ
public float hp_factor; // Ѫջʱʹã 0Ϊ
public short level; //
public ushort color; // ɫλΪ1ʾЧĿǰЧ
public int exp; // ﵱǰ
public int skill_point; // ʣܵ
public char is_bind; // Ƿ˺һһMask0x01 ˺һ0x02 Ѱɽ
public char unused; // ĿǰЧ
public ushort name_len; // ֳ ĿǰЧΪ߻
public char[] name; //
public PetSkill[] skills;
public _evo_prop evo_prop;
public int[] reserved; // δ
public info_pet(bool isDefault = true)
{
honor_point = 0;
hunger = 0;
feed_time = 0;
pet_tid = 0;
pet_vis_tid = 0;
pet_egg_tid = 0;
pet_class = 0;
hp_factor = 0;
level = 0;
color = 0;
exp = 0;
skill_point = 0;
is_bind = (char)0x00;
unused = (char)0x00;
name_len = 0;
name = new char[16];
skills = new PetSkill[(int)GP_PET_SKILL_NUM.GP_PET_SKILL_NUM];
evo_prop = new _evo_prop{
r_attack = 0,
r_defense = 0,
r_hp = 0,
r_atk_lvl = 0,
r_def_lvl = 0,
nature = 0
};
reserved = new int[10];
}
};
}
@@ -425,5 +425,59 @@ namespace BrewMonster.Scripts.Skills
return ret;
}
// 0:ɹ 1:SP 2:
// 3: 4:ܸ 5:ID
// 6:Ǯ 7:С 8:ûм
// 9:ȼ 10:޲ 11:ְҵƥ
// 12:޲ְҵƥ
public static int GoblinLearn(uint id, GoblinRequirement info, int level)
{
Skill s = Skill.Create(id, level);
if(s == null)
return 5;
if(level<1 || level> s.GetMaxLevel())
return 3;
if(s.GetCls() != 258)
return 7;
int ret = 0;
int[] iReqGen = new int[5] {0, 0, 0, 0, 0};
int iReqLevel = s.GetRequiredLevel();
// iReqLevelΪ7λλΪȼǰ5λΪλΪ
int iLevelRequirement = iReqLevel%100;
if(info.level < iLevelRequirement)
return 9;
iReqLevel /= 100;
int i;
for(i=0;i<5;i++)
{
iReqGen[4-i] = iReqLevel%10;
iReqLevel /= 10;
}
for(i=0;i<5;i++)
{
if(info.genius[i] < iReqGen[4-i])
return 2;
}
if(info.sp < s.GetRequiredSp())
ret = 1;
//else if(info.money<s->GetRequiredMoney(id, level))
// ret = 6;
if(info.mp < s.GetMpCost() &&
((s.GetCls() != 0) && (((1 << info.profession) & s.GetCls()) == 0)))
ret = 12;
else if(info.mp < s.GetMpCost())
ret = 10;
else if((s.GetCls() != 0) && (((1 << info.profession) & s.GetCls()) == 0))
ret = 11;
return ret;
}
}
}
@@ -64,6 +64,23 @@ namespace BrewMonster
m_pCur += sizeof(short);
return value;
}
public ushort ReadUShort()
{
BoundCheck(sizeof(ushort));
ushort value = System.BitConverter.ToUInt16(data, m_pCur);
m_pCur += sizeof(ushort);
return value;
}
public ushort[] ReadUShortArray(int size)
{
BoundCheck(size * sizeof(ushort));
ushort[] result = new ushort[size];
System.Array.Copy(data, m_pCur, result, 0, size * sizeof(ushort));
m_pCur += size * sizeof(ushort);
return result;
}
public uint ReadUInt()
{
BoundCheck(sizeof(uint));
+5
View File
@@ -59,6 +59,7 @@ namespace BrewMonster
private int m_iRoleLastLoginTime; // Role last login time
private int m_iAccountTotalCash;
private EC_PetCorral m_pPetCorral;
private List<CECObject> m_aTabSels = new List<CECObject>();
private List<CECSkill> m_aPtSkills = new List<CECSkill>();
private List<CECSkill> m_aPsSkills = new List<CECSkill>();
@@ -6879,5 +6880,9 @@ namespace BrewMonster
}
return iReason == 0? true : false;
}
public EC_PetCorral GetPetCorral()
{
return m_pPetCorral;
}
}
}
+4
View File
@@ -359,4 +359,8 @@ public class CECUIManager : MonoSingleton<CECUIManager>
pDlg = dlg;
}
}
public void FilterBadWords(string str)
{
// TODO: Implement bad word filtering
}
}