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
ad846355
Commit
ad846355
authored
May 06, 2022
by
Melledy
Committed by
GitHub
May 06, 2022
Browse files
Merge pull request #594 from Akka0/tower
Tower Dungeons Handoff between levels
parents
8abd3ace
f2231349
Changes
12
Hide whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/dungeons/BasicDungeonSettleListener.java
0 → 100644
View file @
ad846355
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 @
ad846355
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
;
...
...
@@ -40,7 +32,7 @@ public class DungeonChallenge {
private
int
score
;
private
int
objective
=
0
;
private
IntSet
rewardedPlayers
;
public
DungeonChallenge
(
Scene
scene
,
SceneGroup
group
)
{
this
.
scene
=
scene
;
this
.
group
=
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 @
ad846355
...
...
@@ -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,8 @@ 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 @
ad846355
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 @
ad846355
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 @
ad846355
...
...
@@ -27,6 +27,7 @@ import emu.grasscutter.game.managers.SotSManager.SotSManager;
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
;
...
...
@@ -1083,6 +1084,7 @@ public class Player {
@PostLoad
private
void
onLoad
()
{
this
.
getTeamManager
().
setPlayer
(
this
);
this
.
getTowerManager
().
setPlayer
(
this
);
}
public
void
save
()
{
...
...
@@ -1152,6 +1154,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 @
ad846355
...
...
@@ -3,40 +3,100 @@ 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
{
@Transient
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 @
ad846355
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/scripts/ScriptLib.java
View file @
ad846355
...
...
@@ -207,4 +207,19 @@ public class ScriptLib {
public
void
PrintContextLog
(
String
msg
)
{
Grasscutter
.
getLogger
().
info
(
"[LUA] "
+
msg
);
}
public
int
TowerCountTimeStatus
(
int
var1
,
int
var2
){
return
0
;
}
public
int
GetGroupMonsterCount
(
int
var1
){
// Maybe...
return
GetGroupMonsterCountByGroupId
(
var1
);
}
public
int
SetMonsterBattleByGroup
(
int
var1
,
int
var2
,
int
var3
){
return
0
;
}
public
int
CauseDungeonFail
(
int
var1
){
return
0
;
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketDungeonSettleNotify.java
View file @
ad846355
...
...
@@ -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 @
ad846355
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 @
ad846355
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