2024-08-29 00:05:28 +02:00
|
|
|
package main
|
|
|
|
|
2024-08-30 19:07:56 +02:00
|
|
|
import (
|
|
|
|
"github.com/veandco/go-sdl2/sdl"
|
|
|
|
"image/color"
|
2024-08-31 15:35:19 +02:00
|
|
|
"strconv"
|
|
|
|
"sync"
|
2024-08-30 19:07:56 +02:00
|
|
|
)
|
2024-08-29 00:05:28 +02:00
|
|
|
|
2024-08-31 15:35:19 +02:00
|
|
|
var baseMutex sync.RWMutex
|
|
|
|
|
2024-08-29 00:05:28 +02:00
|
|
|
type Base struct {
|
2024-08-30 19:07:56 +02:00
|
|
|
ownerID uint32
|
2024-08-29 18:48:27 +02:00
|
|
|
openingWidth int32
|
|
|
|
gameObject *GameObject
|
2024-08-29 00:05:28 +02:00
|
|
|
}
|
|
|
|
|
2024-08-30 19:07:56 +02:00
|
|
|
func (base *Base) tick(players map[uint32]*Player) {
|
2024-08-31 15:35:19 +02:00
|
|
|
playersMutex.RLock()
|
2024-08-30 19:07:56 +02:00
|
|
|
for playerID, player := range players {
|
2024-08-31 15:35:19 +02:00
|
|
|
if player.gameObject.baseRect.HasIntersection(base.gameObject.baseRect) {
|
2024-08-30 19:07:56 +02:00
|
|
|
if player.rechargeCooldown == 0 && player.energy < serverConfig.MaxEnergy {
|
|
|
|
if serverConfig.MaxEnergy-player.energy < 4 {
|
2024-08-29 18:48:27 +02:00
|
|
|
player.energy++
|
|
|
|
} else {
|
|
|
|
player.energy += 4
|
|
|
|
}
|
2024-08-30 19:07:56 +02:00
|
|
|
if playerID == base.ownerID {
|
|
|
|
player.rechargeCooldown = serverConfig.RechargeCooldownOwn
|
2024-08-29 00:05:28 +02:00
|
|
|
} else {
|
2024-08-30 19:07:56 +02:00
|
|
|
player.rechargeCooldown = serverConfig.RechargeCooldownOpponent
|
2024-08-29 00:05:28 +02:00
|
|
|
}
|
|
|
|
}
|
2024-08-30 19:07:56 +02:00
|
|
|
if playerID == base.ownerID && player.repairCooldown == 0 && player.shields < serverConfig.MaxShields {
|
2024-08-29 18:48:27 +02:00
|
|
|
player.shields++
|
2024-08-30 19:07:56 +02:00
|
|
|
player.repairCooldown = serverConfig.RepairCooldown
|
2024-08-29 00:05:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-08-31 15:35:19 +02:00
|
|
|
playersMutex.RUnlock()
|
2024-08-29 00:05:28 +02:00
|
|
|
}
|
|
|
|
|
2024-08-30 19:07:56 +02:00
|
|
|
func (base *Base) render(camera *sdl.Rect, surface *sdl.Surface, bases map[uint32]*Base) {
|
2024-08-29 18:48:27 +02:00
|
|
|
base.gameObject.render(camera, surface)
|
2024-08-30 19:07:56 +02:00
|
|
|
if !base.gameObject.inView && !config.Server {
|
|
|
|
delete(bases, base.ownerID)
|
|
|
|
}
|
2024-08-29 00:05:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (base *Base) build(gameMap *GameMap) {
|
2024-08-30 19:07:56 +02:00
|
|
|
if gameMap.width-uint32(base.gameObject.baseRect.X)-uint32(base.gameObject.baseRect.W) <= 0 {
|
2024-08-29 00:05:28 +02:00
|
|
|
panic("Bad base x location")
|
|
|
|
}
|
2024-08-30 19:07:56 +02:00
|
|
|
if gameMap.height-uint32(base.gameObject.baseRect.Y)-uint32(base.gameObject.baseRect.H) <= 0 {
|
2024-08-29 00:05:28 +02:00
|
|
|
panic("Bad base y location")
|
|
|
|
}
|
2024-08-29 18:48:27 +02:00
|
|
|
if base.gameObject.baseRect.X < 0 || base.gameObject.baseRect.Y < 0 {
|
2024-08-31 15:35:19 +02:00
|
|
|
panic("Bad base negative location " + strconv.Itoa(int(base.gameObject.baseRect.X)) + " - " + strconv.Itoa(int(base.gameObject.baseRect.Y)))
|
2024-08-29 00:05:28 +02:00
|
|
|
}
|
2024-08-31 15:35:19 +02:00
|
|
|
base.gameObject.adjustBaseRect()
|
|
|
|
for x := base.gameObject.baseRect.X; x < base.gameObject.baseRect.X+base.gameObject.baseRect.W; x++ {
|
|
|
|
for y := base.gameObject.baseRect.Y; y < base.gameObject.baseRect.Y+base.gameObject.baseRect.H; y++ {
|
2024-08-29 00:05:28 +02:00
|
|
|
gameMap.tiles[x][y] = 0
|
|
|
|
}
|
|
|
|
}
|
2024-08-31 15:35:19 +02:00
|
|
|
for _, rectT := range base.gameObject.getCurrentRects() {
|
|
|
|
rect := sdl.Rect{
|
|
|
|
X: rectT.rect.X + base.gameObject.baseRect.X,
|
|
|
|
Y: rectT.rect.Y + base.gameObject.baseRect.Y,
|
|
|
|
W: rectT.rect.W,
|
|
|
|
H: rectT.rect.H,
|
|
|
|
}
|
|
|
|
for x := rect.X; x < rect.X+rect.W; x++ {
|
|
|
|
for y := rect.Y; y < rect.Y+rect.H; y++ {
|
|
|
|
gameMap.tiles[x][y] = 4
|
|
|
|
}
|
|
|
|
}
|
2024-08-29 00:05:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-30 19:07:56 +02:00
|
|
|
func createBase(gameMap *GameMap, baseColor color.Color, posX, posY, ownerID, openingWidth uint32) *Base {
|
|
|
|
gameObject := &GameObject{}
|
2024-08-31 15:35:19 +02:00
|
|
|
gameObject.baseRect = &sdl.Rect{
|
2024-08-30 19:07:56 +02:00
|
|
|
X: int32(posX),
|
|
|
|
Y: int32(posY),
|
|
|
|
W: 35,
|
|
|
|
H: 35,
|
|
|
|
}
|
|
|
|
if openingWidth%2 == 0 {
|
|
|
|
openingWidth++
|
|
|
|
}
|
2024-08-29 18:48:27 +02:00
|
|
|
|
2024-08-30 19:07:56 +02:00
|
|
|
borderWidth := gameObject.baseRect.W - int32(openingWidth)
|
|
|
|
borderWidthA := borderWidth / 2
|
|
|
|
borderWidthB := borderWidth - borderWidthA + 1
|
|
|
|
if borderWidth < 0 {
|
|
|
|
panic("Bad border width")
|
|
|
|
}
|
|
|
|
gameObject.addColor(baseColor)
|
2024-08-31 15:35:19 +02:00
|
|
|
gameObject.addColoredRect(0, 0, 1, gameObject.baseRect.H-1, 0)
|
|
|
|
gameObject.addColoredRect(gameObject.baseRect.W, 0, 1, gameObject.baseRect.H-1, 0)
|
2024-08-30 19:07:56 +02:00
|
|
|
gameObject.addColoredRect(0, 0, borderWidthA, 1, 0)
|
|
|
|
gameObject.addColoredRect(borderWidthA+int32(openingWidth), 0, borderWidthB, 1, 0)
|
2024-08-31 15:35:19 +02:00
|
|
|
gameObject.addColoredRect(0, gameObject.baseRect.H-1, borderWidthA, 1, 0)
|
|
|
|
gameObject.addColoredRect(borderWidthA+int32(openingWidth), gameObject.baseRect.H-1, borderWidthB, 1, 0)
|
2024-08-30 19:07:56 +02:00
|
|
|
base := &Base{
|
|
|
|
gameObject: gameObject,
|
|
|
|
ownerID: ownerID,
|
|
|
|
openingWidth: int32(openingWidth),
|
|
|
|
}
|
|
|
|
base.build(gameMap)
|
|
|
|
return base
|
|
|
|
}
|
2024-08-29 18:48:27 +02:00
|
|
|
|
2024-08-30 19:07:56 +02:00
|
|
|
func (base *Base) delete(bases map[uint32]*Base) {
|
|
|
|
for x := base.gameObject.baseRect.X; x < base.gameObject.baseRect.X+base.gameObject.baseRect.W+1; x++ {
|
|
|
|
for y := base.gameObject.baseRect.Y; y < base.gameObject.baseRect.Y+base.gameObject.baseRect.H+1; y++ {
|
|
|
|
gameMap.tiles[x][y] = 0
|
2024-08-29 18:48:27 +02:00
|
|
|
}
|
2024-08-30 19:07:56 +02:00
|
|
|
}
|
2024-08-31 15:35:19 +02:00
|
|
|
baseMutex.Lock()
|
2024-08-30 19:07:56 +02:00
|
|
|
delete(bases, base.ownerID)
|
2024-08-31 15:35:19 +02:00
|
|
|
baseMutex.Unlock()
|
2024-08-30 19:07:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func createBases(players map[uint32]*Player, gameMap *GameMap) map[uint32]*Base {
|
|
|
|
bases := map[uint32]*Base{}
|
2024-08-31 15:35:19 +02:00
|
|
|
playersMutex.RLock()
|
2024-08-30 19:07:56 +02:00
|
|
|
for ownerID, player := range players {
|
2024-08-31 15:35:19 +02:00
|
|
|
baseMutex.Lock()
|
2024-08-30 19:07:56 +02:00
|
|
|
bases[ownerID] = createBase(gameMap,
|
|
|
|
player.playerColors.body,
|
|
|
|
uint32(player.gameObject.baseRect.X-14),
|
|
|
|
uint32(player.gameObject.baseRect.Y-14),
|
|
|
|
ownerID,
|
|
|
|
uint32(float64(player.gameObject.baseRect.W)*1.5),
|
|
|
|
)
|
2024-08-31 15:35:19 +02:00
|
|
|
baseMutex.Unlock()
|
2024-08-29 00:05:28 +02:00
|
|
|
}
|
2024-08-31 15:35:19 +02:00
|
|
|
playersMutex.RUnlock()
|
2024-08-29 00:05:28 +02:00
|
|
|
return bases
|
|
|
|
}
|