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
b58bcda0
Commit
b58bcda0
authored
May 07, 2022
by
Akka
Browse files
Tower Dungeons Handoff between level and floor
parent
f683b222
Changes
11
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/dungeons/BasicDungeonSettleListener.java
0 → 100644
View file @
b58bcda0
package
emu.grasscutter.game.dungeons
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.server.packet.send.PacketDungeonSettleNotify
;
import
emu.grasscutter.utils.Utils
;
public
class
BasicDungeonSettleListener
implements
DungeonSettleListener
{
@Override
public
void
onDungeonSettle
(
Scene
scene
)
{
scene
.
setAutoCloseTime
(
Utils
.
getCurrentSeconds
()
+
1000
);
scene
.
broadcastPacket
(
new
PacketDungeonSettleNotify
(
scene
.
getChallenge
()));
}
}
src/main/java/emu/grasscutter/game/dungeons/DungeonChallenge.java
View file @
b58bcda0
package
emu.grasscutter.game.dungeons
;
import
java.util.ArrayList
;
import
java.util.List
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.common.ItemParamData
;
import
emu.grasscutter.data.def.DungeonData
;
import
emu.grasscutter.data.def.MonsterData
;
import
emu.grasscutter.game.entity.EntityMonster
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType
;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
emu.grasscutter.scripts.data.SceneMonster
;
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.PacketDungeonSettleNotify
;
import
emu.grasscutter.server.packet.send.PacketGadgetAutoPickDropInfoNotify
;
import
emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify
;
import
emu.grasscutter.utils.Utils
;
import
it.unimi.dsi.fastutil.ints.IntOpenHashSet
;
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
;
...
...
@@ -129,8 +121,7 @@ public class DungeonChallenge {
}
private
void
settle
()
{
getScene
().
setAutoCloseTime
(
Utils
.
getCurrentSeconds
()
+
1000
);
getScene
().
broadcastPacket
(
new
PacketDungeonSettleNotify
(
this
));
getScene
().
getDungeonSettleObservers
().
forEach
(
o
->
o
.
onDungeonSettle
(
getScene
()));
getScene
().
getScriptManager
().
callEvent
(
EventType
.
EVENT_DUNGEON_SETTLE
,
new
ScriptArgs
(
this
.
isSuccess
()
?
1
:
0
));
}
...
...
src/main/java/emu/grasscutter/game/dungeons/DungeonManager.java
View file @
b58bcda0
...
...
@@ -14,9 +14,11 @@ import emu.grasscutter.server.packet.send.PacketDungeonEntryInfoRsp;
import
emu.grasscutter.server.packet.send.PacketPlayerEnterDungeonRsp
;
import
emu.grasscutter.utils.Position
;
import
java.util.List
;
public
class
DungeonManager
{
private
final
GameServer
server
;
private
static
final
BasicDungeonSettleListener
basicDungeonSettleObserver
=
new
BasicDungeonSettleListener
();
public
DungeonManager
(
GameServer
server
)
{
this
.
server
=
server
;
}
...
...
@@ -49,13 +51,32 @@ public class DungeonManager {
int
sceneId
=
data
.
getSceneId
();
player
.
getScene
().
setPrevScene
(
sceneId
);
player
.
getWorld
().
transferPlayerToScene
(
player
,
sceneId
,
data
);
if
(
player
.
getWorld
().
transferPlayerToScene
(
player
,
sceneId
,
data
)){
player
.
getScene
().
addDungeonSettleObserver
(
basicDungeonSettleObserver
);
}
player
.
getScene
().
setPrevScenePoint
(
pointId
);
player
.
sendPacket
(
new
PacketPlayerEnterDungeonRsp
(
pointId
,
dungeonId
));
return
true
;
}
/**
* used in tower dungeons handoff
*/
public
boolean
handoffDungeon
(
Player
player
,
int
dungeonId
,
List
<
DungeonSettleListener
>
dungeonSettleListeners
)
{
DungeonData
data
=
GameData
.
getDungeonDataMap
().
get
(
dungeonId
);
if
(
data
==
null
)
{
return
false
;
}
Grasscutter
.
getLogger
().
info
(
player
.
getNickname
()
+
" is trying to enter tower dungeon "
+
dungeonId
);
if
(
player
.
getWorld
().
transferPlayerToScene
(
player
,
data
.
getSceneId
(),
data
)){
dungeonSettleListeners
.
forEach
(
player
.
getScene
()::
addDungeonSettleObserver
);
}
return
true
;
}
public
void
exitDungeon
(
Player
player
)
{
if
(
player
.
getScene
().
getSceneType
()
!=
SceneType
.
SCENE_DUNGEON
)
{
return
;
...
...
@@ -77,6 +98,7 @@ public class DungeonManager {
}
// clean temp team if it has
player
.
getTeamManager
().
cleanTemporaryTeam
();
player
.
getTowerManager
().
clearEntry
();
// Transfer player back to world
player
.
getWorld
().
transferPlayerToScene
(
player
,
prevScene
,
prevPos
);
player
.
sendPacket
(
new
BasePacket
(
PacketOpcodes
.
PlayerQuitDungeonRsp
));
...
...
src/main/java/emu/grasscutter/game/dungeons/DungeonSettleListener.java
0 → 100644
View file @
b58bcda0
package
emu.grasscutter.game.dungeons
;
import
emu.grasscutter.game.world.Scene
;
public
interface
DungeonSettleListener
{
void
onDungeonSettle
(
Scene
scene
);
}
src/main/java/emu/grasscutter/game/dungeons/TowerDungeonSettleListener.java
0 → 100644
View file @
b58bcda0
package
emu.grasscutter.game.dungeons
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.server.packet.send.PacketDungeonSettleNotify
;
import
emu.grasscutter.server.packet.send.PacketTowerFloorRecordChangeNotify
;
import
emu.grasscutter.utils.Utils
;
public
class
TowerDungeonSettleListener
implements
DungeonSettleListener
{
@Override
public
void
onDungeonSettle
(
Scene
scene
)
{
scene
.
setAutoCloseTime
(
Utils
.
getCurrentSeconds
()
+
1000
);
var
towerManager
=
scene
.
getPlayers
().
get
(
0
).
getTowerManager
();
towerManager
.
notifyCurLevelRecordChangeWhenDone
();
scene
.
broadcastPacket
(
new
PacketTowerFloorRecordChangeNotify
(
towerManager
.
getCurrentFloorId
()));
scene
.
broadcastPacket
(
new
PacketDungeonSettleNotify
(
scene
.
getChallenge
(),
true
,
towerManager
.
hasNextLevel
(),
towerManager
.
getNextFloorId
()
));
}
}
src/main/java/emu/grasscutter/game/player/Player.java
View file @
b58bcda0
...
...
@@ -25,6 +25,7 @@ import emu.grasscutter.game.managers.MotionManager.MotionManager;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.props.EntityType
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.props.SceneType
;
import
emu.grasscutter.game.shop.ShopLimit
;
import
emu.grasscutter.game.managers.MapMarkManager.*
;
import
emu.grasscutter.game.tower.TowerManager
;
...
...
@@ -1048,6 +1049,7 @@ public class Player {
@PostLoad
private
void
onLoad
()
{
this
.
getTeamManager
().
setPlayer
(
this
);
this
.
getTowerManager
().
setPlayer
(
this
);
}
public
void
save
()
{
...
...
@@ -1117,6 +1119,10 @@ public class Player {
}
public
void
onLogout
()
{
// force to leave the dungeon
if
(
getScene
().
getSceneType
()
==
SceneType
.
SCENE_DUNGEON
){
this
.
getServer
().
getDungeonManager
().
exitDungeon
(
this
);
}
// Leave world
if
(
this
.
getWorld
()
!=
null
)
{
this
.
getWorld
().
removePlayer
(
this
);
...
...
src/main/java/emu/grasscutter/game/tower/TowerManager.java
View file @
b58bcda0
package
emu.grasscutter.game.tower
;
import
dev.morphia.annotations.Entity
;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.def.TowerLevelData
;
import
emu.grasscutter.game.dungeons.DungeonSettleListener
;
import
emu.grasscutter.game.dungeons.TowerDungeonSettleListener
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.server.packet.send.PacketTowerCurLevelRecordChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketTowerEnterLevelRsp
;
import
java.util.List
;
@Entity
public
class
TowerManager
{
private
final
Player
player
;
@Transient
private
Player
player
;
public
TowerManager
(
Player
player
)
{
this
.
player
=
player
;
}
public
void
setPlayer
(
Player
player
)
{
this
.
player
=
player
;
}
private
int
currentFloorId
;
private
int
currentLevel
;
private
int
currentFloor
;
@Transient
private
int
currentLevelId
;
@Transient
private
int
entryScene
;
public
int
getCurrentFloorId
()
{
return
currentFloorId
;
}
private
static
final
List
<
DungeonSettleListener
>
towerDungeonSettleListener
=
List
.
of
(
new
TowerDungeonSettleListener
());
public
void
teamSelect
(
int
floor
,
List
<
List
<
Long
>>
towerTeams
)
{
var
floorData
=
GameData
.
getTowerFloorDataMap
().
get
(
floor
);
this
.
currentFloor
=
floorData
.
getFloorId
();
this
.
currentLevel
=
floorData
.
getLevelId
();
this
.
currentFloorId
=
floorData
.
getFloorId
();
this
.
currentLevel
=
0
;
this
.
currentLevelId
=
GameData
.
getTowerLevelDataMap
().
values
().
stream
()
.
filter
(
x
->
x
.
getLevelId
()
==
floorData
.
getLevelId
()
&&
x
.
getLevelIndex
()
==
1
)
.
findFirst
()
.
map
(
TowerLevelData:
:
getID
)
.
orElse
(
0
);
if
(
entryScene
==
0
){
entryScene
=
player
.
getSceneId
();
}
player
.
getTeamManager
().
setupTemporaryTeam
(
towerTeams
);
}
public
void
enterLevel
(
int
enterPointId
)
{
var
levelData
=
GameData
.
getTowerLevelDataMap
().
get
(
currentLevel
);
var
levelData
=
GameData
.
getTowerLevelDataMap
().
get
(
currentLevelId
+
currentLevel
);
this
.
currentLevel
++;
var
id
=
levelData
.
getDungeonId
();
notifyCurLevelRecordChange
();
// use team user choose
player
.
getTeamManager
().
useTemporaryTeam
(
0
);
player
.
getServer
().
getDungeonManager
()
.
enterDungeon
(
player
,
enterPointId
,
id
);
player
.
getServer
().
getDungeonManager
().
handoffDungeon
(
player
,
id
,
towerDungeonSettleListener
);
// make sure user can exit dungeon correctly
player
.
getScene
().
setPrevScene
(
entryScene
);
player
.
getScene
().
setPrevScenePoint
(
enterPointId
);
player
.
getSession
().
send
(
new
PacketTowerEnterLevelRsp
(
currentFloorId
,
currentLevel
));
}
public
void
notifyCurLevelRecordChange
(){
player
.
getSession
().
send
(
new
PacketTowerCurLevelRecordChangeNotify
(
currentFloorId
,
currentLevel
));
}
public
void
notifyCurLevelRecordChangeWhenDone
(){
player
.
getSession
().
send
(
new
PacketTowerCurLevelRecordChangeNotify
(
currentFloorId
,
currentLevel
+
1
));
}
public
boolean
hasNextLevel
(){
return
this
.
currentLevel
<
3
;
}
public
int
getNextFloorId
()
{
if
(
hasNextLevel
()){
return
0
;
}
this
.
currentFloorId
++;
return
this
.
currentFloorId
;
}
player
.
getSession
().
send
(
new
PacketTowerEnterLevelRsp
(
currentFloor
,
currentLevel
));
public
void
clearEntry
()
{
this
.
entryScene
=
0
;
}
}
src/main/java/emu/grasscutter/game/world/Scene.java
View file @
b58bcda0
package
emu.grasscutter.game.world
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.GameDepot
;
import
emu.grasscutter.data.def.DungeonData
;
...
...
@@ -8,6 +7,7 @@ import emu.grasscutter.data.def.MonsterData;
import
emu.grasscutter.data.def.SceneData
;
import
emu.grasscutter.data.def.WorldLevelData
;
import
emu.grasscutter.game.dungeons.DungeonChallenge
;
import
emu.grasscutter.game.dungeons.DungeonSettleListener
;
import
emu.grasscutter.game.entity.*
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.player.TeamInfo
;
...
...
@@ -20,11 +20,8 @@ import emu.grasscutter.net.packet.BasePacket;
import
emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType
;
import
emu.grasscutter.scripts.SceneScriptManager
;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.scripts.data.SceneBlock
;
import
emu.grasscutter.scripts.data.SceneGadget
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
emu.grasscutter.scripts.data.ScriptArgs
;
import
emu.grasscutter.server.packet.send.PacketAvatarSkillInfoNotify
;
import
emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify
;
...
...
@@ -56,6 +53,7 @@ public class Scene {
private
SceneScriptManager
scriptManager
;
private
DungeonChallenge
challenge
;
private
List
<
DungeonSettleListener
>
dungeonSettleListeners
;
private
DungeonData
dungeonData
;
private
int
prevScene
;
// Id of the previous scene
private
int
prevScenePoint
;
...
...
@@ -205,6 +203,17 @@ public class Scene {
this
.
challenge
=
challenge
;
}
public
void
addDungeonSettleObserver
(
DungeonSettleListener
dungeonSettleListener
){
if
(
dungeonSettleListeners
==
null
){
dungeonSettleListeners
=
new
ArrayList
<>();
}
dungeonSettleListeners
.
add
(
dungeonSettleListener
);
}
public
List
<
DungeonSettleListener
>
getDungeonSettleObservers
()
{
return
dungeonSettleListeners
;
}
public
boolean
isInScene
(
GameEntity
entity
)
{
return
this
.
entities
.
containsKey
(
entity
.
getId
());
}
...
...
src/main/java/emu/grasscutter/server/packet/send/PacketDungeonSettleNotify.java
View file @
b58bcda0
...
...
@@ -4,6 +4,8 @@ import emu.grasscutter.game.dungeons.DungeonChallenge;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.DungeonSettleNotifyOuterClass.DungeonSettleNotify
;
import
emu.grasscutter.net.proto.ItemParamOuterClass
;
import
emu.grasscutter.net.proto.TowerLevelEndNotifyOuterClass.TowerLevelEndNotify
;
public
class
PacketDungeonSettleNotify
extends
BasePacket
{
...
...
@@ -19,4 +21,43 @@ public class PacketDungeonSettleNotify extends BasePacket {
this
.
setData
(
proto
);
}
public
PacketDungeonSettleNotify
(
DungeonChallenge
challenge
,
boolean
canJump
,
boolean
hasNextLevel
,
int
nextFloorId
)
{
super
(
PacketOpcodes
.
DungeonSettleNotify
);
var
continueStatus
=
TowerLevelEndNotify
.
ContinueStateType
.
CONTINUE_STATE_CAN_NOT_CONTINUE_VALUE
;
if
(
challenge
.
isSuccess
()
&&
canJump
){
continueStatus
=
hasNextLevel
?
TowerLevelEndNotify
.
ContinueStateType
.
CONTINUE_STATE_CAN_ENTER_NEXT_LEVEL_VALUE
:
TowerLevelEndNotify
.
ContinueStateType
.
CONTINUE_STATE_CAN_ENTER_NEXT_FLOOR_VALUE
;
}
var
towerLevelEndNotify
=
TowerLevelEndNotify
.
newBuilder
()
.
setIsSuccess
(
challenge
.
isSuccess
())
.
setContinueState
(
continueStatus
)
.
addFinishedStarCondList
(
1
)
.
addFinishedStarCondList
(
2
)
.
addFinishedStarCondList
(
3
)
.
addRewardItemList
(
ItemParamOuterClass
.
ItemParam
.
newBuilder
()
.
setItemId
(
201
)
.
setCount
(
1000
)
.
build
())
;
if
(
nextFloorId
>
0
){
towerLevelEndNotify
.
setNextFloorId
(
nextFloorId
);
}
DungeonSettleNotify
proto
=
DungeonSettleNotify
.
newBuilder
()
.
setDungeonId
(
challenge
.
getScene
().
getDungeonData
().
getId
())
.
setIsSuccess
(
challenge
.
isSuccess
())
.
setCloseTime
(
challenge
.
getScene
().
getAutoCloseTime
())
.
setResult
(
challenge
.
isSuccess
()
?
1
:
0
)
.
setTowerLevelEndNotify
(
towerLevelEndNotify
.
build
())
.
build
();
this
.
setData
(
proto
);
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketTowerCurLevelRecordChangeNotify.java
0 → 100644
View file @
b58bcda0
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.TowerCurLevelRecordChangeNotifyOuterClass.TowerCurLevelRecordChangeNotify
;
import
emu.grasscutter.net.proto.TowerCurLevelRecordOuterClass.TowerCurLevelRecord
;
public
class
PacketTowerCurLevelRecordChangeNotify
extends
BasePacket
{
public
PacketTowerCurLevelRecordChangeNotify
(
int
curFloorId
,
int
curLevelIndex
)
{
super
(
PacketOpcodes
.
TowerCurLevelRecordChangeNotify
);
TowerCurLevelRecordChangeNotify
proto
=
TowerCurLevelRecordChangeNotify
.
newBuilder
()
.
setCurLevelRecord
(
TowerCurLevelRecord
.
newBuilder
()
.
setCurFloorId
(
curFloorId
)
.
setCurLevelIndex
(
curLevelIndex
)
// TODO team info
.
build
())
.
build
();
this
.
setData
(
proto
);
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketTowerFloorRecordChangeNotify.java
0 → 100644
View file @
b58bcda0
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.TowerFloorRecordChangeNotifyOuterClass.TowerFloorRecordChangeNotify
;
import
emu.grasscutter.net.proto.TowerFloorRecordOuterClass.TowerFloorRecord
;
import
emu.grasscutter.net.proto.TowerLevelRecordOuterClass.TowerLevelRecord
;
public
class
PacketTowerFloorRecordChangeNotify
extends
BasePacket
{
public
PacketTowerFloorRecordChangeNotify
(
int
floorId
)
{
super
(
PacketOpcodes
.
TowerFloorRecordChangeNotify
);
TowerFloorRecordChangeNotify
proto
=
TowerFloorRecordChangeNotify
.
newBuilder
()
.
addTowerFloorRecordList
(
TowerFloorRecord
.
newBuilder
()
.
setFloorId
(
floorId
)
.
setFloorStarRewardProgress
(
3
)
.
addPassedLevelRecordList
(
TowerLevelRecord
.
newBuilder
()
.
setLevelId
(
1
)
.
addSatisfiedCondList
(
1
)
.
addSatisfiedCondList
(
2
)
.
addSatisfiedCondList
(
3
)
.
build
())
.
build
())
.
setIsFinishedEntranceFloor
(
true
)
.
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