added GameSystemID to SpellLevelLECost, SkillLearningInfo, SpellLearningInfo
This commit is contained in:
@@ -140,9 +140,10 @@ type ExportableClassSpellSchoolEPCost struct {
|
||||
|
||||
// ExportableSpellLevelLECost represents spell level LE costs for export
|
||||
type ExportableSpellLevelLECost struct {
|
||||
Level int `json:"level"`
|
||||
LERequired int `json:"le_required"`
|
||||
GameSystem string `json:"game_system"`
|
||||
Level int `json:"level"`
|
||||
LERequired int `json:"le_required"`
|
||||
GameSystem string `json:"game_system"`
|
||||
GameSystemId uint `json:"game_system_id"`
|
||||
}
|
||||
|
||||
// ExportableSkillImprovementCost represents skill improvement costs for export
|
||||
@@ -1204,9 +1205,10 @@ func ExportSpellLevelLECosts(outputDir string) error {
|
||||
exportable := make([]ExportableSpellLevelLECost, len(costs))
|
||||
for i, cost := range costs {
|
||||
exportable[i] = ExportableSpellLevelLECost{
|
||||
Level: cost.Level,
|
||||
LERequired: cost.LERequired,
|
||||
GameSystem: cost.GameSystem,
|
||||
Level: cost.Level,
|
||||
LERequired: cost.LERequired,
|
||||
GameSystem: cost.GameSystem,
|
||||
GameSystemId: cost.GameSystemId,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1221,23 +1223,27 @@ func ImportSpellLevelLECosts(inputDir string) error {
|
||||
}
|
||||
|
||||
for _, exp := range exportable {
|
||||
gs := models.GetGameSystem(exp.GameSystemId, exp.GameSystem)
|
||||
var cost models.SpellLevelLECost
|
||||
result := database.DB.Where("level = ? AND game_system = ?", exp.Level, exp.GameSystem).First(&cost)
|
||||
result := database.DB.Where("level = ? AND (game_system = ? OR game_system_id = ?)", exp.Level, gs.Name, gs.ID).First(&cost)
|
||||
|
||||
if result.Error == gorm.ErrRecordNotFound {
|
||||
cost = models.SpellLevelLECost{
|
||||
Level: exp.Level,
|
||||
LERequired: exp.LERequired,
|
||||
GameSystem: exp.GameSystem,
|
||||
Level: exp.Level,
|
||||
LERequired: exp.LERequired,
|
||||
GameSystem: gs.Name,
|
||||
GameSystemId: gs.ID,
|
||||
}
|
||||
if err := database.DB.Create(&cost).Error; err != nil {
|
||||
if err := cost.Create(); err != nil {
|
||||
return fmt.Errorf("failed to create spell level LE cost: %w", err)
|
||||
}
|
||||
} else if result.Error != nil {
|
||||
return fmt.Errorf("failed to query spell level LE cost: %w", result.Error)
|
||||
} else {
|
||||
cost.LERequired = exp.LERequired
|
||||
if err := database.DB.Save(&cost).Error; err != nil {
|
||||
cost.GameSystem = gs.Name
|
||||
cost.GameSystemId = gs.ID
|
||||
if err := cost.Save(); err != nil {
|
||||
return fmt.Errorf("failed to update spell level LE cost: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,10 +95,11 @@ type ClassSpellSchoolEPCost struct {
|
||||
|
||||
// SpellLevelLECost definiert LE-Kosten pro Zauber-Stufe
|
||||
type SpellLevelLECost struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Level int `gorm:"uniqueIndex;not null" json:"level"` // Zauber-Stufe (1-12)
|
||||
LERequired int `gorm:"not null" json:"le_required"` // Benötigte Lerneinheiten
|
||||
GameSystem string `gorm:"index;default:midgard" json:"game_system"`
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Level int `gorm:"uniqueIndex;not null" json:"level"` // Zauber-Stufe (1-12)
|
||||
LERequired int `gorm:"not null" json:"le_required"` // Benötigte Lerneinheiten
|
||||
GameSystem string `gorm:"index;default:midgard" json:"game_system"`
|
||||
GameSystemId uint `json:"game_system_id,omitempty"`
|
||||
}
|
||||
|
||||
// SkillCategoryDifficulty definiert die Schwierigkeit einer Fertigkeit in einer bestimmten Kategorie
|
||||
@@ -155,6 +156,8 @@ type SkillLearningInfo struct {
|
||||
ClassCode string `json:"class_code"`
|
||||
ClassName string `json:"class_name"`
|
||||
EPPerTE int `json:"ep_per_te"`
|
||||
GameSystem string `json:"game_system"`
|
||||
GameSystemId uint `json:"game_system_id,omitempty"`
|
||||
}
|
||||
|
||||
// SpellLearningInfo kombiniert alle Informationen für einen Zauber
|
||||
@@ -169,6 +172,8 @@ type SpellLearningInfo struct {
|
||||
ClassName string `json:"class_name"`
|
||||
EPPerLE int `json:"ep_per_le"`
|
||||
LERequired int `json:"le_required"`
|
||||
GameSystem string `json:"game_system"`
|
||||
GameSystemId uint `json:"game_system_id,omitempty"`
|
||||
}
|
||||
|
||||
// AuditLogEntry repräsentiert einen Eintrag im Audit-Log
|
||||
@@ -232,6 +237,27 @@ func (SkillImprovementCost) TableName() string {
|
||||
return "learning_skill_improvement_costs"
|
||||
}
|
||||
|
||||
func (sllc *SpellLevelLECost) ensureGameSystem() {
|
||||
gs := GetGameSystem(sllc.GameSystemId, sllc.GameSystem)
|
||||
sllc.GameSystemId = gs.ID
|
||||
sllc.GameSystem = gs.Name
|
||||
}
|
||||
|
||||
func (sllc *SpellLevelLECost) BeforeCreate(tx *gorm.DB) error {
|
||||
sllc.ensureGameSystem()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sllc *SpellLevelLECost) BeforeSave(tx *gorm.DB) error {
|
||||
sllc.ensureGameSystem()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sllc *SpellLevelLECost) Save() error {
|
||||
sllc.ensureGameSystem()
|
||||
return database.DB.Save(sllc).Error
|
||||
}
|
||||
|
||||
func (s *Source) ensureGameSystem() {
|
||||
gs := GetGameSystem(s.GameSystemId, s.GameSystem)
|
||||
s.GameSystemId = gs.ID
|
||||
@@ -411,6 +437,7 @@ func (cssec *ClassSpellSchoolEPCost) Create() error {
|
||||
}
|
||||
|
||||
func (sllc *SpellLevelLECost) Create() error {
|
||||
sllc.ensureGameSystem()
|
||||
return database.DB.Create(sllc).Error
|
||||
}
|
||||
|
||||
@@ -457,11 +484,14 @@ func GetEPPerLEForClassAndSpellSchool(classCode string, schoolName string) (int,
|
||||
// GetSkillCategoryAndDifficultyNewSystem findet die beste Kategorie für eine Fertigkeit basierend auf niedrigsten EP-Kosten
|
||||
func GetSkillCategoryAndDifficultyNewSystem(skillName string, classCode string) (*SkillLearningInfo, error) {
|
||||
var results []SkillLearningInfo
|
||||
gs := GetGameSystem(0, "midgard")
|
||||
|
||||
err := database.DB.Raw(`
|
||||
SELECT
|
||||
scd.skill_id,
|
||||
s.name as skill_name,
|
||||
s.game_system as game_system,
|
||||
s.game_system_id as game_system_id,
|
||||
scd.skill_category as category_name,
|
||||
scd.skill_difficulty as difficulty_name,
|
||||
scd.learn_cost,
|
||||
@@ -472,14 +502,20 @@ func GetSkillCategoryAndDifficultyNewSystem(skillName string, classCode string)
|
||||
FROM learning_skill_category_difficulties scd
|
||||
JOIN learning_class_category_ep_costs ccec ON scd.skill_category = ccec.skill_category
|
||||
JOIN gsm_skills s ON scd.skill_id = s.id
|
||||
WHERE s.name = ? AND ccec.character_class = ?
|
||||
WHERE s.name = ? AND ccec.character_class = ? AND (s.game_system = ? OR s.game_system_id = ?)
|
||||
ORDER BY total_cost ASC
|
||||
`, skillName, classCode).Scan(&results).Error
|
||||
`, skillName, classCode, gs.Name, gs.ID).Scan(&results).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range results {
|
||||
gs := GetGameSystem(results[i].GameSystemId, results[i].GameSystem)
|
||||
results[i].GameSystemId = gs.ID
|
||||
results[i].GameSystem = gs.Name
|
||||
}
|
||||
|
||||
if len(results) == 0 {
|
||||
return nil, gorm.ErrRecordNotFound
|
||||
}
|
||||
@@ -490,11 +526,14 @@ func GetSkillCategoryAndDifficultyNewSystem(skillName string, classCode string)
|
||||
// GetSkillInfoCategoryAndDifficultyNewSystem holt die Informationen für eine spezifische Kategorie/Schwierigkeit
|
||||
func GetSkillInfoCategoryAndDifficultyNewSystem(skillName, category, difficulty, classCode string) (*SkillLearningInfo, error) {
|
||||
var result SkillLearningInfo
|
||||
gs := GetGameSystem(0, "midgard")
|
||||
|
||||
err := database.DB.Raw(`
|
||||
SELECT
|
||||
scd.skill_id,
|
||||
s.name as skill_name,
|
||||
s.game_system as game_system,
|
||||
s.game_system_id as game_system_id,
|
||||
scd.skill_category as category_name,
|
||||
scd.skill_difficulty as difficulty_name,
|
||||
scd.learn_cost,
|
||||
@@ -505,13 +544,17 @@ func GetSkillInfoCategoryAndDifficultyNewSystem(skillName, category, difficulty,
|
||||
FROM learning_skill_category_difficulties scd
|
||||
JOIN learning_class_category_ep_costs ccec ON scd.skill_category = ccec.skill_category
|
||||
JOIN gsm_skills s ON scd.skill_id = s.id
|
||||
WHERE s.name = ? AND scd.skill_category = ? AND scd.skill_difficulty = ? AND ccec.character_class = ?
|
||||
`, skillName, category, difficulty, classCode).Scan(&result).Error
|
||||
WHERE s.name = ? AND scd.skill_category = ? AND scd.skill_difficulty = ? AND ccec.character_class = ? AND (s.game_system = ? OR s.game_system_id = ?)
|
||||
`, skillName, category, difficulty, classCode, gs.Name, gs.ID).Scan(&result).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gs = GetGameSystem(result.GameSystemId, result.GameSystem)
|
||||
result.GameSystemId = gs.ID
|
||||
result.GameSystem = gs.Name
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
@@ -523,6 +566,8 @@ func GetSpellLearningInfoNewSystem(spellName string, classCode string) (*SpellLe
|
||||
SELECT
|
||||
s.id as spell_id,
|
||||
s.name as spell_name,
|
||||
s.game_system as game_system,
|
||||
s.game_system_id as game_system_id,
|
||||
s.stufe as spell_level,
|
||||
s.learning_category as school_name,
|
||||
cssec.character_class as class_code,
|
||||
@@ -531,7 +576,7 @@ func GetSpellLearningInfoNewSystem(spellName string, classCode string) (*SpellLe
|
||||
COALESCE(sllc.le_required, 0) as le_required
|
||||
FROM gsm_spells s
|
||||
JOIN learning_class_spell_school_ep_costs cssec ON s.learning_category = cssec.spell_school
|
||||
LEFT JOIN learning_spell_level_le_costs sllc ON s.stufe = sllc.level
|
||||
LEFT JOIN learning_spell_level_le_costs sllc ON s.stufe = sllc.level AND (sllc.game_system = s.game_system OR sllc.game_system_id = s.game_system_id OR sllc.game_system_id IS NULL)
|
||||
WHERE s.name = ? AND cssec.character_class = ?
|
||||
`, spellName, classCode).Scan(&result).Error
|
||||
|
||||
@@ -539,15 +584,19 @@ func GetSpellLearningInfoNewSystem(spellName string, classCode string) (*SpellLe
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Validate that we found a spell (spell_id should be > 0)
|
||||
if result.SpellID == 0 {
|
||||
return nil, gorm.ErrRecordNotFound
|
||||
}
|
||||
|
||||
// Validate spell level - level 0 is not a valid spell level
|
||||
if result.SpellLevel <= 0 {
|
||||
return nil, fmt.Errorf("invalid spell level %d for spell '%s' - spell levels must be 1 or higher", result.SpellLevel, spellName)
|
||||
}
|
||||
|
||||
// Validate that we found a spell (spell_id should be > 0)
|
||||
if result.SpellID == 0 {
|
||||
return nil, gorm.ErrRecordNotFound
|
||||
}
|
||||
gs := GetGameSystem(result.GameSystemId, result.GameSystem)
|
||||
result.GameSystemId = gs.ID
|
||||
result.GameSystem = gs.Name
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
@@ -225,6 +225,28 @@ func TestSkillDifficulty_Create_SetsGameSystem(t *testing.T) {
|
||||
assert.NotZero(t, difficulty.GameSystemId)
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Tests for SpellLevelLECost struct and methods
|
||||
// =============================================================================
|
||||
|
||||
func TestSpellLevelLECost_Create_SetsGameSystem(t *testing.T) {
|
||||
setupLearningCostsTestDB(t)
|
||||
|
||||
gs := GetGameSystem(0, "midgard")
|
||||
|
||||
cost := SpellLevelLECost{
|
||||
Level: 99,
|
||||
LERequired: 1,
|
||||
}
|
||||
|
||||
err := cost.Create()
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.NotZero(t, cost.ID)
|
||||
assert.Equal(t, gs.Name, cost.GameSystem)
|
||||
assert.Equal(t, gs.ID, cost.GameSystemId)
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Tests for SpellSchool struct and methods
|
||||
// =============================================================================
|
||||
@@ -336,6 +358,19 @@ func TestGetSkillCategoryAndDifficultyNewSystem_Success(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSkillCategoryAndDifficultyNewSystem_IncludesGameSystem(t *testing.T) {
|
||||
setupLearningCostsTestDB(t)
|
||||
|
||||
gs := GetGameSystem(0, "midgard")
|
||||
|
||||
skillInfo, err := GetSkillCategoryAndDifficultyNewSystem("Schwimmen", "Bb")
|
||||
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, skillInfo)
|
||||
assert.Equal(t, gs.Name, skillInfo.GameSystem)
|
||||
assert.Equal(t, gs.ID, skillInfo.GameSystemId)
|
||||
}
|
||||
|
||||
func TestGetSkillCategoryAndDifficultyNewSystem_InvalidSkill(t *testing.T) {
|
||||
setupLearningCostsTestDB(t)
|
||||
|
||||
@@ -373,6 +408,53 @@ func TestGetSpellLearningInfoNewSystem_Success(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSpellLearningInfoNewSystem_IncludesGameSystem(t *testing.T) {
|
||||
setupLearningCostsTestDB(t)
|
||||
|
||||
gs := GetGameSystem(0, "midgard")
|
||||
require.NotNil(t, gs)
|
||||
|
||||
var class CharacterClass
|
||||
require.NoError(t, class.FirstByCode("Ma"))
|
||||
|
||||
var school SpellSchool
|
||||
require.NoError(t, school.FirstByName("Dweomer"))
|
||||
|
||||
cost := ClassSpellSchoolEPCost{
|
||||
CharacterClassID: class.ID,
|
||||
SpellSchoolID: school.ID,
|
||||
EPPerLE: 3,
|
||||
}
|
||||
require.NoError(t, cost.Create())
|
||||
|
||||
var spellLevelCost SpellLevelLECost
|
||||
err := database.DB.Where("level = ?", 1).First(&spellLevelCost).Error
|
||||
if err != nil {
|
||||
spellLevelCost = SpellLevelLECost{Level: 1, LERequired: 1, GameSystem: gs.Name, GameSystemId: gs.ID}
|
||||
require.NoError(t, spellLevelCost.Create())
|
||||
} else {
|
||||
spellLevelCost.GameSystem = gs.Name
|
||||
spellLevelCost.GameSystemId = gs.ID
|
||||
require.NoError(t, spellLevelCost.Save())
|
||||
}
|
||||
|
||||
spell := Spell{
|
||||
Name: "TestSpellGS",
|
||||
GameSystem: gs.Name,
|
||||
GameSystemId: gs.ID,
|
||||
Stufe: spellLevelCost.Level,
|
||||
LearningCategory: school.Name,
|
||||
}
|
||||
require.NoError(t, spell.Create())
|
||||
|
||||
spellInfo, err := GetSpellLearningInfoNewSystem(spell.Name, class.Code)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, spellInfo)
|
||||
assert.Equal(t, gs.Name, spellInfo.GameSystem)
|
||||
assert.Equal(t, gs.ID, spellInfo.GameSystemId)
|
||||
}
|
||||
|
||||
func TestGetSpellLearningInfoNewSystem_InvalidSpell(t *testing.T) {
|
||||
setupLearningCostsTestDB(t)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user