Skip to content

Commit d80e032

Browse files
committed
# 新增
支持自定义SequencedParticleShapeStyle
1 parent 9f8be69 commit d80e032

7 files changed

Lines changed: 284 additions & 17 deletions

File tree

src/main/kotlin/cn/coostack/cooparticlesapi/network/buffer/ParticleControlerDataBuffers.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ object ParticleControlerDataBuffers {
165165
register(LongArray::class.java, LongArrayControlerBuffer.id, LongArrayControlerBuffer::class.java)
166166
register(UUID::class.java, UUIDControlerBuffer.id, UUIDControlerBuffer::class.java)
167167
register(Vec3d::class.java, Vec3dControlerBuffer.id, Vec3dControlerBuffer::class.java)
168+
register(RelativeLocation::class.java, RelativeLocationControlerBuffer.id, RelativeLocationControlerBuffer::class.java)
168169
register(Short::class.java, ShortControlerBuffer.id, ShortControlerBuffer::class.java)
169170
register(Unit::class.java, EmptyControlerBuffer.id, EmptyControlerBuffer::class.java)
170171
register(Char::class.java, CharControlerBuffer.id, CharControlerBuffer::class.java)

src/main/kotlin/cn/coostack/cooparticlesapi/network/particle/style/ParticleGroupStyle.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ abstract class ParticleGroupStyle(var visibleRange: Double = 32.0, val uuid: UUI
246246
onDisplay()
247247
return
248248
}
249-
onDisplay()
250249
flush()
250+
onDisplay()
251251
}
252252

