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
2dfdc627
Commit
2dfdc627
authored
May 08, 2022
by
Melledy
Browse files
Implement energy balls (orbs)
parent
897f082b
Changes
9
Hide whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/ability/AbilityManager.java
View file @
2dfdc627
...
...
@@ -7,9 +7,12 @@ import emu.grasscutter.data.GameData;
import
emu.grasscutter.data.custom.AbilityModifier
;
import
emu.grasscutter.data.custom.AbilityModifier.AbilityModifierAction
;
import
emu.grasscutter.data.custom.AbilityModifier.AbilityModifierActionType
;
import
emu.grasscutter.data.def.ItemData
;
import
emu.grasscutter.data.custom.AbilityModifierEntry
;
import
emu.grasscutter.game.entity.EntityItem
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.net.proto.AbilityActionGenerateElemBallOuterClass.AbilityActionGenerateElemBall
;
import
emu.grasscutter.net.proto.AbilityInvokeArgumentOuterClass.AbilityInvokeArgument
;
import
emu.grasscutter.net.proto.AbilityInvokeEntryHeadOuterClass.AbilityInvokeEntryHead
;
import
emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry
;
...
...
@@ -18,6 +21,7 @@ import emu.grasscutter.net.proto.AbilityMetaReInitOverrideMapOuterClass.AbilityM
import
emu.grasscutter.net.proto.AbilityScalarTypeOuterClass.AbilityScalarType
;
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
{
...
...
@@ -143,8 +147,21 @@ public class AbilityManager {
}
}
private
void
handleGenerateElemBall
(
AbilityInvokeEntry
invoke
)
{
// TODO create elemental energy orbs
private
void
handleGenerateElemBall
(
AbilityInvokeEntry
invoke
)
throws
InvalidProtocolBufferException
{
AbilityActionGenerateElemBall
action
=
AbilityActionGenerateElemBall
.
parseFrom
(
invoke
.
getAbilityData
());
if
(
action
==
null
)
{
return
;
}
ItemData
itemData
=
GameData
.
getItemDataMap
().
get
(
2024
);
if
(
itemData
==
null
)
{
return
;
// Should never happen
}
EntityItem
energyBall
=
new
EntityItem
(
getPlayer
().
getScene
(),
getPlayer
(),
itemData
,
new
Position
(
action
.
getPos
()),
1
);
energyBall
.
getRotation
().
set
(
action
.
getRot
());
getPlayer
().
getScene
().
addEntity
(
energyBall
);
}
private
void
invokeAction
(
AbilityModifierAction
action
,
GameEntity
target
,
GameEntity
sourceEntity
)
{
...
...
src/main/java/emu/grasscutter/game/avatar/Avatar.java
View file @
2dfdc627
...
...
@@ -69,6 +69,7 @@ public class Avatar {
@Transient
private
Player
owner
;
@Transient
private
AvatarData
data
;
@Transient
private
AvatarSkillDepotData
skillDepot
;
@Transient
private
long
guid
;
// Player unique id
private
int
avatarId
;
// Id of avatar
...
...
@@ -103,8 +104,8 @@ public class Avatar {
private
int
nameCardRewardId
;
private
int
nameCardId
;
@Deprecated
// Do not use. Morhpia only!
public
Avatar
()
{
// Morhpia only!
this
.
equips
=
new
Int2ObjectOpenHashMap
<>();
this
.
fightProp
=
new
Int2FloatOpenHashMap
();
this
.
extraAbilityEmbryos
=
new
HashSet
<>();
...
...
@@ -140,7 +141,7 @@ public class Avatar {
}
// Skill depot
this
.
setSkillDepot
(
getAvatarData
().
getSkillDepot
());
this
.
setSkillDepot
Data
(
getAvatarData
().
getSkillDepot
());
// Set stats
this
.
recalcStats
();
...
...
@@ -164,7 +165,8 @@ public class Avatar {
}
protected
void
setAvatarData
(
AvatarData
data
)
{
this
.
data
=
data
;
if
(
this
.
data
!=
null
)
return
;
this
.
data
=
data
;
// Used while loading this from the database
}
public
int
getOwnerId
()
{
...
...
@@ -257,9 +259,19 @@ public class Avatar {
return
skillDepotId
;
}
public
void
setSkillDepot
(
AvatarSkillDepotData
skillDepot
)
{
// Set id
public
AvatarSkillDepotData
getSkillDepot
()
{
return
skillDepot
;
}
protected
void
setSkillDepot
(
AvatarSkillDepotData
skillDepot
)
{
if
(
this
.
skillDepot
!=
null
)
return
;
this
.
skillDepot
=
skillDepot
;
// Used while loading this from the database
}
public
void
setSkillDepotData
(
AvatarSkillDepotData
skillDepot
)
{
// Set id and depot
this
.
skillDepotId
=
skillDepot
.
getId
();
this
.
skillDepot
=
skillDepot
;
// Clear, then add skills
getSkillLevelMap
().
clear
();
if
(
skillDepot
.
getEnergySkill
()
>
0
)
{
...
...
@@ -501,8 +513,8 @@ public class Avatar {
// Set energy usage
if
(
data
.
getSkillDepot
()
!=
null
&&
data
.
getSkillDepot
().
getEnergySkillData
()
!=
null
)
{
ElementType
element
=
data
.
getSkillDepot
().
getElementType
();
this
.
setFightProperty
(
element
.
getEnergyProp
erty
(),
data
.
getSkillDepot
().
getEnergySkillData
().
getCostElemVal
());
this
.
setFightProperty
((
element
.
getEnergyProp
erty
().
getId
()
%
70
)
+
1000
,
data
.
getSkillDepot
().
getEnergySkillData
().
getCostElemVal
());
this
.
setFightProperty
(
element
.
get
Max
EnergyProp
(),
data
.
getSkillDepot
().
getEnergySkillData
().
getCostElemVal
());
this
.
setFightProperty
((
element
.
get
Max
EnergyProp
().
getId
()
%
70
)
+
1000
,
data
.
getSkillDepot
().
getEnergySkillData
().
getCostElemVal
());
}
// Artifacts
...
...
src/main/java/emu/grasscutter/game/avatar/AvatarStorage.java
View file @
2dfdc627
...
...
@@ -5,6 +5,7 @@ import java.util.List;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.def.AvatarData
;
import
emu.grasscutter.data.def.AvatarSkillDepotData
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.inventory.GameItem
;
...
...
@@ -139,12 +140,14 @@ public class AvatarStorage implements Iterable<Avatar> {
}
AvatarData
avatarData
=
GameData
.
getAvatarDataMap
().
get
(
avatar
.
getAvatarId
());
if
(
avatarData
==
null
)
{
AvatarSkillDepotData
skillDepot
=
GameData
.
getAvatarSkillDepotDataMap
().
get
(
avatar
.
getSkillDepotId
());
if
(
avatarData
==
null
||
skillDepot
==
null
)
{
continue
;
}
// Set ownerships
avatar
.
setAvatarData
(
avatarData
);
avatar
.
setSkillDepot
(
skillDepot
);
avatar
.
setOwner
(
getPlayer
());
// Force recalc of const boosted skills
...
...
src/main/java/emu/grasscutter/game/entity/EntityAvatar.java
View file @
2dfdc627
...
...
@@ -30,6 +30,7 @@ import emu.grasscutter.net.proto.SceneAvatarInfoOuterClass.SceneAvatarInfo;
import
emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo
;
import
emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo
;
import
emu.grasscutter.net.proto.VectorOuterClass.Vector
;
import
emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropChangeReasonNotify
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify
;
import
emu.grasscutter.utils.Position
;
...
...
@@ -127,6 +128,22 @@ public class EntityAvatar extends GameEntity {
return
healed
;
}
public
void
addEnergy
(
float
amount
)
{
FightProperty
curEnergyProp
=
getAvatar
().
getSkillDepot
().
getElementType
().
getCurEnergyProp
();
FightProperty
maxEnergyProp
=
getAvatar
().
getSkillDepot
().
getElementType
().
getMaxEnergyProp
();
float
curEnergy
=
this
.
getFightProperty
(
curEnergyProp
);
float
maxEnergy
=
this
.
getFightProperty
(
maxEnergyProp
);
float
newEnergy
=
Math
.
min
(
curEnergy
+
amount
,
maxEnergy
);
if
(
newEnergy
!=
curEnergy
)
{
setFightProperty
(
curEnergyProp
,
newEnergy
);
getScene
().
broadcastPacket
(
new
PacketAvatarFightPropUpdateNotify
(
getAvatar
(),
curEnergyProp
));
getScene
().
broadcastPacket
(
new
PacketEntityFightPropChangeReasonNotify
(
this
,
curEnergyProp
,
newEnergy
,
PropChangeReason
.
PROP_CHANGE_ENERGY_BALL
));
}
}
public
SceneAvatarInfo
getSceneAvatarInfo
()
{
SceneAvatarInfo
.
Builder
avatarInfo
=
SceneAvatarInfo
.
newBuilder
()
.
setUid
(
this
.
getPlayer
().
getUid
())
...
...
@@ -258,5 +275,5 @@ public class EntityAvatar extends GameEntity {
//
return
abilityControlBlock
.
build
();
}
}
}
src/main/java/emu/grasscutter/game/inventory/Inventory.java
View file @
2dfdc627
...
...
@@ -172,6 +172,9 @@ public class Inventory implements Iterable<GameItem> {
// Handle
this
.
addVirtualItem
(
item
.
getItemId
(),
item
.
getCount
());
return
item
;
}
else
if
(
item
.
getItemData
().
getMaterialType
()
==
MaterialType
.
MATERIAL_ADSORBATE
)
{
player
.
getTeamManager
().
addEnergyToTeam
(
item
);
return
null
;
}
else
if
(
item
.
getItemData
().
getMaterialType
()
==
MaterialType
.
MATERIAL_AVATAR
)
{
// Get avatar id
int
avatarId
=
(
item
.
getItemId
()
%
1000
)
+
10000000
;
...
...
src/main/java/emu/grasscutter/game/player/TeamManager.java
View file @
2dfdc627
...
...
@@ -10,6 +10,7 @@ import emu.grasscutter.data.def.AvatarSkillDepotData;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.entity.EntityBaseGadget
;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.props.ElementType
;
import
emu.grasscutter.game.props.EnterReason
;
import
emu.grasscutter.game.props.FightProperty
;
...
...
@@ -579,6 +580,24 @@ public class TeamManager {
// Packets
getPlayer
().
sendPacket
(
new
BasePacket
(
PacketOpcodes
.
WorldPlayerReviveRsp
));
}
public
synchronized
void
addEnergyToTeam
(
GameItem
energyBall
)
{
// TODO
float
baseEnergy
=
2
;
for
(
int
i
=
0
;
i
<
getActiveTeam
().
size
();
i
++)
{
EntityAvatar
entity
=
getActiveTeam
().
get
(
i
);
float
energyGain
=
baseEnergy
;
// Active character gets full hp
if
(
getCurrentCharacterIndex
()
!=
i
)
{
energyGain
*=
Math
.
max
(
1.0
-
(
getActiveTeam
().
size
()
*
.
1
f
),
.
6
f
);
}
entity
.
addEnergy
(
energyGain
);
}
}
public
void
saveAvatars
()
{
// Save all avatars from active team
...
...
src/main/java/emu/grasscutter/game/props/ElementType.java
View file @
2dfdc627
...
...
@@ -9,21 +9,22 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
public
enum
ElementType
{
None
(
0
,
FightProperty
.
FIGHT_PROP_MAX_FIRE_ENERGY
),
Fire
(
1
,
FightProperty
.
FIGHT_PROP_MAX_FIRE_ENERGY
,
10101
,
"TeamResonance_Fire_Lv2"
),
Water
(
2
,
FightProperty
.
FIGHT_PROP_MAX_WATER_ENERGY
,
10201
,
"TeamResonance_Water_Lv2"
),
Grass
(
3
,
FightProperty
.
FIGHT_PROP_MAX_GRASS_ENERGY
),
Electric
(
4
,
FightProperty
.
FIGHT_PROP_MAX_ELEC_ENERGY
,
10401
,
"TeamResonance_Electric_Lv2"
),
Ice
(
5
,
FightProperty
.
FIGHT_PROP_MAX_ICE_ENERGY
,
10601
,
"TeamResonance_Ice_Lv2"
),
Frozen
(
6
,
FightProperty
.
FIGHT_PROP_MAX_ICE_ENERGY
),
Wind
(
7
,
FightProperty
.
FIGHT_PROP_MAX_WIND_ENERGY
,
10301
,
"TeamResonance_Wind_Lv2"
),
Rock
(
8
,
FightProperty
.
FIGHT_PROP_MAX_ROCK_ENERGY
,
10701
,
"TeamResonance_Rock_Lv2"
),
AntiFire
(
9
,
FightProperty
.
FIGHT_PROP_MAX_FIRE_ENERGY
),
Default
(
255
,
FightProperty
.
FIGHT_PROP_MAX_FIRE_ENERGY
,
10801
,
"TeamResonance_AllDifferent"
);
None
(
0
,
FightProperty
.
FIGHT_PROP_CUR_FIRE_ENERGY
,
FightProperty
.
FIGHT_PROP_MAX_FIRE_ENERGY
),
Fire
(
1
,
FightProperty
.
FIGHT_PROP_CUR_FIRE_ENERGY
,
FightProperty
.
FIGHT_PROP_MAX_FIRE_ENERGY
,
10101
,
"TeamResonance_Fire_Lv2"
),
Water
(
2
,
FightProperty
.
FIGHT_PROP_CUR_WATER_ENERGY
,
FightProperty
.
FIGHT_PROP_MAX_WATER_ENERGY
,
10201
,
"TeamResonance_Water_Lv2"
),
Grass
(
3
,
FightProperty
.
FIGHT_PROP_CUR_GRASS_ENERGY
,
FightProperty
.
FIGHT_PROP_MAX_GRASS_ENERGY
),
Electric
(
4
,
FightProperty
.
FIGHT_PROP_CUR_ELEC_ENERGY
,
FightProperty
.
FIGHT_PROP_MAX_ELEC_ENERGY
,
10401
,
"TeamResonance_Electric_Lv2"
),
Ice
(
5
,
FightProperty
.
FIGHT_PROP_CUR_ICE_ENERGY
,
FightProperty
.
FIGHT_PROP_MAX_ICE_ENERGY
,
10601
,
"TeamResonance_Ice_Lv2"
),
Frozen
(
6
,
FightProperty
.
FIGHT_PROP_CUR_ICE_ENERGY
,
FightProperty
.
FIGHT_PROP_MAX_ICE_ENERGY
),
Wind
(
7
,
FightProperty
.
FIGHT_PROP_CUR_WIND_ENERGY
,
FightProperty
.
FIGHT_PROP_MAX_WIND_ENERGY
,
10301
,
"TeamResonance_Wind_Lv2"
),
Rock
(
8
,
FightProperty
.
FIGHT_PROP_CUR_ROCK_ENERGY
,
FightProperty
.
FIGHT_PROP_MAX_ROCK_ENERGY
,
10701
,
"TeamResonance_Rock_Lv2"
),
AntiFire
(
9
,
FightProperty
.
FIGHT_PROP_CUR_FIRE_ENERGY
,
FightProperty
.
FIGHT_PROP_MAX_FIRE_ENERGY
),
Default
(
255
,
FightProperty
.
FIGHT_PROP_CUR_FIRE_ENERGY
,
FightProperty
.
FIGHT_PROP_MAX_FIRE_ENERGY
,
10801
,
"TeamResonance_AllDifferent"
);
private
final
int
value
;
private
final
int
teamResonanceId
;
private
final
FightProperty
energyProperty
;
private
final
FightProperty
curEnergyProp
;
private
final
FightProperty
maxEnergyProp
;
private
final
int
configHash
;
private
static
final
Int2ObjectMap
<
ElementType
>
map
=
new
Int2ObjectOpenHashMap
<>();
private
static
final
Map
<
String
,
ElementType
>
stringMap
=
new
HashMap
<>();
...
...
@@ -35,13 +36,14 @@ public enum ElementType {
});
}
private
ElementType
(
int
value
,
FightProperty
e
nergyProp
erty
)
{
this
(
value
,
e
nergyProp
erty
,
0
,
null
);
private
ElementType
(
int
value
,
FightProperty
curE
nergyProp
,
FightProperty
maxEnergyProp
)
{
this
(
value
,
curE
nergyProp
,
maxEnergyProp
,
0
,
null
);
}
private
ElementType
(
int
value
,
FightProperty
e
nergyProp
erty
,
int
teamResonanceId
,
String
configName
)
{
private
ElementType
(
int
value
,
FightProperty
curE
nergyProp
,
FightProperty
maxEnergyProp
,
int
teamResonanceId
,
String
configName
)
{
this
.
value
=
value
;
this
.
energyProperty
=
energyProperty
;
this
.
curEnergyProp
=
curEnergyProp
;
this
.
maxEnergyProp
=
maxEnergyProp
;
this
.
teamResonanceId
=
teamResonanceId
;
if
(
configName
!=
null
)
{
this
.
configHash
=
Utils
.
abilityHash
(
configName
);
...
...
@@ -54,8 +56,12 @@ public enum ElementType {
return
value
;
}
public
FightProperty
getEnergyProperty
()
{
return
energyProperty
;
public
FightProperty
getCurEnergyProp
()
{
return
curEnergyProp
;
}
public
FightProperty
getMaxEnergyProp
()
{
return
maxEnergyProp
;
}
public
int
getTeamResonanceId
()
{
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerSetPlayerBornDataReq.java
View file @
2dfdc627
...
...
@@ -62,7 +62,7 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler {
// Create avatar
if
(
player
.
getAvatars
().
getAvatarCount
()
==
0
)
{
Avatar
mainCharacter
=
new
Avatar
(
avatarId
);
mainCharacter
.
setSkillDepot
(
GameData
.
getAvatarSkillDepotDataMap
().
get
(
startingSkillDepot
));
mainCharacter
.
setSkillDepot
Data
(
GameData
.
getAvatarSkillDepotDataMap
().
get
(
startingSkillDepot
));
player
.
addAvatar
(
mainCharacter
);
player
.
setMainCharacterId
(
avatarId
);
player
.
setHeadImage
(
avatarId
);
...
...
src/main/java/emu/grasscutter/server/packet/send/PacketEntityFightPropChangeReasonNotify.java
View file @
2dfdc627
...
...
@@ -11,21 +11,27 @@ import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
import
java.util.List
;
public
class
PacketEntityFightPropChangeReasonNotify
extends
BasePacket
{
public
PacketEntityFightPropChangeReasonNotify
(
GameEntity
entity
,
FightProperty
prop
,
Float
value
,
List
<
Integer
>
param
,
PropChangeReason
reason
,
ChangeHpReason
changeHpReason
)
{
super
(
PacketOpcodes
.
EntityFightPropChangeReasonNotify
);
EntityFightPropChangeReasonNotify
.
Builder
proto
=
EntityFightPropChangeReasonNotify
.
newBuilder
()
.
setEntityId
(
entity
.
getId
())
.
setPropType
(
prop
.
getId
())
.
setPropDelta
(
value
)
.
setReason
(
reason
)
.
setChangeHpReason
(
changeHpReason
);
for
(
int
p:
param
){
for
(
int
p
:
param
){
proto
.
addParamList
(
p
);
}
this
.
setData
(
proto
);
}
public
PacketEntityFightPropChangeReasonNotify
(
GameEntity
entity
,
FightProperty
prop
,
Float
value
,
PropChangeReason
reason
,
ChangeHpReason
changeHpReason
)
{
super
(
PacketOpcodes
.
EntityFightPropChangeReasonNotify
);
EntityFightPropChangeReasonNotify
proto
=
EntityFightPropChangeReasonNotify
.
newBuilder
()
.
setEntityId
(
entity
.
getId
())
.
setPropType
(
prop
.
getId
())
...
...
@@ -33,6 +39,20 @@ public class PacketEntityFightPropChangeReasonNotify extends BasePacket {
.
setReason
(
reason
)
.
setChangeHpReason
(
changeHpReason
)
.
build
();
this
.
setData
(
proto
);
}
public
PacketEntityFightPropChangeReasonNotify
(
GameEntity
entity
,
FightProperty
prop
,
Float
value
,
PropChangeReason
reason
)
{
super
(
PacketOpcodes
.
EntityFightPropChangeReasonNotify
);
EntityFightPropChangeReasonNotify
proto
=
EntityFightPropChangeReasonNotify
.
newBuilder
()
.
setEntityId
(
entity
.
getId
())
.
setPropType
(
prop
.
getId
())
.
setPropDelta
(
value
)
.
setReason
(
reason
)
.
build
();
this
.
setData
(
proto
);
}
}
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