Skip to content

Commit 1e0aa34

Browse files
authored
Add files via upload
1 parent faaa5a5 commit 1e0aa34

60 files changed

Lines changed: 4184 additions & 225 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/main/kotlin/btc/renaud/vanillaextension/BaseCountObjective.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import com.typewritermc.engine.paper.snippets.snippet
1414
import com.typewritermc.engine.paper.utils.asMini
1515
import com.typewritermc.engine.paper.utils.asMiniWithResolvers
1616
import com.typewritermc.quest.ObjectiveEntry
17+
import btc.renaud.vanillaextension.ObjectiveDisplay
1718
import com.typewritermc.quest.inactiveObjectiveDisplay
1819
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed
1920
import org.bukkit.entity.Player
@@ -155,4 +156,4 @@ abstract class BaseCountObjectiveDisplay<T : BaseCountObjectiveEntry>(ref: Ref<T
155156
}
156157
}
157158
}
158-
}
159+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package btc.renaud.vanillaextension.entries
2+
3+
import com.typewritermc.core.books.pages.Colors
4+
import com.typewritermc.core.entries.Query
5+
import com.typewritermc.core.entries.Ref
6+
import com.typewritermc.core.extension.annotations.ContextKeys
7+
import com.typewritermc.core.extension.annotations.Entry
8+
import com.typewritermc.core.extension.annotations.EntryListener
9+
import com.typewritermc.core.extension.annotations.Help
10+
import com.typewritermc.core.extension.annotations.KeyType
11+
import com.typewritermc.core.interaction.EntryContextKey
12+
import com.typewritermc.core.interaction.context
13+
import com.typewritermc.engine.paper.entry.TriggerableEntry
14+
import com.typewritermc.engine.paper.entry.entries.ConstVar
15+
import com.typewritermc.engine.paper.entry.entries.EventEntry
16+
import com.typewritermc.engine.paper.entry.entries.Var
17+
import com.typewritermc.engine.paper.entry.triggerAllFor
18+
import org.bukkit.entity.Player
19+
import org.bukkit.event.player.PlayerAdvancementDoneEvent
20+
import kotlin.reflect.KClass
21+
22+
@Entry("advancement_grant_event", "Triggered when a player completes an advancement", Colors.YELLOW, "mdi:trophy")
23+
@ContextKeys(AdvancementGrantContextKeys::class)
24+
/**
25+
* The `Advancement Grant Event` is triggered when a player completes an advancement.
26+
*
27+
* ## How could this be used?
28+
* This could be used to complete a quest when the player achieves specific advancements,
29+
* or to give the player additional rewards when they complete certain achievements.
30+
*/
31+
class AdvancementGrantEventEntry(
32+
override val id: String = "",
33+
override val name: String = "",
34+
override val triggers: List<Ref<TriggerableEntry>> = emptyList(),
35+
36+
@Help("The advancement key that needs to be completed. Leave empty to trigger for any advancement.")
37+
val advancementKey: Var<String> = ConstVar(""),
38+
) : EventEntry
39+
40+
enum class AdvancementGrantContextKeys(override val klass: KClass<*>) : EntryContextKey {
41+
@KeyType(String::class)
42+
ADVANCEMENT_KEY(String::class),
43+
44+
@KeyType(String::class)
45+
ADVANCEMENT_TITLE(String::class),
46+
47+
@KeyType(String::class)
48+
ADVANCEMENT_DESCRIPTION(String::class),
49+
}
50+
51+
@EntryListener(AdvancementGrantEventEntry::class)
52+
fun onAdvancementGrant(event: PlayerAdvancementDoneEvent, query: Query<AdvancementGrantEventEntry>) {
53+
val player = event.player
54+
val advancement = event.advancement
55+
56+
val advancementKey = advancement.key.toString()
57+
val advancementTitle = advancement.display?.title()?.toString() ?: "Unknown"
58+
val advancementDescription = advancement.display?.description()?.toString() ?: "Unknown"
59+
60+
// Find matching entries and trigger them
61+
query.findWhere { entry ->
62+
val requiredKey = entry.advancementKey.get(player)
63+
// If no specific advancement is required, trigger for all advancements
64+
requiredKey.isEmpty() || advancementKey.contains(requiredKey)
65+
}.triggerAllFor(player) {
66+
AdvancementGrantContextKeys.ADVANCEMENT_KEY += advancementKey
67+
AdvancementGrantContextKeys.ADVANCEMENT_TITLE += advancementTitle
68+
AdvancementGrantContextKeys.ADVANCEMENT_DESCRIPTION += advancementDescription
69+
}
70+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package btc.renaud.vanillaextension.entries
2+
3+
import com.typewritermc.core.books.pages.Colors
4+
import com.typewritermc.core.entries.Ref
5+
import com.typewritermc.core.entries.emptyRef
6+
import com.typewritermc.core.entries.ref
7+
import com.typewritermc.core.extension.annotations.Entry
8+
import com.typewritermc.core.extension.annotations.Help
9+
import com.typewritermc.engine.paper.entry.Criteria
10+
import com.typewritermc.engine.paper.entry.TriggerableEntry
11+
import com.typewritermc.engine.paper.entry.entries.*
12+
import com.typewritermc.quest.QuestEntry
13+
import btc.renaud.vanillaextension.BaseCountObjectiveEntry
14+
import btc.renaud.vanillaextension.BaseCountObjectiveDisplay
15+
import org.bukkit.entity.Player
16+
import org.bukkit.event.player.PlayerAdvancementDoneEvent
17+
import org.bukkit.event.EventHandler
18+
import org.bukkit.event.EventPriority
19+
import java.util.*
20+
21+
@Entry("advancement_grant_objective", "An objective to complete advancements", Colors.BLUE_VIOLET, "mdi:trophy")
22+
class AdvancementGrantObjectiveEntry(
23+
override val id: String = "",
24+
override val name: String = "",
25+
override val quest: Ref<QuestEntry> = emptyRef(),
26+
override val criteria: List<Criteria> = emptyList(),
27+
override val children: List<Ref<AudienceEntry>> = emptyList(),
28+
override val fact: Ref<CachableFactEntry> = emptyRef(),
29+
@Help("The advancement key that needs to be completed. Leave empty to count any advancement.")
30+
val advancementKey: Var<String> = ConstVar(""),
31+
@Help("The amount of advancements the player needs to complete.")
32+
override val amount: Var<Int> = ConstVar(1),
33+
override val display: Var<String> = ConstVar(""),
34+
override val onComplete: Ref<TriggerableEntry> = emptyRef(),
35+
override val priorityOverride: Optional<Int> = Optional.empty(),
36+
) : BaseCountObjectiveEntry {
37+
override suspend fun display(): AudienceFilter {
38+
return AdvancementGrantObjectiveDisplay(ref())
39+
}
40+
}
41+
42+
private class AdvancementGrantObjectiveDisplay(ref: Ref<AdvancementGrantObjectiveEntry>) :
43+
BaseCountObjectiveDisplay<AdvancementGrantObjectiveEntry>(ref) {
44+
45+
@EventHandler(priority = EventPriority.MONITOR)
46+
fun onAdvancementGrant(event: PlayerAdvancementDoneEvent) {
47+
val player = event.player
48+
val entry = ref.get() ?: return
49+
if (!filter(player)) return
50+
51+
val advancement = event.advancement
52+
val advancementKey = advancement.key.toString()
53+
54+
val requiredKey = entry.advancementKey.get(player)
55+
56+
// If no specific advancement is required, count all advancements
57+
if (requiredKey.isEmpty()) {
58+
incrementCount(player, 1)
59+
return
60+
}
61+
62+
// Check if the advancement key matches the required key
63+
if (advancementKey.contains(requiredKey)) {
64+
incrementCount(player, 1)
65+
}
66+
}
67+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package btc.renaud.vanillaextension.entries
2+
3+
import com.typewritermc.core.books.pages.Colors
4+
import com.typewritermc.core.entries.Query
5+
import com.typewritermc.core.entries.Ref
6+
import com.typewritermc.core.extension.annotations.ContextKeys
7+
import com.typewritermc.core.extension.annotations.Entry
8+
import com.typewritermc.core.extension.annotations.EntryListener
9+
import com.typewritermc.core.extension.annotations.Help
10+
import com.typewritermc.core.extension.annotations.KeyType
11+
import com.typewritermc.core.interaction.EntryContextKey
12+
import com.typewritermc.core.interaction.context
13+
import com.typewritermc.engine.paper.entry.TriggerableEntry
14+
import com.typewritermc.engine.paper.entry.entries.ConstVar
15+
import com.typewritermc.engine.paper.entry.entries.EventEntry
16+
import com.typewritermc.engine.paper.entry.entries.Var
17+
import com.typewritermc.engine.paper.entry.triggerAllFor
18+
import com.typewritermc.engine.paper.utils.item.Item
19+
import org.bukkit.entity.Player
20+
import org.bukkit.event.inventory.InventoryClickEvent
21+
import org.bukkit.event.inventory.InventoryType
22+
import kotlin.reflect.KClass
23+
24+
@Entry("anvil_repair_event", "Triggered when a player repairs or combines items in an anvil", Colors.YELLOW, "mdi:anvil")
25+
@ContextKeys(AnvilRepairContextKeys::class)
26+
/**
27+
* The `Anvil Repair Event` is triggered when a player repairs or combines items using an anvil.
28+
*
29+
* ## How could this be used?
30+
* This could be used to complete a quest where the player has to repair a certain item,
31+
* or to give the player a reward when they repair items in an anvil.
32+
*/
33+
class AnvilRepairEventEntry(
34+
override val id: String = "",
35+
override val name: String = "",
36+
override val triggers: List<Ref<TriggerableEntry>> = emptyList(),
37+
38+
@Help("The item that needs to be repaired. Leave empty to trigger for any repaired item.")
39+
val repairedItem: Var<Item> = ConstVar(Item.Empty),
40+
) : EventEntry
41+
42+
enum class AnvilRepairContextKeys(override val klass: KClass<*>) : EntryContextKey {
43+
@KeyType(Item::class)
44+
REPAIRED_ITEM(Item::class),
45+
46+
@KeyType(Item::class)
47+
FIRST_INPUT_ITEM(Item::class),
48+
49+
@KeyType(Item::class)
50+
SECOND_INPUT_ITEM(Item::class),
51+
52+
@KeyType(Int::class)
53+
EXPERIENCE_COST(Int::class),
54+
}
55+
56+
@EntryListener(AnvilRepairEventEntry::class)
57+
fun onAnvilRepair(event: InventoryClickEvent, query: Query<AnvilRepairEventEntry>) {
58+
// Only trigger for anvil
59+
if (event.inventory.type != InventoryType.ANVIL) return
60+
61+
// Get player
62+
val player = event.whoClicked as? Player ?: return
63+
64+
// Check if clicking on the result slot (slot 2 in anvil)
65+
if (event.rawSlot != 2) return
66+
67+
// Get the result item
68+
val resultItem = event.currentItem ?: return
69+
if (resultItem.type.isAir) return
70+
71+
// Get input items
72+
val firstInput = event.inventory.getItem(0)
73+
val secondInput = event.inventory.getItem(1)
74+
75+
// Find matching entries and trigger them
76+
query.findWhere { entry ->
77+
val requiredItem = entry.repairedItem.get(player)
78+
// If no specific item is required, trigger for all repaired items
79+
requiredItem == Item.Empty || requiredItem.isSameAs(player, resultItem, context())
80+
}.triggerAllFor(player) {
81+
AnvilRepairContextKeys.REPAIRED_ITEM += resultItem
82+
AnvilRepairContextKeys.FIRST_INPUT_ITEM += (firstInput ?: org.bukkit.inventory.ItemStack(org.bukkit.Material.AIR))
83+
AnvilRepairContextKeys.SECOND_INPUT_ITEM += (secondInput ?: org.bukkit.inventory.ItemStack(org.bukkit.Material.AIR))
84+
AnvilRepairContextKeys.EXPERIENCE_COST += event.inventory.getItem(2)?.let {
85+
// Calculate experience cost based on anvil mechanics
86+
// This is a simplified calculation
87+
val firstInputLevel = firstInput?.enchantments?.values?.sum() ?: 0
88+
val secondInputLevel = secondInput?.enchantments?.values?.sum() ?: 0
89+
firstInputLevel + secondInputLevel
90+
} ?: 0
91+
}
92+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package btc.renaud.vanillaextension.entries
2+
3+
import com.typewritermc.core.books.pages.Colors
4+
import com.typewritermc.core.entries.Ref
5+
import com.typewritermc.core.entries.emptyRef
6+
import com.typewritermc.core.entries.ref
7+
import com.typewritermc.core.extension.annotations.Entry
8+
import com.typewritermc.core.extension.annotations.Help
9+
import com.typewritermc.core.interaction.context
10+
import com.typewritermc.engine.paper.entry.Criteria
11+
import com.typewritermc.engine.paper.entry.TriggerableEntry
12+
import com.typewritermc.engine.paper.entry.entries.*
13+
import com.typewritermc.quest.QuestEntry
14+
import btc.renaud.vanillaextension.BaseCountObjectiveEntry
15+
import btc.renaud.vanillaextension.BaseCountObjectiveDisplay
16+
import com.typewritermc.engine.paper.utils.item.Item
17+
import org.bukkit.event.inventory.InventoryClickEvent
18+
import org.bukkit.event.inventory.InventoryType
19+
import org.bukkit.event.EventHandler
20+
import org.bukkit.event.EventPriority
21+
import org.bukkit.entity.Player
22+
import java.util.*
23+
24+
@Entry("anvil_repair_objective", "An objective to repair items using an anvil", Colors.BLUE_VIOLET, "mdi:anvil")
25+
class AnvilRepairObjectiveEntry(
26+
override val id: String = "",
27+
override val name: String = "",
28+
override val quest: Ref<QuestEntry> = emptyRef(),
29+
override val criteria: List<Criteria> = emptyList(),
30+
override val children: List<Ref<AudienceEntry>> = emptyList(),
31+
override val fact: Ref<CachableFactEntry> = emptyRef(),
32+
@Help("The item that needs to be repaired. Leave empty to count any repaired item.")
33+
val repairedItem: Var<Item> = ConstVar(Item.Empty),
34+
@Help("The amount of times the player needs to repair items.")
35+
override val amount: Var<Int> = ConstVar(1),
36+
override val display: Var<String> = ConstVar(""),
37+
override val onComplete: Ref<TriggerableEntry> = emptyRef(),
38+
override val priorityOverride: Optional<Int> = Optional.empty(),
39+
) : BaseCountObjectiveEntry {
40+
override suspend fun display(): AudienceFilter {
41+
return AnvilRepairObjectiveDisplay(ref())
42+
}
43+
}
44+
45+
private class AnvilRepairObjectiveDisplay(ref: Ref<AnvilRepairObjectiveEntry>) :
46+
BaseCountObjectiveDisplay<AnvilRepairObjectiveEntry>(ref) {
47+
48+
@EventHandler(priority = EventPriority.MONITOR)
49+
fun onInventoryClick(event: InventoryClickEvent) {
50+
val player = event.whoClicked as? Player ?: return
51+
val entry = ref.get() ?: return
52+
if (!filter(player)) return
53+
54+
// Only trigger for anvil
55+
if (event.inventory.type != InventoryType.ANVIL) return
56+
57+
// Check if clicking on the result slot (slot 2 in anvil)
58+
if (event.rawSlot != 2) return
59+
60+
val resultItem = event.currentItem ?: return
61+
if (resultItem.type.isAir) return
62+
63+
val requiredItem = entry.repairedItem.get(player)
64+
65+
// If no specific item is required, count all repaired items
66+
if (requiredItem == Item.Empty) {
67+
incrementCount(player, 1)
68+
return
69+
}
70+
71+
// Check if the result item matches the required item
72+
if (requiredItem.isSameAs(player, resultItem, context())) {
73+
incrementCount(player, 1)
74+
}
75+
}
76+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package btc.renaud.vanillaextension.entries
2+
3+
import com.typewritermc.core.books.pages.Colors
4+
import com.typewritermc.core.entries.Query
5+
import com.typewritermc.core.entries.Ref
6+
import com.typewritermc.core.extension.annotations.ContextKeys
7+
import com.typewritermc.core.extension.annotations.Entry
8+
import com.typewritermc.core.extension.annotations.EntryListener
9+
import com.typewritermc.core.extension.annotations.KeyType
10+
import com.typewritermc.core.interaction.EntryContextKey
11+
import com.typewritermc.engine.paper.entry.TriggerableEntry
12+
import com.typewritermc.engine.paper.entry.entries.EventEntry
13+
import com.typewritermc.engine.paper.entry.triggerAllFor
14+
import com.typewritermc.engine.paper.utils.toPosition
15+
import com.typewritermc.core.utils.point.Position
16+
import org.bukkit.Material
17+
import org.bukkit.entity.Player
18+
import org.bukkit.event.inventory.InventoryCloseEvent
19+
import kotlin.reflect.KClass
20+
21+
@Entry("barrel_close_event", "Triggered when a player closes a barrel", Colors.YELLOW, "mdi:barrel-outline")
22+
@ContextKeys(BarrelCloseContextKeys::class)
23+
/**
24+
* The `Barrel Close Event` is triggered when a player closes a barrel.
25+
*
26+
* ## How could this be used?
27+
* This could be used to track storage access completion,
28+
* complete quests involving barrel interaction, or trigger events when players finish accessing barrels.
29+
*/
30+
class BarrelCloseEventEntry(
31+
override val id: String = "",
32+
override val name: String = "",
33+
override val triggers: List<Ref<TriggerableEntry>> = emptyList(),
34+
) : EventEntry
35+
36+
enum class BarrelCloseContextKeys(override val klass: KClass<*>) : EntryContextKey {
37+
@KeyType(Position::class)
38+
BARREL_LOCATION(Position::class),
39+
}
40+
41+
@EntryListener(BarrelCloseEventEntry::class)
42+
fun onBarrelClose(event: InventoryCloseEvent, query: Query<BarrelCloseEventEntry>) {
43+
val player = event.player as? Player ?: return
44+
val inventory = event.inventory
45+
val location = inventory.location ?: return
46+
47+
// Check if the closed inventory is a barrel
48+
val block = location.block
49+
if (block.type != Material.BARREL) return
50+
51+
query.findWhere { true } // No specific conditions for closing barrels
52+
.triggerAllFor(player) {
53+
BarrelCloseContextKeys.BARREL_LOCATION += location.toPosition()
54+
}
55+
}

0 commit comments

Comments
 (0)