253253
open fun flush() {
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
package cn.coostack.cooparticlesapi.network.particle.style
2+
3+
import cn.coostack.cooparticlesapi.network.buffer.ParticleControlerDataBuffer
4+
import cn.coostack.cooparticlesapi.particles.ParticleDisplayer
5+
import cn.coostack.cooparticlesapi.utils.RelativeLocation
6+
import cn.coostack.cooparticlesapi.utils.builder.PointsBuilder
7+
import cn.coostack.cooparticlesapi.utils.helper.ScaleHelper
8+
import cn.coostack.cooparticlesapi.utils.helper.impl.StyleBezierValueScaleHelper
9+
import cn.coostack.cooparticlesapi.utils.helper.impl.StyleScaleHelper
10+
import cn.coostack.cooparticlesapi.utils.helper.impl.StyleStatusHelper
11+
import net.minecraft.client.particle.ParticleTextureSheet
12+
import net.minecraft.entity.player.PlayerEntity
13+
import net.minecraft.util.math.Vec3d
14+
import java.util.SortedMap
15+
import java.util.TreeMap
16+
import java.util.UUID
17+
import java.util.function.Predicate
18+
19+
/**
20+
* 为了方便制作子图形作用于父图形 (进行不同方向的旋转, rotate)
21+
* 专门创建此类
22+
*
23+
* 无法单独生成
24+
* 继承此类的目的是为这个类创建一个专属形状的子类
25+
* client属性始终为true
26+
*/
27+
class SequencedParticleShapeStyle(uuid: UUID) :
28+
SequencedParticleStyle(64.0, uuid) {
29+
var scaleHelper: ScaleHelper? = null
30+
private var onDisplayInvoke: SequencedParticleShapeStyle.() -> Unit = {}
31+
private var beforeDisplayInvoke: SequencedParticleShapeStyle.(SortedMap<SortedStyleData, RelativeLocation>) -> Unit =
32+
{}
33+
private val pointBuilders = LinkedHashMap<PointsBuilder, (RelativeLocation) -> SortedStyleData>()
34+
35+
/**
36+
* 用于控制粒子的播放顺序
37+
* 如果满足 animationConditions[animationIndex].first的条件
38+
* 则会执行 addMultiple(second (second > 0))
39+
* 或者 removeMultiple(second (second < 0)
40+
* 符合条件后 animationIndex 会递增
41+
* 直到到达边界
42+
*/
43+
private val animationConditions = ArrayList<Pair<Predicate<SequencedParticleStyle>, Int>>()
44+
var animationIndex = 0
45+
private set
46+
47+
/**
48+
* 通过判断(外层) 提供的状态工具来决定是否反转缩放
49+
* 在toggleDisplay执行这个方法
50+
*/
51+
val reverseFunctionFromStatus: (SequencedParticleShapeStyle, StyleStatusHelper) -> Unit =
52+
function@{ it, displayStatus ->
53+
// 必须设置缩放工具
54+
if (scaleHelper == null) return@function
55+
it.addPreTickAction {
56+
if (it.scaleReversed && it.scaleHelper!!.isZero()) {
57+
it.remove()
58+
return@addPreTickAction
59+
}
60+
if (displayStatus.displayStatus != 2) {
61+
return@addPreTickAction
62+
}
63+
if (!it.scaleReversed) {
64+
it.scaleReversed(false)
65+
}
66+
}
67+
}
68+
69+
/**
70+
* 设置为true时 会利用scaleHelper 每tick增长一点
71+
*/
72+
var scalePreTick = false
73+
private set
74+
75+
/**
76+
* 设置为true时 利用scaleHelper 每tick减弱一点
77+
*/
78+
var scaleReversed = false
79+
private set
80+
81+
fun appendBuilder(
82+
pointsBuilder: PointsBuilder,
83+
dataBuilder: (RelativeLocation) -> SortedStyleData
84+
): SequencedParticleShapeStyle {
85+
pointBuilders[pointsBuilder] = dataBuilder
86+
return this
87+
}
88+
89+
fun appendPoint(
90+
point: RelativeLocation,
91+
dataBuilder: (RelativeLocation) -> SortedStyleData
92+
): SequencedParticleShapeStyle {
93+
pointBuilders[
94+
PointsBuilder().also { it.addPoint(point) }
95+
] = dataBuilder
96+
return this
97+
}
98+
99+
/**
100+
* @param predicate 设置添加/删除动画的要求
101+
* @param add 向下的个数
102+
*/
103+
fun appendAnimateCondition(predicate: Predicate<SequencedParticleStyle>, add: Int): SequencedParticleShapeStyle {
104+
animationConditions.add(predicate to add)
105+
return this
106+
}
107+
108+
/**
109+
* @param max 直接让scale从最大开始
110+
*/
111+
fun scaleReversed(max: Boolean): SequencedParticleShapeStyle {
112+
scaleHelper ?: return this
113+
scaleReversed = true
114+
if (max) {
115+
scaleHelper!!.toggleScale(scaleHelper!!.maxScale)
116+
}
117+
return this
118+
}
119+
120+
fun loadScaleHelper(minScale: Double, maxScale: Double, scaleTick: Int): SequencedParticleShapeStyle {
121+
scaleHelper = StyleScaleHelper(minScale, maxScale, scaleTick)
122+
scalePreTick = true
123+
scaleHelper!!.loadControler(this)
124+
return this
125+
}
126+
127+
fun loadScaleHelperBezierValue(
128+
minScale: Double,
129+
maxScale: Double,
130+
scaleTick: Int,
131+
c1: RelativeLocation,
132+
c2: RelativeLocation
133+
): SequencedParticleShapeStyle {
134+
scaleHelper = StyleBezierValueScaleHelper(scaleTick, minScale, maxScale, c1, c2)
135+
scalePreTick = true
136+
scaleHelper!!.loadControler(this)
137+
return this
138+
}
139+
140+
/**
141+
* 在display之前执行
142+
*/
143+
fun toggleOnDisplay(toggleMethod: SequencedParticleShapeStyle.() -> Unit): SequencedParticleShapeStyle {
144+
onDisplayInvoke = toggleMethod
145+
return this
146+
}
147+
148+
/**
149+
* 在生成粒子之前执行
150+
*/
151+
fun toggleBeforeDisplay(toggleMethod: SequencedParticleShapeStyle.(Map<SortedStyleData, RelativeLocation>) -> Unit): SequencedParticleShapeStyle {
152+
beforeDisplayInvoke = toggleMethod
153+
return this
154+
}
155+
156+
157+
override fun beforeDisplay(styles: SortedMap<SortedStyleData, RelativeLocation>) {
158+
beforeDisplayInvoke(styles)
159+
}
160+
161+
162+
override fun onDisplay() {
163+
onDisplayInvoke()
164+
addPreTickAction {
165+
if (animationIndex >= animationConditions.size) {
166+
return@addPreTickAction
167+
}
168+
val (predicate, add) = animationConditions[animationIndex]
169+
if (predicate.test(this@SequencedParticleShapeStyle)) {
170+
if (add > 0) {
171+
addMultiple(add)
172+
} else {
173+
removeMultiple(add)
174+
}
175+
animationIndex++
176+
}
177+
}
178+
addPreTickAction {
179+
if (!scalePreTick || scaleHelper == null) {
180+
return@addPreTickAction
181+
}
182+
183+
if (scaleReversed) {
184+
scaleHelper!!.doScaleReversed()
185+
} else {
186+
scaleHelper!!.doScale()
187+
}
188+
}
189+
}
190+
191+
private val bufferFrame: SortedMap<SortedStyleData, RelativeLocation> = TreeMap()
192+
override fun getParticlesCount(): Int {
193+
return bufferFrame.size
194+
}
195+
196+
override fun getCurrentFramesSequenced(): SortedMap<SortedStyleData, RelativeLocation> {
197+
val res = TreeMap<SortedStyleData, RelativeLocation>()
198+
pointBuilders.forEach { entry ->
199+
res.putAll(entry.key.createWithSequencedStyleData { it, order ->
200+
entry.value(it)
201+
})
202+
}
203+
return res
204+
}
205+
206+
override fun writePacketArgsSequenced(): Map<String, ParticleControlerDataBuffer<*>> {
207+
return mapOf()
208+
}
209+
210+
override fun readPacketArgsSequenced(args: Map<String, ParticleControlerDataBuffer<*>>) {
211+
}
212+
213+
214+
fun fastRotateToPlayerView(player: PlayerEntity) {
215+
rotateParticlesToPoint(RelativeLocation.of(player.rotationVector))
216+
}
217+
218+
fun fastStyleData(order: Int, color: Vec3d, displayer: (UUID) -> ParticleDisplayer): SortedStyleData {
219+
return SortedStyleData(displayer, order).withParticleHandler {
220+
this.colorOfRGB(color.x.toInt(), color.y.toInt(), color.z.toInt())
221+
} as SortedStyleData
222+
}
223+
224+
fun fastStyleData(
225+
order: Int,
226+
color: Vec3d,
227+
sheet: ParticleTextureSheet,
228+
displayer: (UUID) -> ParticleDisplayer
229+
): SortedStyleData {
230+
return SortedStyleData(displayer, order).withParticleHandler {
231+
this.colorOfRGB(color.x.toInt(), color.y.toInt(), color.z.toInt())
232+
this.textureSheet = sheet
233+
} as SortedStyleData
234+
}
235+
236+
fun fastStyleData(
237+
order: Int,
238+
color: Vec3d,
239+
sheet: ParticleTextureSheet,
240+
size: Float,
241+
displayer: (UUID) -> ParticleDisplayer
242+
): SortedStyleData {
243+
return SortedStyleData(displayer, order).withParticleHandler {
244+
this.colorOfRGB(color.x.toInt(), color.y.toInt(), color.z.toInt())
245+
this.textureSheet = sheet
246+
this.size = size
247+
} as SortedStyleData
248+
}
249+
250+
fun fastStyleData(
251+
order: Int,
252+
color: Vec3d,
253+
sheet: ParticleTextureSheet,
254+
size: Float,
255+
alpha: Float,
256+
displayer: (UUID) -> ParticleDisplayer
257+
): SortedStyleData {
258+
return SortedStyleData(displayer, order).withParticleHandler {
259+
this.colorOfRGB(color.x.toInt(), color.y.toInt(), color.z.toInt())
260+
this.textureSheet = sheet
261+
this.size = size
262+
this.particleAlpha = alpha
263+
} as SortedStyleData
264+
}
265+
266+
fun fastStyleData(
267+
order: Int,
268+
sheet: ParticleTextureSheet,
269+
displayer: (UUID) -> ParticleDisplayer
270+
): SortedStyleData {
271+
return SortedStyleData(displayer, order).withParticleHandler {
272+
this.textureSheet = sheet
273+
} as SortedStyleData
274+
}
275+
}

src/main/kotlin/cn/coostack/cooparticlesapi/network/particle/style/SequencedParticleStyle.kt

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,9 @@ abstract class SequencedParticleStyle(visibleRange: Double = 32.0, uuid: UUID =
272272
onDisplay()
273273
return
274274
}
275-
onDisplay()
276275
flush()
277276
toggleDataStatus()
277+
onDisplay()
278278
}
279279

