Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
ziqian zhang
Grasscutter
Commits
95bc6558
Commit
95bc6558
authored
May 25, 2022
by
logictc
Committed by
Melledy
May 25, 2022
Browse files
implement skill particle generation
parent
2a76e904
Changes
5
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/ability/AbilityManager.java
View file @
95bc6558
...
...
@@ -19,6 +19,8 @@ import emu.grasscutter.game.entity.GameEntity;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.ElementType
;
import
emu.grasscutter.net.proto.AbilityActionGenerateElemBallOuterClass.AbilityActionGenerateElemBall
;
import
emu.grasscutter.net.proto.AbilityIdentifierOuterClass.AbilityIdentifier
;
import
emu.grasscutter.net.proto.AbilityInvocationsNotifyOuterClass.AbilityInvocationsNotify
;
import
emu.grasscutter.net.proto.AbilityInvokeEntryHeadOuterClass.AbilityInvokeEntryHead
;
import
emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry
;
import
emu.grasscutter.net.proto.AbilityMetaModifierChangeOuterClass.AbilityMetaModifierChange
;
...
...
@@ -42,6 +44,14 @@ public class AbilityManager {
public
void
onAbilityInvoke
(
AbilityInvokeEntry
invoke
)
throws
Exception
{
// Grasscutter.getLogger().info(invoke.getArgumentType() + " (" + invoke.getArgumentTypeValue() + "): " + Utils.bytesToHex(invoke.toByteArray()));
//AbilityIdentifier identifier = AbilityIdentifier.parseFrom(invoke.getAbilityData());
//AbilityInvocationsNotify notify = AbilityInvocationsNotify.parseFrom(invoke.getAbilityData());
//Grasscutter.getLogger().info("Ability id: " + Integer.toString(invoke.getEntityId()));
//Grasscutter.getLogger().info("invoke count: " + Double.toString(invoke.getTotalTickTime()));
switch
(
invoke
.
getArgumentType
())
{
case
ABILITY_META_OVERRIDE_PARAM:
handleOverrideParam
(
invoke
);
...
...
src/main/java/emu/grasscutter/game/managers/EnergyManager/EnergyManager.java
View file @
95bc6558
...
...
@@ -31,6 +31,7 @@ import java.io.Reader;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Optional
;
import
java.util.concurrent.ThreadLocalRandom
;
import
com.google.gson.reflect.TypeToken
;
import
com.google.protobuf.InvalidProtocolBufferException
;
...
...
@@ -38,6 +39,7 @@ import com.google.protobuf.InvalidProtocolBufferException;
public
class
EnergyManager
{
private
final
Player
player
;
private
final
static
Int2ObjectMap
<
List
<
EnergyDropInfo
>>
energyDropData
=
new
Int2ObjectOpenHashMap
<>();
private
final
static
Int2ObjectMap
<
List
<
SkillParticleGenerationInfo
>>
skillParticleGenerationData
=
new
Int2ObjectOpenHashMap
<>();
public
EnergyManager
(
Player
player
)
{
this
.
player
=
player
;
...
...
@@ -61,12 +63,26 @@ public class EnergyManager {
catch
(
Exception
ex
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to load energy drop data."
,
ex
);
}
// Read the data for particle generation from skills
try
(
Reader
fileReader
=
new
InputStreamReader
(
DataLoader
.
load
(
"SkillParticleGeneration.json"
)))
{
List
<
SkillParticleGenerationEntry
>
skillParticleGenerationList
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
TypeToken
.
getParameterized
(
Collection
.
class
,
SkillParticleGenerationEntry
.
class
).
getType
());
for
(
SkillParticleGenerationEntry
entry
:
skillParticleGenerationList
)
{
skillParticleGenerationData
.
put
(
entry
.
getAvatarId
(),
entry
.
getAmountList
());
}
Grasscutter
.
getLogger
().
info
(
"Skill particle generation data successfully loaded."
);
}
catch
(
Exception
ex
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to load skill particle generation data data."
,
ex
);
}
}
/**********
Particle creation for elemental skills.
**********/
private
int
getCastingAvatarIdForElemBall
(
int
invokeEntityId
)
{
private
int
getCastingAvatar
Entity
IdForElemBall
(
int
invokeEntityId
)
{
// To determine the avatar that has cast the skill that caused the energy particle to be generated,
// we have to look at the entity that has invoked the ability. This can either be that avatar directly,
// or it can be an `EntityClientGadget`, owned (some way up the owner hierarchy) by the avatar
...
...
@@ -111,19 +127,41 @@ public class EnergyManager {
// We can get that from the avatar's skill depot.
int
itemId
=
2024
;
// Generate 2 particles by default
int
amount
=
2
;
// Try to fetch the avatar from the player's party and determine their element.
// ToDo: Does this work in co-op?
int
avatarId
=
getCastingAvatarIdForElemBall
(
invoke
.
getEntityId
());
int
avatar
Entity
Id
=
getCastingAvatar
Entity
IdForElemBall
(
invoke
.
getEntityId
());
Optional
<
EntityAvatar
>
avatarEntity
=
player
.
getTeamManager
().
getActiveTeam
()
.
stream
()
.
filter
(
character
->
character
.
getId
()
==
avatarId
)
.
filter
(
character
->
character
.
getId
()
==
avatar
Entity
Id
)
.
findFirst
();
// Bug: invokes twice sometimes, Ayato, Keqing
// Amber not getting element properly
// ToDo: deal with press, hold difference. deal with charge(Beidou, Yunjin)
if
(
avatarEntity
.
isPresent
())
{
Avatar
avatar
=
avatarEntity
.
get
().
getAvatar
();
if
(
avatar
!=
null
)
{
int
avatarId
=
avatar
.
getAvatarId
();
AvatarSkillDepotData
skillDepotData
=
avatar
.
getSkillDepot
();
if
(!
skillParticleGenerationData
.
containsKey
(
avatarId
))
{
Grasscutter
.
getLogger
().
warn
(
"No particle generation data for avatarId {} found."
,
avatarId
);
}
else
{
int
roll
=
ThreadLocalRandom
.
current
().
nextInt
(
0
,
100
);
int
percentageStack
=
0
;
for
(
SkillParticleGenerationInfo
info
:
skillParticleGenerationData
.
get
(
avatarId
))
{
int
chance
=
info
.
getChance
();
percentageStack
+=
chance
;
if
(
roll
<
percentageStack
)
{
amount
=
info
.
getValue
();
break
;
}
}
}
if
(
skillDepotData
!=
null
)
{
ElementType
element
=
skillDepotData
.
getElementType
();
...
...
@@ -147,6 +185,7 @@ public class EnergyManager {
}
// Generate the particle/orb.
for
(
int
i
=
0
;
i
<
amount
;
i
++)
generateElemBall
(
itemId
,
new
Position
(
action
.
getPos
()),
1
);
}
...
...
src/main/java/emu/grasscutter/game/managers/EnergyManager/SkillParticleGenerationEntry.java
0 → 100644
View file @
95bc6558
package
emu.grasscutter.game.managers.EnergyManager
;
import
java.util.List
;
public
class
SkillParticleGenerationEntry
{
private
int
avatarId
;
private
List
<
SkillParticleGenerationInfo
>
amountList
;
public
int
getAvatarId
()
{
return
this
.
avatarId
;
}
public
List
<
SkillParticleGenerationInfo
>
getAmountList
()
{
return
this
.
amountList
;
}
}
src/main/java/emu/grasscutter/game/managers/EnergyManager/SkillParticleGenerationInfo.java
0 → 100644
View file @
95bc6558
package
emu.grasscutter.game.managers.EnergyManager
;
public
class
SkillParticleGenerationInfo
{
private
int
value
;
private
int
chance
;
public
int
getValue
()
{
return
this
.
value
;
}
public
int
getChance
()
{
return
this
.
chance
;
}
}
src/main/resources/defaults/data/SkillParticleGeneration.json
0 → 100644
View file @
95bc6558
[
{
"avatarId"
:
10000002
,
"name"
:
"Kamisato Ayaka"
,
"amountList"
:
[
{
"value"
:
4
,
"chance"
:
50
},
{
"value"
:
5
,
"chance"
:
50
}
]
},
{
"avatarId"
:
10000003
,
"name"
:
"Jean"
,
"amountList"
:
[
{
"value"
:
2
,
"chance"
:
33
},
{
"value"
:
3
,
"chance"
:
67
}
]
},
{
"avatarId"
:
10000005
,
"name"
:
"Traveler"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
67
},
{
"value"
:
4
,
"chance"
:
33
}
]
},
{
"avatarId"
:
10000006
,
"name"
:
"Lisa"
,
"amountList"
:
[
{
"value"
:
5
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000007
,
"name"
:
"Traveler"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
67
},
{
"value"
:
4
,
"chance"
:
33
}
]
},
{
"avatarId"
:
10000014
,
"name"
:
"Barbara"
,
"amountList"
:
[
{
"value"
:
0
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000015
,
"name"
:
"Kaeya"
,
"amountList"
:
[
{
"value"
:
2
,
"chance"
:
33
},
{
"value"
:
3
,
"chance"
:
67
}
]
},
{
"avatarId"
:
10000016
,
"name"
:
"Diluc"
,
"amountList"
:
[
{
"value"
:
1
,
"chance"
:
33
},
{
"value"
:
2
,
"chance"
:
67
}
]
},
{
"avatarId"
:
10000020
,
"name"
:
"Razor"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000021
,
"name"
:
"Amber"
,
"amountList"
:
[
{
"value"
:
4
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000022
,
"name"
:
"Venti"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000023
,
"name"
:
"Xiangling"
,
"amountList"
:
[
{
"value"
:
1
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000024
,
"name"
:
"Beidou"
,
"amountList"
:
[
{
"value"
:
2
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000025
,
"name"
:
"Xingqiu"
,
"amountList"
:
[
{
"value"
:
5
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000026
,
"name"
:
"Xiao"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000027
,
"name"
:
"Ningguang"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
33
},
{
"value"
:
4
,
"chance"
:
67
}
]
},
{
"avatarId"
:
10000029
,
"name"
:
"Klee"
,
"amountList"
:
[
{
"value"
:
4
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000030
,
"name"
:
"Zhongli"
,
"amountList"
:
[
{
"value"
:
0
,
"chance"
:
50
},
{
"value"
:
1
,
"chance"
:
50
}
]
},
{
"avatarId"
:
10000031
,
"name"
:
"Fischl"
,
"amountList"
:
[
{
"value"
:
0
,
"chance"
:
33
},
{
"value"
:
1
,
"chance"
:
67
}
]
},
{
"avatarId"
:
10000032
,
"name"
:
"Bennett"
,
"amountList"
:
[
{
"value"
:
2
,
"chance"
:
75
},
{
"value"
:
3
,
"chance"
:
25
}
]
},
{
"avatarId"
:
10000033
,
"name"
:
"Tartaglia"
,
"amountList"
:
[
{
"value"
:
1
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000034
,
"name"
:
"Noelle"
,
"amountList"
:
[
{
"value"
:
0
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000035
,
"name"
:
"Qiqi"
,
"amountList"
:
[
{
"value"
:
0
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000036
,
"name"
:
"Chongyun"
,
"amountList"
:
[
{
"value"
:
4
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000037
,
"name"
:
"Ganyu"
,
"amountList"
:
[
{
"value"
:
2
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000038
,
"name"
:
"Albedo"
,
"amountList"
:
[
{
"value"
:
0
,
"chance"
:
33
},
{
"value"
:
1
,
"chance"
:
67
}
]
},
{
"avatarId"
:
10000039
,
"name"
:
"Diona"
,
"amountList"
:
[
{
"value"
:
0
,
"chance"
:
20
},
{
"value"
:
1
,
"chance"
:
80
}
]
},
{
"avatarId"
:
10000041
,
"name"
:
"Mona"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
67
},
{
"value"
:
4
,
"chance"
:
33
}
]
},
{
"avatarId"
:
10000042
,
"name"
:
"Keqing"
,
"amountList"
:
[
{
"value"
:
2
,
"chance"
:
50
},
{
"value"
:
3
,
"chance"
:
50
}
]
},
{
"avatarId"
:
10000043
,
"name"
:
"Sucrose"
,
"amountList"
:
[
{
"value"
:
4
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000044
,
"name"
:
"Xinyan"
,
"amountList"
:
[
{
"value"
:
4
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000045
,
"name"
:
"Rosaria"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000046
,
"name"
:
"Hu Tao"
,
"amountList"
:
[
{
"value"
:
2
,
"chance"
:
50
},
{
"value"
:
3
,
"chance"
:
50
}
]
},
{
"avatarId"
:
10000047
,
"name"
:
"Kaedehara Kazuha"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
50
},
{
"value"
:
4
,
"chance"
:
50
}
]
},
{
"avatarId"
:
10000048
,
"name"
:
"Yanfei"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000049
,
"name"
:
"Yoimiya"
,
"amountList"
:
[
{
"value"
:
1
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000050
,
"name"
:
"Thoma"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
50
},
{
"value"
:
4
,
"chance"
:
50
}
]
},
{
"avatarId"
:
10000051
,
"name"
:
"Eula"
,
"amountList"
:
[
{
"value"
:
1
,
"chance"
:
50
},
{
"value"
:
2
,
"chance"
:
50
}
]
},
{
"avatarId"
:
10000052
,
"name"
:
"Raiden Shogun"
,
"amountList"
:
[
{
"value"
:
0
,
"chance"
:
50
},
{
"value"
:
1
,
"chance"
:
50
}
]
},
{
"avatarId"
:
10000053
,
"name"
:
"Sayu"
,
"amountList"
:
[
{
"value"
:
2
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000054
,
"name"
:
"Sangonomiya Kokomi"
,
"amountList"
:
[
{
"value"
:
0
,
"chance"
:
33
},
{
"value"
:
1
,
"chance"
:
67
}
]
},
{
"avatarId"
:
10000055
,
"name"
:
"Gorou"
,
"amountList"
:
[
{
"value"
:
2
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000056
,
"name"
:
"Kujou Sara"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000057
,
"name"
:
"Arataki Itto"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
50
},
{
"value"
:
4
,
"chance"
:
50
}
]
},
{
"avatarId"
:
10000058
,
"name"
:
"Yae Miko"
,
"amountList"
:
[
{
"value"
:
1
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000062
,
"name"
:
"Aloy"
,
"amountList"
:
[
{
"value"
:
5
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000063
,
"name"
:
"Shenhe"
,
"amountList"
:
[
{
"value"
:
3
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000064
,
"name"
:
"Yun Jin"
,
"amountList"
:
[
{
"value"
:
2
,
"chance"
:
100
}
]
},
{
"avatarId"
:
10000066
,
"name"
:
"Kamisato Ayato"
,
"amountList"
:
[
{
"value"
:
1
,
"chance"
:
50
},
{
"value"
:
2
,
"chance"
:
50
}
]
}
]
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment