Files
2026-04-18 17:40:33 +07:00

766 lines
30 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 BrewMonster.Scripts
{
/// <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;
uint[] m_aEquipID;
IVTR_ESSENCE_GOBLIN m_Essence; // Goblin essence data
// Data in database
GOBLIN_ESSENCE m_pDBEssence;
/// <summary>
/// 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;
m_iPrice = 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.Length;
m_aEquipID = new 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;
// TODO: need optimize m_aEquipID, becasue iEquipCnt is big
m_aEquipID = new 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() + ")" + e.StackTrace);
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.Length; 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.Length != 0)
m_strDesc += "\\r";
for(i=0; i< m_aEquipID.Length; 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.Length == 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.Length; 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.Length; 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