2025-07-24 07:39:43 +02:00
|
|
|
package character
|
|
|
|
|
|
|
|
|
|
import (
|
2026-04-15 21:50:18 +02:00
|
|
|
"bamort/bmrt/models"
|
2026-05-01 14:38:49 +02:00
|
|
|
"bamort/database"
|
2025-07-25 09:32:44 +02:00
|
|
|
"fmt"
|
2025-07-24 07:39:43 +02:00
|
|
|
"net/http"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// PracticePointResponse repräsentiert die Antwort für Praxispunkte einer Fertigkeit
|
|
|
|
|
type PracticePointResponse struct {
|
|
|
|
|
SkillName string `json:"skill_name"`
|
|
|
|
|
Amount int `json:"amount"`
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 09:32:44 +02:00
|
|
|
// PracticePointActionResponse repräsentiert die erweiterte Antwort für PP-Aktionen
|
|
|
|
|
type PracticePointActionResponse struct {
|
|
|
|
|
Success bool `json:"success"`
|
|
|
|
|
Message string `json:"message"`
|
|
|
|
|
RequestedSkill string `json:"requested_skill"` // Ursprünglich angefragter Name
|
|
|
|
|
TargetSkill string `json:"target_skill"` // Tatsächlich betroffene Fertigkeit
|
|
|
|
|
IsSpell bool `json:"is_spell"` // Ob es sich um einen Zauber handelt
|
|
|
|
|
PracticePoints []PracticePointResponse `json:"practice_points"` // Aktuelle PP-Liste
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-24 07:39:43 +02:00
|
|
|
// GetPracticePoints gibt die verfügbaren Praxispunkte eines Charakters zurück
|
|
|
|
|
func GetPracticePoints(c *gin.Context) {
|
|
|
|
|
// Charakter-ID aus der URL abrufen
|
|
|
|
|
charID := c.Param("id")
|
|
|
|
|
|
|
|
|
|
// Charakter aus der Datenbank laden
|
2025-07-28 21:35:29 +02:00
|
|
|
var character models.Char
|
2025-07-24 07:39:43 +02:00
|
|
|
if err := character.FirstID(charID); err != nil {
|
|
|
|
|
respondWithError(c, http.StatusNotFound, "Charakter nicht gefunden")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Praxispunkte aus den Fertigkeiten extrahieren
|
|
|
|
|
var practicePoints []PracticePointResponse
|
|
|
|
|
for _, skill := range character.Fertigkeiten {
|
|
|
|
|
if skill.Pp > 0 {
|
|
|
|
|
practicePoints = append(practicePoints, PracticePointResponse{
|
|
|
|
|
SkillName: skill.Name,
|
|
|
|
|
Amount: skill.Pp,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, practicePoints)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UpdatePracticePoints aktualisiert die Praxispunkte eines Charakters
|
|
|
|
|
func UpdatePracticePoints(c *gin.Context) {
|
|
|
|
|
// Charakter-ID aus der URL abrufen
|
|
|
|
|
charID := c.Param("id")
|
|
|
|
|
|
|
|
|
|
// Charakter aus der Datenbank laden
|
2025-07-28 21:35:29 +02:00
|
|
|
var character models.Char
|
2025-07-24 07:39:43 +02:00
|
|
|
if err := character.FirstID(charID); err != nil {
|
|
|
|
|
respondWithError(c, http.StatusNotFound, "Charakter nicht gefunden")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-01 22:48:07 +01:00
|
|
|
// Check ownership
|
|
|
|
|
if !checkCharacterOwnership(c, &character) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-24 07:39:43 +02:00
|
|
|
// Request-Parameter abrufen
|
|
|
|
|
var practicePoints []PracticePointResponse
|
|
|
|
|
if err := c.ShouldBindJSON(&practicePoints); err != nil {
|
|
|
|
|
respondWithError(c, http.StatusBadRequest, "Ungültige Praxispunkt-Daten: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Alle Fertigkeiten durchgehen und Praxispunkte zurücksetzen
|
2025-08-01 07:19:02 +02:00
|
|
|
/*
|
|
|
|
|
for i := range character.Fertigkeiten {
|
|
|
|
|
character.Fertigkeiten[i].Pp = 0
|
|
|
|
|
}
|
|
|
|
|
*/
|
2025-07-24 07:39:43 +02:00
|
|
|
|
|
|
|
|
// Neue Praxispunkte setzen
|
|
|
|
|
for _, pp := range practicePoints {
|
|
|
|
|
for i := range character.Fertigkeiten {
|
|
|
|
|
if character.Fertigkeiten[i].Name == pp.SkillName {
|
|
|
|
|
character.Fertigkeiten[i].Pp = pp.Amount
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Charakter in der Datenbank speichern
|
|
|
|
|
if err := database.DB.Save(&character).Error; err != nil {
|
|
|
|
|
respondWithError(c, http.StatusInternalServerError, "Fehler beim Speichern der Praxispunkte: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Aktualisierte Praxispunkte zurückgeben
|
|
|
|
|
var updatedPracticePoints []PracticePointResponse
|
|
|
|
|
for _, skill := range character.Fertigkeiten {
|
|
|
|
|
if skill.Pp > 0 {
|
|
|
|
|
updatedPracticePoints = append(updatedPracticePoints, PracticePointResponse{
|
|
|
|
|
SkillName: skill.Name,
|
|
|
|
|
Amount: skill.Pp,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, updatedPracticePoints)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AddPracticePoint fügt einen Praxispunkt zu einer Fertigkeit hinzu
|
2025-08-01 07:19:02 +02:00
|
|
|
// TODO prüfe speichern der PP für Spells
|
2025-07-24 07:39:43 +02:00
|
|
|
func AddPracticePoint(c *gin.Context) {
|
|
|
|
|
// Charakter-ID aus der URL abrufen
|
|
|
|
|
charID := c.Param("id")
|
|
|
|
|
|
|
|
|
|
// Charakter aus der Datenbank laden
|
2025-07-28 21:35:29 +02:00
|
|
|
var character models.Char
|
2025-07-24 07:39:43 +02:00
|
|
|
if err := character.FirstID(charID); err != nil {
|
|
|
|
|
respondWithError(c, http.StatusNotFound, "Charakter nicht gefunden")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-01 22:48:07 +01:00
|
|
|
// Check ownership
|
|
|
|
|
if !checkCharacterOwnership(c, &character) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-24 07:39:43 +02:00
|
|
|
// Request-Parameter abrufen
|
|
|
|
|
type AddPPRequest struct {
|
|
|
|
|
SkillName string `json:"skill_name" binding:"required"`
|
|
|
|
|
Amount int `json:"amount"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var request AddPPRequest
|
|
|
|
|
if err := c.ShouldBindJSON(&request); err != nil {
|
|
|
|
|
respondWithError(c, http.StatusBadRequest, "Ungültige Anfrageparameter: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if request.Amount <= 0 {
|
|
|
|
|
request.Amount = 1
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 09:32:44 +02:00
|
|
|
// Prüfen, ob es sich um einen Zauber handelt
|
|
|
|
|
var targetSkillName string
|
|
|
|
|
var isSpellFlag bool
|
2025-08-01 07:19:02 +02:00
|
|
|
if isSpellNewSystem(request.SkillName) {
|
2025-07-25 09:32:44 +02:00
|
|
|
// Bei Zaubern: PP werden der entsprechenden Zaubergruppe zugeordnet
|
2025-08-01 07:19:02 +02:00
|
|
|
targetSkillName = getSpellCategoryNewSystem(request.SkillName)
|
2025-07-25 09:32:44 +02:00
|
|
|
isSpellFlag = true
|
|
|
|
|
} else {
|
|
|
|
|
// Bei normalen Fertigkeiten: PP werden direkt der Fertigkeit zugeordnet
|
|
|
|
|
targetSkillName = request.SkillName
|
|
|
|
|
isSpellFlag = false
|
|
|
|
|
}
|
2025-07-24 07:39:43 +02:00
|
|
|
|
|
|
|
|
// Praxispunkt zur entsprechenden Fertigkeit hinzufügen
|
2026-05-01 14:38:49 +02:00
|
|
|
foundSkill := false
|
2025-07-24 07:39:43 +02:00
|
|
|
for i := range character.Fertigkeiten {
|
|
|
|
|
if character.Fertigkeiten[i].Name == targetSkillName {
|
|
|
|
|
character.Fertigkeiten[i].Pp += request.Amount
|
2026-05-01 14:38:49 +02:00
|
|
|
foundSkill = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
foundWeaponSkill := false
|
|
|
|
|
for i := range character.Waffenfertigkeiten {
|
|
|
|
|
if character.Waffenfertigkeiten[i].Name == targetSkillName {
|
|
|
|
|
character.Waffenfertigkeiten[i].Pp += request.Amount
|
|
|
|
|
foundWeaponSkill = true
|
2025-07-24 07:39:43 +02:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-01 14:38:49 +02:00
|
|
|
if !foundSkill && !foundWeaponSkill {
|
2025-07-24 07:39:43 +02:00
|
|
|
respondWithError(c, http.StatusBadRequest, "Fertigkeit nicht gefunden: "+targetSkillName)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fertigkeiten explizit speichern
|
2026-05-01 14:38:49 +02:00
|
|
|
if foundSkill {
|
|
|
|
|
for i := range character.Fertigkeiten {
|
|
|
|
|
if character.Fertigkeiten[i].Name == targetSkillName {
|
|
|
|
|
if err := database.DB.Save(&character.Fertigkeiten[i]).Error; err != nil {
|
|
|
|
|
respondWithError(c, http.StatusInternalServerError, "Fehler beim Speichern der Fertigkeit: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if foundWeaponSkill {
|
|
|
|
|
for i := range character.Waffenfertigkeiten {
|
|
|
|
|
if character.Waffenfertigkeiten[i].Name == targetSkillName {
|
|
|
|
|
if err := database.DB.Save(&character.Waffenfertigkeiten[i]).Error; err != nil {
|
|
|
|
|
respondWithError(c, http.StatusInternalServerError, "Fehler beim Speichern der Waffenfertigkeit: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
break
|
2025-07-24 07:39:43 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 09:32:44 +02:00
|
|
|
// Aktualisierte Praxispunkte sammeln
|
2025-07-24 07:39:43 +02:00
|
|
|
var practicePoints []PracticePointResponse
|
|
|
|
|
for _, skill := range character.Fertigkeiten {
|
|
|
|
|
if skill.Pp > 0 {
|
|
|
|
|
practicePoints = append(practicePoints, PracticePointResponse{
|
|
|
|
|
SkillName: skill.Name,
|
|
|
|
|
Amount: skill.Pp,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-01 14:38:49 +02:00
|
|
|
for _, skill := range character.Waffenfertigkeiten {
|
|
|
|
|
if skill.Pp > 0 {
|
|
|
|
|
practicePoints = append(practicePoints, PracticePointResponse{
|
|
|
|
|
SkillName: skill.Name,
|
|
|
|
|
Amount: skill.Pp,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 09:32:44 +02:00
|
|
|
// Erfolgreiche Response mit Details zurückgeben
|
|
|
|
|
var message string
|
|
|
|
|
if isSpellFlag {
|
|
|
|
|
message = "Praxispunkt für Zauber '" + request.SkillName + "' wurde der Zaubergruppe '" + targetSkillName + "' hinzugefügt"
|
2026-05-01 14:38:49 +02:00
|
|
|
} else if foundSkill {
|
2025-07-25 09:32:44 +02:00
|
|
|
message = "Praxispunkt für Fertigkeit '" + targetSkillName + "' hinzugefügt"
|
2026-05-01 14:38:49 +02:00
|
|
|
} else if foundWeaponSkill {
|
|
|
|
|
message = "Praxispunkt für Waffenfertigkeit '" + targetSkillName + "' hinzugefügt"
|
2025-07-25 09:32:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
response := PracticePointActionResponse{
|
|
|
|
|
Success: true,
|
|
|
|
|
Message: message,
|
|
|
|
|
RequestedSkill: request.SkillName,
|
|
|
|
|
TargetSkill: targetSkillName,
|
|
|
|
|
IsSpell: isSpellFlag,
|
|
|
|
|
PracticePoints: practicePoints,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, response)
|
2025-07-24 07:39:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UsePracticePoint verbraucht Praxispunkte für eine spezifische Fertigkeit
|
|
|
|
|
func UsePracticePoint(c *gin.Context) {
|
|
|
|
|
// Charakter-ID aus der URL abrufen
|
|
|
|
|
charID := c.Param("id")
|
|
|
|
|
|
|
|
|
|
// Charakter aus der Datenbank laden
|
2025-07-28 21:35:29 +02:00
|
|
|
var character models.Char
|
2025-07-24 07:39:43 +02:00
|
|
|
if err := character.FirstID(charID); err != nil {
|
|
|
|
|
respondWithError(c, http.StatusNotFound, "Charakter nicht gefunden")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-01 22:48:07 +01:00
|
|
|
// Check ownership
|
|
|
|
|
if !checkCharacterOwnership(c, &character) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-24 07:39:43 +02:00
|
|
|
// Request-Parameter abrufen
|
|
|
|
|
type UsePPRequest struct {
|
|
|
|
|
SkillName string `json:"skill_name" binding:"required"`
|
|
|
|
|
Amount int `json:"amount"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var request UsePPRequest
|
|
|
|
|
if err := c.ShouldBindJSON(&request); err != nil {
|
|
|
|
|
respondWithError(c, http.StatusBadRequest, "Ungültige Anfrageparameter: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if request.Amount <= 0 {
|
|
|
|
|
request.Amount = 1
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 09:32:44 +02:00
|
|
|
// Prüfen, ob es sich um einen Zauber handelt
|
|
|
|
|
var targetSkillName string
|
|
|
|
|
var isSpellFlag bool
|
2025-08-01 07:19:02 +02:00
|
|
|
if isSpellNewSystem(request.SkillName) {
|
2025-07-25 09:32:44 +02:00
|
|
|
// Bei Zaubern: PP werden von der entsprechenden Zaubergruppe abgezogen
|
2025-08-01 07:19:02 +02:00
|
|
|
targetSkillName = getSpellCategoryNewSystem(request.SkillName)
|
2025-07-25 09:32:44 +02:00
|
|
|
isSpellFlag = true
|
|
|
|
|
} else {
|
|
|
|
|
// Bei normalen Fertigkeiten: PP werden direkt von der Fertigkeit abgezogen
|
|
|
|
|
targetSkillName = request.SkillName
|
|
|
|
|
isSpellFlag = false
|
|
|
|
|
}
|
2025-07-24 07:39:43 +02:00
|
|
|
|
|
|
|
|
// Praxispunkt von der entsprechenden Fertigkeit abziehen
|
2026-05-01 14:38:49 +02:00
|
|
|
foundSkill := false
|
2025-07-24 07:39:43 +02:00
|
|
|
for i := range character.Fertigkeiten {
|
|
|
|
|
if character.Fertigkeiten[i].Name == targetSkillName {
|
|
|
|
|
if character.Fertigkeiten[i].Pp >= request.Amount {
|
|
|
|
|
character.Fertigkeiten[i].Pp -= request.Amount
|
2026-05-01 14:38:49 +02:00
|
|
|
foundSkill = true
|
|
|
|
|
} else {
|
|
|
|
|
respondWithError(c, http.StatusBadRequest, "Nicht genügend Praxispunkte verfügbar")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
foundWeaponSkill := false
|
|
|
|
|
for i := range character.Waffenfertigkeiten {
|
|
|
|
|
if character.Waffenfertigkeiten[i].Name == targetSkillName {
|
|
|
|
|
if character.Waffenfertigkeiten[i].Pp >= request.Amount {
|
|
|
|
|
character.Waffenfertigkeiten[i].Pp -= request.Amount
|
|
|
|
|
foundWeaponSkill = true
|
2025-07-24 07:39:43 +02:00
|
|
|
} else {
|
|
|
|
|
respondWithError(c, http.StatusBadRequest, "Nicht genügend Praxispunkte verfügbar")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-01 14:38:49 +02:00
|
|
|
if !foundSkill && !foundWeaponSkill {
|
2025-07-24 07:39:43 +02:00
|
|
|
respondWithError(c, http.StatusBadRequest, "Fertigkeit nicht gefunden: "+targetSkillName)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fertigkeiten explizit speichern
|
2026-05-01 14:38:49 +02:00
|
|
|
if foundSkill {
|
|
|
|
|
for i := range character.Fertigkeiten {
|
|
|
|
|
if character.Fertigkeiten[i].Name == targetSkillName {
|
|
|
|
|
if err := database.DB.Save(&character.Fertigkeiten[i]).Error; err != nil {
|
|
|
|
|
respondWithError(c, http.StatusInternalServerError, "Fehler beim Speichern der Fertigkeit: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if foundWeaponSkill {
|
|
|
|
|
for i := range character.Waffenfertigkeiten {
|
|
|
|
|
if character.Waffenfertigkeiten[i].Name == targetSkillName {
|
|
|
|
|
if err := database.DB.Save(&character.Waffenfertigkeiten[i]).Error; err != nil {
|
|
|
|
|
respondWithError(c, http.StatusInternalServerError, "Fehler beim Speichern der Waffenfertigkeit: "+err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
break
|
2025-07-24 07:39:43 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 09:32:44 +02:00
|
|
|
// Erfolgreiche Antwort mit detaillierten Informationen und aktueller PP-Liste
|
2025-07-24 07:39:43 +02:00
|
|
|
var practicePoints []PracticePointResponse
|
|
|
|
|
for _, skill := range character.Fertigkeiten {
|
|
|
|
|
if skill.Pp > 0 {
|
|
|
|
|
practicePoints = append(practicePoints, PracticePointResponse{
|
|
|
|
|
SkillName: skill.Name,
|
|
|
|
|
Amount: skill.Pp,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-01 14:38:49 +02:00
|
|
|
for _, skill := range character.Waffenfertigkeiten {
|
|
|
|
|
if skill.Pp > 0 {
|
|
|
|
|
practicePoints = append(practicePoints, PracticePointResponse{
|
|
|
|
|
SkillName: skill.Name,
|
|
|
|
|
Amount: skill.Pp,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 09:32:44 +02:00
|
|
|
response := PracticePointActionResponse{
|
|
|
|
|
Success: true,
|
2026-05-01 14:38:49 +02:00
|
|
|
Message: fmt.Sprintf("%d Praxispunkte erfolgreich von %s verwendet/reduziert", request.Amount, targetSkillName),
|
2025-07-25 09:32:44 +02:00
|
|
|
RequestedSkill: request.SkillName,
|
|
|
|
|
TargetSkill: targetSkillName,
|
|
|
|
|
IsSpell: isSpellFlag,
|
|
|
|
|
PracticePoints: practicePoints,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, response)
|
2025-07-24 07:39:43 +02:00
|
|
|
}
|