Skip to content

Commit

Permalink
feat: Equipment Presets
Browse files Browse the repository at this point in the history
Added the ability to save equipment presets.
  • Loading branch information
pacampbell committed Oct 9, 2024
1 parent 3696012 commit 8ed1473
Show file tree
Hide file tree
Showing 26 changed files with 802 additions and 8 deletions.
4 changes: 0 additions & 4 deletions Arrowgene.Ddon.Database/Arrowgene.Ddon.Database.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@
</ContentWithTargetPath>
</ItemGroup>

<ItemGroup>
<ContentWithTargetPath Remove="files\database\script\migration_quest_variant_refactor.sql" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Arrowgene.Ddon.Shared\Arrowgene.Ddon.Shared.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
CREATE TABLE "ddon_equip_preset"
(
"character_common_id" INTEGER NOT NULL,
"preset_no" INTEGER NOT NULL,
"job_id" INTEGER NOT NULL,
"preset_name" TEXT NOT NULL,
CONSTRAINT "pk_ddon_equip_preset" PRIMARY KEY ("character_common_id", "job_id", "preset_no"),
CONSTRAINT "fk_ddon_equip_preset_character_common_id" FOREIGN KEY ("character_common_id") REFERENCES "ddon_character_common" ("character_common_id") ON DELETE CASCADE
);

CREATE TABLE "ddon_equip_preset_template"
(
"character_common_id" INTEGER NOT NULL,
"preset_no" INTEGER NOT NULL,
"job_id" INTEGER NOT NULL,
"slot_no" INTEGER NOT NULL,
"item_uid" VARCHAR(8) NOT NULL,
CONSTRAINT "pk_ddon_equip_preset_template" PRIMARY KEY ("character_common_id", "job_id", "preset_no", "slot_no"),
CONSTRAINT "fk_ddon_equip_preset_template_character_common_id" FOREIGN KEY ("character_common_id", "job_id", "preset_no") REFERENCES "ddon_equip_preset" ("character_common_id", "job_id", "preset_no") ON DELETE CASCADE
);
22 changes: 21 additions & 1 deletion Arrowgene.Ddon.Database/Files/Database/Script/schema_sqlite.sql
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,6 @@ CREATE TABLE IF NOT EXISTS "ddon_contact_list"
"requester_favorite" BOOLEAN NOT NULL,
"requested_favorite" BOOLEAN NOT NULL,
CONSTRAINT "fk_ddon_contact_list_requester_character_id" FOREIGN KEY ("requester_character_id") REFERENCES "ddon_character" ("character_id") ON DELETE CASCADE,
CONSTRAINT "fk_ddon_contact_list_requested_character_id" FOREIGN KEY ("requested_character_id") REFERENCES "ddon_character" ("character_id") ON DELETE CASCADE,
CONSTRAINT "uq_ddon_contact_list_requester_character_id_requested_character_id" UNIQUE ("requester_character_id", "requested_character_id")
);

Expand Down Expand Up @@ -750,3 +749,24 @@ CREATE TABLE IF NOT EXISTS "ddon_clan_membership"
CONSTRAINT "fk_ddon_clan_membership_character_id" FOREIGN KEY ("character_id") REFERENCES "ddon_character" ("character_id") ON DELETE CASCADE,
CONSTRAINT "fk_ddon_clan_membership_clan_id" FOREIGN KEY ("clan_id") REFERENCES "ddon_clan_param" ("clan_id") ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS "ddon_equip_preset"
(
"character_common_id" INTEGER NOT NULL,
"job_id" INTEGER NOT NULL,
"preset_no" INTEGER NOT NULL,
"preset_name" TEXT NOT NULL,
CONSTRAINT "pk_ddon_equip_preset" PRIMARY KEY ("character_common_id", "job_id", "preset_no"),
CONSTRAINT "fk_ddon_equip_preset_character_common_id" FOREIGN KEY ("character_common_id") REFERENCES "ddon_character_common" ("character_common_id") ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS "ddon_equip_preset_template"
(
"character_common_id" INTEGER NOT NULL,
"job_id" INTEGER NOT NULL,
"preset_no" INTEGER NOT NULL,
"slot_no" INTEGER NOT NULL,
"item_uid" VARCHAR(8) NOT NULL,
CONSTRAINT "pk_ddon_equip_preset_template" PRIMARY KEY ("character_common_id", "job_id", "preset_no", "slot_no"),
CONSTRAINT "fk_ddon_equip_preset_template_character_common_id" FOREIGN KEY ("character_common_id", "job_id", "preset_no") REFERENCES "ddon_equip_preset" ("character_common_id", "job_id", "preset_no") ON DELETE CASCADE
);
10 changes: 10 additions & 0 deletions Arrowgene.Ddon.Database/IDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -582,5 +582,15 @@ bool InsertBBMContentTreasure(
List<CDataClanMemberInfo> GetClanMemberList(uint clanId, DbConnection? connectionIn = null);
CDataClanMemberInfo GetClanMember(uint characterId, DbConnection? connectionIn = null);
bool UpdateClanMember(CDataClanMemberInfo memberInfo, uint clanId, DbConnection? connectionIn = null);

// Equipment Preset
bool InsertEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo, string presetName);
bool UpdateEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo, string presetName);
List<CDataEquipPreset> SelectEquipmentPresets(uint characterCommonId, JobId jobId);
bool DeleteEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo);

