mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-02 19:42:05 -04:00
EXP and levels now get saved and loaded from database, changed battlecommand id dictionary to hold lists to account for archer and DoH/DoLs getting multiple abilities at certain levels. Level 1 abilities are now added to the hotbar on character creation.
This commit is contained in:
parent
ab98f3662f
commit
5dfbc0f249
@ -231,15 +231,51 @@ namespace FFXIVClassic_Lobby_Server
|
||||
catch (MySqlException e)
|
||||
{
|
||||
Program.Log.Error(e.ToString());
|
||||
conn.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
//Create Hotbar
|
||||
try
|
||||
{
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = "SELECT id FROM server_battle_commands WHERE classJob = @classjob AND lvl = 1 ORDER BY id DESC";
|
||||
cmd.Prepare();
|
||||
|
||||
cmd.Parameters.AddWithValue("@classJob", charaInfo.currentClass);
|
||||
List<uint> defaultActions = new List<uint>();
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while(reader.Read())
|
||||
{
|
||||
defaultActions.Add(reader.GetUInt32("id"));
|
||||
}
|
||||
}
|
||||
MySqlCommand cmd2 = new MySqlCommand();
|
||||
cmd2.Connection = conn;
|
||||
cmd2.CommandText = "INSERT INTO characters_hotbar (characterId, classId, hotbarSlot, commandId, recastTime) VALUES (@characterId, @classId, @hotbarSlot, @commandId, 0)";
|
||||
cmd2.Prepare();
|
||||
cmd2.Parameters.AddWithValue("@characterId", cid);
|
||||
cmd2.Parameters.AddWithValue("@classId", charaInfo.currentClass);
|
||||
cmd2.Parameters.Add("@hotbarSlot", MySqlDbType.Int16);
|
||||
cmd2.Parameters.Add("@commandId", MySqlDbType.Int16);
|
||||
|
||||
for(int i = 0; i < defaultActions.Count; i++)
|
||||
{
|
||||
cmd2.Parameters["@hotbarSlot"].Value = i;
|
||||
cmd2.Parameters["@commandId"].Value = defaultActions[i];
|
||||
cmd2.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch(MySqlException e)
|
||||
{
|
||||
Program.Log.Error(e.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.Dispose();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Program.Log.Debug("[SQL] CID={0} state updated to active(2).", cid);
|
||||
|
@ -785,6 +785,62 @@ namespace FFXIVClassic_Map_Server
|
||||
}
|
||||
}
|
||||
|
||||
//Get class experience
|
||||
query = @"
|
||||
SELECT
|
||||
pug,
|
||||
gla,
|
||||
mrd,
|
||||
arc,
|
||||
lnc,
|
||||
|
||||
thm,
|
||||
cnj,
|
||||
|
||||
crp,
|
||||
bsm,
|
||||
arm,
|
||||
gsm,
|
||||
ltw,
|
||||
wvr,
|
||||
alc,
|
||||
cul,
|
||||
|
||||
min,
|
||||
btn,
|
||||
fsh
|
||||
FROM characters_class_exp WHERE characterId = @charId";
|
||||
|
||||
cmd = new MySqlCommand(query, conn);
|
||||
cmd.Parameters.AddWithValue("@charId", player.actorId);
|
||||
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_PUG - 1] = reader.GetInt16("pug");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_GLA - 1] = reader.GetInt16("gla");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_MRD - 1] = reader.GetInt16("mrd");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_ARC - 1] = reader.GetInt16("arc");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_LNC - 1] = reader.GetInt16("lnc");
|
||||
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_THM - 1] = reader.GetInt16("thm");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_CNJ - 1] = reader.GetInt16("cnj");
|
||||
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_CRP - 1] = reader.GetInt16("crp");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_BSM - 1] = reader.GetInt16("bsm");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_ARM - 1] = reader.GetInt16("arm");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_GSM - 1] = reader.GetInt16("gsm");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_LTW - 1] = reader.GetInt16("ltw");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_WVR - 1] = reader.GetInt16("wvr");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_ALC - 1] = reader.GetInt16("alc");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_CUL - 1] = reader.GetInt16("cul");
|
||||
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_MIN - 1] = reader.GetInt16("min");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_BTN - 1] = reader.GetInt16("btn");
|
||||
player.charaWork.battleSave.skillPoint[Player.CLASSID_FSH - 1] = reader.GetInt16("fsh");
|
||||
}
|
||||
}
|
||||
|
||||
//Load Saved Parameters
|
||||
query = @"
|
||||
SELECT
|
||||
@ -1327,7 +1383,7 @@ namespace FFXIVClassic_Map_Server
|
||||
|
||||
cmd = new MySqlCommand(query, conn);
|
||||
cmd.Parameters.AddWithValue("@charId", player.actorId);
|
||||
cmd.Parameters.AddWithValue("@classId", player.charaWork.parameterSave.state_mainSkill[0]);
|
||||
cmd.Parameters.AddWithValue("@classId", player.GetCurrentClassOrJob());
|
||||
|
||||
player.charaWork.commandBorder = 32;
|
||||
|
||||
@ -2197,10 +2253,8 @@ namespace FFXIVClassic_Map_Server
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadGlobalBattleCommandList(Dictionary<ushort, BattleCommand> battleCommandDict, Dictionary<Tuple<byte, short>, uint> battleCommandIdByLevel)
|
||||
public static void LoadGlobalBattleCommandList(Dictionary<ushort, BattleCommand> battleCommandDict, Dictionary<Tuple<byte, short>, List<uint>> battleCommandIdByLevel)
|
||||
{
|
||||
//var battleCommands = new Dictionary<ushort, BattleCommand>();
|
||||
|
||||
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
||||
{
|
||||
try
|
||||
@ -2248,9 +2302,16 @@ namespace FFXIVClassic_Map_Server
|
||||
|
||||
battleCommandDict.Add(id, battleCommand);
|
||||
|
||||
//Handle level 1 abilities separately because of FUCKING ARCHER REEE, just add those to the hotbar when the job is unlocked or on char creation, ez
|
||||
if(battleCommand.level > 1)
|
||||
battleCommandIdByLevel.Add(Tuple.Create<byte, short>(battleCommand.job, battleCommand.level), id | 0xA0F00000);
|
||||
Tuple<byte, short> tuple = Tuple.Create<byte, short>(battleCommand.job, battleCommand.level);
|
||||
if (battleCommandIdByLevel.ContainsKey(tuple))
|
||||
{
|
||||
battleCommandIdByLevel[tuple].Add(id | 0xA0F00000);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<uint> list = new List<uint>() { id | 0xA0F00000 };
|
||||
battleCommandIdByLevel.Add(tuple, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2264,6 +2325,72 @@ namespace FFXIVClassic_Map_Server
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetExp(Player player, byte classId, int exp)
|
||||
{
|
||||
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
||||
{
|
||||
try
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
var query = String.Format(@"
|
||||
UPDATE characters_class_exp
|
||||
SET
|
||||
{0} = @exp
|
||||
WHERE
|
||||
characterId = @characterId", CharacterUtils.GetClassNameForId(classId));
|
||||
MySqlCommand cmd = new MySqlCommand(query, conn);
|
||||
|
||||
cmd.Prepare();
|
||||
cmd = new MySqlCommand(query, conn);
|
||||
cmd.Parameters.AddWithValue("@characterId", player.actorId);
|
||||
cmd.Parameters.AddWithValue("@exp", exp);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
catch (MySqlException e)
|
||||
{
|
||||
Program.Log.Error(e.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetLevel(Player player, byte classId, short level)
|
||||
{
|
||||
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
||||
{
|
||||
try
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
var query = String.Format(@"
|
||||
UPDATE characters_class_levels
|
||||
SET
|
||||
{0} = @lvl
|
||||
WHERE
|
||||
characterId = @characterId", CharacterUtils.GetClassNameForId(classId));
|
||||
MySqlCommand cmd = new MySqlCommand(query, conn);
|
||||
|
||||
cmd.Prepare();
|
||||
cmd = new MySqlCommand(query, conn);
|
||||
cmd.Parameters.AddWithValue("@characterId", player.actorId);
|
||||
cmd.Parameters.AddWithValue("@lvl", level);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
catch (MySqlException e)
|
||||
{
|
||||
Program.Log.Error(e.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ namespace FFXIVClassic_Map_Server
|
||||
private Dictionary<ulong, Party> currentPlayerParties = new Dictionary<ulong, Party>(); //GroupId, Party object
|
||||
private Dictionary<uint, StatusEffect> statusEffectList = new Dictionary<uint, StatusEffect>();
|
||||
private Dictionary<ushort, BattleCommand> battleCommandList = new Dictionary<ushort, BattleCommand>();
|
||||
private Dictionary<Tuple<byte, short>, uint> battleCommandIdByLevel = new Dictionary<Tuple<byte, short>, uint>();//Holds battle command ids keyed by class id and level (in that order)
|
||||
private Dictionary<Tuple<byte, short>, List<uint>> battleCommandIdByLevel = new Dictionary<Tuple<byte, short>, List<uint>>();//Holds battle command ids keyed by class id and level (in that order)
|
||||
private Dictionary<uint, ModifierList> battleNpcGenusMods = new Dictionary<uint, ModifierList>();
|
||||
private Dictionary<uint, ModifierList> battleNpcPoolMods = new Dictionary<uint, ModifierList>();
|
||||
private Dictionary<uint, ModifierList> battleNpcSpawnMods = new Dictionary<uint, ModifierList>();
|
||||
@ -1432,10 +1432,10 @@ namespace FFXIVClassic_Map_Server
|
||||
return battleCommandList.TryGetValue((ushort)id, out battleCommand) ? battleCommand.Clone() : null;
|
||||
}
|
||||
|
||||
public uint GetBattleCommandIdByLevel(byte classId, short level)
|
||||
public List<uint> GetBattleCommandIdByLevel(byte classId, short level)
|
||||
{
|
||||
uint id = 0;
|
||||
return battleCommandIdByLevel.TryGetValue(Tuple.Create(classId, level), out id) ? id : 0;
|
||||
List<uint> ids;
|
||||
return battleCommandIdByLevel.TryGetValue(Tuple.Create(classId, level), out ids) ? ids : new List<uint>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -389,11 +389,28 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
propPacketUtil.AddProperty("charaWork.battleTemp.castGauge_speed[1]");
|
||||
|
||||
//Battle Save Skillpoint
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_ALC - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_ARC - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_ARM - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_BSM - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_BTN - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_CNJ - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_CRP - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_CUL - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_FSH - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_GLA - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_GSM - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_LNC - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_LTW - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_MIN - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_MRD - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_PUG - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_THM - 1}]");
|
||||
propPacketUtil.AddProperty($"charaWork.battleSave.skillPoint[{CLASSID_WVR - 1}]");
|
||||
|
||||
//Commands
|
||||
propPacketUtil.AddProperty("charaWork.commandBorder");
|
||||
|
||||
|
||||
for (int i = 0; i < charaWork.command.Length; i++)
|
||||
{
|
||||
if (charaWork.command[i] != 0)
|
||||
@ -408,7 +425,6 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < charaWork.commandCategory.Length; i++)
|
||||
{
|
||||
charaWork.commandCategory[i] = 1;
|
||||
@ -422,7 +438,6 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
propPacketUtil.AddProperty(String.Format("charaWork.commandAcquired[{0}]", i));
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < charaWork.additionalCommandAcquired.Length; i++)
|
||||
{
|
||||
if (charaWork.additionalCommandAcquired[i] != false)
|
||||
@ -436,13 +451,11 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
propPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_compatibility[{0}]", i));
|
||||
}
|
||||
|
||||
/*
|
||||
for (int i = 0; i < charaWork.parameterSave.commandSlot_recastTime.Length; i++)
|
||||
{
|
||||
if (charaWork.parameterSave.commandSlot_recastTime[i] != 0)
|
||||
propPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_recastTime[{0}]", i));
|
||||
}
|
||||
*/
|
||||
for (int i = 0; i < charaWork.parameterSave.commandSlot_recastTime.Length; i++)
|
||||
{
|
||||
if (charaWork.parameterSave.commandSlot_recastTime[i] != 0)
|
||||
propPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_recastTime[{0}]", i));
|
||||
}
|
||||
|
||||
//System
|
||||
propPacketUtil.AddProperty("charaWork.parameterTemp.forceControl_float_forClientSelf[0]");
|
||||
@ -2219,7 +2232,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
|
||||
bool leveled = false;
|
||||
int diff = MAXEXP[GetLevel() - 1] - charaWork.battleSave.skillPoint[classId - 1];
|
||||
//While there is enough experience to level up, keep leveling up and unlocking skills and removing experience
|
||||
//While there is enough experience to level up, keep leveling up, unlocking skills and removing experience from exp until we don't have enough to level up
|
||||
while (exp >= diff && GetLevel() < charaWork.battleSave.skillLevelCap[classId])
|
||||
{
|
||||
//Level up
|
||||
@ -2243,14 +2256,17 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
QueuePackets(expPropertyPacket3.Done());
|
||||
//play levelup animation (do this outside LevelUp so that it only plays once if multiple levels are earned
|
||||
//also i dunno how to do this
|
||||
|
||||
Database.SetLevel(this, classId, GetLevel());
|
||||
}
|
||||
//Cap experience for level 50
|
||||
charaWork.battleSave.skillPoint[classId - 1] = Math.Min(charaWork.battleSave.skillPoint[classId - 1] + exp, MAXEXP[GetLevel() - 1]);
|
||||
|
||||
ActorPropertyPacketUtil expPropertyPacket = new ActorPropertyPacketUtil("charaWork/battleStateForSelf", this);
|
||||
expPropertyPacket.AddProperty($"charaWork.battleSave.skillPoint[{classId - 1}]");
|
||||
|
||||
//Cap experience for level 50
|
||||
QueuePackets(expPropertyPacket.Done());
|
||||
Database.SetExp(this, classId, charaWork.battleSave.skillPoint[classId - 1]);
|
||||
}
|
||||
|
||||
public void LevelUp(byte classId)
|
||||
@ -2263,12 +2279,12 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
|
||||
SendGameMessage(this, Server.GetWorldManager().GetActor(), 33909, 0x44, this, 0, 0, 0, 0, 0, 0, 0, 0, 0, (int) GetLevel());
|
||||
//If there's an ability that unlocks at this level, equip it.
|
||||
uint commandId = Server.GetWorldManager().GetBattleCommandIdByLevel(classId, GetLevel());
|
||||
if (commandId > 0)
|
||||
List<uint> commandIds = Server.GetWorldManager().GetBattleCommandIdByLevel(classId, GetLevel());
|
||||
foreach(uint commandId in commandIds)
|
||||
{
|
||||
EquipAbilityInFirstOpenSlot(classId, commandId, false);
|
||||
byte jobId = ConvertClassIdToJobId(classId);
|
||||
if (jobId != classId)
|
||||
if (jobId != classId)
|
||||
EquipAbilityInFirstOpenSlot(jobId, commandId, false);
|
||||
}
|
||||
}
|
||||
@ -2287,7 +2303,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
break;
|
||||
case CLASSID_ARC:
|
||||
case CLASSID_LNC:
|
||||
jobId += 10;
|
||||
jobId += 11;
|
||||
break;
|
||||
case CLASSID_THM:
|
||||
case CLASSID_CNJ:
|
||||
@ -2297,5 +2313,20 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
|
||||
return jobId;
|
||||
}
|
||||
|
||||
public void SetCurrentJob(byte jobId)
|
||||
{
|
||||
currentJob = jobId;
|
||||
BroadcastPacket(SetCurrentJobPacket.BuildPacket(actorId, jobId), true);
|
||||
Database.LoadHotbar(this);
|
||||
}
|
||||
|
||||
public byte GetCurrentClassOrJob()
|
||||
{
|
||||
if (currentJob != 0)
|
||||
return (byte) currentJob;
|
||||
|
||||
return charaWork.parameterSave.state_mainSkill[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,5 +96,31 @@ namespace FFXIVClassic_Map_Server.utils
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetClassNameForId(short id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 2: return "pug";
|
||||
case 3: return "gla";
|
||||
case 4: return "mrd";
|
||||
case 7: return "arc";
|
||||
case 8: return "lnc";
|
||||
case 22: return "thm";
|
||||
case 23: return "cnj";
|
||||
case 29: return "crp";
|
||||
case 30: return "bsm";
|
||||
case 31: return "arm";
|
||||
case 32: return "gsm";
|
||||
case 33: return "ltw";
|
||||
case 34: return "wvr";
|
||||
case 35: return "alc";
|
||||
case 36: return "cul";
|
||||
case 39: return "min";
|
||||
case 40: return "btn";
|
||||
case 41: return "fsh";
|
||||
default: return "undefined";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user