Skip to content

Commit

Permalink
Merge pull request #2370 from kuroma6666/feat-digging-stop-mana-fully…
Browse files Browse the repository at this point in the history
…-consumed

feat: マナが無くなったら掘れなくするパッシブスキルを追加
  • Loading branch information
rito528 authored Dec 21, 2024
2 parents ef1f396 + 1cfc829 commit 3b84a4f
Show file tree
Hide file tree
Showing 12 changed files with 325 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
USE seichiassist;

CREATE TABLE player_break_suppression_preference(
uuid CHAR(36) NOT NULL,
do_break_suppression_due_to_mana BOOL NOT NULL DEFAULT FALSE,
PRIMARY KEY (uuid),
CONSTRAINT fk_player_break_suppression_preference_uuid FOREIGN KEY (uuid) REFERENCES playerdata(uuid)
);
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import com.github.unchama.seichiassist.subsystems.autosave.application.SystemCon
import com.github.unchama.seichiassist.subsystems.breakcount.{BreakCountAPI, BreakCountReadAPI}
import com.github.unchama.seichiassist.subsystems.breakcountbar.BreakCountBarAPI
import com.github.unchama.seichiassist.subsystems.breakskilltargetconfig.BreakSkillTargetConfigAPI
import com.github.unchama.seichiassist.subsystems.breaksuppressionpreference.BreakSuppressionPreferenceAPI
import com.github.unchama.seichiassist.subsystems.buildcount.BuildCountAPI
import com.github.unchama.seichiassist.subsystems.discordnotification.DiscordNotificationAPI
import com.github.unchama.seichiassist.subsystems.donate.DonatePremiumPointAPI
Expand Down Expand Up @@ -495,6 +496,10 @@ class SeichiAssist extends JavaPlugin() {
lazy val breakSkillTargetConfigSystem: subsystems.breakskilltargetconfig.System[IO, Player] =
subsystems.breakskilltargetconfig.System.wired[IO, SyncIO].unsafeRunSync()

lazy val breakSuppressionPreferenceSystem
: subsystems.breaksuppressionpreference.System[IO, Player] =
subsystems.breaksuppressionpreference.System.wired[IO, SyncIO].unsafeRunSync()

/* TODO: mineStackSystemは本来privateであるべきだが、mineStackにアイテムを格納するAPIが現状の
BreakUtilの実装から呼び出されている都合上やむを得ずpublicになっている。*/
lazy val mineStackSystem: subsystems.minestack.System[IO, Player, ItemStack] =
Expand Down Expand Up @@ -562,6 +567,7 @@ class SeichiAssist extends JavaPlugin() {
openirontrapdoor.System.wired,
gridRegionSystem,
breakSkillTargetConfigSystem,
breakSuppressionPreferenceSystem,
joinAndQuitMessenger,
elevatorSystem,
blockLiquidStreamSystem,
Expand Down Expand Up @@ -746,6 +752,8 @@ class SeichiAssist extends JavaPlugin() {
implicit val gridRegionAPI: GridRegionAPI[IO, Player, Location] = gridRegionSystem.api
implicit val breakSkillTargetConfigAPI: BreakSkillTargetConfigAPI[IO, Player] =
breakSkillTargetConfigSystem.api
implicit val breakSuppressionPreferenceAPI: BreakSuppressionPreferenceAPI[IO, Player] =
breakSuppressionPreferenceSystem.api
implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player] = playerHeadSkinSystem.api

val menuRouter = TopLevelRouter.apply
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
import com.github.unchama.seichiassist.util.BreakUtil
import com.github.unchama.seichiassist.{MaterialSets, SeichiAssist}
import com.github.unchama.targetedeffect.player.FocusedSoundEffect
import com.github.unchama.targetedeffect.player.ActionBarMessageEffect
import com.github.unchama.util.bukkit.ItemStackUtil
import com.github.unchama.util.effect.BukkitResources
import com.github.unchama.util.external.WorldGuardWrapper
Expand Down Expand Up @@ -101,20 +102,66 @@ class PlayerBlockBreakListener(
return
}

// 追加マナ獲得
manaApi
.manaAmount(player)
.restoreAbsolute(ManaAmount(BreakUtil.calcManaDrop(player)))
.unsafeRunSync()

// 選択したスキル
val selectedSkill = skillState
.activeSkill
.getOrElse(
return
)

if (!selectedSkill.range.isInstanceOf[MultiArea] || skillState.usageMode == Disabled) return

// 消費するマナが不足しているか判定
{
// プレイヤーのY座標
val playerLocY = player.getLocation.getBlockY - 1
// スキル破壊範囲
val skillArea = BreakArea(selectedSkill, skillState.usageMode)
// 破壊エリアリスト
val breakAreaList = skillArea.makeBreakArea(player).unsafeRunSync()
// 複数種類ブロック同時破壊設定
val isMultiTypeBreakingSkillEnabled =
BreakUtil.performsMultipleIDBlockBreakWhenUsingSkills(player).unsafeRunSync()
// 破壊範囲のブロック計算
val totalBreakRangeVolume = {
val breakLength = skillArea.breakLength
breakLength.x * breakLength.y * breakLength.z * skillArea.breakNum
}
breakAreaList.foreach { breakArea =>
import com.github.unchama.seichiassist.data.syntax._
val BlockSearching.Result(breakBlocks, waterBlocks, lavaBlocks) =
BlockSearching
.searchForBlocksBreakableWithSkill(player, breakArea.gridPoints(), block)
.unsafeRunSync()
.filterSolids(targetBlock =>
isMultiTypeBreakingSkillEnabled || BlockSearching
.multiTypeBreakingFilterPredicate(block)(targetBlock)
)
.filterAll(targetBlock =>
player.isSneaking || targetBlock
.getLocation
.getBlockY > playerLocY || targetBlock == block
)

// 破壊範囲で消費されるマナ計算
val manaToConsumeOnBreakArea = ManaAmount {
(gravity + 1) * selectedSkill.manaCost * (breakBlocks.size + 1).toDouble / totalBreakRangeVolume
}
// 消費マナが不足している場合は処理を終了
manaApi.manaAmount(player).canAcquire(manaToConsumeOnBreakArea).unsafeRunSync() match {
case false if isBreakBlockManaFullyConsumed(player).unsafeRunSync() =>
event.setCancelled(true)
return
case _ =>
}
}
}

// 追加マナ獲得
manaApi
.manaAmount(player)
.restoreAbsolute(ManaAmount(BreakUtil.calcManaDrop(player)))
.unsafeRunSync()

// 破壊不可能ブロックの時処理を終了
if (!BreakUtil.canBreakWithSkill(player, block)) {
event.setCancelled(true)
Expand All @@ -123,21 +170,22 @@ class PlayerBlockBreakListener(

event.setCancelled(true)

// ブロック破壊時に行う処理
{
// プレイヤーの足のy座標を取得
// プレイヤーのY座標
val playerLocY = player.getLocation.getBlockY - 1

// スキル破壊範囲
val skillArea = BreakArea(selectedSkill, skillState.usageMode)
// 破壊エリアリスト
val breakAreaList = skillArea.makeBreakArea(player).unsafeRunSync()

// 複数種類ブロック同時破壊設定
val isMultiTypeBreakingSkillEnabled =
BreakUtil.performsMultipleIDBlockBreakWhenUsingSkills(player).unsafeRunSync()

// 破壊範囲のブロック計算
val totalBreakRangeVolume = {
val breakLength = skillArea.breakLength
breakLength.x * breakLength.y * breakLength.z * skillArea.breakNum
}

// エフェクト用に壊されるブロック全てのリストデータ
val multiBreakList = new ArrayBuffer[Set[BlockBreakableBySkill]]
// 壊される溶岩の全てのリストデータ
Expand Down Expand Up @@ -169,7 +217,6 @@ class PlayerBlockBreakListener(
.getLocation
.getBlockY > playerLocY || targetBlock == block
)

// このチャンクで消費されるマナ
val manaToConsumeOnThisChunk = ManaAmount {
(gravity + 1) * selectedSkill.manaCost * (breakBlocks.size + 1).toDouble / totalBreakRangeVolume
Expand Down Expand Up @@ -373,4 +420,22 @@ class PlayerBlockBreakListener(
event.setCancelled(true)
player.sendMessage(s"${RED}Y-59以下に敷かれたハーフブロックは破壊不可能です。")
}

/**
* ブロック破壊時、「マナ切れブロック破壊停止設定」を取得する。
* マナ切れブロック破壊設定が `true` になっている場合、プレイヤーに破壊抑制メッセージを送信する。
* @param player マナ切れブロック破壊停止設定を取得するプレイヤー
*/
private def isBreakBlockManaFullyConsumed(player: Player): IO[Boolean] = {
for {
breakSuppressionPreference <- SeichiAssist
.instance
.breakSuppressionPreferenceSystem
.api
.isBreakSuppressionEnabled(player)
_ <- ActionBarMessageEffect(s"${RED}マナ切れでブロック破壊を止めるスキルは有効化されています")
.run(player)
.whenA(breakSuppressionPreference)
} yield breakSuppressionPreference
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountAPI
import com.github.unchama.seichiassist.subsystems.breakcount.domain.SeichiAmountData
import com.github.unchama.seichiassist.subsystems.breakcountbar.BreakCountBarAPI
import com.github.unchama.seichiassist.subsystems.breakskilltargetconfig.BreakSkillTargetConfigAPI
import com.github.unchama.seichiassist.subsystems.breaksuppressionpreference.BreakSuppressionPreferenceAPI
import com.github.unchama.seichiassist.subsystems.buildcount.domain.playerdata.BuildAmountData
import com.github.unchama.seichiassist.subsystems.discordnotification.DiscordNotificationAPI
import com.github.unchama.seichiassist.subsystems.donate.DonatePremiumPointAPI
Expand Down Expand Up @@ -104,6 +105,7 @@ object TopLevelRouter {
fairySpeechAPI: FairySpeechAPI[IO, Player],
gridRegionAPI: GridRegionAPI[IO, Player, Location],
breakSkillTargetConfigAPI: BreakSkillTargetConfigAPI[IO, Player],
breakSuppressionPreferenceAPI: BreakSuppressionPreferenceAPI[IO, Player],
playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
): TopLevelRouter[IO] = new TopLevelRouter[IO] {
import assortedRankingApi._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.github.unchama.seichiassist.menus.stickmenu.FirstPage
import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountAPI
import com.github.unchama.seichiassist.subsystems.breakskilltargetconfig.BreakSkillTargetConfigAPI
import com.github.unchama.seichiassist.subsystems.breakskilltargetconfig.domain.BreakSkillTargetConfigKey
import com.github.unchama.seichiassist.subsystems.breaksuppressionpreference.BreakSuppressionPreferenceAPI
import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
import com.github.unchama.targetedeffect._
import com.github.unchama.targetedeffect.commandsender.MessageEffect
Expand All @@ -34,6 +35,7 @@ object PassiveSkillMenu extends Menu {
class Environment(
implicit val breakCountApi: BreakCountAPI[IO, SyncIO, Player],
implicit val breakSkillTargetConfigAPI: BreakSkillTargetConfigAPI[IO, Player],
implicit val breakSuppressionPreferenceAPI: BreakSuppressionPreferenceAPI[IO, Player],
val ioCanOpenFirstPage: IO CanOpen FirstPage.type,
implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
)
Expand Down Expand Up @@ -62,6 +64,7 @@ object PassiveSkillMenu extends Menu {
val dynamicPartComputation = List(
ChestSlotRef(0, 0) -> computeToggleMultipleBlockTypeDestructionButton,
ChestSlotRef(0, 1) -> computeToggleChestBreakButton,
ChestSlotRef(0, 2) -> computeToggleManaFullyConsumedBreakStopButton,
ChestSlotRef(1, 0) -> computeGiganticBerserkButton,
ChestSlotRef(1, 1) -> computeToggleNetherQuartzBlockButton
).traverse(_.sequence)
Expand Down Expand Up @@ -231,6 +234,49 @@ object PassiveSkillMenu extends Menu {
)
})

val computeToggleManaFullyConsumedBreakStopButton: IO[Button] = RecomputedButton(for {
isBreakSuppressionEnabled <- breakSuppressionPreferenceAPI.isBreakSuppressionEnabled(
player
)

} yield {
val baseLore = List(s"${YELLOW}マナ切れでブロック破壊を止めるスキル")
val statusLore = if (isBreakSuppressionEnabled) {
List(s"${GREEN}ON (マナが切れるとブロック破壊を止めます。)", s"${DARK_RED}クリックでOFF")
} else {
List(s"${RED}OFF (マナが切れてもブロック破壊を続けます。)", s"${DARK_GREEN}クリックでON")
}

Button(
new IconItemStackBuilder(Material.LAPIS_LAZULI)
.tap { builder =>
if (isBreakSuppressionEnabled)
builder.enchanted()
}
.title(s"$WHITE$UNDERLINE${BOLD}マナ切れでブロック破壊を止めるスキル切り替え")
.lore(baseLore ++ statusLore)
.build(),
LeftClickButtonEffect {
SequentialEffect(
breakSuppressionPreferenceAPI.toggleBreakSuppression,
DeferredEffect(IO {
if (isBreakSuppressionEnabled) {
SequentialEffect(
MessageEffect(s"${RED}マナが切れたらブロック破壊を止めるスキルを無効化しました。"),
FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 0.5f)
)
} else {
SequentialEffect(
MessageEffect(s"${GREEN}マナが切れたらブロック破壊を止めるスキルを有効化しました。"),
FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 1f)
)
}
})
)
}
)
})

val computeGiganticBerserkButton: IO[Button] = RecomputedButton {
environment
.breakCountApi
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.github.unchama.seichiassist.subsystems.breaksuppressionpreference

import cats.data.Kleisli

trait BreakSuppressionPreferenceAPI[F[_], Player] {

/**
* @return 破壊抑制の設定をトグルする作用
*/
def toggleBreakSuppression: Kleisli[F, Player, Unit]

/**
* @return 現在の破壊抑制の設定を取得する作用
*/
def isBreakSuppressionEnabled(player: Player): F[Boolean]

}

object BreakSkillTriggerConfigAPI {

def apply[F[_], Player](
implicit ev: BreakSuppressionPreferenceAPI[F, Player]
): BreakSuppressionPreferenceAPI[F, Player] = ev

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.github.unchama.seichiassist.subsystems.breaksuppressionpreference

import cats.data.Kleisli
import cats.effect.SyncEffect
import com.github.unchama.datarepository.bukkit.player.BukkitRepositoryControls
import com.github.unchama.generic.ContextCoercion
import com.github.unchama.seichiassist.meta.subsystem.Subsystem
import com.github.unchama.seichiassist.subsystems.breaksuppressionpreference.application.repository.BreakSuppressionPreferenceRepositoryDefinition
import com.github.unchama.seichiassist.subsystems.breaksuppressionpreference.domain.BreakSuppressionPreferencePersistence
import com.github.unchama.seichiassist.subsystems.breaksuppressionpreference.persistence.JdbcBreakSuppressionPreferencePersistence
import org.bukkit.entity.Player

trait System[F[_], Player] extends Subsystem[F] {
val api: BreakSuppressionPreferenceAPI[F, Player]
}

object System {

import cats.implicits._

def wired[F[_], G[_]: SyncEffect: ContextCoercion[*[_], F]]: G[System[F, Player]] = {
implicit val breakSuppressionPreferencePersistence
: BreakSuppressionPreferencePersistence[G] =
new JdbcBreakSuppressionPreferencePersistence[G]

for {
breakSuppressionPreferenceRepositoryControls <- BukkitRepositoryControls.createHandles(
BreakSuppressionPreferenceRepositoryDefinition.withContext[G, Player]
)
} yield {
val breakSuppressionPreferenceRepository =
breakSuppressionPreferenceRepositoryControls.repository

new System[F, Player] {
override val api: BreakSuppressionPreferenceAPI[F, Player] =
new BreakSuppressionPreferenceAPI[F, Player] {
override def toggleBreakSuppression: Kleisli[F, Player, Unit] =
Kleisli { player =>
ContextCoercion(
breakSuppressionPreferenceRepository(player)
.update(_.toggleBreakSuppression())
)
}

override def isBreakSuppressionEnabled(player: Player): F[Boolean] =
ContextCoercion(
breakSuppressionPreferenceRepository(player).get.map(_.doBreakSuppression)
)
}

override val managedRepositoryControls: Seq[BukkitRepositoryControls[F, _]] = Seq(
breakSuppressionPreferenceRepositoryControls.coerceFinalizationContextTo[F]
)
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.github.unchama.seichiassist.subsystems.breaksuppressionpreference.application.repository

import cats.effect.Sync
import cats.effect.concurrent.Ref
import com.github.unchama.datarepository.definitions.RefDictBackedRepositoryDefinition
import com.github.unchama.datarepository.template.RepositoryDefinition
import com.github.unchama.seichiassist.subsystems.breaksuppressionpreference.domain.{
BreakSuppressionPreference,
BreakSuppressionPreferencePersistence
}

object BreakSuppressionPreferenceRepositoryDefinition {

def withContext[F[_]: Sync, Player](
implicit persistence: BreakSuppressionPreferencePersistence[F]
): RepositoryDefinition[F, Player, Ref[F, BreakSuppressionPreference]] =
RefDictBackedRepositoryDefinition
.usingUuidRefDict[F, Player, BreakSuppressionPreference](persistence)(
BreakSuppressionPreference.initial
)
.toRefRepository

}
Loading

0 comments on commit 3b84a4f

Please sign in to comment.