Files
bamort/backend/gsmaster/lernkosten_maps.go
T

863 lines
28 KiB
Go

package gsmaster
import (
"fmt"
)
type LernCostRequest struct {
CharId uint `json:"char_id" binding:"required"` // Charakter-ID
Name string `json:"name" binding:"required"` // Name der Fertigkeit / des Zaubers
CurrentLevel int `json:"current_level,omitempty"` // Aktueller Wert (nur für Verbesserung)
Type string `json:"type" binding:"required,oneof=skill spell weapon"` // 'skill', 'spell' oder 'weapon' Waffenfertigkeiten sind normale Fertigkeiten (evtl. kann hier später der Name der Waffe angegeben werden )
Action string `json:"action" binding:"required,oneof=learn improve"` // 'learn' oder 'improve'
TargetLevel int `json:"target_level,omitempty"` // Zielwert (optional, für Kostenberechnung bis zu einem bestimmten Level)
UsePP int `json:"use_pp,omitempty"` // Anzahl der zu verwendenden Praxispunkte
UseGold int `json:"use_gold,omitempty"` // Anzahl der zu verwendenden Goldstücke
// Belohnungsoptionen
Reward *string `json:"reward" binding:"required,oneof=default noGold halveep halveepnoGold"` // Belohnungsoptionen Lernen als Belohnung
// default
// learn: ohne Gold
// improve/spell: halbe EP kein Gold
}
// DifficultyData enthält Skills und Trainingskosten für eine Schwierigkeitsstufe
type DifficultyData struct {
LearnCost int `json:"learncosts"`
Skills []string `json:"skills"`
TrainCosts map[int]int `json:"traincosts"`
}
// LearningCostsTable strukturiert die Daten aus Lerntabellen.md
type LearningCostsTable2 struct {
// EP-Kosten für 1 Trainingseinheit (TE) pro Charakterklasse und Fertigkeitskategorie
EPPerTE map[string]map[string]int
// EP-Kosten für 1 Lerneinheit (LE) für Zauber pro Charakterklasse und Zauberschule
SpellEPPerLE map[string]map[string]int
SpellLEPerLevel map[int]int
// LE-Kosten für Fertigkeiten basierend auf Schwierigkeit
BaseLearnCost map[string]map[string]int
// TE-Kosten für Verbesserungen basierend auf Kategorie, Schwierigkeit und aktuellem Wert
ImprovementCost map[string]map[string]DifficultyData
}
// learningCostsData enthält alle statischen Lerntabellendaten
var learningCostsData = &LearningCostsTable2{
// EP-Kosten für 1 Trainingseinheit (TE) nach Klasse und Kategorie
EPPerTE: map[string]map[string]int{
"As": { // Assassine
"Alltag": 20,
"Freiland": 20,
"Halbwelt": 20,
"Kampf": 30,
"Körper": 10,
"Sozial": 20,
"Unterwelt": 10,
"Waffen": 20,
"Wissen": 20,
},
"Bb": { // Barbar
"Alltag": 20,
"Freiland": 10,
"Halbwelt": 30,
"Kampf": 10,
"Körper": 10,
"Sozial": 30,
"Unterwelt": 30,
"Waffen": 20,
"Wissen": 40,
},
"Gl": { // Glücksritter
"Alltag": 20,
"Freiland": 30,
"Halbwelt": 10,
"Kampf": 20,
"Körper": 30,
"Sozial": 10,
"Unterwelt": 30,
"Waffen": 20,
"Wissen": 20,
},
"Hä": { // Händler
"Alltag": 10,
"Freiland": 20,
"Halbwelt": 20,
"Kampf": 20,
"Körper": 20,
"Sozial": 10,
"Unterwelt": 40,
"Waffen": 20,
"Wissen": 20,
},
"Kr": { // Krieger
"Alltag": 20,
"Freiland": 30,
"Halbwelt": 30,
"Kampf": 10,
"Körper": 20,
"Sozial": 20,
"Unterwelt": 30,
"Waffen": 10,
"Wissen": 40,
},
"Sp": { // Spitzbube
"Alltag": 20,
"Freiland": 30,
"Halbwelt": 10,
"Kampf": 40,
"Körper": 10,
"Sozial": 10,
"Unterwelt": 10,
"Waffen": 20,
"Wissen": 30,
},
"Wa": { // Waldläufer
"Alltag": 20,
"Freiland": 10,
"Halbwelt": 20,
"Kampf": 20,
"Körper": 10,
"Sozial": 30,
"Unterwelt": 30,
"Waffen": 20,
"Wissen": 30,
},
"Ba": { // Barde
"Alltag": 10,
"Freiland": 20,
"Halbwelt": 20,
"Kampf": 40,
"Körper": 20,
"Sozial": 30,
"Unterwelt": 40,
"Waffen": 40,
"Wissen": 10,
},
"Or": { // Ordenskrieger
"Alltag": 20,
"Freiland": 30,
"Halbwelt": 40,
"Kampf": 10,
"Körper": 20,
"Sozial": 20,
"Unterwelt": 40,
"Waffen": 10,
"Wissen": 20,
},
"Dr": { // Druide
"Alltag": 20,
"Freiland": 10,
"Halbwelt": 30,
"Kampf": 40,
"Körper": 20,
"Sozial": 30,
"Unterwelt": 40,
"Waffen": 40,
"Wissen": 10,
},
"Hx": { // Hexer
"Alltag": 20,
"Freiland": 20,
"Halbwelt": 30,
"Kampf": 40,
"Körper": 30,
"Sozial": 20,
"Unterwelt": 30,
"Waffen": 40,
"Wissen": 20,
},
"Ma": { // Magier
"Alltag": 20,
"Freiland": 30,
"Halbwelt": 40,
"Kampf": 40,
"Körper": 30,
"Sozial": 30,
"Unterwelt": 40,
"Waffen": 40,
"Wissen": 10,
},
"PB": { // Priester Beschützer
"Alltag": 20,
"Freiland": 30,
"Halbwelt": 30,
"Kampf": 40,
"Körper": 30,
"Sozial": 10,
"Unterwelt": 40,
"Waffen": 40,
"Wissen": 20,
},
"PS": { // Priester Streiter
"Alltag": 20,
"Freiland": 30,
"Halbwelt": 40,
"Kampf": 30,
"Körper": 30,
"Sozial": 30,
"Unterwelt": 40,
"Waffen": 30,
"Wissen": 20,
},
"Sc": { // Schamane
"Alltag": 20,
"Freiland": 10,
"Halbwelt": 40,
"Kampf": 40,
"Körper": 20,
"Sozial": 20,
"Unterwelt": 40,
"Waffen": 40,
"Wissen": 20,
},
},
// EP-Kosten für 1 Lerneinheit (LE) für Zauber pro Charakterklasse und Zauberschule
SpellEPPerLE: map[string]map[string]int{
"Dr": { // Druide
"Beherrschen": 90,
"Bewegen": 60,
"Erkennen": 120,
"Erschaffen": 90,
"Formen": 60,
"Verändern": 90,
"Zerstören": 120,
"Wunder": 0, // Nicht verfügbar
"Dweomer": 30,
"Lied": 0, // Nicht verfügbar
},
"Hx": { // Hexer
"Beherrschen": 30,
"Bewegen": 90,
"Erkennen": 90,
"Erschaffen": 90,
"Formen": 60,
"Verändern": 30,
"Zerstören": 60,
"Wunder": 0, // Nicht verfügbar
"Dweomer": 90,
"Lied": 0, // Nicht verfügbar
},
"Ma": { // Magier (* = Spezialgebiet für 30 EP)
"Beherrschen": 60, // *30
"Bewegen": 60, // *30
"Erkennen": 60, // *30
"Erschaffen": 60, // *30
"Formen": 60, // *30
"Verändern": 60, // *30
"Zerstören": 60, // *30
"Wunder": 0, // Nicht verfügbar
"Dweomer": 120,
"Lied": 0, // Nicht verfügbar
},
"PB": { // Priester Beschützer
"Beherrschen": 90,
"Bewegen": 90,
"Erkennen": 60,
"Erschaffen": 90,
"Formen": 90,
"Verändern": 90,
"Zerstören": 90,
"Wunder": 30,
"Dweomer": 120,
"Lied": 0, // Nicht verfügbar
},
"PS": { // Priester Streiter
"Beherrschen": 90,
"Bewegen": 90,
"Erkennen": 90,
"Erschaffen": 90,
"Formen": 90,
"Verändern": 90,
"Zerstören": 60,
"Wunder": 30,
"Dweomer": 120,
"Lied": 0, // Nicht verfügbar
},
"Sc": { // Schamane
"Beherrschen": 90,
"Bewegen": 90,
"Erkennen": 60,
"Erschaffen": 60,
"Formen": 90,
"Verändern": 90,
"Zerstören": 90,
"Wunder": 30,
"Dweomer": 120,
"Lied": 0, // Nicht verfügbar
},
"Ba": { // Barde
"Beherrschen": 0, // Nicht verfügbar
"Bewegen": 0, // Nicht verfügbar
"Erkennen": 0, // Nicht verfügbar
"Erschaffen": 0, // Nicht verfügbar
"Formen": 0, // Nicht verfügbar
"Verändern": 0, // Nicht verfügbar
"Zerstören": 0, // Nicht verfügbar
"Wunder": 0, // Nicht verfügbar
"Dweomer": 0, // Nicht verfügbar
"Lied": 30,
},
},
// Lernen von Zaubern
// LE pro Stufe des Zaubers
SpellLEPerLevel: map[int]int{1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 10, 7: 15, 8: 20, 9: 30, 10: 40, 11: 60, 12: 90},
// TE-Kosten für Verbesserungen basierend auf Kategorie, Schwierigkeit und aktuellem Wert
ImprovementCost: map[string]map[string]DifficultyData{
"Alltag": {
"leicht": DifficultyData{
LearnCost: 1,
Skills: []string{"Klettern", "Reiten", "Seilkunst", "Bootfahren", "Glücksspiel", "Wagenlenken", "Musizieren"},
TrainCosts: map[int]int{9: 0, 10: 0, 11: 0, 12: 0, 13: 1, 14: 2, 15: 5, 16: 10, 17: 10, 18: 20},
},
"normal": DifficultyData{
LearnCost: 1,
Skills: []string{"Schreiben", "Sprache"},
TrainCosts: map[int]int{9: 1, 10: 1, 11: 1, 12: 1, 13: 2, 14: 2, 15: 5, 16: 10, 17: 10, 18: 20},
},
"schwer": DifficultyData{
LearnCost: 2,
Skills: []string{"Erste Hilfe", "Etikette"},
TrainCosts: map[int]int{9: 2, 10: 2, 11: 5, 12: 5, 13: 10, 14: 10, 15: 20, 16: 20, 17: 50, 18: 50},
},
"sehr schwer": DifficultyData{
LearnCost: 10,
Skills: []string{"Gerätekunde", "Geschäftssinn"},
TrainCosts: map[int]int{9: 5, 10: 5, 11: 10, 12: 10, 13: 20, 14: 20, 15: 50, 16: 50, 17: 100, 18: 100},
},
},
"Freiland": {
"leicht": DifficultyData{
LearnCost: 1,
Skills: []string{"Überleben"},
TrainCosts: map[int]int{9: 1, 10: 1, 11: 1, 12: 2, 13: 2, 14: 2, 15: 5, 16: 5, 17: 10, 18: 10},
},
"normal": DifficultyData{
LearnCost: 2,
Skills: []string{"Naturkunde", "Pflanzenkunde", "Tierkunde"},
TrainCosts: map[int]int{9: 2, 10: 5, 11: 5, 12: 10, 13: 10, 14: 20, 15: 20, 16: 20, 17: 50, 18: 50},
},
"schwer": DifficultyData{
LearnCost: 4,
Skills: []string{"Schleichen", "Spurensuche", "Tarnen"},
TrainCosts: map[int]int{9: 5, 10: 5, 11: 10, 12: 10, 13: 20, 14: 20, 15: 50, 16: 50, 17: 100, 18: 100},
},
},
"Halbwelt": {
"leicht": DifficultyData{
LearnCost: 1,
Skills: []string{"Klettern", "Glücksspiel", "Balancieren"},
TrainCosts: map[int]int{9: 0, 10: 0, 11: 0, 12: 0, 13: 1, 14: 2, 15: 5, 16: 10, 17: 10, 18: 20},
},
"normal": DifficultyData{
LearnCost: 2,
Skills: []string{"Akrobatik"},
TrainCosts: map[int]int{9: 2, 10: 2, 11: 5, 12: 5, 13: 10, 14: 10, 15: 20, 16: 20, 17: 50, 18: 50},
},
"schwer": DifficultyData{
LearnCost: 2,
Skills: []string{"Gassenwissen", "Stehlen"},
TrainCosts: map[int]int{9: 2, 10: 5, 11: 5, 12: 10, 13: 10, 14: 20, 15: 20, 16: 50, 17: 50, 18: 50},
},
"sehr schwer": DifficultyData{
LearnCost: 10,
Skills: []string{"Betäuben"},
TrainCosts: map[int]int{9: 5, 10: 10, 11: 20, 12: 20, 13: 30, 14: 50, 15: 80, 16: 80, 17: 100, 18: 100},
},
},
"Kampf": {
"leicht": DifficultyData{
LearnCost: 1,
Skills: []string{"Reiten"},
TrainCosts: map[int]int{6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 1, 14: 2, 15: 5, 16: 10, 17: 10, 18: 20},
},
"normal": DifficultyData{
LearnCost: 2,
Skills: []string{"Anführen", "Athletik"},
TrainCosts: map[int]int{6: 0, 7: 0, 8: 0, 9: 2, 10: 2, 11: 5, 12: 5, 13: 10, 14: 10, 15: 20, 16: 20, 17: 50, 18: 50},
},
"schwer": DifficultyData{
LearnCost: 10,
Skills: []string{"Betäuben"},
TrainCosts: map[int]int{6: 0, 7: 0, 8: 0, 9: 5, 10: 10, 11: 20, 12: 20, 13: 30, 14: 50, 15: 80, 16: 80, 17: 100, 18: 100},
},
"sehr schwer": DifficultyData{
LearnCost: 10,
Skills: []string{},
TrainCosts: map[int]int{6: 2, 7: 5, 8: 10, 9: 10, 10: 20, 11: 20, 12: 30, 13: 50, 14: 50, 15: 100, 16: 100, 17: 150, 18: 200},
},
},
"Körper": {
"leicht": DifficultyData{
LearnCost: 1,
Skills: []string{"Geländelauf", "Klettern", "Schwimmen", "Balancieren"},
TrainCosts: map[int]int{9: 0, 10: 0, 11: 0, 12: 0, 13: 1, 14: 2, 15: 5, 16: 10, 17: 10, 18: 20},
},
"normal": DifficultyData{
LearnCost: 1,
Skills: []string{"Tauchen"},
TrainCosts: map[int]int{9: 1, 10: 1, 11: 2, 12: 2, 13: 5, 14: 10, 15: 10, 16: 20, 17: 20, 18: 50},
},
"schwer": DifficultyData{
LearnCost: 2,
Skills: []string{"Akrobatik", "Athletik", "Laufen", "Meditieren"},
TrainCosts: map[int]int{9: 2, 10: 2, 11: 5, 12: 5, 13: 10, 14: 10, 15: 20, 16: 20, 17: 50, 18: 50},
},
},
"Sozial": {
"leicht": DifficultyData{
LearnCost: 1,
Skills: []string{"Anführen", "Verführen", "Verstellen", "Etikette"},
TrainCosts: map[int]int{9: 2, 10: 2, 11: 5, 12: 5, 13: 10, 14: 10, 15: 20, 16: 20, 17: 50, 18: 50},
},
"normal": DifficultyData{
LearnCost: 2,
Skills: []string{"Gassenwissen", "Beredsamkeit", "Verhören"},
TrainCosts: map[int]int{9: 2, 10: 5, 11: 5, 12: 10, 13: 10, 14: 20, 15: 20, 16: 50, 17: 50, 18: 50},
},
"schwer": DifficultyData{
LearnCost: 4,
Skills: []string{"Menschenkenntnis"},
TrainCosts: map[int]int{9: 5, 10: 5, 11: 10, 12: 10, 13: 20, 14: 20, 15: 50, 16: 50, 17: 100, 18: 100},
},
},
"Unterwelt": {
"leicht": DifficultyData{
LearnCost: 2,
Skills: []string{"Gassenwissen", "Stehlen"},
TrainCosts: map[int]int{9: 2, 10: 5, 11: 5, 12: 10, 13: 10, 14: 20, 15: 20, 16: 50, 17: 50, 18: 50},
},
"normal": DifficultyData{
LearnCost: 4,
Skills: []string{"Schleichen", "Spurensuche", "Tarnen", "Fallen entdecken", "Schlösser öffnen"},
TrainCosts: map[int]int{9: 5, 10: 5, 11: 10, 12: 10, 13: 20, 14: 20, 15: 50, 16: 50, 17: 100, 18: 100},
},
"schwer": DifficultyData{
LearnCost: 10,
Skills: []string{"Fallenmechanik", "Meucheln", "Menschenkenntnis"},
TrainCosts: map[int]int{9: 5, 10: 10, 11: 20, 12: 20, 13: 30, 14: 50, 15: 80, 16: 80, 17: 100, 18: 100},
},
},
"Waffen": {
"leicht": DifficultyData{
LearnCost: 2,
Skills: []string{"Stichwaffen"},
TrainCosts: map[int]int{6: 1, 7: 1, 8: 1, 9: 2, 10: 2, 11: 5, 12: 10, 13: 20, 14: 50, 15: 100, 16: 100, 17: 150, 18: 150},
},
"normal": DifficultyData{
LearnCost: 4,
Skills: []string{"Einhandschlagwaffen"},
TrainCosts: map[int]int{6: 1, 7: 1, 8: 2, 9: 2, 10: 5, 11: 10, 12: 20, 13: 50, 14: 50, 15: 100, 16: 150, 17: 150, 18: 200},
},
"schwer": DifficultyData{
LearnCost: 6,
Skills: []string{"Zweihandschlagwaffen"},
TrainCosts: map[int]int{6: 1, 7: 2, 8: 2, 9: 5, 10: 5, 11: 10, 12: 20, 13: 50, 14: 100, 15: 150, 16: 200, 17: 300, 18: 300},
},
"sehr schwer": DifficultyData{
LearnCost: 8,
Skills: []string{},
TrainCosts: map[int]int{6: 1, 7: 2, 8: 2, 9: 5, 10: 10, 11: 20, 12: 50, 13: 100, 14: 150, 15: 200, 16: 300, 17: 300, 18: 400},
},
},
"Wissen": {
"leicht": DifficultyData{
LearnCost: 1,
Skills: []string{"Lesen von Zauberschrift", "Schreiben", "Sprache"},
TrainCosts: map[int]int{9: 1, 10: 1, 11: 1, 12: 1, 13: 2, 14: 2, 15: 5, 16: 10, 17: 10, 18: 20},
},
"normal": DifficultyData{
LearnCost: 2,
Skills: []string{"Erste Hilfe", "Meditieren"},
TrainCosts: map[int]int{9: 2, 10: 2, 11: 5, 12: 5, 13: 10, 14: 10, 15: 20, 16: 20, 17: 50, 18: 50},
},
"schwer": DifficultyData{
LearnCost: 2,
Skills: []string{"Alchimie", "Heilkunde", "Landeskunde", "Zauberkunde", "Naturkunde", "Pflanzenkunde", "Tierkunde"},
TrainCosts: map[int]int{9: 2, 10: 5, 11: 5, 12: 10, 13: 10, 14: 20, 15: 20, 16: 20, 17: 50, 18: 50},
},
},
"Schilde und Parierwaffen": {
"normal": DifficultyData{
LearnCost: 0, // Not defined in BaseLearnCost, using 0 as default
Skills: []string{},
TrainCosts: map[int]int{2: 1, 3: 2, 4: 10, 5: 30, 6: 50, 7: 100, 8: 150},
},
},
},
}
func GetSkillCategory(skillName string) string {
for category, difficulties := range learningCostsData.ImprovementCost {
for _, data := range difficulties {
if contains(data.Skills, skillName) {
return category
}
}
}
return "Unbekannt"
}
func GetSkillDifficulty(category string, skillName string) string {
// Wenn eine Kategorie angegeben ist, suche nur in dieser Kategorie
if category != "" {
difficulties, ok := learningCostsData.ImprovementCost[category]
if !ok {
return "Unbekannt" // Kategorie nicht gefunden
}
for difficulty, data := range difficulties {
if contains(data.Skills, skillName) {
return difficulty
}
}
return "Unbekannt" // Skill in der angegebenen Kategorie nicht gefunden
}
// Wenn keine Kategorie angegeben ist, durchsuche alle Kategorien und gib das erste Vorkommen zurück
for _, difficulties := range learningCostsData.ImprovementCost {
for difficulty, data := range difficulties {
if contains(data.Skills, skillName) {
return difficulty
}
}
}
return "Unbekannt"
}
// contains checks if a slice contains a specific string
func contains(slice []string, item string) bool {
for _, s := range slice {
if s == item {
return true
}
}
return false
}
//### End of Helper functions ###
// GetSpellInfo returns the school and level of a spell from the database
func GetSpellInfo(spellName string) (string, int, error) {
// Create a Spell instance to search in the database
var spell Spell
// Search for the spell in the database
err := spell.First(spellName)
if err != nil {
return "", 0, fmt.Errorf("spell '%s' not found in database: %w", spellName, err)
}
return spell.Category, spell.Stufe, nil
}
// GetSpecialization returns the specialization school for a character (placeholder)
// This should be implemented to get the actual specialization from character data
func GetSpecialization(characterID string) string {
// TODO: Implement actual character specialization lookup
// For now, return a default specialization
return "Beherrschen"
}
// findBestCategoryForSkillImprovement findet die Kategorie mit den niedrigsten EP-Kosten für eine Fertigkeit
func findBestCategoryForSkillImprovement(skillName, characterClass string, level int) (string, string, error) {
classKey := characterClass
// Sammle alle Kategorien und Schwierigkeiten, in denen die Fertigkeit verfügbar ist
type categoryOption struct {
category string
difficulty string
epCost int
}
var options []categoryOption
for category, difficulties := range learningCostsData.ImprovementCost {
for difficulty, data := range difficulties {
if contains(data.Skills, skillName) {
// Prüfe ob EP-Kosten für diese Kategorie und Klasse existieren
epPerTE, exists := learningCostsData.EPPerTE[classKey][category]
if exists {
// Hole die Trainingskosten für level
trainCost, hasCost := data.TrainCosts[level]
if hasCost {
totalEP := epPerTE * trainCost
options = append(options, categoryOption{
category: category,
difficulty: difficulty,
epCost: totalEP,
})
}
}
}
}
}
if len(options) == 0 {
return "", "", fmt.Errorf("keine verfügbare Kategorie für Fertigkeit '%s' und Klasse '%s' auf Level %d gefunden", skillName, characterClass, level)
}
// Finde die Option mit den niedrigsten EP-Kosten
bestOption := options[0]
for _, option := range options[1:] {
if option.epCost < bestOption.epCost {
bestOption = option
}
}
return bestOption.category, bestOption.difficulty, nil
}
// findBestCategoryForSkillLearning findet die Kategorie mit den niedrigsten EP-Kosten für das Lernen einer Fertigkeit
func findBestCategoryForSkillLearning(skillName, characterClass string) (string, string, error) {
classKey := characterClass
// Sammle alle Kategorien und Schwierigkeiten, in denen die Fertigkeit verfügbar ist
type categoryOption struct {
category string
difficulty string
epCost int
}
var options []categoryOption
for category, difficulties := range learningCostsData.ImprovementCost {
for difficulty, data := range difficulties {
if contains(data.Skills, skillName) {
// Prüfe ob EP-Kosten für diese Kategorie und Klasse existieren
epPerTE, exists := learningCostsData.EPPerTE[classKey][category]
if exists {
// Für das Lernen verwenden wir LearnCost * 3
learnCost := data.LearnCost
totalEP := epPerTE * learnCost * 3
options = append(options, categoryOption{
category: category,
difficulty: difficulty,
epCost: totalEP,
})
}
}
}
}
if len(options) == 0 {
return "", "", fmt.Errorf("keine verfügbare Kategorie für Fertigkeit '%s' und Klasse '%s' gefunden", skillName, characterClass)
}
// Finde die Option mit den niedrigsten EP-Kosten
bestOption := options[0]
for _, option := range options[1:] {
if option.epCost < bestOption.epCost {
bestOption = option
}
}
return bestOption.category, bestOption.difficulty, nil
}
func CalcSkillLernCost(costResult *SkillCostResultNew, reward *string) error {
// Berechne die Lernkosten basierend auf den aktuellen Werten im costResult
// Hier sollte die Logik zur Berechnung der Lernkosten implementiert werden
//Finde EP kosten für die Kategorie für die Charakterklasse aus learningCostsData.EPPerTE
// Konvertiere Vollnamen der Charakterklasse zu Abkürzungen falls nötig
//classKey := getClassAbbreviation(costResult.CharacterClass)
classKey := costResult.CharacterClass
// Wenn Kategorie und Schwierigkeit noch nicht gesetzt sind, finde die beste Option
if costResult.Category == "" || costResult.Difficulty == "" {
bestCategory, bestDifficulty, err := findBestCategoryForSkillLearning(costResult.SkillName, classKey)
if err != nil {
return err
}
costResult.Category = bestCategory
costResult.Difficulty = bestDifficulty
}
epPerTE, ok := learningCostsData.EPPerTE[classKey][costResult.Category]
if !ok {
return fmt.Errorf("EP-Kosten für Kategorie '%s' und Klasse '%s' nicht gefunden", costResult.Category, costResult.CharacterClass)
}
// finde LE für den Skill aufgrund der Kategorie und schwierigkeit aus DifficultyData
learnCost, ok := learningCostsData.ImprovementCost[costResult.Category][costResult.Difficulty]
if !ok {
return fmt.Errorf("Lernkosten für Kategorie '%s' und Schwierigkeit '%s' nicht gefunden", costResult.Category, costResult.Difficulty)
}
costResult.LE = learnCost.LearnCost
costResult.EP = epPerTE * costResult.LE * 3
costResult.GoldCost = costResult.LE * 200 // Beispiel: 200 Gold pro LE
// Apply reward logic
if reward != nil {
switch *reward {
case "noGold":
costResult.GoldCost = 0 // Keine Goldkosten für diese Belohnung
case "halveep":
costResult.EP = costResult.EP / 2 // Halbe EP-Kosten
costResult.GoldCost = 0 // Keine Goldkosten bei halven EP
case "halveepnoGold":
costResult.GoldCost = 0 // Keine Goldkosten für diese Belohnung
costResult.EP = costResult.EP / 2 // Halbe EP-Kosten
case "default":
// Keine Änderungen, normale Kosten
}
}
return nil
}
// CalcSkillImproveCost berechnet die Kosten für die Verbesserung einer Fertigkeit
func CalcSkillImproveCost(costResult *SkillCostResultNew, currentLevel int, reward *string) error {
// Für Skill-Verbesserung könnten die Kosten vom aktuellen Level abhängen
//Finde EP kosten für die Kategorie für die Charakterklasse aus learningCostsData.EPPerTE
//classKey := getClassAbbreviation(costResult.CharacterClass)
classKey := costResult.CharacterClass
if costResult.TargetLevel > 0 {
currentLevel = costResult.TargetLevel - 1 // Wenn ein Ziellevel angegeben ist, verwende dieses
}
// Wenn Kategorie und Schwierigkeit noch nicht gesetzt sind, finde die beste Option
if costResult.Category == "" || costResult.Difficulty == "" {
bestCategory, bestDifficulty, err := findBestCategoryForSkillImprovement(costResult.SkillName, classKey, currentLevel+1)
if err != nil {
return err
}
costResult.Category = bestCategory
costResult.Difficulty = bestDifficulty
}
epPerTE, ok := learningCostsData.EPPerTE[classKey][costResult.Category]
if !ok {
return fmt.Errorf("EP-Kosten für Kategorie '%s' und Klasse '%s' nicht gefunden", costResult.Category, costResult.CharacterClass)
}
diffData := learningCostsData.ImprovementCost[costResult.Category][costResult.Difficulty]
trainCost := diffData.TrainCosts[currentLevel+1]
if trainCost < costResult.PPUsed {
costResult.PPUsed = trainCost //maximal so viele PP verwenden wie TE benötigt werden
trainCost = 0 // Wenn PP verwendet werden, setze die Kosten auf
} else if costResult.PPUsed > 0 {
trainCost -= costResult.PPUsed // Wenn PP verwendet werden, setze die Kosten auf die PP
}
// Apply reward logic
costResult.LE = trainCost
costResult.EP = epPerTE * trainCost
costResult.GoldCost = trainCost * 20 // Beispiel: 20 Gold pro TE
if reward != nil && *reward == "halveep" {
costResult.EP = costResult.EP / 2 // Halbiere die EP-Kosten für diese Belohnung
}
if reward != nil && *reward == "halveepnoGold" {
costResult.GoldCost = 0 // Keine Goldkosten für diese Belohnung
costResult.EP = costResult.EP / 2 // Halbiere die EP-Kosten für diese Belohnung
}
if costResult.GoldUsed > 0 {
// 10 Gold = 1 EP
epFromGold := costResult.GoldUsed / 10
if epFromGold > costResult.EP {
// Maximal so viel Gold verwenden wie EP benötigt werden
costResult.GoldUsed = costResult.EP * 10
costResult.EP = 0
} else {
// Reduziere EP um die Menge, die durch Gold ersetzt wird
costResult.EP -= epFromGold
}
}
return nil
}
// CalcSpellLernCost berechnet die Kosten für das Erlernen eines Zaubers
func CalcSpellLernCost(costResult *SkillCostResultNew, reward *string) error {
// Für Zauber verwenden wir eine ähnliche Logik wie für Skills
// TODO: Implementiere spezifische Zauber-Kostenlogik wenn verfügbar
classKey := costResult.CharacterClass
spellCategory, spellLevel, err := GetSpellInfo(costResult.SkillName)
if err != nil {
return fmt.Errorf("failed to get spell info: %w", err)
}
SpellEPPerLE, ok := learningCostsData.SpellEPPerLE[classKey][spellCategory]
if !ok {
return fmt.Errorf("EP-Kosten für Zauber '%s' und Klasse '%s' nicht gefunden", costResult.SkillName, classKey)
}
if classKey == "Ma" {
spezialgebiet := GetSpecialization(costResult.CharacterID)
if spellCategory == spezialgebiet {
SpellEPPerLE = 30 // Spezialgebiet für Magier
}
}
trainCost := learningCostsData.SpellLEPerLevel[spellLevel] // LE pro Stufe des Zaubers
if costResult.PPUsed > 0 {
trainCost -= costResult.PPUsed // Wenn PP verwendet werden, reduziere die LE-Kosten
if trainCost < 0 {
trainCost = 0 // Verhindere negative LE-Kosten
}
}
costResult.LE = trainCost // Setze die LE-Kosten
costResult.EP = trainCost * SpellEPPerLE // EP-Kosten für das Lernen des Zaubers
costResult.GoldCost = trainCost * 100 // Beispiel: 100 Gold pro LE
costResult.Category = spellCategory
costResult.Difficulty = fmt.Sprintf("Stufe %d", spellLevel) // Zauber haben keine Schwierigkeit, sondern eine Stufe
if reward != nil && *reward == "spruchrolle" {
costResult.GoldCost = 20 // 20 Gold für Jeden Versuch
costResult.EP = costResult.EP / 3 // 1/3 EP-Kosten bei Erfolg
} else {
if reward != nil && *reward == "halveep" {
costResult.EP = costResult.EP / 2 // Halbiere die EP-Kosten für diese Belohnung
}
if reward != nil && *reward == "halveepnoGold" {
costResult.EP = costResult.EP / 2 // Halbiere die EP-Kosten für diese Belohnung
costResult.GoldCost = 0 // Keine Goldkosten für diese Belohnung
}
}
return nil
}
func GetLernCostNextLevel(request *LernCostRequest, costResult *SkillCostResultNew, reward *string, level int, characterTyp string) error {
// Diese Funktion berechnet die Kosten für das Erlernen oder Verbessern einer Fertigkeit oder eines Zaubers
// abhängig von der Aktion (learn/improve) und der Belohnung.
// die Berechnung erfolgt immer für genau 1 Level
// Diese Funktion wird in GetLernCost aufgerufen.
// Übertrage PP und Gold aus dem Request für die Kostenberechnung
costResult.PPUsed = request.UsePP
costResult.GoldUsed = request.UseGold
switch {
case request.Action == "learn" && request.Type == "skill":
err := CalcSkillLernCost(costResult, request.Reward)
if err != nil {
return fmt.Errorf("fehler bei der Kostenberechnung: %w", err)
}
// extrakosten für elfen
if characterTyp == "Elf" {
costResult.EP += 6
}
case request.Action == "learn" && request.Type == "spell":
err := CalcSpellLernCost(costResult, request.Reward)
if err != nil {
return fmt.Errorf("fehler bei der Kostenberechnung: %w", err)
}
// extrakosten für elfen
if characterTyp == "Elf" {
costResult.EP += 6
}
case request.Action == "improve" && request.Type == "skill":
err := CalcSkillImproveCost(costResult, request.CurrentLevel, request.Reward)
if err != nil {
return fmt.Errorf("fehler bei der Kostenberechnung: %w", err)
}
default:
}
return nil
}