bool InsertEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo, uint slotNo, string itemUId);
List<CDataPresetEquipInfo> SelectEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo);
bool DeleteEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo);
}
}
89 changes: 89 additions & 0 deletions Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbEquipPresetTemplate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Data.Common;
using System.Reflection.Metadata.Ecma335;
using System.Xml;
using Arrowgene.Ddon.Shared.Entity.Structure;
using Arrowgene.Ddon.Shared.Model;

namespace Arrowgene.Ddon.Database.Sql.Core
{
public abstract partial class DdonSqlDb<TCon, TCom, TReader> : SqlDb<TCon, TCom, TReader>
where TCon : DbConnection
where TCom : DbCommand
where TReader : DbDataReader
{
protected static readonly string[] EquipmentTmeplateFields = new string[]
{
"character_common_id", "job_id", "preset_no", "slot_no", "item_uid"
};

private readonly string SqlInsertEquipmentPresetTemplate = $"INSERT INTO \"ddon_equip_preset_template\" ({BuildQueryField(EquipmentTmeplateFields)}) VALUES ({BuildQueryInsert(EquipmentTmeplateFields)});";
private static readonly string SqlSelectEquipmentPresetTemplate = $"SELECT {BuildQueryField(EquipmentTmeplateFields)} FROM \"ddon_equip_preset_template\" WHERE \"character_common_id\" = @character_common_id AND \"job_id\" = @job_id AND \"preset_no\" = @preset_no;";
private static readonly string SqlDeleteEquipmentPresetTemplate = $"DELETE FROM \"ddon_equip_preset_template\" WHERE \"character_common_id\"=@character_common_id AND \"job_id\"=@job_id AND \"preset_no\"=@preset_no;";

public bool InsertEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo, uint slotNo, string itemUId)
{
using TCon connection = OpenNewConnection();
return InsertEquipmentPresetTemplate(connection, characterCommonId, jobId, presetNo, slotNo, itemUId);
}

public bool InsertEquipmentPresetTemplate(TCon conn, uint characterCommonId, JobId jobId, uint presetNo, uint slotNo, string itemUId)
{
return ExecuteNonQuery(conn, SqlInsertEquipmentPresetTemplate, command =>
{
AddParameter(command, "character_common_id", characterCommonId);
AddParameter(command, "job_id", (byte)jobId);
AddParameter(command, "preset_no", presetNo);
AddParameter(command, "slot_no", slotNo);
AddParameter(command, "item_uid", itemUId);
}) == 1;
}

public List<CDataPresetEquipInfo> SelectEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo)
{
using TCon connection = OpenNewConnection();
return SelectEquipmentPresetTemplate(connection, characterCommonId, jobId, presetNo);
}

public List<CDataPresetEquipInfo> SelectEquipmentPresetTemplate(TCon conn, uint characterCommonId, JobId jobId, uint presetNo)
{
var results = new List<CDataPresetEquipInfo>();
ExecuteInTransaction(conn =>
{
ExecuteReader(conn, SqlSelectEquipmentPresetTemplate,
command => {
AddParameter(command, "character_common_id", characterCommonId);
AddParameter(command, "job_id", (byte)jobId);
AddParameter(command, "preset_no", presetNo);
}, reader => {
while (reader.Read())
{
results.Add(new CDataPresetEquipInfo()
{
ItemUId = GetString(reader, "item_uid"),
EquipSlotNo = GetByte(reader, "slot_no")
});
}
});
});
return results;
}

