Skip to content

Commit

Permalink
clubsets: add upgrade/downgrade logic
Browse files Browse the repository at this point in the history
  • Loading branch information
hex-agon committed Aug 11, 2023
1 parent 1e95116 commit 723d024
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package work.fking.pangya.game.net

import work.fking.pangya.game.packet.handler.AchievementStatusRequestPacketHandler
import work.fking.pangya.game.packet.handler.ClubSetUpgradePacketHandler
import work.fking.pangya.game.packet.handler.EquipmentUpdatePacketHandler
import work.fking.pangya.game.packet.handler.JoinLobbyPacketHandler
import work.fking.pangya.game.packet.handler.LeaveLobbyPacketHandler
Expand Down Expand Up @@ -63,6 +64,7 @@ enum class ClientPacketType(
MATCH_FINISH_PLAYER_PREVIEW(0x34, MatchFinishPlayerPreviewPacketHandler()),
MATCH_PLAYER_SHOT_ARROW(0x42),
PLAYER_LOAD_PROGRESS(0x48),
CLUBSET_UPGRADE(0x4b, ClubSetUpgradePacketHandler()),
LOUNGE_USER_ACTION(0x63),
MATCH_PLAYER_USE_TIME_BOOSTER(0x65, MatchPlayerUseTimeBoosterPacketHandler()),
UPDATE_MACROS(0x69, UpdateChatMacrosPacketHandler()),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package work.fking.pangya.game.packet.handler

import io.netty.buffer.ByteBuf
import work.fking.pangya.game.GameServer
import work.fking.pangya.game.net.ClientPacketHandler
import work.fking.pangya.game.packet.outbound.ClubSetReplies
import work.fking.pangya.game.player.Player
import work.fking.pangya.game.player.statById
import work.fking.pangya.game.task.ChangeClubSetStatTask

class ClubSetUpgradePacketHandler : ClientPacketHandler {

override fun handle(server: GameServer, player: Player, packet: ByteBuf) {
val type = packet.readByte() // clubset upgrade = 1, clubset downgrade = 3
val statId = packet.readUnsignedByte()
val itemUid = packet.readIntLE()

val stat = statById(statId.toInt()) ?: throw IllegalStateException("Player ${player.nickname} tried to upgrade an item with an invalid stat ($statId)")

server.runTask(
ChangeClubSetStatTask(
persistenceCtx = server.persistenceCtx,
player = player,
itemUid = itemUid,
type = type.toInt(),
stat = stat
)
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package work.fking.pangya.game.packet.outbound

import work.fking.pangya.networking.protocol.OutboundPacket

object ClubSetReplies {

fun upgradeAck(type: Int, stat: Int, itemUid: Int, cost: Long): OutboundPacket {
return OutboundPacket { buffer ->
buffer.writeShortLE(0xa5)
buffer.writeByte(type)
buffer.writeByte(1) // 0 doesn't upgrade a clubset but 1 does?
buffer.writeByte(stat)
buffer.writeIntLE(itemUid)
buffer.writeLongLE(cost) // TODO: how to calculate the upgrade cost?
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import work.fking.pangya.game.player.PlayerWallet

interface PlayerRepository {
fun loadWallet(txCtx: TransactionalContext, playerUid: Int): PlayerWallet
fun saveWallet(txCtx: TransactionalContext, playerUid: Int, playerWallet: PlayerWallet)
fun updateNickname(txCtx: TransactionalContext, playerUid: Int, nickname: String)
}

class InMemoryPlayerRepository : PlayerRepository {
private val wallets = mutableMapOf<Int, PlayerWallet>()

override fun loadWallet(txCtx: TransactionalContext, playerUid: Int): PlayerWallet = wallets[playerUid] ?: PlayerWallet()
override fun saveWallet(txCtx: TransactionalContext, playerUid: Int, playerWallet: PlayerWallet) {
}

override fun updateNickname(txCtx: TransactionalContext, playerUid: Int, nickname: String) {
}
}
Expand All @@ -31,6 +35,14 @@ class JooqPlayerRepository : PlayerRepository {
return wallet ?: throw IllegalStateException("could not load player wallet for playerUid=$playerUid")
}

override fun saveWallet(txCtx: TransactionalContext, playerUid: Int, playerWallet: PlayerWallet) {
txCtx.jooq().update(ACCOUNT)
.set(ACCOUNT.PANG_BALANCE, playerWallet.pangBalance)
.set(ACCOUNT.COOKIE_BALANCE, playerWallet.cookieBalance)
.where(ACCOUNT.UID.eq(playerUid))
.execute()
}

override fun updateNickname(txCtx: TransactionalContext, playerUid: Int, nickname: String) {
txCtx.jooq().update(ACCOUNT)
.set(ACCOUNT.NICKNAME, nickname)
Expand Down
11 changes: 11 additions & 0 deletions game-server/src/main/kotlin/work/fking/pangya/game/player/Stat.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package work.fking.pangya.game.player

enum class Stat {
POWER,
CONTROL,
ACCURACY,
SPIN,
CURVE
}

fun statById(id: Int) = Stat.entries.find { it.ordinal == id }
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package work.fking.pangya.game.task

import work.fking.pangya.game.model.IFF_TYPE_CLUBSET
import work.fking.pangya.game.model.iffTypeFromId
import work.fking.pangya.game.packet.outbound.ClubSetReplies
import work.fking.pangya.game.persistence.PersistenceContext
import work.fking.pangya.game.player.Item
import work.fking.pangya.game.player.Player
import work.fking.pangya.game.player.Stat
import work.fking.pangya.game.player.Stat.ACCURACY
import work.fking.pangya.game.player.Stat.CONTROL
import work.fking.pangya.game.player.Stat.CURVE
import work.fking.pangya.game.player.Stat.POWER
import work.fking.pangya.game.player.Stat.SPIN

private const val TYPE_UPGRADE_CLUBSET = 1
private const val TYPE_DOWNGRADE_CLUBSET = 3

class ChangeClubSetStatTask(
private val persistenceCtx: PersistenceContext,
private val player: Player,
private val itemUid: Int,
private val type: Int,
private val stat: Stat
) : Runnable {


override fun run() {
val clubSet = player.inventory.findByUid(itemUid) ?: throw IllegalStateException("Player ${player.nickname} tried to upgrade an item it does not own")
require(iffTypeFromId(clubSet.iffId) == IFF_TYPE_CLUBSET) { "Player ${player.nickname} tried to upgrade an item that is not a ClubSet" }

when (type) {
TYPE_UPGRADE_CLUBSET -> upgrade(clubSet)
TYPE_DOWNGRADE_CLUBSET -> downgrade(clubSet)
else -> throw IllegalStateException("Player ${player.nickname} tried to upgrade an item but the type is invalid ($type)")
}
}

private fun upgrade(clubSet: Item) {
val level = clubSet.stats[stat.ordinal]
val cost = (level + 1) * when (stat) {
POWER -> 2100
CONTROL -> 1700
ACCURACY -> 2400
SPIN, CURVE -> 1900
}
val wallet = player.wallet
require(wallet.pangBalance >= cost) { "Player ${player.nickname} tried to upgrade an item but doesn't have enough pang" }
// TODO: verify clubset upgrade limits

persistenceCtx.transactional { tx ->
wallet.pangBalance -= cost
clubSet.stats[stat.ordinal]++
persistenceCtx.playerRepository.saveWallet(tx, player.uid, wallet)
persistenceCtx.inventoryRepository.saveItem(tx, player.uid, clubSet)
}
player.writeAndFlush(ClubSetReplies.upgradeAck(type, stat.ordinal, itemUid, cost.toLong()))
}

private fun downgrade(clubSet: Item) {
require(clubSet.stats[stat.ordinal] > 0) { "Player ${player.nickname} tried to downgrade an item but the stat is already at 0" }

clubSet.stats[stat.ordinal]--
persistenceCtx.inventoryRepository.saveItem(persistenceCtx.noTxContext(), player.uid, clubSet)
player.writeAndFlush(ClubSetReplies.upgradeAck(type, stat.ordinal, itemUid, 0))
}
}

0 comments on commit 723d024

Please sign in to comment.