Skip to content

Commit 14fc966

Browse files
committed
feat: Job Emblems
- Added support for job emblems - Created new personal quests to unlock emblems. - Added support for emblems using the menus at Renton. - Created new handlers and packets for the new menus.
1 parent c73ee85 commit 14fc966

121 files changed

Lines changed: 3969 additions & 238 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Arrowgene.Ddon.Database/DdonDatabaseBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public static class DdonDatabaseBuilder
1313
{
1414
private const string DefaultSchemaFile = "Script/schema_sqlite.sql";
1515

16-
public const uint Version = 41;
16+
public const uint Version = 42;
1717
private static readonly ILogger Logger = LogProvider.Logger<Logger>(typeof(DdonDatabaseBuilder));
1818

1919
public static IDatabase Build(DatabaseSetting settings)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
CREATE TABLE ddon_job_emblem (
2+
"character_id" INTEGER NOT NULL,
3+
"job_id" INTEGER NOT NULL,
4+
"emblem_level" SMALLINT NOT NULL,
5+
"emblem_points_used" SMALLINT NOT NULL,
6+
"physical_attack" SMALLINT NOT NULL,
7+
"magick_attack" SMALLINT NOT NULL,
8+
"physical_defense" SMALLINT NOT NULL,
9+
"magick_defense" SMALLINT NOT NULL,
10+
"max_hp" SMALLINT NOT NULL,
11+
"max_stamina" SMALLINT NOT NULL,
12+
"healing_power" SMALLINT NOT NULL,
13+
"endurance" SMALLINT NOT NULL,
14+
"blow_power" SMALLINT NOT NULL,
15+
"chance_attack" SMALLINT NOT NULL,
16+
"exhaust_attack" SMALLINT NOT NULL,
17+
"knockout_power" SMALLINT NOT NULL,
18+
"fire_resist" SMALLINT NOT NULL,
19+
"ice_resist" SMALLINT NOT NULL,
20+
"thunder_resist" SMALLINT NOT NULL,
21+
"holy_resist" SMALLINT NOT NULL,
22+
"dark_resist" SMALLINT NOT NULL,
23+
CONSTRAINT pk_ddon_job_emblem PRIMARY KEY ("character_id", "job_id"),
24+
CONSTRAINT fk_ddon_job_emblem_character_id FOREIGN KEY ("character_id") REFERENCES "ddon_character" ("character_id") ON DELETE CASCADE
25+
);

Arrowgene.Ddon.Database/Files/Database/Script/schema_sqlite.sql

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,3 +996,29 @@ CREATE TABLE IF NOT EXISTS "ddon_skill_augmentation_released_elements" (
996996
CONSTRAINT pk_ddon_skill_augmentation_released_elements PRIMARY KEY ("character_id", "job_id", "release_id"),
997997
CONSTRAINT fk_ddon_skill_augmentation_released_elements_character_id FOREIGN KEY ("character_id") REFERENCES "ddon_character" ("character_id") ON DELETE CASCADE
998998
);
999+
1000+
CREATE TABLE IF NOT EXISTS "ddon_job_emblem" (
1001+
"character_id" INTEGER NOT NULL,
1002+
"job_id" INTEGER NOT NULL,
1003+
"emblem_level" SMALLINT NOT NULL,
1004+
"emblem_points_used" SMALLINT NOT NULL,
1005+
"physical_attack" SMALLINT NOT NULL,
1006+
"magick_attack" SMALLINT NOT NULL,
1007+
"physical_defense" SMALLINT NOT NULL,
1008+
"magick_defense" SMALLINT NOT NULL,
1009+
"max_hp" SMALLINT NOT NULL,
1010+
"max_stamina" SMALLINT NOT NULL,
1011+
"healing_power" SMALLINT NOT NULL,
1012+
"endurance" SMALLINT NOT NULL,
1013+
"blow_power" SMALLINT NOT NULL,
1014+
"chance_attack" SMALLINT NOT NULL,
1015+
"exhaust_attack" SMALLINT NOT NULL,
1016+
"knockout_power" SMALLINT NOT NULL,
1017+
"fire_resist" SMALLINT NOT NULL,
1018+
"ice_resist" SMALLINT NOT NULL,
1019+
"thunder_resist" SMALLINT NOT NULL,
1020+
"holy_resist" SMALLINT NOT NULL,
1021+
"dark_resist" SMALLINT NOT NULL,
1022+
CONSTRAINT pk_ddon_job_emblem PRIMARY KEY ("character_id", "job_id"),
1023+
CONSTRAINT fk_ddon_job_emblem_character_id FOREIGN KEY ("character_id") REFERENCES "ddon_character" ("character_id") ON DELETE CASCADE
1024+
);

Arrowgene.Ddon.Database/IDatabase.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,10 +407,11 @@ bool UpdateCrest(
407407
string itemUId,
408408
uint slot,
409409
uint crestId,
410-
uint crestAmount
410+
uint crestAmount,
411+
DbConnection? ConnectionIn = null
411412
);
412413

413-
bool RemoveCrest(uint characterCommonId, string itemUId, uint slot);
414+
bool RemoveCrest(uint characterCommonId, string itemUId, uint slot, DbConnection? connectionIn = null);
414415
List<Crest> GetCrests(uint characterCommonId, string itemUId);
415416

416417
// Bitterblack Maze Progress
@@ -582,6 +583,10 @@ List<CDataJobOrderProgress> GetJobMasterActiveOrderProgress(uint characterId, Jo
582583
bool InsertSkillAugmentationReleasedElement(uint characterId, JobId jobId, uint releaseId, DbConnection? connectionIn = null);
583584
HashSet<uint> GetSkillAugmentationReleasedElements(uint characterId, JobId jobId, DbConnection? connectionIn = null);
584585

586+
public bool UpsertJobEmblemData(uint characterId, JobEmblem jobEmblem, DbConnection? connectionIn = null);
587+
public JobEmblem GetJobEmblemData(uint characterId, JobId jobId, DbConnection? connectionIn = null);
588+
public List<JobEmblem> GetAllJobEmblemData(uint characterId, DbConnection? connectionIn = null);
589+
585590
#region Pawn craft progress
586591

587592
bool ReplacePawnCraftProgress(CraftProgress craftProgress, DbConnection? connectionIn = null);

Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbCharacterCommon.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ private void QueryCharacterCommonData(DbConnection conn, CharacterCommon common)
157157

158158
using DbConnection connection3 = OpenNewConnection();
159159
item.AddStatusParamList = GetEquipmentLimitBreakRecord(item.UId, connection3);
160+
item.EquipStatParamList.Add(new CDataEquipStatParam() { EffectID = (byte) EquipStatId.MaxHp, EffectValue = 50 });
160161

161162
common.EquipmentTemplate.SetEquipItem(item, job, equipType, equipSlot);
162163
}

Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbCrest.cs

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -49,39 +49,32 @@ public override bool InsertCrest(uint characterCommonId, string itemUId, uint sl
4949
}
5050
}
5151