public bool DeleteEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo)
{
using TCon connection = OpenNewConnection();
return DeleteEquipmentPresetTemplate(connection, characterCommonId, jobId, presetNo);
}

public bool DeleteEquipmentPresetTemplate(TCon conn, uint characterCommonId, JobId jobId, uint presetNo)
{
return ExecuteNonQuery(conn, SqlDeleteEquipmentPresetTemplate, command =>
{
AddParameter(command, "character_common_id", characterCommonId);
AddParameter(command, "job_id", (byte)jobId);
AddParameter(command, "preset_no", presetNo);
}) == 1;
}
}
}
106 changes: 106 additions & 0 deletions Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbEquipmentPreset.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Data.Common;
using System.Reflection.Metadata.Ecma335;
using System.Xml;
using Arrowgene.Ddon.Shared.Entity.Structure;
using Arrowgene.Ddon.Shared.Model;

namespace Arrowgene.Ddon.Database.Sql.Core
{
public abstract partial class DdonSqlDb<TCon, TCom, TReader> : SqlDb<TCon, TCom, TReader>
where TCon : DbConnection
where TCom : DbCommand
where TReader : DbDataReader
{
protected static readonly string[] EquipmentPresetFields = new string[]
{
"character_common_id", "job_id", "preset_no", "preset_name"
};

private readonly string SqlInsertEquipmentPreset = $"INSERT INTO \"ddon_equip_preset\" ({BuildQueryField(EquipmentPresetFields)}) VALUES ({BuildQueryInsert(EquipmentPresetFields)});";
private static readonly string SqlSelectEquipmentPresets = $"SELECT {BuildQueryField(EquipmentPresetFields)} FROM \"ddon_equip_preset\" WHERE \"character_common_id\" = @character_common_id AND \"job_id\" = @job_id;";
private static readonly string SqlUpdateEquipmentPreset = $"UPDATE \"ddon_equip_preset\" SET {BuildQueryUpdate(EquipmentPresetFields)} WHERE \"character_common_id\"=@character_common_id AND \"preset_no\"=@preset_no";
private static readonly string SqlDeleteEquipmentPreset = $"DELETE FROM \"ddon_equip_preset\" WHERE \"character_common_id\"=@character_common_id AND \"job_id\"=@job_id AND \"preset_no\"=@preset_no;";

public bool InsertEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo, string presetName)
{
using TCon connection = OpenNewConnection();
return InsertEquipmentPreset(connection, characterCommonId, jobId, presetNo, presetName);
}

public bool InsertEquipmentPreset(TCon conn, uint characterCommonId, JobId jobId, uint presetNo, string presetName)
{
return ExecuteNonQuery(conn, SqlInsertEquipmentPreset, command =>
{
AddParameter(command, "character_common_id", characterCommonId);
AddParameter(command, "job_id", (byte)jobId);
AddParameter(command, "preset_no", presetNo);
AddParameter(command, "preset_name", presetName);
}) == 1;
}

public bool UpdateEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo, string presetName)
{
using TCon connection = OpenNewConnection();
return UpdateEquipmentPreset(connection, characterCommonId, jobId, presetNo, presetName);
}

public bool UpdateEquipmentPreset(TCon conn, uint characterCommonId, JobId jobId, uint presetNo, string presetName)
{
return ExecuteNonQuery(conn, SqlUpdateEquipmentPreset, command =>
{
AddParameter(command, "character_common_id", characterCommonId);
AddParameter(command, "job_id", (byte)jobId);
AddParameter(command, "preset_no", presetNo);
AddParameter(command, "preset_name", presetName);
}) == 1;
}

public List<CDataEquipPreset> SelectEquipmentPresets(uint characterCommonId, JobId jobId)
{
using TCon connection = OpenNewConnection();
return SelectEquipmentPresets(connection, characterCommonId, jobId);
}

