aboutsummaryrefslogtreecommitdiff
path: root/internal/combat/state.go
blob: 0d8de455580175ac62dcd246f5cb8c6042ab2d45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package combat

import "sync"

type State struct {
	PlayerName   string
	MobID        string
	MobAttacks   int    // attacks mob has made (3-hit flee rule)
	PlayerDamage int    // total damage player dealt this combat
	Active       bool
	LockedTicks  int    // ticks remaining before player can move
}

var (
	mu          sync.Mutex
	combatants  = make(map[string]*State) // player name -> state
	mobTargets  = make(map[string]string) // mob ID -> player name
)

func EnterCombat(playerName, mobID string) {
	mu.Lock()
	defer mu.Unlock()
	combatants[playerName] = &State{
		PlayerName:  playerName,
		MobID:       mobID,
		Active:      true,
		LockedTicks: 15,
	}
	mobTargets[mobID] = playerName
}

func LeaveCombat(playerName string) {
	mu.Lock()
	defer mu.Unlock()
	state, ok := combatants[playerName]
	if !ok {
		return
	}
	delete(mobTargets, state.MobID)
	delete(combatants, playerName)
}

func GetCombat(playerName string) *State {
	mu.Lock()
	defer mu.Unlock()
	return combatants[playerName]
}

func IsMobInCombat(mobID string) bool {
	mu.Lock()
	defer mu.Unlock()
	_, ok := mobTargets[mobID]
	return ok
}

func GetMobTarget(mobID string) string {
	mu.Lock()
	defer mu.Unlock()
	return mobTargets[mobID]
}

func RecordMobAttack(playerName string) {
	mu.Lock()
	defer mu.Unlock()
	if state, ok := combatants[playerName]; ok {
		state.MobAttacks++
	}
}

func CanFlee(playerName string) bool {
	mu.Lock()
	defer mu.Unlock()
	state, ok := combatants[playerName]
	if !ok {
		return true
	}
	return state.MobAttacks >= 3
}

func RecordPlayerDamage(playerName string, dmg int) {
	mu.Lock()
	defer mu.Unlock()
	if state, ok := combatants[playerName]; ok {
		state.PlayerDamage += dmg
	}
}

func TickCombat() {
	mu.Lock()
	defer mu.Unlock()
	for _, state := range combatants {
		if state.LockedTicks > 0 {
			state.LockedTicks--
		}
	}
}

func GetTotalDamage(playerName string) int {
	mu.Lock()
	defer mu.Unlock()
	if state, ok := combatants[playerName]; ok {
		d := state.PlayerDamage
		state.PlayerDamage = 0
		return d
	}
	return 0
}