Skip to content

Commit

Permalink
Achievements First Release
Browse files Browse the repository at this point in the history
- This is the first release of the achievements system. Everything functionality-wise has been tested and implemented.
- 20+ achievement parents.
- ~80+ achievements are being added in this release.
  • Loading branch information
Mew2K authored and chatasma committed Aug 18, 2023
1 parent 24eb484 commit be1f7e5
Show file tree
Hide file tree
Showing 29 changed files with 586 additions and 194 deletions.
1 change: 0 additions & 1 deletion src/main/kotlin/network/warzone/mars/Mars.kt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ class Mars : JavaPlugin() {
lateinit var matchTabManager: MatchTabManager

override fun onEnable() = runBlocking {
println("MEWTWO IS HERE HERE HERE HERE HERE HERE!")
instance = this@Mars

this@Mars.saveDefaultConfig()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ data class DestroyablePartial(
val blockCount: Int
)

data class DestroyableDestroyData(val destroyableId: String, val contributions: List<Contribution>)
data class DestroyableDamageData(val destroyableId: String, val playerId: UUID, val damage: Int)
data class DestroyableDestroyData(val destroyableId: String, val material: String, val contributions: List<Contribution>)
data class DestroyableDamageData(val destroyableId: String, val material: String, val playerId: UUID, val damage: Int)
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ sealed class PlayerUpdateData {
@SerialName("MatchEndUpdateData")
data class MatchEndUpdateData(val data: MatchEndData) : PlayerUpdateData()
@SerialName("DestroyableDamageUpdateData")
data class DestroyableDamageUpdateData(val blockCount: Int) : PlayerUpdateData()
data class DestroyableDamageUpdateData(val data: DestroyableDamageData, val blockCount: Int) : PlayerUpdateData()
@SerialName("DestroyableDestroyUpdateData")
data class DestroyableDestroyUpdateData(val percentage: Float, val blockCount: Int) : PlayerUpdateData()
@SerialName("CoreLeakUpdateData")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import network.warzone.mars.api.socket.models.DestroyableDestroyData
import network.warzone.mars.match.models.Contribution
import network.warzone.mars.utils.KEvent
import org.bukkit.Bukkit
import org.bukkit.event.Event
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.scheduler.BukkitTask
import tc.oc.pgm.api.match.event.MatchStartEvent
import tc.oc.pgm.api.player.MatchPlayer
import tc.oc.pgm.api.player.ParticipantState
import tc.oc.pgm.destroyable.Destroyable
import tc.oc.pgm.destroyable.DestroyableHealthChange
import tc.oc.pgm.destroyable.DestroyableHealthChangeEvent
import java.util.*
import java.util.concurrent.ConcurrentHashMap
Expand All @@ -30,6 +30,7 @@ class DestroyableTracker : Listener {

internal class DestroyableDamageBatch(
val destroyable: Destroyable,
val change: DestroyableHealthChange,
var count: Int
)

Expand All @@ -54,7 +55,7 @@ class DestroyableTracker : Listener {

val destroyableBatch = batchList.find { it.destroyable == event.destroyable }
if (destroyableBatch == null) {
batchList.add(DestroyableDamageBatch(event.destroyable, 1))
batchList.add(DestroyableDamageBatch(event.destroyable, change, 1))
val task = Bukkit.getScheduler().runTaskLaterAsynchronously(Mars.get(), {
val batch = batchList.find { it.destroyable == event.destroyable } ?: return@runTaskLaterAsynchronously

Expand All @@ -79,6 +80,7 @@ class DestroyableTracker : Listener {
OutboundEvent.DestroyableDestroy,
DestroyableDestroyData(
event.destroyable.id,
change.oldState.material.name,
event.destroyable
.contributions
.map { Contribution(it.playerState.id, it.percentage.toFloat(), it.blocks) }
Expand All @@ -92,6 +94,7 @@ class DestroyableTracker : Listener {
OutboundEvent.DestroyableDamage,
DestroyableDamageData(
batch.destroyable.id,
batch.change.oldState.material.name,
player.id,
batch.count
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.bukkit.Bukkit
import org.bukkit.ChatColor
import org.bukkit.entity.Player

@Deprecated("Remove this")
interface AchievementDebugger {
val debugPrefix: String
get() = ChatColor.DARK_GRAY.toString() + "[@] " + ChatColor.GRAY.toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package network.warzone.mars.player.achievements
import network.warzone.api.database.models.Achievement
import network.warzone.api.database.models.AgentParams
import network.warzone.mars.Mars
import network.warzone.mars.match.MatchManager
import network.warzone.mars.player.achievements.models.AchievementParent
import network.warzone.mars.player.achievements.variants.*
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import tc.oc.pgm.api.map.Gamemode
import tc.oc.pgm.api.match.event.MatchFinishEvent

object AchievementManager : Listener, AchievementDebugger {
Expand All @@ -28,6 +30,7 @@ object AchievementManager : Listener, AchievementDebugger {

fun filterAchievementsWithParent(parent: AchievementParent, achievements: List<Achievement>) : List<Achievement>{
return achievements.filter { it.parent == parent }

}

@EventHandler
Expand All @@ -46,172 +49,84 @@ object AchievementManager : Listener, AchievementDebugger {
val emitter = AchievementEmitter(achievement)
return when (val agentParams = achievement.agent.params) {
is AgentParams.KillStreakAgentParams -> {
KillstreakAchievement(agentParams, emitter)
KillstreakAchievement(agentParams.targetStreak, emitter)
}
is AgentParams.TotalKillsAgentParams -> {
TotalKillsAchievement(agentParams, emitter)
TotalKillsAchievement(agentParams.targetKills, emitter)
}
is AgentParams.FireDeathAgentParams -> {
FireDeathAchievement(agentParams, emitter)
FireDeathAchievement(emitter)
}
is AgentParams.CaptureNoSprintAgentParams -> {
CaptureNoSprintAchievement(emitter)
}
//TODO: Refactor all single-parameter achievements to just
// pass the parameter, like how it's being done here.
is AgentParams.ChatMessageAgentParams -> {
ChatMessageAchievement(agentParams.message, emitter)
}
is AgentParams.LevelUpAgentParams -> {
LevelUpAchievement(agentParams.level, emitter)
}
is AgentParams.WoolCapturesAgentParams -> {
WoolCapturesAchievement(agentParams.captures, emitter)
is AgentParams.WoolCaptureAgentParams -> {
WoolCaptureAchievement(agentParams.captures, emitter)
}
is AgentParams.FirstBloodAgentParams -> {
FirstBloodAchievement(agentParams.target, emitter)
}
is AgentParams.BowDistanceAgentParams -> {
BowDistanceAchievement(agentParams.distance, emitter)
}
is AgentParams.FlagCapturesAgentParams -> {
FlagCapturesAchievement(agentParams.captures, emitter)
is AgentParams.FlagCaptureAgentParams -> {
FlagCaptureAchievement(agentParams.captures, emitter)
}
is AgentParams.FlagDefendAgentParams -> {
FlagDefendAchievement(agentParams.defends, emitter)
}
is AgentParams.WoolDefendAgentParams -> {
WoolDefendAchievement(agentParams.defends, emitter)
}
is AgentParams.MonumentDamageAgentParams -> {
MonumentDamageAchievement(agentParams.breaks, emitter)
}
is AgentParams.KillConsecutiveAgentParams -> {
KillConsecutiveAchievement(agentParams, emitter)
}
is AgentParams.PlayTimeAgentParams -> {
PlayTimeAchievement(agentParams.hours, emitter)
}
is AgentParams.RecordAgentParams<*> -> {
RecordAchievement(agentParams as AgentParams.RecordAgentParams<Number>, emitter)
}
is AgentParams.ControlPointCaptureAgentParams -> {
ControlPointCaptureAchievement(agentParams.captures, emitter)
}
is AgentParams.FlagDefendsAgentParams -> {
FlagDefendsAchievement(agentParams.defends, emitter)
is AgentParams.TotalWinsAgentParams -> {
TotalWinsAchievement(agentParams.wins, emitter)
}
is AgentParams.WoolDefendsAgentParams -> {
WoolDefendsAchievement(agentParams.defends, emitter)
is AgentParams.TotalDeathsAgentParams -> {
TotalDeathsAchievement(agentParams.deaths, emitter)
}
is AgentParams.TotalLossesAgentParams -> {
TotalLossesAchievement(agentParams.losses, emitter)
}
// ...
else -> throw IllegalArgumentException("Unknown AgentParams for achievement ${achievement.name}")
}
}

//TODO: Deleting an achievement currently requires a restart for it to completely go away.
private fun fetchNewAchievements() {
Mars.async {
// Fetch the current achievements from the API
val currentAchievements = AchievementFeature.list()



// Find the achievements that are not in the currently loaded achievements
val newAchievements = currentAchievements.filter { it !in achievements }

// If there are new achievements, add them to the list and activate their agents
if (newAchievements.isNotEmpty()) {

achievements += newAchievements
activeAgents += newAchievements.map(::findAgentForAchievement).onEach { it.load() }

sendDebugMessage("Achievements updated via fetchNewAchievements()")
sendConsoleMessage("Achievements updated via fetchNewAchievements()")
sendConsoleMessage("New Achievements added: ")
newAchievements.forEach { sendConsoleMessage("- ${it.name}")}
sendConsoleMessage("Current Achievements: ")
currentAchievements.forEach { sendConsoleMessage("- ${it.name}")}
sendConsoleMessage("Existing database achievements: ")
AchievementFeature.printAchievements()
}
}
}
}
/**
val debugPrefix: String = ChatColor.DARK_GRAY.toString() + "[@] " + ChatColor.GRAY.toString()
val MewTwoKing: Player?
get() = Bukkit.getPlayer("MewTwoKing")
private var initializedAgents = false
private var initializedParentAgents = false
val achievementAgents: MutableList<AchievementAgent> = mutableListOf()
val achievementParentAgents: MutableMap<AchievementParentAgent, MutableList<AchievementAgent>> = mutableMapOf()
// TODO: Achievement parents for the GUI are currently initialized once a player joins for the first time.
// This may need to be changed to a different event.
@EventHandler
private fun onMatchStart(event: MatchStartEvent) {
sendDebugMessage("AchievementManager.onMatchStart called")
if (!initializedAgents) {
initializeAgents()
}
for (agent in achievementAgents) agent.match = event.match
if (!initializedParentAgents) {
initializeParentAgents()
}
sendDebugMessage("AchievementManager.onMatchStart finished")
}
//TODO: Instead of using Achievement.values(), we will be using whatever
// is in the API database.
private fun initializeAgents() {
for (achievement in Achievement.values()) {
println("Enabling achievement: $achievement")
val agent = achievement.agentProvider()
//if (!isValidGamemode(agent.gamemode)) return;
agent.load()
achievementAgents += agent
}
initializedAgents = true
}
private fun initializeParentAgents() {
sendDebugMessage("AchievementManager.initializeParentAgents() called")
for (achievement in Achievement.values()) {
val parent = achievement.agentProvider().parent
achievementParentAgents.getOrPut(parent.agent) { mutableListOf() }.add(achievement.agentProvider())
}
initializedParentAgents = true
sendDebugMessage("AchievementManager.initializeParentAgents() finished")
}
fun unload() {
HandlerList.unregisterAll(this)
for (agent in achievementAgents) agent.unload()
}
fun isValidGamemode(gamemode: String) : Boolean {
try {
GamemodeEnum.valueOf(gamemode.toUpperCase())
return true
}
catch (e: IllegalArgumentException) {
throw InvalidGamemodeException(gamemode)
}
}
fun sendDebugMessage(message: String) {
MewTwoKing?.sendMessage(debugPrefix + message)
}
fun sendDebugStartMessage(achievement: Achievement, functionName: String) {
MewTwoKing?.sendMessage(debugPrefix + "\\u00A7e" + achievement.name + "." + functionName + " started.")
}
fun sendDebugFinishMessage(achievement: Achievement, functionName: String) {
MewTwoKing?.sendMessage(debugPrefix + "\\u00A7e" + achievement.name + "." + functionName + " finished.")
}
}**/
}
Loading

0 comments on commit be1f7e5

Please sign in to comment.