public List<CDataEquipPreset> SelectEquipmentPresets(TCon conn, uint characterCommonId, JobId jobId)
{
var results = new List<CDataEquipPreset>();
ExecuteInTransaction(conn =>
{
ExecuteReader(conn, SqlSelectEquipmentPresets,
command => {
AddParameter(command, "@character_common_id", characterCommonId);
AddParameter(command, "@job_id", (byte) jobId);
}, reader => {
while (reader.Read())
{
results.Add(new CDataEquipPreset()
{
Job = (JobId)GetByte(reader, "job_id"),
PresetNo = GetUInt32(reader, "preset_no"),
PresetName = GetString(reader, "preset_name")
});
}
});
});
return results;
}

public bool DeleteEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo)
{
using TCon connection = OpenNewConnection();
return DeleteEquipmentPreset(connection, characterCommonId, jobId, presetNo);
}

public bool DeleteEquipmentPreset(TCon conn, uint characterCommonId, JobId jobId, uint presetNo)
{
return ExecuteNonQuery(conn, SqlDeleteEquipmentPreset, command =>
{
AddParameter(command, "character_common_id", characterCommonId);
AddParameter(command, "job_id", (byte) jobId);
AddParameter(command, "preset_no", presetNo);
}) == 1;
}
}
}
3 changes: 3 additions & 0 deletions Arrowgene.Ddon.GameServer/DdonGameServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,9 @@ private void LoadPacketHandler()
AddHandler(new EquipUpdateHideCharacterLanternHandler(this));
AddHandler(new EquipUpdateHidePawnHeadArmorHandler(this));
AddHandler(new EquipUpdateHidePawnLanternHandler(this));
AddHandler(new EquipGetEquipPresetListHandler(this));
AddHandler(new EquipUpdateEquipPresetHandler(this));
AddHandler(new EquipUpdateEquipPresetNameHandler(this));

AddHandler(new EventStartHandler(this));
AddHandler(new EventEndHandler(this));
Expand Down
1 change: 1 addition & 0 deletions Arrowgene.Ddon.GameServer/GameClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public void UpdateIdentity()
public InstanceEventDropItemManager InstanceEventDropItemManager { get; }

public GameMode GameMode { get; set; }
public uint EquipPresetIndex { get; set; }

// TODO: Place somewhere else more sensible
public uint LastWarpPointId { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

using Arrowgene.Ddon.GameServer.Characters;
using Arrowgene.Ddon.Server;
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
using Arrowgene.Ddon.Shared.Entity.Structure;
using Arrowgene.Ddon.Shared.Model;
using Arrowgene.Logging;
using System.Drawing;
using System.Linq;

namespace Arrowgene.Ddon.GameServer.Handler
{
public class EquipGetEquipPresetListHandler : GameRequestPacketHandler<C2SEquipGetEquipPresetListReq, S2CEquipGetEquipPresetListRes>
{
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(EquipGetEquipPresetListHandler));

public EquipGetEquipPresetListHandler(DdonGameServer server) : base(server)
{
}

public override S2CEquipGetEquipPresetListRes Handle(GameClient client, C2SEquipGetEquipPresetListReq request)
{
var results = new S2CEquipGetEquipPresetListRes();

CharacterCommon characterCommon;
if (client.EquipPresetIndex == 0)
{
characterCommon = client.Character;
}
else
{
characterCommon = client.Character.PawnBySlotNo((byte)client.EquipPresetIndex);
}

foreach (var presetInfo in Server.Database.SelectEquipmentPresets(characterCommon.CommonId, characterCommon.Job))
{
var presetItems = Server.Database.SelectEquipmentPresetTemplate(characterCommon.CommonId, presetInfo.Job, presetInfo.PresetNo);
foreach (var presetItem in presetItems)
{
var matches = client.Character.Storage.FindItemByUIdInStorage(ItemManager.AllItemStorages, presetItem.ItemUId);
if (matches == null)
{
// Item was deleted or sold?
continue;
}

var storageType = matches.Item1;
var item = matches.Item2.Item2;

presetItem.ItemId = item.ItemId;
presetItem.Color = item.Color;
presetItem.PlusValue = item.PlusValue;
presetItem.EquipElementParamList = item.EquipElementParamList;

presetInfo.PresetEquipInfoList.Add(presetItem);
}

results.EquipPresetList.Add(presetInfo);
}

return results;
}
}
}
Loading

0 comments on commit 8ed1473

Please sign in to comment.