Skip to content

Commit

Permalink
Merge pull request #71 from gabber235/develop
Browse files Browse the repository at this point in the history
Bugfixes
  • Loading branch information
gabber235 authored Sep 1, 2023
2 parents 7af3b64 + f73b3dd commit 2b4a72f
Show file tree
Hide file tree
Showing 77 changed files with 1,632 additions and 965 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package me.gabber235.typewriter.entries.cinematic

import com.github.shynixn.mccoroutine.bukkit.minecraftDispatcher
import kotlinx.coroutines.withContext
import me.gabber235.typewriter.adapters.Colors
import me.gabber235.typewriter.adapters.Entry
import me.gabber235.typewriter.adapters.modifiers.*
import me.gabber235.typewriter.entry.Criteria
import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction
import me.gabber235.typewriter.entry.entries.CinematicAction
import me.gabber235.typewriter.entry.entries.CinematicEntry
import me.gabber235.typewriter.entry.entries.Segment
import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders
import me.gabber235.typewriter.plugin
import me.gabber235.typewriter.utils.Icons
import org.bukkit.entity.Player

interface CinematicCommandEntry : CinematicEntry {
val segments: List<CommandSegment>
}

@Entry("cinematic_console_command", "Runs command as the console at a specific frame.", Colors.YELLOW, Icons.TERMINAL)
/**
* The `Cinematic Console Command` entry runs a command as the console at a specific frame.
*
* ## How could this be used?
*
* You can use a different plugin to animate blocks, hide a scoreboard, or trigger something in another plugin.
*/
class CinematicConsoleCommandEntry(
override val id: String,
override val name: String,
override val criteria: List<Criteria>,
@Segments(Colors.YELLOW, Icons.TERMINAL)
@Placeholder
@InnerMax(Max(1))
// Run commands on different segments
override val segments: List<CommandSegment>,
) : CinematicCommandEntry {
override fun create(player: Player): CinematicAction {
return CommandAction(
player,
this
) { command ->
player.server.dispatchCommand(player.server.consoleSender, command)
}
}
}

@Entry("cinematic_player_command", "Runs command as the player at a specific frame.", Colors.YELLOW, Icons.TERMINAL)
/**
* The `Cinematic Player Command` entry runs a command as the player at a specific frame.
*
* ## How could this be used?
*
* You can use a different plugin to animate blocks, hide a scoreboard, or trigger something in another plugin.
*/
class CinematicPlayerCommandEntry(
override val id: String,
override val name: String,
override val criteria: List<Criteria>,
@Segments(Colors.YELLOW, Icons.TERMINAL)
@Placeholder
@InnerMax(Max(1))
// Run commands on different segments
override val segments: List<CommandSegment>,
) : CinematicCommandEntry {
override fun create(player: Player): CinematicAction {
return CommandAction(
player,
this
) { command ->
player.performCommand(command)
}
}
}

data class CommandSegment(
override val startFrame: Int,
override val endFrame: Int,
@Help("The command to run")
val command: String,
) : Segment

class CommandAction(
private val player: Player,
entry: CinematicCommandEntry,
private val run: (String) -> Unit,
) : SimpleCinematicAction<CommandSegment>() {
override val segments: List<CommandSegment> = entry.segments

override suspend fun startSegment(segment: CommandSegment) {
super.startSegment(segment)
withContext(plugin.minecraftDispatcher) {
run(segment.command.parsePlaceholders(player))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ class DisplayDialogueCinematicAction(
override suspend fun setup() {
super.setup()
state = player.state(EXP, LEVEL)
player.exp = 0f
player.level = 0
setup?.invoke(player)
}

Expand All @@ -67,9 +65,11 @@ class DisplayDialogueCinematicAction(
val segment = (segments activeSegmentAt frame)

if (segment == null) {
if (previousSegment != null) {
if (player.exp > 0f || player.level > 0) {
player.exp = 0f
player.level = 0
}
if (previousSegment != null) {
reset?.invoke(player)
previousSegment = null
}
Expand All @@ -88,6 +88,12 @@ class DisplayDialogueCinematicAction(
// The percentage of the dialogue that should be displayed.
val displayPercentage = percentage / splitPercentage

if (displayPercentage > 1) {
// When the dialogue is fully displayed, we don't need to display it every tick and should avoid spamming the player.
val needsDisplay = (frame - segment.startFrame) % 20 == 0
if (!needsDisplay) return
}

val text = segment.text.parsePlaceholders(player)

display(player, speaker?.displayName ?: "", text, displayPercentage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ class JavaOptionDialogueDialogueMessenger(player: Player, entry: OptionDialogueE
override fun tick(cycle: Int) {
if (state != MessengerState.RUNNING) return

if (cycle % 100 > 0) {
// Only update periodically to avoid spamming the player
return
}

val message = optionFormat.asMiniWithResolvers(
Placeholder.parsed("speaker", speakerDisplayName),
Placeholder.parsed("text", entry.text.parsePlaceholders(player)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@ val spokenFormat: String by snippet(
""".trimMargin()
)

val spokenInstructionNextText: String by snippet("dialogue.spoken.instruction.next", "continue")
val spokenInstructionFinishText: String by snippet("dialogue.spoken.instruction.finish", "finish")
val spokenInstructionBaseColor: String by snippet("dialogue.spoken.instruction.color.base", "<gray>")
val spokenInstructionHighlightColor: String by snippet("dialogue.spoken.instruction.color.highlight", "<red>")
val spokenPadding: String by snippet("dialogue.spoken.padding", " ")
val spokenMinLines: Int by snippet("dialogue.spoken.minLines", 3)
val spokenMaxLineLength: Int by snippet("dialogue.spoken.maxLineLength", 40)
val spokenInstructionTicksHighlighted: Int by snippet("dialogue.spoken.instruction.ticks.highlighted", 10)
val spokenInstructionTicksBase: Int by snippet("dialogue.spoken.instruction.ticks.base", 30)


@Messenger(SpokenDialogueEntry::class)
Expand Down Expand Up @@ -73,9 +79,20 @@ fun Player.sendSpokenDialogue(

val percentage = (cycle / durationInTicks.toDouble())

val nextColor = if (cycle > durationInTicks * 2.5 && (cycle / 6) % 3 == 0) "<red>" else "<gray>"
val totalInstructionDuration = spokenInstructionTicksHighlighted + spokenInstructionTicksBase
val instructionCycle = cycle % totalInstructionDuration
if (percentage > 1) {
// Change in highlight color
val shouldDisplay = instructionCycle == 0 || instructionCycle == spokenInstructionTicksHighlighted
if (!shouldDisplay) return
}

val highlightStarted = cycle > durationInTicks * 2.5
val needsHighlight = instructionCycle < spokenInstructionTicksHighlighted
val nextColor =
if (highlightStarted && needsHighlight) spokenInstructionHighlightColor else spokenInstructionBaseColor

val continueOrFinish = if (canFinish) "finish" else "continue"
val continueOrFinish = if (canFinish) spokenInstructionFinishText else spokenInstructionNextText

val message = text.parsePlaceholders(this).asPartialFormattedMini(
percentage,
Expand Down
2 changes: 1 addition & 1 deletion app/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,4 @@ custom_lint:
provider_parameters: true
unsupported_provider_value: true
generator_class_extends: true
avoid_manual_providers_as_generated_provider_dependency: false
avoid_manual_providers_as_generated_provider_dependency: false
3 changes: 2 additions & 1 deletion app/lib/app_router.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 2b4a72f

Please sign in to comment.