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
791b9534
Commit
791b9534
authored
May 23, 2022
by
Akka
Committed by
Melledy
May 23, 2022
Browse files
refactor the challenge
parent
717c2d1d
Changes
29
Hide whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/dungeons/DungeonChallenge.java
→
src/main/java/emu/grasscutter/game/dungeons/
challenge/
DungeonChallenge.java
View file @
791b9534
package
emu.grasscutter.game.dungeons
;
package
emu.grasscutter.game.dungeons
.challenge
;
import
emu.grasscutter.data.common.ItemParamData
;
import
emu.grasscutter.data.def.DungeonData
;
import
emu.grasscutter.game.
entity.EntityMonst
er
;
import
emu.grasscutter.game.
dungeons.challenge.trigger.ChallengeTrigg
er
;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.ActionReason
;
...
...
@@ -10,9 +10,6 @@ import emu.grasscutter.game.world.Scene;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
emu.grasscutter.scripts.data.ScriptArgs
;
import
emu.grasscutter.server.packet.send.PacketChallengeDataNotify
;
import
emu.grasscutter.server.packet.send.PacketDungeonChallengeBeginNotify
;
import
emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify
;
import
emu.grasscutter.server.packet.send.PacketGadgetAutoPickDropInfoNotify
;
import
it.unimi.dsi.fastutil.ints.IntOpenHashSet
;
import
it.unimi.dsi.fastutil.ints.IntSet
;
...
...
@@ -20,79 +17,23 @@ import it.unimi.dsi.fastutil.ints.IntSet;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
DungeonChallenge
{
private
final
Scene
scene
;
private
final
SceneGroup
group
;
private
int
challengeIndex
;
private
int
challengeId
;
private
boolean
success
;
private
boolean
progress
;
public
class
DungeonChallenge
extends
WorldChallenge
{
/**
* has more challenge
*/
private
boolean
stage
;
private
int
score
;
private
int
objective
=
0
;
private
IntSet
rewardedPlayers
;
public
DungeonChallenge
(
Scene
scene
,
SceneGroup
group
,
int
challengeId
,
int
challengeIndex
,
int
objective
)
{
this
.
scene
=
scene
;
this
.
group
=
group
;
this
.
challengeId
=
challengeId
;
this
.
challengeIndex
=
challengeIndex
;
this
.
objective
=
objective
;
public
DungeonChallenge
(
Scene
scene
,
SceneGroup
group
,
int
challengeId
,
int
challengeIndex
,
List
<
Integer
>
paramList
,
int
timeLimit
,
int
goal
,
List
<
ChallengeTrigger
>
challengeTriggers
)
{
super
(
scene
,
group
,
challengeId
,
challengeIndex
,
paramList
,
timeLimit
,
goal
,
challengeTriggers
)
;
this
.
setRewardedPlayers
(
new
IntOpenHashSet
());
}
public
Scene
getScene
()
{
return
scene
;
}
public
SceneGroup
getGroup
()
{
return
group
;
}
public
int
getChallengeIndex
()
{
return
challengeIndex
;
}
public
void
setChallengeIndex
(
int
challengeIndex
)
{
this
.
challengeIndex
=
challengeIndex
;
}
public
int
getChallengeId
()
{
return
challengeId
;
}
public
void
setChallengeId
(
int
challengeId
)
{
this
.
challengeId
=
challengeId
;
}
public
int
getObjective
()
{
return
objective
;
}
public
void
setObjective
(
int
objective
)
{
this
.
objective
=
objective
;
}
public
boolean
isSuccess
()
{
return
success
;
}
public
void
setSuccess
(
boolean
isSuccess
)
{
this
.
success
=
isSuccess
;
}
public
boolean
inProgress
()
{
return
progress
;
}
public
int
getScore
()
{
return
score
;
}
public
boolean
isStage
()
{
return
stage
;
}
...
...
@@ -101,10 +42,6 @@ public class DungeonChallenge {
this
.
stage
=
stage
;
}
public
int
getTimeLimit
()
{
return
600
;
}
public
IntSet
getRewardedPlayers
()
{
return
rewardedPlayers
;
}
...
...
@@ -113,48 +50,22 @@ public class DungeonChallenge {
this
.
rewardedPlayers
=
rewardedPlayers
;
}
public
void
start
()
{
this
.
progress
=
true
;
getScene
().
broadcastPacket
(
new
PacketDungeonChallengeBeginNotify
(
this
));
}
public
void
finish
()
{
this
.
progress
=
false
;
getScene
().
broadcastPacket
(
new
PacketDungeonChallengeFinishNotify
(
this
));
@Override
public
void
done
()
{
super
.
done
();
if
(
this
.
isSuccess
())
{
// Call success script event
this
.
getScene
().
getScriptManager
().
callEvent
(
EventType
.
EVENT_CHALLENGE_SUCCESS
,
// TODO record the time in PARAM2 and used in action
new
ScriptArgs
().
setParam2
(
100
));
// Settle
settle
();
}
else
{
this
.
getScene
().
getScriptManager
().
callEvent
(
EventType
.
EVENT_CHALLENGE_FAIL
,
null
);
}
}
private
void
settle
()
{
getScene
().
getDungeonSettleObservers
().
forEach
(
o
->
o
.
onDungeonSettle
(
getScene
()));
if
(!
stage
){
getScene
().
getDungeonSettleObservers
().
forEach
(
o
->
o
.
onDungeonSettle
(
getScene
()));
getScene
().
getScriptManager
().
callEvent
(
EventType
.
EVENT_DUNGEON_SETTLE
,
new
ScriptArgs
(
this
.
isSuccess
()
?
1
:
0
));
}
}
public
void
onMonsterDie
(
EntityMonster
entity
)
{
score
=
getScore
()
+
1
;
getScene
().
broadcastPacket
(
new
PacketChallengeDataNotify
(
this
,
1
,
getScore
()));
if
(
getScore
()
>=
getObjective
()
&&
this
.
progress
)
{
this
.
setSuccess
(
true
);
finish
();
}
}
public
void
getStatueDrops
(
Player
player
)
{
DungeonData
dungeonData
=
getScene
().
getDungeonData
();
...
...
src/main/java/emu/grasscutter/game/dungeons/challenge/WorldChallenge.java
0 → 100644
View file @
791b9534
package
emu.grasscutter.game.dungeons.challenge
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.dungeons.challenge.trigger.ChallengeTrigger
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.entity.EntityMonster
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
emu.grasscutter.scripts.data.ScriptArgs
;
import
emu.grasscutter.server.packet.send.PacketDungeonChallengeBeginNotify
;
import
emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify
;
import
lombok.Getter
;
import
lombok.Setter
;
import
java.util.List
;
import
java.util.concurrent.atomic.AtomicInteger
;
@Getter
@Setter
public
class
WorldChallenge
{
private
final
Scene
scene
;
private
final
SceneGroup
group
;
private
final
int
challengeId
;
private
final
int
challengeIndex
;
private
final
List
<
Integer
>
paramList
;
private
final
int
timeLimit
;
private
final
List
<
ChallengeTrigger
>
challengeTriggers
;
private
boolean
progress
;
private
boolean
success
;
private
long
startedAt
;
private
int
finishedTime
;
private
final
int
goal
;
private
final
AtomicInteger
score
;
public
WorldChallenge
(
Scene
scene
,
SceneGroup
group
,
int
challengeId
,
int
challengeIndex
,
List
<
Integer
>
paramList
,
int
timeLimit
,
int
goal
,
List
<
ChallengeTrigger
>
challengeTriggers
){
this
.
scene
=
scene
;
this
.
group
=
group
;
this
.
challengeId
=
challengeId
;
this
.
challengeIndex
=
challengeIndex
;
this
.
paramList
=
paramList
;
this
.
timeLimit
=
timeLimit
;
this
.
challengeTriggers
=
challengeTriggers
;
this
.
goal
=
goal
;
this
.
score
=
new
AtomicInteger
(
0
);
}
public
boolean
inProgress
(){
return
this
.
progress
;
}
public
void
onCheckTimeOut
(){
if
(!
inProgress
()){
return
;
}
if
(
timeLimit
<=
0
){
return
;
}
challengeTriggers
.
forEach
(
t
->
t
.
onCheckTimeout
(
this
));
}
public
void
start
(){
if
(
inProgress
()){
Grasscutter
.
getLogger
().
info
(
"Could not start a in progress challenge."
);
return
;
}
this
.
progress
=
true
;
this
.
startedAt
=
System
.
currentTimeMillis
();
getScene
().
broadcastPacket
(
new
PacketDungeonChallengeBeginNotify
(
this
));
challengeTriggers
.
forEach
(
t
->
t
.
onBegin
(
this
));
}
public
void
done
(){
if
(!
inProgress
()){
return
;
}
finish
(
true
);
this
.
getScene
().
getScriptManager
().
callEvent
(
EventType
.
EVENT_CHALLENGE_SUCCESS
,
// TODO record the time in PARAM2 and used in action
new
ScriptArgs
().
setParam2
(
finishedTime
));
challengeTriggers
.
forEach
(
t
->
t
.
onFinish
(
this
));
}
public
void
fail
(){
if
(!
inProgress
()){
return
;
}
finish
(
false
);
this
.
getScene
().
getScriptManager
().
callEvent
(
EventType
.
EVENT_CHALLENGE_FAIL
,
null
);
challengeTriggers
.
forEach
(
t
->
t
.
onFinish
(
this
));
}
private
void
finish
(
boolean
success
){
this
.
progress
=
false
;
this
.
success
=
success
;
this
.
finishedTime
=
(
int
)((
System
.
currentTimeMillis
()
-
this
.
startedAt
)
/
1000L
);
getScene
().
broadcastPacket
(
new
PacketDungeonChallengeFinishNotify
(
this
));
}
public
int
increaseScore
(){
return
score
.
incrementAndGet
();
}
public
void
onMonsterDeath
(
EntityMonster
monster
){
if
(!
inProgress
()){
return
;
}
if
(
monster
.
getGroupId
()
!=
getGroup
().
id
){
return
;
}
this
.
challengeTriggers
.
forEach
(
t
->
t
.
onMonsterDeath
(
this
,
monster
));
}
public
void
onGadgetDeath
(
EntityGadget
gadget
){
if
(!
inProgress
()){
return
;
}
if
(
gadget
.
getGroupId
()
!=
getGroup
().
id
){
return
;
}
this
.
challengeTriggers
.
forEach
(
t
->
t
.
onGadgetDeath
(
this
,
gadget
));
}
public
void
onGadgetDamage
(
EntityGadget
gadget
){
if
(!
inProgress
()){
return
;
}
if
(
gadget
.
getGroupId
()
!=
getGroup
().
id
){
return
;
}
this
.
challengeTriggers
.
forEach
(
t
->
t
.
onGadgetDamage
(
this
,
gadget
));
}
}
src/main/java/emu/grasscutter/game/dungeons/challenge/factory/ChallengeFactory.java
0 → 100644
View file @
791b9534
package
emu.grasscutter.game.dungeons.challenge.factory
;
import
emu.grasscutter.game.dungeons.challenge.WorldChallenge
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
ChallengeFactory
{
private
static
final
List
<
ChallengeFactoryHandler
>
challengeFactoryHandlers
=
new
ArrayList
<>();
static
{
challengeFactoryHandlers
.
add
(
new
DungeonChallengeFactoryHandler
());
challengeFactoryHandlers
.
add
(
new
DungeonGuardChallengeFactoryHandler
());
challengeFactoryHandlers
.
add
(
new
KillGadgetChallengeFactoryHandler
());
challengeFactoryHandlers
.
add
(
new
KillMonsterChallengeFactoryHandler
());
}
public
static
WorldChallenge
getChallenge
(
int
param1
,
int
param2
,
int
param3
,
int
param4
,
int
param5
,
int
param6
,
Scene
scene
,
SceneGroup
group
){
for
(
var
handler
:
challengeFactoryHandlers
){
if
(!
handler
.
isThisType
(
param1
,
param2
,
param3
,
param4
,
param5
,
param6
,
scene
,
group
)){
continue
;
}
return
handler
.
build
(
param1
,
param2
,
param3
,
param4
,
param5
,
param6
,
scene
,
group
);
}
return
null
;
}
}
src/main/java/emu/grasscutter/game/dungeons/challenge/factory/ChallengeFactoryHandler.java
0 → 100644
View file @
791b9534
package
emu.grasscutter.game.dungeons.challenge.factory
;
import
emu.grasscutter.game.dungeons.challenge.WorldChallenge
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.scripts.data.SceneGroup
;
public
interface
ChallengeFactoryHandler
{
boolean
isThisType
(
int
challengeIndex
,
int
challengeId
,
int
param3
,
int
param4
,
int
param5
,
int
param6
,
Scene
scene
,
SceneGroup
group
);
WorldChallenge
build
(
int
challengeIndex
,
int
challengeId
,
int
param3
,
int
param4
,
int
param5
,
int
param6
,
Scene
scene
,
SceneGroup
group
);
}
src/main/java/emu/grasscutter/game/dungeons/challenge/factory/DungeonChallengeFactoryHandler.java
0 → 100644
View file @
791b9534
package
emu.grasscutter.game.dungeons.challenge.factory
;
import
emu.grasscutter.game.dungeons.challenge.DungeonChallenge
;
import
emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger
;
import
emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterTrigger
;
import
emu.grasscutter.game.props.SceneType
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.game.dungeons.challenge.WorldChallenge
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
java.util.List
;
public
class
DungeonChallengeFactoryHandler
implements
ChallengeFactoryHandler
{
@Override
public
boolean
isThisType
(
int
challengeIndex
,
int
challengeId
,
int
param3
,
int
param4
,
int
param5
,
int
param6
,
Scene
scene
,
SceneGroup
group
)
{
// ActiveChallenge with 1,1000,300,233101003,15,0
return
scene
.
getSceneType
()
==
SceneType
.
SCENE_DUNGEON
&&
param4
==
group
.
id
;
}
@Override
public
WorldChallenge
build
(
int
challengeIndex
,
int
challengeId
,
int
param3
,
int
param4
,
int
param5
,
int
param6
,
Scene
scene
,
SceneGroup
group
)
{
var
realGroup
=
scene
.
getScriptManager
().
getGroupById
(
param4
);
return
new
DungeonChallenge
(
scene
,
realGroup
,
challengeId
,
// Id
challengeIndex
,
// Index
List
.
of
(
param5
,
param3
),
param3
,
// Limit
param5
,
// Goal
List
.
of
(
new
InTimeTrigger
(),
new
KillMonsterTrigger
()));
}
}
src/main/java/emu/grasscutter/game/dungeons/challenge/factory/DungeonGuardChallengeFactoryHandler.java
0 → 100644
View file @
791b9534
package
emu.grasscutter.game.dungeons.challenge.factory
;
import
emu.grasscutter.game.dungeons.challenge.DungeonChallenge
;
import
emu.grasscutter.game.dungeons.challenge.WorldChallenge
;
import
emu.grasscutter.game.dungeons.challenge.trigger.GuardTrigger
;
import
emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger
;
import
emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterTrigger
;
import
emu.grasscutter.game.props.SceneType
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
java.util.List
;
public
class
DungeonGuardChallengeFactoryHandler
implements
ChallengeFactoryHandler
{
@Override
public
boolean
isThisType
(
int
challengeIndex
,
int
challengeId
,
int
param3
,
int
param4
,
int
param5
,
int
param6
,
Scene
scene
,
SceneGroup
group
)
{
// ActiveChallenge with 1,188,234101003,12,3030,0
return
scene
.
getSceneType
()
==
SceneType
.
SCENE_DUNGEON
&&
param3
==
group
.
id
;
}
@Override
public
WorldChallenge
build
(
int
challengeIndex
,
int
challengeId
,
int
param3
,
int
param4
,
int
param5
,
int
param6
,
Scene
scene
,
SceneGroup
group
)
{
var
realGroup
=
scene
.
getScriptManager
().
getGroupById
(
param3
);
return
new
DungeonChallenge
(
scene
,
realGroup
,
challengeId
,
// Id
challengeIndex
,
// Index
List
.
of
(
param4
,
0
),
0
,
// Limit
param5
,
// Goal
List
.
of
(
new
GuardTrigger
()));
}
}
src/main/java/emu/grasscutter/game/dungeons/challenge/factory/KillGadgetChallengeFactoryHandler.java
0 → 100644
View file @
791b9534
package
emu.grasscutter.game.dungeons.challenge.factory
;
import
emu.grasscutter.game.dungeons.challenge.WorldChallenge
;
import
emu.grasscutter.game.dungeons.challenge.factory.ChallengeFactoryHandler
;
import
emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger
;
import
emu.grasscutter.game.dungeons.challenge.trigger.KillGadgetTrigger
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
java.util.List
;
public
class
KillGadgetChallengeFactoryHandler
implements
ChallengeFactoryHandler
{
@Override
public
boolean
isThisType
(
int
challengeIndex
,
int
challengeId
,
int
param3
,
int
param4
,
int
param5
,
int
param6
,
Scene
scene
,
SceneGroup
group
)
{
// kill gadgets(explosive barrel) in time
// ActiveChallenge with 56,201,20,2,201,4
// open chest in time
// ActiveChallenge with 666,202,30,7,202,1
return
challengeId
==
201
||
challengeId
==
202
;
}
@Override
public
WorldChallenge
build
(
int
challengeIndex
,
int
challengeId
,
int
param3
,
int
param4
,
int
param5
,
int
param6
,
Scene
scene
,
SceneGroup
group
)
{
return
new
WorldChallenge
(
scene
,
group
,
challengeId
,
// Id
challengeIndex
,
// Index
List
.
of
(
param3
,
param6
,
0
),
param3
,
// Limit
param6
,
// Goal
List
.
of
(
new
InTimeTrigger
(),
new
KillGadgetTrigger
())
);
}
}
src/main/java/emu/grasscutter/game/dungeons/challenge/factory/KillMonsterChallengeFactoryHandler.java
0 → 100644
View file @
791b9534
package
emu.grasscutter.game.dungeons.challenge.factory
;
import
emu.grasscutter.game.dungeons.challenge.WorldChallenge
;
import
emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger
;
import
emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterTrigger
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
java.util.List
;
public
class
KillMonsterChallengeFactoryHandler
implements
ChallengeFactoryHandler
{
@Override
public
boolean
isThisType
(
int
challengeIndex
,
int
challengeId
,
int
param3
,
int
param4
,
int
param5
,
int
param6
,
Scene
scene
,
SceneGroup
group
)
{
// ActiveChallenge with 180,180,45,133108061,1,0
return
challengeId
==
180
;
}
@Override
public
WorldChallenge
build
(
int
challengeIndex
,
int
challengeId
,
int
param3
,
int
param4
,
int
param5
,
int
param6
,
Scene
scene
,
SceneGroup
group
)
{
var
realGroup
=
scene
.
getScriptManager
().
getGroupById
(
param4
);
return
new
WorldChallenge
(
scene
,
realGroup
,
challengeId
,
// Id
challengeIndex
,
// Index
List
.
of
(
param5
,
param3
),
param3
,
// Limit
param5
,
// Goal
List
.
of
(
new
KillMonsterTrigger
(),
new
InTimeTrigger
())
);
}
}
src/main/java/emu/grasscutter/game/dungeons/challenge/trigger/ChallengeTrigger.java
0 → 100644
View file @
791b9534
package
emu.grasscutter.game.dungeons.challenge.trigger
;
import
emu.grasscutter.game.dungeons.challenge.WorldChallenge
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.entity.EntityMonster
;
public
abstract
class
ChallengeTrigger
{
public
void
onBegin
(
WorldChallenge
challenge
){}
public
void
onFinish
(
WorldChallenge
challenge
){}
public
void
onMonsterDeath
(
WorldChallenge
challenge
,
EntityMonster
monster
){}
public
void
onGadgetDeath
(
WorldChallenge
challenge
,
EntityGadget
gadget
){}
public
void
onCheckTimeout
(
WorldChallenge
challenge
){}
public
void
onGadgetDamage
(
WorldChallenge
challenge
,
EntityGadget
gadget
){}
}
src/main/java/emu/grasscutter/game/dungeons/challenge/trigger/GuardTrigger.java
0 → 100644
View file @
791b9534
package
emu.grasscutter.game.dungeons.challenge.trigger
;
import
emu.grasscutter.game.dungeons.challenge.WorldChallenge
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.entity.EntityMonster
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.server.packet.send.PacketChallengeDataNotify
;
public
class
GuardTrigger
extends
KillMonsterTrigger
{
@Override
public
void
onBegin
(
WorldChallenge
challenge
)
{
super
.
onBegin
(
challenge
);
challenge
.
getScene
().
broadcastPacket
(
new
PacketChallengeDataNotify
(
challenge
,
2
,
100
));
}
@Override
public
void
onGadgetDamage
(
WorldChallenge
challenge
,
EntityGadget
gadget
)
{
var
curHp
=
gadget
.
getFightProperties
().
get
(
FightProperty
.
FIGHT_PROP_CUR_HP
.
getId
());
var
maxHp
=
gadget
.
getFightProperties
().
get
(
FightProperty
.
FIGHT_PROP_BASE_HP
.
getId
());
int
percent
=
(
int
)
(
curHp
/
maxHp
);
challenge
.
getScene
().
broadcastPacket
(
new
PacketChallengeDataNotify
(
challenge
,
2
,
percent
));
if
(
percent
<=
0
){
challenge
.
fail
();
}
}
}
src/main/java/emu/grasscutter/game/dungeons/challenge/trigger/InTimeTrigger.java
0 → 100644
View file @
791b9534
package
emu.grasscutter.game.dungeons.challenge.trigger
;
import
emu.grasscutter.game.dungeons.challenge.WorldChallenge
;
public
class
InTimeTrigger
extends
ChallengeTrigger
{
@Override
public
void
onCheckTimeout
(
WorldChallenge
challenge
)
{
var
current
=
System
.
currentTimeMillis
();
if
(
current
-
challenge
.
getStartedAt
()
>
challenge
.
getTimeLimit
()
*
1000L
){
challenge
.
fail
();
}
}
}
src/main/java/emu/grasscutter/game/dungeons/challenge/trigger/KillGadgetTrigger.java
0 → 100644
View file @
791b9534
package
emu.grasscutter.game.dungeons.challenge.trigger
;
import
emu.grasscutter.game.dungeons.challenge.WorldChallenge
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.server.packet.send.PacketChallengeDataNotify
;
public
class
KillGadgetTrigger
extends
ChallengeTrigger
{
@Override
public
void
onBegin
(
WorldChallenge
challenge
)
{
challenge
.
getScene
().
broadcastPacket
(
new
PacketChallengeDataNotify
(
challenge
,
2
,
challenge
.
getScore
().
get
()));
}
@Override
public
void
onGadgetDeath
(
WorldChallenge
challenge
,
EntityGadget
gadget
)
{
var
newScore
=
challenge
.
increaseScore
();
challenge
.
getScene
().
broadcastPacket
(
new
PacketChallengeDataNotify
(
challenge
,
2
,
newScore
));
if
(
newScore
>=
challenge
.
getGoal
()){
challenge
.
done
();
}
}
}
src/main/java/emu/grasscutter/game/dungeons/challenge/trigger/KillMonsterTrigger.java
0 → 100644
View file @
791b9534
package
emu.grasscutter.game.dungeons.challenge.trigger
;
import
emu.grasscutter.game.dungeons.challenge.WorldChallenge
;
import
emu.grasscutter.game.entity.EntityMonster
;
import
emu.grasscutter.server.packet.send.PacketChallengeDataNotify
;
public
class
KillMonsterTrigger
extends
ChallengeTrigger
{
@Override
public
void
onBegin
(
WorldChallenge
challenge
)
{
challenge
.
getScene
().
broadcastPacket
(
new
PacketChallengeDataNotify
(
challenge
,
1
,
challenge
.
getScore
().
get
()));
}
@Override
public
void
onMonsterDeath
(
WorldChallenge
challenge
,
EntityMonster
monster
)
{
var
newScore
=
challenge
.
increaseScore
();
challenge
.
getScene
().
broadcastPacket
(
new
PacketChallengeDataNotify
(
challenge
,
1
,
newScore
));
if
(
newScore
>=
challenge
.
getGoal
()){
challenge
.
done
();
}
}
}
src/main/java/emu/grasscutter/game/entity/EntityGadget.java
View file @
791b9534
package
emu.grasscutter.game.entity
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.def.GadgetData
;
import
emu.grasscutter.game.entity.gadget.GadgetChest
;
import
emu.grasscutter.game.entity.gadget.GadgetContent
;
import
emu.grasscutter.game.entity.gadget.GadgetGatherPoint
;
import
emu.grasscutter.game.entity.gadget.GadgetRewardStatue
;
import
emu.grasscutter.game.entity.gadget.GadgetWorktop
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.EntityIdType
;
import
emu.grasscutter.game.props.EntityType
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.data.def.GadgetPropData
;
import
emu.grasscutter.game.entity.gadget.*
;
import
emu.grasscutter.game.props.*
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo
;
import
emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair
;
...
...
@@ -32,6 +24,7 @@ import emu.grasscutter.scripts.constants.EventType;
import
emu.grasscutter.scripts.data.SceneGadget
;
import
emu.grasscutter.scripts.data.ScriptArgs
;
import
emu.grasscutter.server.packet.send.PacketGadgetStateNotify
;
import
emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify
;
import
emu.grasscutter.utils.Position
;
import
emu.grasscutter.utils.ProtoHelper
;
import
it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap
;
...
...
@@ -160,7 +153,10 @@ public class EntityGadget extends EntityBaseGadget {
@Override
public
void
onDeath
(
int
killerId
)
{
if
(
getScene
().
getChallenge
()
!=
null
){
getScene
().
getChallenge
().
onGadgetDeath
(
this
);
}
getScene
().
getScriptManager
().
callEvent
(
EventType
.
EVENT_ANY_GADGET_DIE
,
new
ScriptArgs
(
this
.
getConfigId
()));
}
@Override
...
...
@@ -203,4 +199,8 @@ public class EntityGadget extends EntityBaseGadget {
return
entityInfo
.
build
();
}
public
void
die
()
{
getScene
().
broadcastPacket
(
new
PacketLifeStateChangeNotify
(
this
,
LifeState
.
LIFE_DEAD
));
this
.
onDeath
(
0
);
}
}
src/main/java/emu/grasscutter/game/entity/EntityMonster.java
View file @
791b9534
...
...
@@ -122,8 +122,8 @@ public class EntityMonster extends GameEntity {
this
.
getScene
().
getDeadSpawnedEntities
().
add
(
getSpawnEntry
());
}
// first set the challenge data
if
(
getScene
().
getChallenge
()
!=
null
&&
getScene
().
getChallenge
().
getGroup
().
id
==
this
.
getGroupId
()
)
{
getScene
().
getChallenge
().
onMonsterD
i
e
(
this
);
if
(
getScene
().
getChallenge
()
!=
null
)
{
getScene
().
getChallenge
().
onMonsterDe
ath
(
this
);
}
if
(
getScene
().
getScriptManager
().
isInit
()
&&
this
.
getGroupId
()
>
0
)
{
if
(
getScene
().
getScriptManager
().
getScriptMonsterSpawnService
()
!=
null
){
...
...
src/main/java/emu/grasscutter/game/entity/gadget/GadgetChest.java
View file @
791b9534
...
...
@@ -38,6 +38,8 @@ public class GadgetChest extends GadgetContent {
getGadget
().
updateState
(
ScriptGadgetState
.
ChestOpened
);
player
.
sendPacket
(
new
PacketGadgetInteractRsp
(
this
.
getGadget
(),
InteractTypeOuterClass
.
InteractType
.
INTERACT_OPEN_CHEST
));
// let the chest disappear
getGadget
().
die
();
return
true
;
}
}
...
...
src/main/java/emu/grasscutter/game/entity/gadget/GadgetRewardStatue.java
View file @
791b9534
package
emu.grasscutter.game.entity.gadget
;
import
emu.grasscutter.game.dungeons.challenge.DungeonChallenge
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.net.proto.InterOpTypeOuterClass
;
...
...
@@ -14,8 +15,8 @@ public class GadgetRewardStatue extends GadgetContent {
}
public
boolean
onInteract
(
Player
player
,
InterOpTypeOuterClass
.
InterOpType
opType
)
{
if
(
player
.
getScene
().
getChallenge
()
!=
null
)
{
player
.
getScene
().
get
Challenge
()
.
getStatueDrops
(
player
);
if
(
player
.
getScene
().
getChallenge
()
!=
null
&&
player
.
getScene
().
getChallenge
()
instanceof
DungeonChallenge
dungeonChallenge
)
{
dungeon
Challenge
.
getStatueDrops
(
player
);
}
player
.
sendPacket
(
new
PacketGadgetInteractRsp
(
getGadget
(),
InteractType
.
INTERACT_OPEN_STATUE
));
...
...
src/main/java/emu/grasscutter/game/entity/gadget/chest/BossChestInteractHandler.java
View file @
791b9534
package
emu.grasscutter.game.entity.gadget.chest
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.common.ItemParamData
;
import
emu.grasscutter.game.entity.gadget.GadgetChest
;
import
emu.grasscutter.game.inventory.GameItem
;
...
...
@@ -22,6 +23,10 @@ public class BossChestInteractHandler implements ChestInteractHandler{
var
monster
=
chest
.
getGadget
().
getMetaGadget
().
group
.
monsters
.
get
(
chest
.
getGadget
().
getMetaGadget
().
boss_chest
.
monster_config_id
);
var
reward
=
worldDataManager
.
getRewardByBossId
(
monster
.
monster_id
);
if
(
reward
==
null
){
Grasscutter
.
getLogger
().
warn
(
"Could not found the reward of boss monster {}"
,
monster
.
monster_id
);
return
false
;
}
List
<
GameItem
>
rewards
=
new
ArrayList
<>();
for
(
ItemParamData
param
:
reward
.
getPreviewItems
())
{
rewards
.
add
(
new
GameItem
(
param
.
getId
(),
Math
.
max
(
param
.
getCount
(),
1
)));
...
...
src/main/java/emu/grasscutter/game/world/Scene.java
View file @
791b9534
...
...
@@ -4,7 +4,6 @@ import emu.grasscutter.Grasscutter;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.GameDepot
;
import
emu.grasscutter.data.def.*
;
import
emu.grasscutter.game.dungeons.DungeonChallenge
;
import
emu.grasscutter.game.dungeons.DungeonSettleListener
;
import
emu.grasscutter.game.entity.*
;
import
emu.grasscutter.game.player.Player
;
...
...
@@ -14,6 +13,7 @@ import emu.grasscutter.game.props.FightProperty;
import
emu.grasscutter.game.props.LifeState
;
import
emu.grasscutter.game.props.SceneType
;
import
emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry
;
import
emu.grasscutter.game.dungeons.challenge.WorldChallenge
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType
;
...
...
@@ -32,8 +32,6 @@ import org.danilopianini.util.SpatialIndex;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
static
emu
.
grasscutter
.
utils
.
Language
.
translate
;
public
class
Scene
{
private
final
World
world
;
private
final
SceneData
sceneData
;
...
...
@@ -51,7 +49,7 @@ public class Scene {
private
int
weather
;
private
SceneScriptManager
scriptManager
;
private
Dungeon
Challenge
challenge
;
private
World
Challenge
challenge
;
private
List
<
DungeonSettleListener
>
dungeonSettleListeners
;
private
DungeonData
dungeonData
;
private
int
prevScene
;
// Id of the previous scene
...
...
@@ -199,11 +197,11 @@ public class Scene {
this
.
dungeonData
=
dungeonData
;
}
public
Dungeon
Challenge
getChallenge
()
{
public
World
Challenge
getChallenge
()
{
return
challenge
;
}
public
void
setChallenge
(
Dungeon
Challenge
challenge
)
{
public
void
setChallenge
(
World
Challenge
challenge
)
{
this
.
challenge
=
challenge
;
}
...
...
@@ -353,7 +351,14 @@ public class Scene {
this
.
broadcastPacket
(
new
PacketSceneEntityDisappearNotify
(
removed
,
visionType
));
}
}
public
synchronized
void
removeEntities
(
List
<
GameEntity
>
entity
,
VisionType
visionType
)
{
var
toRemove
=
entity
.
stream
()
.
map
(
this
::
removeEntityDirectly
)
.
toList
();
if
(
toRemove
.
size
()
>
0
)
{
this
.
broadcastPacket
(
new
PacketSceneEntityDisappearNotify
(
toRemove
,
visionType
));
}
}
public
synchronized
void
replaceEntity
(
EntityAvatar
oldEntity
,
EntityAvatar
newEntity
)
{
this
.
removeEntityDirectly
(
oldEntity
);
this
.
addEntityDirectly
(
newEntity
);
...
...
@@ -418,6 +423,10 @@ public class Scene {
}
// Triggers
this
.
scriptManager
.
checkRegions
();
if
(
challenge
!=
null
){
challenge
.
onCheckTimeOut
();
}
}
// TODO - Test
...
...
@@ -590,21 +599,21 @@ public class Scene {
if
(
suite
==
0
||
group
.
suites
==
null
||
group
.
suites
.
size
()
==
0
)
{
continue
;
}
do
{
var
suiteData
=
group
.
getSuiteByIndex
(
suite
);
suiteData
.
sceneTriggers
.
forEach
(
getScriptManager
()::
registerTrigger
);
entities
.
addAll
(
suiteData
.
sceneGadgets
.
stream
()
.
map
(
g
->
scriptManager
.
createGadget
(
group
.
id
,
group
.
block_id
,
g
)).
toList
());
entities
.
addAll
(
suiteData
.
sceneMonsters
.
stream
()
.
map
(
mob
->
scriptManager
.
createMonster
(
group
.
id
,
group
.
block_id
,
mob
)).
toList
());
suite
++;
}
while
(
suite
<
group
.
init_config
.
end_suite
);
// just load the 'init' suite, avoid spawn the suite added by AddExtraGroupSuite etc.
var
suiteData
=
group
.
getSuiteByIndex
(
suite
);
suiteData
.
sceneTriggers
.
forEach
(
getScriptManager
()::
registerTrigger
);
entities
.
addAll
(
suiteData
.
sceneGadgets
.
stream
()
.
map
(
g
->
scriptManager
.
createGadget
(
group
.
id
,
group
.
block_id
,
g
)).
toList
());
entities
.
addAll
(
suiteData
.
sceneMonsters
.
stream
()
.
map
(
mob
->
scriptManager
.
createMonster
(
group
.
id
,
group
.
block_id
,
mob
)).
toList
());
}
scriptManager
.
meetEntities
(
entities
);
//scriptManager.callEvent(EventType.EVENT_GROUP_LOAD, null);
//groups.forEach(g -> scriptManager.callEvent(EventType.EVENT_GROUP_LOAD, null));
Grasscutter
.
getLogger
().
info
(
"Scene {} loaded {} group(s)"
,
this
.
getId
(),
groups
.
size
());
}
...
...
src/main/java/emu/grasscutter/scripts/SceneScriptManager.java
View file @
791b9534
...
...
@@ -26,16 +26,13 @@ import java.util.concurrent.ExecutorService;
import
java.util.concurrent.LinkedBlockingDeque
;
import
java.util.concurrent.ThreadPoolExecutor
;
import
java.util.concurrent.TimeUnit
;
import
java.util.stream.Collectors
;
public
class
SceneScriptManager
{
private
final
Scene
scene
;
private
final
Map
<
String
,
Integer
>
variables
;
private
SceneMeta
meta
;
private
boolean
isInit
;
/**
* SceneTrigger Set
*/
private
final
Map
<
String
,
SceneTrigger
>
triggers
;
/**
* current triggers controlled by RefreshGroup
*/
...
...
@@ -51,12 +48,11 @@ public class SceneScriptManager {
public
static
final
ExecutorService
eventExecutor
;
static
{
eventExecutor
=
new
ThreadPoolExecutor
(
4
,
4
,
60
,
TimeUnit
.
SECONDS
,
new
LinkedBlockingDeque
<>(
100
),
60
,
TimeUnit
.
SECONDS
,
new
LinkedBlockingDeque
<>(
100
0
),
FastThreadLocalThread:
:
new
,
new
ThreadPoolExecutor
.
AbortPolicy
());
}
public
SceneScriptManager
(
Scene
scene
)
{
this
.
scene
=
scene
;
this
.
triggers
=
new
HashMap
<>();
this
.
currentTriggers
=
new
Int2ObjectOpenHashMap
<>();
this
.
regions
=
new
Int2ObjectOpenHashMap
<>();
...
...
@@ -96,13 +92,16 @@ public class SceneScriptManager {
public
Set
<
SceneTrigger
>
getTriggersByEvent
(
int
eventId
)
{
return
currentTriggers
.
computeIfAbsent
(
eventId
,
e
->
new
HashSet
<>());
}
public
void
registerTrigger
(
List
<
SceneTrigger
>
triggers
)
{
triggers
.
forEach
(
this
::
registerTrigger
);
}
public
void
registerTrigger
(
SceneTrigger
trigger
)
{
this
.
triggers
.
put
(
trigger
.
name
,
trigger
);
getTriggersByEvent
(
trigger
.
event
).
add
(
trigger
);
}
public
void
deregisterTrigger
(
List
<
SceneTrigger
>
triggers
)
{
triggers
.
forEach
(
this
::
deregisterTrigger
);
}
public
void
deregisterTrigger
(
SceneTrigger
trigger
)
{
this
.
triggers
.
remove
(
trigger
.
name
);
getTriggersByEvent
(
trigger
.
event
).
remove
(
trigger
);
}
public
void
resetTriggers
(
int
eventId
)
{
...
...
@@ -205,7 +204,17 @@ public class SceneScriptManager {
}
}
}
public
void
addGroupSuite
(
SceneGroup
group
,
SceneSuite
suite
){
spawnMonstersInGroup
(
group
,
suite
);
spawnGadgetsInGroup
(
group
,
suite
);
registerTrigger
(
suite
.
sceneTriggers
);
}
public
void
removeGroupSuite
(
SceneGroup
group
,
SceneSuite
suite
){
removeMonstersInGroup
(
group
,
suite
);
removeGadgetsInGroup
(
group
,
suite
);
deregisterTrigger
(
suite
.
sceneTriggers
);
}
public
void
spawnGadgetsInGroup
(
SceneGroup
group
,
int
suiteIndex
)
{
spawnGadgetsInGroup
(
group
,
group
.
getSuiteByIndex
(
suiteIndex
));
}
...
...
@@ -241,7 +250,6 @@ public class SceneScriptManager {
}
this
.
addEntities
(
suite
.
sceneMonsters
.
stream
()
.
map
(
mob
->
createMonster
(
group
.
id
,
group
.
block_id
,
mob
)).
toList
());
}
public
void
spawnMonstersInGroup
(
SceneGroup
group
)
{
...
...
@@ -326,7 +334,7 @@ public class SceneScriptManager {
try
{
return
func
.
call
(
ScriptLoader
.
getScriptLibLua
(),
args
);
}
catch
(
LuaError
error
){
ScriptLib
.
logger
.
error
(
"[LUA] call trigger failed {},{}
,{}
"
,
name
,
args
,
error
.
getMessage
()
);
ScriptLib
.
logger
.
error
(
"[LUA] call trigger failed {},{}"
,
name
,
args
,
error
);
return
LuaValue
.
valueOf
(-
1
);
}
}
...
...
@@ -388,6 +396,7 @@ public class SceneScriptManager {
entity
.
setGroupId
(
groupId
);
entity
.
setBlockId
(
blockId
);
entity
.
setConfigId
(
monster
.
config_id
);
entity
.
setPoseId
(
monster
.
pose_id
);
this
.
getScriptMonsterSpawnService
()
.
onMonsterCreatedListener
.
forEach
(
action
->
action
.
onNotify
(
entity
));
...
...
@@ -410,4 +419,28 @@ public class SceneScriptManager {
public
PhTree
<
SceneBlock
>
getBlocksIndex
()
{
return
meta
.
sceneBlockIndex
;
}
public
void
removeMonstersInGroup
(
SceneGroup
group
,
SceneSuite
suite
)
{
var
configSet
=
suite
.
sceneMonsters
.
stream
()
.
map
(
m
->
m
.
config_id
)
.
collect
(
Collectors
.
toSet
());
var
toRemove
=
getScene
().
getEntities
().
values
().
stream
()
.
filter
(
e
->
e
instanceof
EntityMonster
)
.
filter
(
e
->
e
.
getGroupId
()
==
group
.
id
)
.
filter
(
e
->
configSet
.
contains
(
e
.
getConfigId
()))
.
toList
();
getScene
().
removeEntities
(
toRemove
,
VisionTypeOuterClass
.
VisionType
.
VISION_MISS
);
}
public
void
removeGadgetsInGroup
(
SceneGroup
group
,
SceneSuite
suite
)
{
var
configSet
=
suite
.
sceneGadgets
.
stream
()
.
map
(
m
->
m
.
config_id
)
.
collect
(
Collectors
.
toSet
());
var
toRemove
=
getScene
().
getEntities
().
values
().
stream
()
.
filter
(
e
->
e
instanceof
EntityGadget
)
.
filter
(
e
->
e
.
getGroupId
()
==
group
.
id
)
.
filter
(
e
->
configSet
.
contains
(
e
.
getConfigId
()))
.
toList
();
getScene
().
removeEntities
(
toRemove
,
VisionTypeOuterClass
.
VisionType
.
VISION_MISS
);
}
}
Prev
1
2
Next
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