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
d56ca209
Commit
d56ca209
authored
Aug 07, 2022
by
Magix
Committed by
GitHub
Aug 07, 2022
Browse files
Implement working* burst/ultimate invincibility
Merge pull request #1622 from Grasscutters/ult-invincibility
parents
423b235c
6ec372e6
Changes
4
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/ability/AbilityManager.java
View file @
d56ca209
...
...
@@ -17,43 +17,84 @@ import emu.grasscutter.net.proto.AbilityMetaReInitOverrideMapOuterClass.AbilityM
import
emu.grasscutter.net.proto.AbilityMixinCostStaminaOuterClass.AbilityMixinCostStamina
;
import
emu.grasscutter.net.proto.AbilityScalarValueEntryOuterClass.AbilityScalarValueEntry
;
import
emu.grasscutter.net.proto.ModifierActionOuterClass.ModifierAction
;
import
lombok.Getter
;
public
class
AbilityManager
extends
BasePlayerManager
{
public
final
class
AbilityManager
extends
BasePlayerManager
{
HealAbilityManager
healAbilityManager
;
@Getter
private
boolean
abilityInvulnerable
=
false
;
public
AbilityManager
(
Player
player
)
{
super
(
player
);
this
.
healAbilityManager
=
new
HealAbilityManager
(
player
);
}
public
void
onAbilityInvoke
(
AbilityInvokeEntry
invoke
)
throws
Exception
{
healAbilityManager
.
healHandler
(
invoke
);
this
.
healAbilityManager
.
healHandler
(
invoke
);
//Grasscutter.getLogger().info(invoke.getArgumentType() + " (" + invoke.getArgumentTypeValue() + "): " + Utils.bytesToHex(invoke.toByteArray()));
switch
(
invoke
.
getArgumentType
())
{
case
ABILITY_INVOKE_ARGUMENT_META_OVERRIDE_PARAM:
handleOverrideParam
(
invoke
);
break
;
case
ABILITY_INVOKE_ARGUMENT_META_REINIT_OVERRIDEMAP:
handleReinitOverrideMap
(
invoke
);
break
;
case
ABILITY_INVOKE_ARGUMENT_META_MODIFIER_CHANGE:
handleModifierChange
(
invoke
);
break
;
case
ABILITY_INVOKE_ARGUMENT_MIXIN_COST_STAMINA:
handleMixinCostStamina
(
invoke
);
break
;
case
ABILITY_INVOKE_ARGUMENT_ACTION_GENERATE_ELEM_BALL:
handleGenerateElemBall
(
invoke
);
break
;
default
:
break
;
case
ABILITY_INVOKE_ARGUMENT_META_OVERRIDE_PARAM
->
this
.
handleOverrideParam
(
invoke
);
case
ABILITY_INVOKE_ARGUMENT_META_REINIT_OVERRIDEMAP
->
this
.
handleReinitOverrideMap
(
invoke
);
case
ABILITY_INVOKE_ARGUMENT_META_MODIFIER_CHANGE
->
this
.
handleModifierChange
(
invoke
);
case
ABILITY_INVOKE_ARGUMENT_MIXIN_COST_STAMINA
->
this
.
handleMixinCostStamina
(
invoke
);
case
ABILITY_INVOKE_ARGUMENT_ACTION_GENERATE_ELEM_BALL
->
this
.
handleGenerateElemBall
(
invoke
);
default
->
{}
}
}
/**
* Invoked when a player starts a skill.
* @param player The player who started the skill.
* @param skillId The skill ID.
* @param casterId The caster ID.
*/
public
void
onSkillStart
(
Player
player
,
int
skillId
,
int
casterId
)
{
// Check if the player matches this player.
if
(
player
.
getUid
()
!=
this
.
player
.
getUid
())
{
return
;
}
// Check if the caster matches the player.
if
(
player
.
getTeamManager
().
getCurrentAvatarEntity
().
getId
()
!=
casterId
)
{
return
;
}
var
skillData
=
GameData
.
getAvatarSkillDataMap
().
get
(
skillId
);
if
(
skillData
==
null
)
{
return
;
}
// Check if the skill is an elemental burst.
if
(
skillData
.
getCostElemVal
()
<=
0
)
{
return
;
}
// Set the player as invulnerable.
this
.
abilityInvulnerable
=
true
;
}
/**
* Invoked when a player ends a skill.
* @param player The player who started the skill.
*/
public
void
onSkillEnd
(
Player
player
)
{
// Check if the player matches this player.
if
(
player
.
getUid
()
!=
this
.
player
.
getUid
())
{
return
;
}
// Check if the player is invulnerable.
if
(!
this
.
abilityInvulnerable
)
{
return
;
}
// Set the player as not invulnerable.
this
.
abilityInvulnerable
=
false
;
}
private
void
handleOverrideParam
(
AbilityInvokeEntry
invoke
)
throws
Exception
{
GameEntity
entity
=
player
.
getScene
().
getEntityById
(
invoke
.
getEntityId
());
GameEntity
entity
=
this
.
player
.
getScene
().
getEntityById
(
invoke
.
getEntityId
());
if
(
entity
==
null
)
{
return
;
...
...
@@ -65,7 +106,7 @@ public class AbilityManager extends BasePlayerManager {
}
private
void
handleReinitOverrideMap
(
AbilityInvokeEntry
invoke
)
throws
Exception
{
GameEntity
entity
=
player
.
getScene
().
getEntityById
(
invoke
.
getEntityId
());
GameEntity
entity
=
this
.
player
.
getScene
().
getEntityById
(
invoke
.
getEntityId
());
if
(
entity
==
null
)
{
return
;
...
...
@@ -80,7 +121,7 @@ public class AbilityManager extends BasePlayerManager {
private
void
handleModifierChange
(
AbilityInvokeEntry
invoke
)
throws
Exception
{
// Sanity checks
GameEntity
target
=
player
.
getScene
().
getEntityById
(
invoke
.
getEntityId
());
GameEntity
target
=
this
.
player
.
getScene
().
getEntityById
(
invoke
.
getEntityId
());
if
(
target
==
null
)
{
return
;
}
...
...
@@ -104,7 +145,7 @@ public class AbilityManager extends BasePlayerManager {
return
;
}
GameEntity
sourceEntity
=
player
.
getScene
().
getEntityById
(
data
.
getApplyEntityId
());
GameEntity
sourceEntity
=
this
.
player
.
getScene
().
getEntityById
(
data
.
getApplyEntityId
());
if
(
sourceEntity
==
null
)
{
return
;
}
...
...
@@ -117,7 +158,7 @@ public class AbilityManager extends BasePlayerManager {
if
(
modifier
!=
null
&&
modifier
.
getOnAdded
().
size
()
>
0
)
{
for
(
AbilityModifierAction
action
:
modifier
.
getOnAdded
())
{
invokeAction
(
action
,
target
,
sourceEntity
);
this
.
invokeAction
(
action
,
target
,
sourceEntity
);
}
}
...
...
@@ -133,7 +174,7 @@ public class AbilityManager extends BasePlayerManager {
if
(
modifier
!=
null
&&
modifier
.
getOnRemoved
().
size
()
>
0
)
{
for
(
AbilityModifierAction
action
:
modifier
.
getOnRemoved
())
{
invokeAction
(
action
,
target
,
sourceEntity
);
this
.
invokeAction
(
action
,
target
,
sourceEntity
);
}
}
...
...
@@ -145,7 +186,7 @@ public class AbilityManager extends BasePlayerManager {
private
void
handleMixinCostStamina
(
AbilityInvokeEntry
invoke
)
throws
InvalidProtocolBufferException
{
AbilityMixinCostStamina
costStamina
=
AbilityMixinCostStamina
.
parseFrom
((
invoke
.
getAbilityData
()));
getPlayer
().
getStaminaManager
().
handleMixinCostStamina
(
costStamina
.
getIsSwim
());
this
.
getPlayer
().
getStaminaManager
().
handleMixinCostStamina
(
costStamina
.
getIsSwim
());
}
private
void
handleGenerateElemBall
(
AbilityInvokeEntry
invoke
)
throws
InvalidProtocolBufferException
{
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerClientAbilityInitFinishNotify.java
View file @
d56ca209
...
...
@@ -17,6 +17,10 @@ public class HandlerClientAbilityInitFinishNotify extends PacketHandler {
ClientAbilityInitFinishNotify
notif
=
ClientAbilityInitFinishNotify
.
parseFrom
(
payload
);
Player
player
=
session
.
getPlayer
();
// Call skill end in the player's ability manager.
player
.
getAbilityManager
().
onSkillEnd
(
player
);
for
(
AbilityInvokeEntry
entry
:
notif
.
getInvokesList
())
{
player
.
getAbilityManager
().
onAbilityInvoke
(
entry
);
player
.
getClientAbilityInitFinishHandler
().
addEntry
(
entry
.
getForwardType
(),
entry
);
...
...
@@ -26,5 +30,4 @@ public class HandlerClientAbilityInitFinishNotify extends PacketHandler {
session
.
getPlayer
().
getClientAbilityInitFinishHandler
().
update
(
session
.
getPlayer
());
}
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/packet/recv/HandlerCombatInvocationsNotify.java
View file @
d56ca209
...
...
@@ -6,7 +6,6 @@ import emu.grasscutter.game.player.Player;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.AttackResultOuterClass
;
import
emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult
;
import
emu.grasscutter.net.proto.CombatInvocationsNotifyOuterClass.CombatInvocationsNotify
;
import
emu.grasscutter.net.proto.CombatInvokeEntryOuterClass.CombatInvokeEntry
;
...
...
@@ -18,7 +17,6 @@ import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
import
emu.grasscutter.net.proto.MotionStateOuterClass.MotionState
;
import
emu.grasscutter.net.proto.PlayerDieTypeOuterClass
;
import
emu.grasscutter.server.event.entity.EntityMoveEvent
;
import
emu.grasscutter.server.event.game.ReceiveCommandFeedbackEvent
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify
;
import
emu.grasscutter.utils.Position
;
...
...
@@ -36,16 +34,22 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
for
(
CombatInvokeEntry
entry
:
notif
.
getInvokeListList
())
{
// Handle combat invoke
switch
(
entry
.
getArgumentType
())
{
case
COMBAT_TYPE_ARGUMENT_EVT_BEING_HIT
:
case
COMBAT_TYPE_ARGUMENT_EVT_BEING_HIT
->
{
EvtBeingHitInfo
hitInfo
=
EvtBeingHitInfo
.
parseFrom
(
entry
.
getCombatData
());
AttackResult
attackResult
=
hitInfo
.
getAttackResult
();
Player
player
=
session
.
getPlayer
();
// Check if the player is invulnerable.
if
(
attackResult
.
getAttackerId
()
!=
player
.
getTeamManager
().
getCurrentAvatarEntity
().
getId
()
&&
player
.
getAbilityManager
().
isAbilityInvulnerable
()
)
break
;
// Handle damage
player
.
getAttackResults
().
add
(
attackResult
);
player
.
getEnergyManager
().
handleAttackHit
(
hitInfo
);
break
;
case
COMBAT_TYPE_ARGUMENT_ENTITY_MOVE
:
}
case
COMBAT_TYPE_ARGUMENT_ENTITY_MOVE
->
{
// Handle movement
EntityMoveInfo
moveInfo
=
EntityMoveInfo
.
parseFrom
(
entry
.
getCombatData
());
GameEntity
entity
=
session
.
getPlayer
().
getScene
().
getEntityById
(
moveInfo
.
getEntityId
());
...
...
@@ -90,17 +94,16 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
continue
;
}
}
break
;
case
COMBAT_TYPE_ARGUMENT_ANIMATOR_PARAMETER_CHANGED
:
}
case
COMBAT_TYPE_ARGUMENT_ANIMATOR_PARAMETER_CHANGED
->
{
EvtAnimatorParameterInfo
paramInfo
=
EvtAnimatorParameterInfo
.
parseFrom
(
entry
.
getCombatData
());
if
(
paramInfo
.
getIsServerCache
())
{
paramInfo
=
paramInfo
.
toBuilder
().
setIsServerCache
(
false
).
build
();
entry
=
entry
.
toBuilder
().
setCombatData
(
paramInfo
.
toByteString
()).
build
();
}
break
;
default
:
break
;
}
default
->
{
}
}
session
.
getPlayer
().
getCombatInvokeHandler
().
addEntry
(
entry
.
getForwardType
(),
entry
);
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerEvtDoSkillSuccNotify.java
View file @
d56ca209
...
...
@@ -12,10 +12,16 @@ public class HandlerEvtDoSkillSuccNotify extends PacketHandler {
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
EvtDoSkillSuccNotify
notify
=
EvtDoSkillSuccNotify
.
parseFrom
(
payload
);
var
player
=
session
.
getPlayer
();
int
skillId
=
notify
.
getSkillId
();
int
casterId
=
notify
.
getCasterId
();
session
.
getPlayer
().
getStaminaManager
().
handleEvtDoSkillSuccNotify
(
session
,
skillId
,
casterId
);
session
.
getPlayer
().
getEnergyManager
().
handleEvtDoSkillSuccNotify
(
session
,
skillId
,
casterId
);
// Call skill perform in the player's ability manager.
player
.
getAbilityManager
().
onSkillStart
(
session
.
getPlayer
(),
skillId
,
casterId
);
// Handle skill notify in other managers.
player
.
getStaminaManager
().
handleEvtDoSkillSuccNotify
(
session
,
skillId
,
casterId
);
player
.
getEnergyManager
().
handleEvtDoSkillSuccNotify
(
session
,
skillId
,
casterId
);
}
}
\ 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