280280
/**
@@ -338,10 +338,6 @@ abstract class SequencedParticleStyle(visibleRange: Double = 32.0, uuid: UUID =
338338
if (method == SequencedChangeMethod.CHANGE_LINKED) {
339339
// 一个客户端和服务端同时执行完 addSingle -> particleLinkageDisplayCurrentIndex + count(客户端当前值) -> index (来自服务器)
340340
// 一个客户端和服务端同时执行完 removeSingle -> particleLinkageDisplayCurrentIndex - count(客户端当前值) -> index (来自服务器)
341-
val index = if (status) indexes[0] else indexes[indexes.size - 1]
342-
if (index != particleLinkageDisplayCurrentIndex) {
343-
return@let
344-
}
345341
if (status) {
346342
addMultiple(indexes.size)
347343
} else {
@@ -397,7 +393,7 @@ abstract class SequencedParticleStyle(visibleRange: Double = 32.0, uuid: UUID =
397393
// 同步到其他客户端
398394
change(
399395
mapOf(
400-
"rotate_to" to ParticleControlerDataBuffers.vec3d(to.toVector()),
396+
"rotate_to" to ParticleControlerDataBuffers.relative(to),
401397
"rotate_angle" to ParticleControlerDataBuffers.double(angle)
402398
)
403399
)
@@ -414,7 +410,7 @@ abstract class SequencedParticleStyle(visibleRange: Double = 32.0, uuid: UUID =
414410
// 同步到其他客户端
415411
change(
416412
mapOf(
417-
"rotate_to" to ParticleControlerDataBuffers.vec3d(to.toVector())
413+
"rotate_to" to ParticleControlerDataBuffers.relative(to)
418414
)
419415
)
420416
}
@@ -439,9 +435,7 @@ abstract class SequencedParticleStyle(visibleRange: Double = 32.0, uuid: UUID =
439435
return
440436
}
441437

442-
val pair = sequencedParticles[index]
443-
val rl = pair.second
444-
val data = pair.first
438+
val (data, rl) = sequencedParticles[index]
445439
val uuid = data.uuid
446440

447441
val displayer = data.displayerBuilder(uuid)

src/main/kotlin/cn/coostack/cooparticlesapi/particles/ControlableParticle.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,10 @@ import net.minecraft.util.math.Box
1616
import net.minecraft.util.math.MathHelper
1717
import net.minecraft.util.math.Vec3d
1818
import net.minecraft.util.math.random.Random
19-
import org.joml.Matrix4f
2019
import org.joml.Quaternionf
2120
import org.joml.Vector2f
2221
import org.joml.Vector3f
23-
import org.joml.Vector4f
24-
import org.lwjgl.opengl.GL11
2522
import java.util.*
26-
import kotlin.math.PI
2723

2824

2925
@Environment(EnvType.CLIENT)

src/main/kotlin/cn/coostack/cooparticlesapi/utils/helper/AlphaHelper.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,15 @@ abstract class AlphaHelper(var minAlpha: Double, var maxAlpha: Double, var alpha
7575
fun increaseAlpha() {
7676
getLoadedGroup()?.takeUnless { over() }?.let {
7777
current++
78-
setAlpha(getCurrentAlpha() + step)
78+
setAlpha(minAlpha + step * current)
7979
}
8080
}
8181

8282
// 反向逐步降低透明度(更透明)
8383
fun decreaseAlpha() {
8484
getLoadedGroup()?.takeUnless { isZero() }?.let {
8585
current--
86-
setAlpha(getCurrentAlpha() - step)
86+
setAlpha(minAlpha + step * current)
8787
}
8888
}
8989

src/main/kotlin/cn/coostack/cooparticlesapi/utils/helper/impl/StyleAlphaHelper.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,6 @@ class StyleAlphaHelper(minAlpha: Double, maxAlpha: Double, alphaTick: Int) :
4747
return
4848
}
4949
this.style = controler
50+
setAlpha(minAlpha)
5051
}
5152
}

0 commit comments

Comments
 (0)