Files
Catacombs/game/event.go

149 lines
3.2 KiB
Go

package game
import (
"math/rand"
"github.com/tolelom/catacombs/dungeon"
"github.com/tolelom/catacombs/entity"
)
func (s *GameSession) EnterRoom(roomIdx int) {
s.mu.Lock()
defer s.mu.Unlock()
s.state.Floor.CurrentRoom = roomIdx
dungeon.UpdateVisibility(s.state.Floor)
room := s.state.Floor.Rooms[roomIdx]
if room.Cleared {
return
}
switch room.Type {
case dungeon.RoomCombat:
s.spawnMonsters()
s.state.Phase = PhaseCombat
s.state.CombatTurn = 0
s.signalCombat()
case dungeon.RoomBoss:
s.spawnBoss()
s.state.Phase = PhaseCombat
s.state.CombatTurn = 0
s.signalCombat()
case dungeon.RoomShop:
s.generateShopItems()
s.state.Phase = PhaseShop
case dungeon.RoomTreasure:
s.grantTreasure()
room.Cleared = true
case dungeon.RoomEvent:
s.triggerEvent()
room.Cleared = true
case dungeon.RoomEmpty:
room.Cleared = true
}
}
func (s *GameSession) spawnMonsters() {
count := 1 + rand.Intn(5)
floor := s.state.FloorNum
s.state.Monsters = make([]*entity.Monster, count)
type floorRange struct {
mt entity.MonsterType
minFloor int
maxFloor int
}
ranges := []floorRange{
{entity.MonsterSlime, 1, 5},
{entity.MonsterSkeleton, 3, 10},
{entity.MonsterOrc, 6, 14},
{entity.MonsterDarkKnight, 12, 20},
}
var valid []entity.MonsterType
for _, r := range ranges {
if floor >= r.minFloor && floor <= r.maxFloor {
valid = append(valid, r.mt)
}
}
if len(valid) == 0 {
valid = []entity.MonsterType{entity.MonsterSlime}
}
for i := 0; i < count; i++ {
mt := valid[rand.Intn(len(valid))]
m := entity.NewMonster(mt, floor)
if s.state.SoloMode {
m.HP = m.HP / 2
if m.HP < 1 {
m.HP = 1
}
m.MaxHP = m.HP
}
s.state.Monsters[i] = m
}
}
func (s *GameSession) spawnBoss() {
var mt entity.MonsterType
switch s.state.FloorNum {
case 5:
mt = entity.MonsterBoss5
case 10:
mt = entity.MonsterBoss10
case 15:
mt = entity.MonsterBoss15
case 20:
mt = entity.MonsterBoss20
default:
mt = entity.MonsterBoss5
}
boss := entity.NewMonster(mt, s.state.FloorNum)
if s.state.SoloMode {
boss.HP = boss.HP / 2
boss.MaxHP = boss.HP
}
s.state.Monsters = []*entity.Monster{boss}
}
func (s *GameSession) grantTreasure() {
// Random item for each player
for _, p := range s.state.Players {
if rand.Float64() < 0.5 {
p.Inventory = append(p.Inventory, entity.Item{
Name: "Iron Sword", Type: entity.ItemWeapon, Bonus: 3 + rand.Intn(6),
})
} else {
p.Inventory = append(p.Inventory, entity.Item{
Name: "Iron Shield", Type: entity.ItemArmor, Bonus: 2 + rand.Intn(4),
})
}
}
}
func (s *GameSession) generateShopItems() {
s.state.ShopItems = []entity.Item{
{Name: "HP Potion", Type: entity.ItemConsumable, Bonus: 30, Price: 20},
{Name: "Iron Sword", Type: entity.ItemWeapon, Bonus: 3 + rand.Intn(6), Price: 40 + rand.Intn(41)},
{Name: "Iron Shield", Type: entity.ItemArmor, Bonus: 2 + rand.Intn(4), Price: 30 + rand.Intn(31)},
}
}
func (s *GameSession) triggerEvent() {
// Random event: 50% trap, 50% blessing
for _, p := range s.state.Players {
if p.IsDead() {
continue
}
if rand.Float64() < 0.5 {
// Trap: 10~20 damage
dmg := 10 + rand.Intn(11)
p.TakeDamage(dmg)
} else {
// Blessing: heal 15~25
heal := 15 + rand.Intn(11)
p.Heal(heal)
}
}
}