415 lines
12 KiB
Go
415 lines
12 KiB
Go
package world
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
// AchievementEventType represents different types of achievement events
|
|
type AchievementEventType int
|
|
|
|
const (
|
|
// Combat events
|
|
EventNPCKill AchievementEventType = iota
|
|
EventPlayerKill
|
|
EventDeathByNPC
|
|
EventDeathByPlayer
|
|
EventDamageDealt
|
|
EventHealingDone
|
|
|
|
// Quest events
|
|
EventQuestCompleted
|
|
EventQuestStep
|
|
EventQuestStarted
|
|
EventQuestAbandoned
|
|
|
|
// Skill events
|
|
EventSkillIncrease
|
|
EventSkillMastery
|
|
EventSpellLearned
|
|
EventSpellCast
|
|
|
|
// Item events
|
|
EventItemDiscovered
|
|
EventItemCrafted
|
|
EventItemLooted
|
|
EventItemEquipped
|
|
EventItemSold
|
|
EventItemBought
|
|
|
|
// Exploration events
|
|
EventZoneDiscovered
|
|
EventLocationDiscovered
|
|
EventPOIDiscovered
|
|
|
|
// Social events
|
|
EventGuildJoin
|
|
EventGuildLeave
|
|
EventGroupJoin
|
|
EventGroupLeave
|
|
EventFriendAdded
|
|
EventPlayerTell
|
|
|
|
// Harvesting/Crafting events
|
|
EventHarvest
|
|
EventRareHarvest
|
|
EventCraftingSuccess
|
|
EventCraftingFailure
|
|
EventRecipeDiscovered
|
|
|
|
// Level/Experience events
|
|
EventLevelGain
|
|
EventAAPoint
|
|
EventExperienceGain
|
|
EventStatusGain
|
|
|
|
// PvP events
|
|
EventPvPKill
|
|
EventPvPDeath
|
|
EventPvPAssist
|
|
EventArenaWin
|
|
EventArenaLoss
|
|
|
|
// Special events
|
|
EventHeroicOpportunity
|
|
EventRaidBoss
|
|
EventInstanceComplete
|
|
EventCollectionComplete
|
|
)
|
|
|
|
// AchievementEvent represents a single achievement-related event
|
|
type AchievementEvent struct {
|
|
Type AchievementEventType
|
|
CharacterID int32
|
|
Data map[string]interface{}
|
|
Timestamp int64
|
|
}
|
|
|
|
// AchievementEventHandler processes achievement events
|
|
type AchievementEventHandler struct {
|
|
world *World
|
|
}
|
|
|
|
// NewAchievementEventHandler creates a new achievement event handler
|
|
func NewAchievementEventHandler(world *World) *AchievementEventHandler {
|
|
return &AchievementEventHandler{
|
|
world: world,
|
|
}
|
|
}
|
|
|
|
// ProcessEvent processes an achievement event and updates progress
|
|
func (aeh *AchievementEventHandler) ProcessEvent(event *AchievementEvent) error {
|
|
if event == nil {
|
|
return fmt.Errorf("event cannot be nil")
|
|
}
|
|
|
|
// Get player's achievement manager
|
|
achievementMgr := aeh.world.GetAchievementManager()
|
|
if achievementMgr == nil {
|
|
return fmt.Errorf("achievement manager not available")
|
|
}
|
|
|
|
// Process different event types
|
|
switch event.Type {
|
|
case EventNPCKill:
|
|
return aeh.handleNPCKill(event, achievementMgr)
|
|
case EventQuestCompleted:
|
|
return aeh.handleQuestCompleted(event, achievementMgr)
|
|
case EventLevelGain:
|
|
return aeh.handleLevelGain(event, achievementMgr)
|
|
case EventSkillIncrease:
|
|
return aeh.handleSkillIncrease(event, achievementMgr)
|
|
case EventItemDiscovered:
|
|
return aeh.handleItemDiscovered(event, achievementMgr)
|
|
case EventZoneDiscovered:
|
|
return aeh.handleZoneDiscovered(event, achievementMgr)
|
|
case EventHarvest:
|
|
return aeh.handleHarvest(event, achievementMgr)
|
|
case EventPvPKill:
|
|
return aeh.handlePvPKill(event, achievementMgr)
|
|
default:
|
|
// For unhandled events, try generic processing
|
|
return aeh.handleGenericEvent(event, achievementMgr)
|
|
}
|
|
}
|
|
|
|
// handleNPCKill processes NPC kill events
|
|
func (aeh *AchievementEventHandler) handleNPCKill(event *AchievementEvent, achievementMgr *AchievementManager) error {
|
|
npcID, ok := event.Data["npc_id"].(int32)
|
|
if !ok {
|
|
return fmt.Errorf("npc_id not found in event data")
|
|
}
|
|
|
|
level, ok := event.Data["level"].(int32)
|
|
if !ok {
|
|
level = 1 // Default level
|
|
}
|
|
|
|
// Update generic kill count achievements
|
|
err := achievementMgr.UpdateProgress(event.CharacterID, 1, 1) // Achievement ID 1: "First Blood"
|
|
if err != nil {
|
|
fmt.Printf("Error updating kill achievement: %v\n", err)
|
|
}
|
|
|
|
// Update level-specific kill achievements
|
|
if level >= 10 {
|
|
achievementMgr.UpdateProgress(event.CharacterID, 2, 1) // Achievement ID 2: "Veteran Hunter"
|
|
}
|
|
|
|
// Update specific NPC kill achievements (example)
|
|
if npcID == 100 { // Boss NPC
|
|
achievementMgr.UpdateProgress(event.CharacterID, 10, 1) // Achievement ID 10: "Boss Slayer"
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// handleQuestCompleted processes quest completion events
|
|
func (aeh *AchievementEventHandler) handleQuestCompleted(event *AchievementEvent, achievementMgr *AchievementManager) error {
|
|
questID, ok := event.Data["quest_id"].(int32)
|
|
if !ok {
|
|
return fmt.Errorf("quest_id not found in event data")
|
|
}
|
|
|
|
// Update quest completion achievements
|
|
err := achievementMgr.UpdateProgress(event.CharacterID, 20, 1) // Achievement ID 20: "Quest Master"
|
|
if err != nil {
|
|
fmt.Printf("Error updating quest achievement: %v\n", err)
|
|
}
|
|
|
|
// Update specific quest achievements
|
|
if questID == 1000 { // Main story quest
|
|
achievementMgr.UpdateProgress(event.CharacterID, 21, 1) // Achievement ID 21: "Hero's Journey"
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// handleLevelGain processes level gain events
|
|
func (aeh *AchievementEventHandler) handleLevelGain(event *AchievementEvent, achievementMgr *AchievementManager) error {
|
|
newLevel, ok := event.Data["level"].(int32)
|
|
if !ok {
|
|
return fmt.Errorf("level not found in event data")
|
|
}
|
|
|
|
// Update level-based achievements
|
|
switch newLevel {
|
|
case 10:
|
|
achievementMgr.UpdateProgress(event.CharacterID, 30, 1) // Achievement ID 30: "Growing Strong"
|
|
case 20:
|
|
achievementMgr.UpdateProgress(event.CharacterID, 31, 1) // Achievement ID 31: "Seasoned Adventurer"
|
|
case 50:
|
|
achievementMgr.UpdateProgress(event.CharacterID, 32, 1) // Achievement ID 32: "Veteran"
|
|
case 90:
|
|
achievementMgr.UpdateProgress(event.CharacterID, 33, 1) // Achievement ID 33: "Master Adventurer"
|
|
}
|
|
|
|
// Update max level achievement
|
|
achievementMgr.UpdateProgress(event.CharacterID, 34, uint32(newLevel)) // Achievement ID 34: "Level Up!"
|
|
|
|
return nil
|
|
}
|
|
|
|
// handleSkillIncrease processes skill increase events
|
|
func (aeh *AchievementEventHandler) handleSkillIncrease(event *AchievementEvent, achievementMgr *AchievementManager) error {
|
|
skillID, ok := event.Data["skill_id"].(int32)
|
|
if !ok {
|
|
return fmt.Errorf("skill_id not found in event data")
|
|
}
|
|
|
|
skillLevel, ok := event.Data["skill_level"].(int32)
|
|
if !ok {
|
|
return fmt.Errorf("skill_level not found in event data")
|
|
}
|
|
|
|
// Update skill mastery achievements based on skill type
|
|
switch skillID {
|
|
case 1: // Melee skill
|
|
if skillLevel >= 300 {
|
|
achievementMgr.UpdateProgress(event.CharacterID, 40, 1) // Achievement ID 40: "Weapon Master"
|
|
}
|
|
case 10: // Magic skill
|
|
if skillLevel >= 300 {
|
|
achievementMgr.UpdateProgress(event.CharacterID, 41, 1) // Achievement ID 41: "Arcane Scholar"
|
|
}
|
|
case 20: // Crafting skill
|
|
if skillLevel >= 300 {
|
|
achievementMgr.UpdateProgress(event.CharacterID, 42, 1) // Achievement ID 42: "Master Craftsman"
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// handleItemDiscovered processes item discovery events
|
|
func (aeh *AchievementEventHandler) handleItemDiscovered(event *AchievementEvent, achievementMgr *AchievementManager) error {
|
|
itemID, ok := event.Data["item_id"].(int32)
|
|
if !ok {
|
|
return fmt.Errorf("item_id not found in event data")
|
|
}
|
|
|
|
rarity, ok := event.Data["rarity"].(string)
|
|
if !ok {
|
|
rarity = "common"
|
|
}
|
|
|
|
// Update item discovery achievements
|
|
achievementMgr.UpdateProgress(event.CharacterID, 50, 1) // Achievement ID 50: "Treasure Hunter"
|
|
|
|
// Update rarity-specific achievements
|
|
switch rarity {
|
|
case "rare":
|
|
achievementMgr.UpdateProgress(event.CharacterID, 51, 1) // Achievement ID 51: "Rare Collector"
|
|
case "legendary":
|
|
achievementMgr.UpdateProgress(event.CharacterID, 52, 1) // Achievement ID 52: "Legend Seeker"
|
|
case "mythical":
|
|
achievementMgr.UpdateProgress(event.CharacterID, 53, 1) // Achievement ID 53: "Myth Walker"
|
|
}
|
|
|
|
// Specific item achievements
|
|
if itemID == 12345 { // Special artifact
|
|
achievementMgr.UpdateProgress(event.CharacterID, 54, 1) // Achievement ID 54: "Ancient Artifact"
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// handleZoneDiscovered processes zone discovery events
|
|
func (aeh *AchievementEventHandler) handleZoneDiscovered(event *AchievementEvent, achievementMgr *AchievementManager) error {
|
|
zoneID, ok := event.Data["zone_id"].(int32)
|
|
if !ok {
|
|
return fmt.Errorf("zone_id not found in event data")
|
|
}
|
|
|
|
// Update exploration achievements
|
|
achievementMgr.UpdateProgress(event.CharacterID, 60, 1) // Achievement ID 60: "Explorer"
|
|
|
|
// Update specific zone achievements
|
|
switch zoneID {
|
|
case 1: // Starting zone
|
|
achievementMgr.UpdateProgress(event.CharacterID, 61, 1) // Achievement ID 61: "First Steps"
|
|
case 100: // End game zone
|
|
achievementMgr.UpdateProgress(event.CharacterID, 62, 1) // Achievement ID 62: "Into the Unknown"
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// handleHarvest processes harvesting events
|
|
func (aeh *AchievementEventHandler) handleHarvest(event *AchievementEvent, achievementMgr *AchievementManager) error {
|
|
resourceType, ok := event.Data["resource_type"].(string)
|
|
if !ok {
|
|
return fmt.Errorf("resource_type not found in event data")
|
|
}
|
|
|
|
isRare, _ := event.Data["is_rare"].(bool)
|
|
|
|
// Update harvesting achievements
|
|
achievementMgr.UpdateProgress(event.CharacterID, 70, 1) // Achievement ID 70: "Gatherer"
|
|
|
|
// Update resource-specific achievements
|
|
switch resourceType {
|
|
case "ore":
|
|
achievementMgr.UpdateProgress(event.CharacterID, 71, 1) // Achievement ID 71: "Miner"
|
|
case "wood":
|
|
achievementMgr.UpdateProgress(event.CharacterID, 72, 1) // Achievement ID 72: "Lumberjack"
|
|
case "fish":
|
|
achievementMgr.UpdateProgress(event.CharacterID, 73, 1) // Achievement ID 73: "Angler"
|
|
}
|
|
|
|
// Update rare harvest achievement
|
|
if isRare {
|
|
achievementMgr.UpdateProgress(event.CharacterID, 74, 1) // Achievement ID 74: "Lucky Find"
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// handlePvPKill processes PvP kill events
|
|
func (aeh *AchievementEventHandler) handlePvPKill(event *AchievementEvent, achievementMgr *AchievementManager) error {
|
|
targetLevel, ok := event.Data["target_level"].(int32)
|
|
if !ok {
|
|
targetLevel = 1
|
|
}
|
|
|
|
// Update PvP achievements
|
|
achievementMgr.UpdateProgress(event.CharacterID, 80, 1) // Achievement ID 80: "First Blood PvP"
|
|
|
|
// Update level-based PvP achievements
|
|
if targetLevel >= 50 {
|
|
achievementMgr.UpdateProgress(event.CharacterID, 81, 1) // Achievement ID 81: "Veteran Slayer"
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// handleGenericEvent processes generic events
|
|
func (aeh *AchievementEventHandler) handleGenericEvent(event *AchievementEvent, achievementMgr *AchievementManager) error {
|
|
// For events without specific handlers, attempt generic progress updates
|
|
// This allows for easy extension without requiring handler updates
|
|
|
|
// Log unhandled event types for debugging
|
|
fmt.Printf("Unhandled achievement event type: %d for character %d\n",
|
|
int(event.Type), event.CharacterID)
|
|
|
|
return nil
|
|
}
|
|
|
|
// TriggerEvent is a convenience method for triggering achievement events
|
|
func (w *World) TriggerAchievementEvent(eventType AchievementEventType, characterID int32, data map[string]interface{}) {
|
|
if w.achievementMgr == nil {
|
|
return // Achievement system not initialized
|
|
}
|
|
|
|
event := &AchievementEvent{
|
|
Type: eventType,
|
|
CharacterID: characterID,
|
|
Data: data,
|
|
Timestamp: int64(w.worldTime.Year), // Use game time as timestamp
|
|
}
|
|
|
|
handler := NewAchievementEventHandler(w)
|
|
go func() {
|
|
if err := handler.ProcessEvent(event); err != nil {
|
|
fmt.Printf("Error processing achievement event: %v\n", err)
|
|
}
|
|
}()
|
|
}
|
|
|
|
// Convenience methods for common events
|
|
|
|
// OnNPCKill triggers an NPC kill achievement event
|
|
func (w *World) OnNPCKill(characterID int32, npcID int32, npcLevel int32) {
|
|
w.TriggerAchievementEvent(EventNPCKill, characterID, map[string]interface{}{
|
|
"npc_id": npcID,
|
|
"level": npcLevel,
|
|
})
|
|
}
|
|
|
|
// OnQuestComplete triggers a quest completion achievement event
|
|
func (w *World) OnQuestComplete(characterID int32, questID int32) {
|
|
w.TriggerAchievementEvent(EventQuestCompleted, characterID, map[string]interface{}{
|
|
"quest_id": questID,
|
|
})
|
|
}
|
|
|
|
// OnLevelGain triggers a level gain achievement event
|
|
func (w *World) OnLevelGain(characterID int32, newLevel int32) {
|
|
w.TriggerAchievementEvent(EventLevelGain, characterID, map[string]interface{}{
|
|
"level": newLevel,
|
|
})
|
|
}
|
|
|
|
// OnItemDiscovered triggers an item discovery achievement event
|
|
func (w *World) OnItemDiscovered(characterID int32, itemID int32, rarity string) {
|
|
w.TriggerAchievementEvent(EventItemDiscovered, characterID, map[string]interface{}{
|
|
"item_id": itemID,
|
|
"rarity": rarity,
|
|
})
|
|
}
|
|
|
|
// OnZoneDiscovered triggers a zone discovery achievement event
|
|
func (w *World) OnZoneDiscovered(characterID int32, zoneID int32) {
|
|
w.TriggerAchievementEvent(EventZoneDiscovered, characterID, map[string]interface{}{
|
|
"zone_id": zoneID,
|
|
})
|
|
} |