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
1df9acbb
Commit
1df9acbb
authored
May 19, 2022
by
ImmuState
Committed by
Melledy
May 22, 2022
Browse files
Generate energy particle of the correct element for abilities.
parent
2d2dc5d0
Changes
1
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/ability/AbilityManager.java
View file @
1df9acbb
package
emu.grasscutter.game.ability
;
import
java.util.Optional
;
import
com.google.protobuf.InvalidProtocolBufferException
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.custom.AbilityModifier.AbilityModifierAction
;
import
emu.grasscutter.data.def.AvatarSkillDepotData
;
import
emu.grasscutter.data.def.ItemData
;
import
emu.grasscutter.data.custom.AbilityModifierEntry
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.entity.EntityClientGadget
;
import
emu.grasscutter.game.entity.EntityItem
;
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.AbilityInvokeEntryHeadOuterClass.AbilityInvokeEntryHead
;
import
emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry
;
...
...
@@ -18,6 +27,7 @@ import emu.grasscutter.net.proto.AbilityMixinCostStaminaOuterClass.AbilityMixinC
import
emu.grasscutter.net.proto.AbilityScalarValueEntryOuterClass.AbilityScalarValueEntry
;
import
emu.grasscutter.net.proto.ModifierActionOuterClass.ModifierAction
;
import
emu.grasscutter.utils.Position
;
import
emu.grasscutter.utils.Utils
;
public
class
AbilityManager
{
private
Player
player
;
...
...
@@ -31,7 +41,7 @@ public class AbilityManager {
}
public
void
onAbilityInvoke
(
AbilityInvokeEntry
invoke
)
throws
Exception
{
//
System.out.println
(invoke.getArgumentType() + " (" + invoke.getArgumentTypeValue() + "): " + Utils.bytesToHex(invoke.toByteArray()));
//
Grasscutter.getLogger().info
(invoke.getArgumentType() + " (" + invoke.getArgumentTypeValue() + "): " + Utils.bytesToHex(invoke.toByteArray()));
switch
(
invoke
.
getArgumentType
())
{
case
ABILITY_META_OVERRIDE_PARAM:
handleOverrideParam
(
invoke
);
...
...
@@ -138,17 +148,88 @@ public class AbilityManager {
getPlayer
().
getStaminaManager
().
handleMixinCostStamina
(
costStamina
.
getIsSwim
());
}
private
int
getCastingAvatarIdForElemBall
(
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
// that cast the skill.
int
res
=
0
;
// Try to get the invoking entity from the scene.
GameEntity
entity
=
player
.
getScene
().
getEntityById
(
invokeEntityId
);
// If this entity is null, or not an `EntityClientGadget`, we assume that we are directly
// looking at the casting avatar.
if
(!(
entity
instanceof
EntityClientGadget
))
{
res
=
invokeEntityId
;
}
// If the entity is a `EntityClientGadget`, we need to "walk up" the owner hierarchy,
// until the owner is no longer a gadget. This should then be the ID of the casting avatar.
else
{
while
(
entity
instanceof
EntityClientGadget
gadget
)
{
res
=
gadget
.
getOwnerEntityId
();
entity
=
player
.
getScene
().
getEntityById
(
gadget
.
getOwnerEntityId
());
}
}
return
res
;
}
private
void
handleGenerateElemBall
(
AbilityInvokeEntry
invoke
)
throws
InvalidProtocolBufferException
{
// Get action info.
AbilityActionGenerateElemBall
action
=
AbilityActionGenerateElemBall
.
parseFrom
(
invoke
.
getAbilityData
());
if
(
action
==
null
)
{
return
;
}
ItemData
itemData
=
GameData
.
getItemDataMap
().
get
(
2024
);
// Determine the element of the energy particle that we have to generate.
// In case we can't, we default to an elementless particle.
// The element is the element of the avatar that has cast the ability.
// We can get that from the avatar's skill depot.
int
itemId
=
2024
;
// 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
());
Optional
<
EntityAvatar
>
avatarEntity
=
player
.
getTeamManager
().
getActiveTeam
()
.
stream
()
.
filter
(
character
->
character
.
getId
()
==
avatarId
)
.
findFirst
();
if
(
avatarEntity
.
isPresent
())
{
Avatar
avatar
=
avatarEntity
.
get
().
getAvatar
();
if
(
avatar
!=
null
)
{
AvatarSkillDepotData
skillDepotData
=
avatar
.
getSkillDepot
();
if
(
skillDepotData
!=
null
)
{
ElementType
element
=
skillDepotData
.
getElementType
();
// If we found the element, we use it to deterine the ID of the
// energy particle that we have to generate.
if
(
element
!=
null
)
{
itemId
=
switch
(
element
)
{
case
Fire
->
2017
;
case
Water
->
2018
;
case
Grass
->
2019
;
case
Electric
->
2020
;
case
Wind
->
2021
;
case
Ice
->
2022
;
case
Rock
->
2023
;
default
->
2024
;
};
}
}
}
}
// Get the item data for an energy particle of the correct element.
ItemData
itemData
=
GameData
.
getItemDataMap
().
get
(
itemId
);
if
(
itemData
==
null
)
{
return
;
// Should never happen
}
// Generate entity.
EntityItem
energyBall
=
new
EntityItem
(
getPlayer
().
getScene
(),
getPlayer
(),
itemData
,
new
Position
(
action
.
getPos
()),
1
);
energyBall
.
getRotation
().
set
(
action
.
getRot
());
...
...
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