52-
public override bool UpdateCrest(uint characterCommonId, string itemUId, uint slot, uint crestId, uint crestAmount)
52+
public override bool UpdateCrest(uint characterCommonId, string itemUId, uint slot, uint crestId, uint crestAmount, DbConnection? connectionIn = null)
5353
{
54-
using DbConnection connection = OpenNewConnection();
55-
return UpdateCrest(connection, characterCommonId, itemUId, slot, crestId, crestAmount);
56-
}
57-
58-
public bool UpdateCrest(DbConnection connection, uint characterCommonId, string itemUId, uint slot, uint crestId, uint crestAmount)
59-
{
60-
return ExecuteNonQuery(connection, SqlUpdateCrestData, command =>
54+
return ExecuteQuerySafe(connectionIn, connection =>
6155
{
62-
AddParameter(command, "character_common_id", characterCommonId);
63-
AddParameter(command, "item_uid", itemUId);
64-
AddParameter(command, "slot", slot);
65-
AddParameter(command, "crest_id", crestId);
66-
AddParameter(command, "crest_amount", crestAmount);
67-
}) == 1;
68-
;
69-
}
70-
71-
public override bool RemoveCrest(uint characterCommonId, string itemUId, uint slot)
72-
{
73-
using DbConnection connection = OpenNewConnection();
74-
return RemoveCrest(connection, characterCommonId, itemUId, slot);
56+
return ExecuteNonQuery(connection, SqlUpdateCrestData, command =>
57+
{
58+
AddParameter(command, "character_common_id", characterCommonId);
59+
AddParameter(command, "item_uid", itemUId);
60+
AddParameter(command, "slot", slot);
61+
AddParameter(command, "crest_id", crestId);
62+
AddParameter(command, "crest_amount", crestAmount);
63+
}) == 1;
64+
});
7565
}
7666

77-
public bool RemoveCrest(DbConnection connection, uint characterCommonId, string itemUId, uint slot)
67+
public override bool RemoveCrest(uint characterCommonId, string itemUId, uint slot, DbConnection? connectionIn = null)
7868
{
79-
return ExecuteNonQuery(connection, SqlDeleteCrestData, command =>
69+
return ExecuteQuerySafe(connectionIn, connection =>
8070
{
81-
AddParameter(command, "character_common_id", characterCommonId);
82-
AddParameter(command, "item_uid", itemUId);
83-
AddParameter(command, "slot", slot);
84-
}) == 1;
71+
return ExecuteNonQuery(connection, SqlDeleteCrestData, command =>
72+
{
73+
AddParameter(command, "character_common_id", characterCommonId);
74+
AddParameter(command, "item_uid", itemUId);
75+
AddParameter(command, "slot", slot);
76+
}) == 1;
77+
});
8578
}
8679

8780
public override List<Crest> GetCrests(uint characterCommonId, string itemUId)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Data.Common;
2+
3+
namespace Arrowgene.Ddon.Database.Sql.Core.Migration
4+
{
5+
public class JobEmblemMigration : IMigrationStrategy
6+
{
7+
public uint From => 41;
8+
public uint To => 42;
9+
10+
private readonly DatabaseSetting DatabaseSetting;
11+
12+
public JobEmblemMigration(DatabaseSetting databaseSetting)
13+
{
14+
DatabaseSetting = databaseSetting;
15+
}
16+
17+
public bool Migrate(IDatabase db, DbConnection conn)
18+
{
19+
string adaptedSchema = DdonDatabaseBuilder.GetAdaptedSchema(DatabaseSetting, "Script/migration_job_emblem.sql");
20+
db.Execute(conn, adaptedSchema, true);
21+
return true;
22+
}
23+
24+
}
25+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
using Arrowgene.Ddon.Shared.Model;
2+
using System.Collections.Generic;
3+
using System.Data.Common;
4+
5+
namespace Arrowgene.Ddon.Database.Sql.Core;
6+
7+
public partial class DdonSqlDb : SqlDb
8+
{
9+
/* ddon_job_emblem */
10+
protected static readonly string[] JobEmblemFields = new[]
11+
{
12+
"character_id", "job_id", "emblem_level", "emblem_points_used",
13+
"physical_attack", "magick_attack", "physical_defense", "magick_defense",
14+
"max_hp", "max_stamina", "healing_power", "endurance", "blow_power", "chance_attack", "exhaust_attack",
15+
"knockout_power", "fire_resist", "ice_resist", "thunder_resist", "holy_resist", "dark_resist"
16+
};
17+
18+
private readonly string SqlUpsertJobEmblemData = $"""
19+
INSERT INTO ddon_job_emblem ({BuildQueryField(JobEmblemFields)})
20+
VALUES ({BuildQueryInsert(JobEmblemFields)})
21+
ON CONFLICT (character_id, job_id)
22+
DO UPDATE SET {BuildQueryUpdate(JobEmblemFields)};
23+
""";
24+
25+
private readonly string SqlSelectAllJobEmblemData =
26+
$"SELECT {BuildQueryField(JobEmblemFields)} FROM \"ddon_job_emblem\" WHERE \"character_id\"=@character_id;";
27+
28+
private readonly string SqlSelectJobEmblemData =
29+
$"SELECT {BuildQueryField(JobEmblemFields)} FROM \"ddon_job_emblem\" WHERE \"character_id\"=@character_id AND \"job_id\"=@job_id;";
30+
31+
public override bool UpsertJobEmblemData(uint characterId, JobEmblem jobEmblem, DbConnection? connectionIn = null)
32+
{
33+
return ExecuteQuerySafe(connectionIn, connection =>
34+
{
35+
return ExecuteNonQuery(connection, SqlUpsertJobEmblemData, command =>
36+
{
37+
AddParameter(command, "character_id", characterId);
38+
AddParameter(command, "job_id", (byte)jobEmblem.JobId);
39+
AddParameter(command, "emblem_level", jobEmblem.EmblemLevel);
40+
AddParameter(command, "emblem_points_used", jobEmblem.EmblemPointsUsed);
41+
AddParameter(command, "physical_attack", jobEmblem.StatLevels[EquipStatId.PhysicalAttack]);
42+
AddParameter(command, "magick_attack", jobEmblem.StatLevels[EquipStatId.MagickAttack]);
43+
AddParameter(command, "physical_defense", jobEmblem.StatLevels[EquipStatId.PhysicalDefense]);
44+
AddParameter(command, "magick_defense", jobEmblem.StatLevels[EquipStatId.MagickDefense]);
45+
AddParameter(command, "max_hp", jobEmblem.StatLevels[EquipStatId.MaxHp]);
46+
AddParameter(command, "max_stamina", jobEmblem.StatLevels[EquipStatId.MaxStamina]);
47+
AddParameter(command, "healing_power", jobEmblem.StatLevels[EquipStatId.HealingPower]);
48+
AddParameter(command, "endurance", jobEmblem.StatLevels[EquipStatId.Endurance]);
49+
AddParameter(command, "blow_power", jobEmblem.StatLevels[EquipStatId.BlowPower]);
50+
AddParameter(command, "chance_attack", jobEmblem.StatLevels[EquipStatId.ChanceAttack]);
51+
AddParameter(command, "exhaust_attack", jobEmblem.StatLevels[EquipStatId.ExhaustAttack]);
52+
AddParameter(command, "knockout_power", jobEmblem.StatLevels[EquipStatId.KnockoutPower]);
53+
AddParameter(command, "fire_resist", jobEmblem.StatLevels[EquipStatId.FireResist]);
54+
AddParameter(command, "ice_resist", jobEmblem.StatLevels[EquipStatId.IceResist]);
55+
AddParameter(command, "thunder_resist", jobEmblem.StatLevels[EquipStatId.ThunderResist]);
56+
AddParameter(command, "holy_resist", jobEmblem.StatLevels[EquipStatId.HolyResist]);
57+
AddParameter(command, "dark_resist", jobEmblem.StatLevels[EquipStatId.DarkResist]);
58+
}) == 1;
59+
});
60+
}
61+
62+
public override List<JobEmblem> GetAllJobEmblemData(uint characterId, DbConnection? connectionIn = null)
63+
{
64+
List<JobEmblem> results = new();
65+
ExecuteQuerySafe(connectionIn, connection =>
66+
{
67+
ExecuteReader(connection, SqlSelectAllJobEmblemData, command =>
68+
{
69+
AddParameter(command, "character_id", characterId);
70+
},
71+
reader =>
72+
{
73+
while (reader.Read())
74+
{
75+
results.Add(ReadEmblemData(reader));
76+
}
77+
});
78+
});
79+
return results;
80+
}
81+
82+
public override JobEmblem GetJobEmblemData(uint characterId, JobId jobId, DbConnection? connectionIn = null)
83+
{
84+
JobEmblem result = null;
85+
ExecuteQuerySafe(connectionIn, connection =>
86+
{
87+
ExecuteReader(connection, SqlSelectJobEmblemData, command =>
88+
{
89+
AddParameter(command, "character_id", characterId);
90+
AddParameter(command, "job_id", (byte)jobId);
91+
}, reader =>
92+
{
93+
if (reader.Read())
94+
{
95+
result = ReadEmblemData(reader);
96+
}
97+
});
98+
});
99+
return result;
100+
}
101+
102+
private JobEmblem ReadEmblemData(DbDataReader reader)
103+
{
104+
var result = new JobEmblem
105+
{
106+
JobId = (JobId)GetByte(reader, "job_id"),
107+
EmblemLevel = GetByte(reader, "emblem_level"),
108+
EmblemPointsUsed = GetUInt16(reader, "emblem_points_used"),
109+
};
110+
111+
result.StatLevels[EquipStatId.PhysicalAttack] = GetByte(reader, "physical_attack");
112+
result.StatLevels[EquipStatId.PhysicalDefense] = GetByte(reader, "physical_defense");
113+
result.StatLevels[EquipStatId.MagickAttack] = GetByte(reader, "magick_attack");
114+
result.StatLevels[EquipStatId.MagickDefense] = GetByte(reader, "magick_defense");
115+
result.StatLevels[EquipStatId.MaxHp] = GetByte(reader, "max_hp");
116+
result.StatLevels[EquipStatId.MaxStamina] = GetByte(reader, "max_stamina");
117+
result.StatLevels[EquipStatId.HealingPower] = GetByte(reader, "healing_power");
118+
result.StatLevels[EquipStatId.Endurance] = GetByte(reader, "endurance");
119+
result.StatLevels[EquipStatId.BlowPower] = GetByte(reader, "blow_power");
120+
result.StatLevels[EquipStatId.ChanceAttack] = GetByte(reader, "chance_attack");
121+
result.StatLevels[EquipStatId.ExhaustAttack] = GetByte(reader, "exhaust_attack");
122+
result.StatLevels[EquipStatId.KnockoutPower] = GetByte(reader, "knockout_power");
123+
result.StatLevels[EquipStatId.FireResist] = GetByte(reader, "fire_resist");
124+
result.StatLevels[EquipStatId.IceResist] = GetByte(reader, "ice_resist");
125+
result.StatLevels[EquipStatId.ThunderResist] = GetByte(reader, "thunder_resist");
126+
result.StatLevels[EquipStatId.HolyResist] = GetByte(reader, "holy_resist");
127+
result.StatLevels[EquipStatId.DarkResist] = GetByte(reader, "dark_resist");
128+
129+
return result;
130+
}
131+
}

Arrowgene.Ddon.Database/Sql/SqlDb.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,8 @@ public abstract int UpdateContact(uint requestingCharacterId, uint requestedChar
481481
public abstract bool InsertCharacterStampData(uint id, CharacterStampBonus stampData);
482482
public abstract bool UpdateCharacterStampData(uint id, CharacterStampBonus stampData);
483483
public abstract bool InsertCrest(uint characterCommonId, string itemUId, uint slot, uint crestId, uint crestAmount, DbConnection? connectionIn = null);
484-
public abstract bool UpdateCrest(uint characterCommonId, string itemUId, uint slot, uint crestId, uint crestAmount);
485-
public abstract bool RemoveCrest(uint characterCommonId, string itemUId, uint slot);
484+
public abstract bool UpdateCrest(uint characterCommonId, string itemUId, uint slot, uint crestId, uint crestAmount, DbConnection? ConnectionIn = null);
485+
public abstract bool RemoveCrest(uint characterCommonId, string itemUId, uint slot, DbConnection? connectionIn = null);
486486
public abstract List<Crest> GetCrests(uint characterCommonId, string itemUId);
487487
public abstract bool InsertBBMCharacterId(uint characterId, uint bbmCharacterId);
488488
public abstract uint SelectBBMCharacterId(uint characterId, DbConnection? connectionIn = null);
@@ -608,6 +608,10 @@ public abstract List<CDataJobOrderProgress> GetJobMasterActiveOrderProgress(uint
608608
public abstract bool InsertSkillAugmentationReleasedElement(uint characterId, JobId jobId, uint releaseId, DbConnection? connectionIn = null);
609609
public abstract HashSet<uint> GetSkillAugmentationReleasedElements(uint characterId, JobId jobId, DbConnection? connectionIn = null);
610610

611+
public abstract bool UpsertJobEmblemData(uint characterId, JobEmblem jobEmblem, DbConnection? connectionIn = null);
612+
public abstract JobEmblem GetJobEmblemData(uint characterId, JobId jobId, DbConnection? connectionIn = null);
613+
public abstract List<JobEmblem> GetAllJobEmblemData(uint characterId, DbConnection? connectionIn = null);
614+
611615
protected virtual DbCommand Command(string query, DbConnection connection)
612616
{
613617
throw new NotImplementedException("This is driver-dependent and must be implemented.");

0 commit comments

Comments
 (0)