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
8050f0cc
Commit
8050f0cc
authored
Jul 23, 2022
by
akatatsu27
Browse files
and misc bug fixes
parent
02a56fce
Changes
28
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/data/ResourceLoader.java
View file @
8050f0cc
...
@@ -67,6 +67,7 @@ public class ResourceLoader {
...
@@ -67,6 +67,7 @@ public class ResourceLoader {
// Load spawn data and quests
// Load spawn data and quests
loadSpawnData
();
loadSpawnData
();
loadQuests
();
loadQuests
();
loadScriptSceneData
();
// Load scene points - must be done AFTER resources are loaded
// Load scene points - must be done AFTER resources are loaded
loadScenePoints
();
loadScenePoints
();
// Load default home layout
// Load default home layout
...
@@ -420,8 +421,30 @@ public class ResourceLoader {
...
@@ -420,8 +421,30 @@ public class ResourceLoader {
Grasscutter
.
getLogger
().
debug
(
"Loaded "
+
GameData
.
getMainQuestDataMap
().
size
()
+
" MainQuestDatas."
);
Grasscutter
.
getLogger
().
debug
(
"Loaded "
+
GameData
.
getMainQuestDataMap
().
size
()
+
" MainQuestDatas."
);
}
}
public
static
void
loadScriptSceneData
()
{
File
folder
=
new
File
(
RESOURCE
(
"ScriptSceneData/"
));
if
(!
folder
.
exists
())
{
return
;
}
for
(
File
file
:
folder
.
listFiles
())
{
ScriptSceneData
sceneData
;
try
(
FileReader
fileReader
=
new
FileReader
(
file
))
{
sceneData
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
ScriptSceneData
.
class
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
continue
;
}
GameData
.
getScriptSceneDataMap
().
put
(
file
.
getName
(),
sceneData
);
}
Grasscutter
.
getLogger
().
debug
(
"Loaded "
+
GameData
.
getScriptSceneDataMap
().
size
()
+
" ScriptSceneDatas."
);
}
@SneakyThrows
@SneakyThrows
private
static
void
loadHomeworldDefaultSaveData
()
{
private
static
void
loadHomeworldDefaultSaveData
(){
var
folder
=
Files
.
list
(
Path
.
of
(
RESOURCE
(
"BinOutput/HomeworldDefaultSave"
))).
toList
();
var
folder
=
Files
.
list
(
Path
.
of
(
RESOURCE
(
"BinOutput/HomeworldDefaultSave"
))).
toList
();
var
pattern
=
Pattern
.
compile
(
"scene(.*)_home_config.json"
);
var
pattern
=
Pattern
.
compile
(
"scene(.*)_home_config.json"
);
...
...
src/main/java/emu/grasscutter/data/binout/MainQuestData.java
View file @
8050f0cc
package
emu.grasscutter.data.binout
;
package
emu.grasscutter.data.binout
;
import
dev.morphia.annotations.Entity
;
import
emu.grasscutter.game.quest.enums.QuestType
;
import
emu.grasscutter.game.quest.enums.QuestType
;
import
lombok.Data
;
import
lombok.Data
;
import
java.util.List
;
import
java.util.Objects
;
public
class
MainQuestData
{
public
class
MainQuestData
{
private
int
id
;
private
int
id
;
private
int
ICLLDPJFIMA
;
private
int
series
;
private
int
series
;
private
QuestType
type
;
private
QuestType
type
;
...
@@ -13,6 +17,8 @@ public class MainQuestData {
...
@@ -13,6 +17,8 @@ public class MainQuestData {
private
int
[]
rewardIdList
;
private
int
[]
rewardIdList
;
private
SubQuestData
[]
subQuests
;
private
SubQuestData
[]
subQuests
;
private
List
<
TalkData
>
talks
;
private
long
[]
preloadLuaList
;
public
int
getId
()
{
public
int
getId
()
{
return
id
;
return
id
;
...
@@ -41,10 +47,24 @@ public class MainQuestData {
...
@@ -41,10 +47,24 @@ public class MainQuestData {
public
SubQuestData
[]
getSubQuests
()
{
public
SubQuestData
[]
getSubQuests
()
{
return
subQuests
;
return
subQuests
;
}
}
public
List
<
TalkData
>
getTalks
()
{
return
talks
;
}
public
void
onLoad
()
{
this
.
talks
=
talks
.
stream
().
filter
(
Objects:
:
nonNull
).
toList
();
}
@Data
@Data
public
static
class
SubQuestData
{
public
static
class
SubQuestData
{
private
int
subId
;
private
int
subId
;
private
int
order
;
private
int
order
;
}
}
@Data
@Entity
public
static
class
TalkData
{
private
int
id
;
private
String
heroTalk
;
}
}
}
src/main/java/emu/grasscutter/data/excels/QuestData.java
View file @
8050f0cc
...
@@ -36,10 +36,14 @@ public class QuestData extends GameResource {
...
@@ -36,10 +36,14 @@ public class QuestData extends GameResource {
private
List
<
QuestExecParam
>
beginExec
;
private
List
<
QuestExecParam
>
beginExec
;
private
List
<
QuestExecParam
>
finishExec
;
private
List
<
QuestExecParam
>
finishExec
;
private
List
<
QuestExecParam
>
failExec
;
private
List
<
QuestExecParam
>
failExec
;
private
Guide
guide
;
//ResourceLoader not happy if you remove getId() ~~
public
int
getId
()
{
public
int
getId
()
{
return
subId
;
return
subId
;
}
}
//Added getSubId() for clarity
public
int
getSubId
()
{
return
subId
;}
public
int
getMainId
()
{
public
int
getMainId
()
{
return
mainId
;
return
mainId
;
...
@@ -62,7 +66,7 @@ public class QuestData extends GameResource {
...
@@ -62,7 +66,7 @@ public class QuestData extends GameResource {
}
}
public
LogicType
getAcceptCondComb
()
{
public
LogicType
getAcceptCondComb
()
{
return
acceptCondComb
;
return
acceptCondComb
==
null
?
LogicType
.
LOGIC_NONE
:
acceptCondComb
;
}
}
public
List
<
QuestCondition
>
getAcceptCond
()
{
public
List
<
QuestCondition
>
getAcceptCond
()
{
...
@@ -70,7 +74,7 @@ public class QuestData extends GameResource {
...
@@ -70,7 +74,7 @@ public class QuestData extends GameResource {
}
}
public
LogicType
getFinishCondComb
()
{
public
LogicType
getFinishCondComb
()
{
return
finishCondComb
;
return
finishCondComb
==
null
?
LogicType
.
LOGIC_NONE
:
finishCondComb
;
}
}
public
List
<
QuestCondition
>
getFinishCond
()
{
public
List
<
QuestCondition
>
getFinishCond
()
{
...
@@ -78,7 +82,7 @@ public class QuestData extends GameResource {
...
@@ -78,7 +82,7 @@ public class QuestData extends GameResource {
}
}
public
LogicType
getFailCondComb
()
{
public
LogicType
getFailCondComb
()
{
return
failCondComb
;
return
failCondComb
==
null
?
LogicType
.
LOGIC_NONE
:
failCondComb
;
}
}
public
List
<
QuestCondition
>
getFailCond
()
{
public
List
<
QuestCondition
>
getFailCond
()
{
...
@@ -118,4 +122,11 @@ public class QuestData extends GameResource {
...
@@ -118,4 +122,11 @@ public class QuestData extends GameResource {
private
String
count
;
private
String
count
;
}
}
@Data
public
static
class
Guide
{
private
String
type
;
private
List
<
String
>
param
;
private
int
guideScene
;
}
}
}
src/main/java/emu/grasscutter/game/player/Player.java
View file @
8050f0cc
...
@@ -14,12 +14,8 @@ import emu.grasscutter.game.activity.ActivityManager;
...
@@ -14,12 +14,8 @@ import emu.grasscutter.game.activity.ActivityManager;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.avatar.AvatarStorage
;
import
emu.grasscutter.game.avatar.AvatarStorage
;
import
emu.grasscutter.game.battlepass.BattlePassManager
;
import
emu.grasscutter.game.battlepass.BattlePassManager
;
import
emu.grasscutter.game.entity.EntityMonster
;
import
emu.grasscutter.game.entity.*
;
import
emu.grasscutter.game.entity.EntityVehicle
;
import
emu.grasscutter.game.home.GameHome
;
import
emu.grasscutter.game.home.GameHome
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.entity.EntityItem
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.game.expedition.ExpeditionInfo
;
import
emu.grasscutter.game.expedition.ExpeditionInfo
;
import
emu.grasscutter.game.friends.FriendsList
;
import
emu.grasscutter.game.friends.FriendsList
;
import
emu.grasscutter.game.friends.PlayerProfile
;
import
emu.grasscutter.game.friends.PlayerProfile
;
...
@@ -43,6 +39,7 @@ import emu.grasscutter.game.props.ClimateType;
...
@@ -43,6 +39,7 @@ import emu.grasscutter.game.props.ClimateType;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.props.WatcherTriggerType
;
import
emu.grasscutter.game.props.WatcherTriggerType
;
import
emu.grasscutter.game.quest.QuestManager
;
import
emu.grasscutter.game.quest.QuestManager
;
import
emu.grasscutter.game.quest.enums.QuestTrigger
;
import
emu.grasscutter.game.shop.ShopLimit
;
import
emu.grasscutter.game.shop.ShopLimit
;
import
emu.grasscutter.game.tower.TowerData
;
import
emu.grasscutter.game.tower.TowerData
;
import
emu.grasscutter.game.tower.TowerManager
;
import
emu.grasscutter.game.tower.TowerManager
;
...
@@ -61,6 +58,7 @@ import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo
...
@@ -61,6 +58,7 @@ import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo
import
emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture
;
import
emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture
;
import
emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail
;
import
emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType
;
import
emu.grasscutter.scripts.data.SceneRegion
;
import
emu.grasscutter.server.event.player.PlayerJoinEvent
;
import
emu.grasscutter.server.event.player.PlayerJoinEvent
;
import
emu.grasscutter.server.event.player.PlayerQuitEvent
;
import
emu.grasscutter.server.event.player.PlayerQuitEvent
;
import
emu.grasscutter.server.game.GameServer
;
import
emu.grasscutter.server.game.GameServer
;
...
@@ -74,6 +72,7 @@ import emu.grasscutter.utils.Utils;
...
@@ -74,6 +72,7 @@ import emu.grasscutter.utils.Utils;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
import
lombok.Getter
;
import
lombok.Getter
;
import
lombok.Setter
;
import
static
emu
.
grasscutter
.
config
.
Configuration
.*;
import
static
emu
.
grasscutter
.
config
.
Configuration
.*;
...
@@ -122,6 +121,7 @@ public class Player {
...
@@ -122,6 +121,7 @@ public class Player {
@Getter
private
Map
<
Long
,
ExpeditionInfo
>
expeditionInfo
;
@Getter
private
Map
<
Long
,
ExpeditionInfo
>
expeditionInfo
;
@Getter
private
Map
<
Integer
,
Integer
>
unlockedRecipies
;
@Getter
private
Map
<
Integer
,
Integer
>
unlockedRecipies
;
@Getter
private
List
<
ActiveForgeData
>
activeForges
;
@Getter
private
List
<
ActiveForgeData
>
activeForges
;
@Getter
private
Map
<
Integer
,
Integer
>
questGlobalVariables
;
@Transient
private
long
nextGuid
=
0
;
@Transient
private
long
nextGuid
=
0
;
@Transient
private
int
peerId
;
@Transient
private
int
peerId
;
...
@@ -579,6 +579,35 @@ public class Player {
...
@@ -579,6 +579,35 @@ public class Player {
return
towerData
;
return
towerData
;
}
}
public
void
setQuestManager
(
QuestManager
questManager
)
{
this
.
questManager
=
questManager
;
}
public
void
onEnterRegion
(
SceneRegion
region
)
{
getQuestManager
().
forEachActiveQuest
(
quest
->
{
if
(
quest
.
getTriggers
().
containsKey
(
"ENTER_REGION_"
+
String
.
valueOf
(
region
.
config_id
)))
{
// If trigger hasn't been fired yet
if
(!
Boolean
.
TRUE
.
equals
(
quest
.
getTriggers
().
put
(
"ENTER_REGION_"
+
String
.
valueOf
(
region
.
config_id
),
true
)))
{
//getSession().send(new PacketServerCondMeetQuestListUpdateNotify());
getQuestManager
().
triggerEvent
(
QuestTrigger
.
QUEST_CONTENT_TRIGGER_FIRE
,
quest
.
getTriggerData
().
get
(
"ENTER_REGION_"
+
String
.
valueOf
(
region
.
config_id
)).
getId
(),
0
);
}
}
});
}
public
void
onLeaveRegion
(
SceneRegion
region
)
{
getQuestManager
().
forEachActiveQuest
(
quest
->
{
if
(
quest
.
getTriggers
().
containsKey
(
"LEAVE_REGION_"
+
String
.
valueOf
(
region
.
config_id
)))
{
// If trigger hasn't been fired yet
if
(!
Boolean
.
TRUE
.
equals
(
quest
.
getTriggers
().
put
(
"LEAVE_REGION_"
+
String
.
valueOf
(
region
.
config_id
),
true
)))
{
getSession
().
send
(
new
PacketServerCondMeetQuestListUpdateNotify
());
getQuestManager
().
triggerEvent
(
QuestTrigger
.
QUEST_CONTENT_TRIGGER_FIRE
,
quest
.
getTriggerData
().
get
(
"LEAVE_REGION_"
+
String
.
valueOf
(
region
.
config_id
)).
getId
(),
0
);
}
}
});
}
public
PlayerGachaInfo
getGachaInfo
()
{
public
PlayerGachaInfo
getGachaInfo
()
{
return
gachaInfo
;
return
gachaInfo
;
}
}
...
@@ -1327,6 +1356,10 @@ public class Player {
...
@@ -1327,6 +1356,10 @@ public class Player {
// Execute daily reset logic if this is a new day.
// Execute daily reset logic if this is a new day.
this
.
doDailyReset
();
this
.
doDailyReset
();
// Rewind active quests, and put the player to the first rewind position it finds (if any) of an active quest
getQuestManager
().
onLogin
();
// Packets
// Packets
session
.
send
(
new
PacketPlayerDataNotify
(
this
));
// Player data
session
.
send
(
new
PacketPlayerDataNotify
(
this
));
// Player data
session
.
send
(
new
PacketStoreWeightLimitNotify
());
session
.
send
(
new
PacketStoreWeightLimitNotify
());
...
...
src/main/java/emu/grasscutter/game/quest/GameMainQuest.java
View file @
8050f0cc
...
@@ -2,7 +2,15 @@ package emu.grasscutter.game.quest;
...
@@ -2,7 +2,15 @@ package emu.grasscutter.game.quest;
import
java.util.*
;
import
java.util.*
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.binout.ScriptSceneData
;
import
emu.grasscutter.data.excels.QuestData
;
import
emu.grasscutter.game.quest.enums.LogicType
;
import
emu.grasscutter.game.quest.enums.QuestTrigger
;
import
emu.grasscutter.scripts.ScriptLoader
;
import
emu.grasscutter.server.packet.send.PacketCodexDataUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketCodexDataUpdateNotify
;
import
emu.grasscutter.utils.Position
;
import
lombok.Getter
;
import
org.bson.types.ObjectId
;
import
org.bson.types.ObjectId
;
import
dev.morphia.annotations.Entity
;
import
dev.morphia.annotations.Entity
;
...
@@ -11,6 +19,7 @@ import dev.morphia.annotations.Indexed;
...
@@ -11,6 +19,7 @@ import dev.morphia.annotations.Indexed;
import
dev.morphia.annotations.Transient
;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.binout.MainQuestData
;
import
emu.grasscutter.data.binout.MainQuestData
;
import
emu.grasscutter.data.binout.MainQuestData.*
;
import
emu.grasscutter.data.excels.RewardData
;
import
emu.grasscutter.data.excels.RewardData
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.player.Player
;
...
@@ -23,24 +32,33 @@ import emu.grasscutter.net.proto.QuestOuterClass.Quest;
...
@@ -23,24 +32,33 @@ import emu.grasscutter.net.proto.QuestOuterClass.Quest;
import
emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify
;
import
emu.grasscutter.utils.Utils
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
javax.script.Bindings
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
import
javax.script.CompiledScript
;
import
javax.script.ScriptException
;
import
static
emu
.
grasscutter
.
config
.
Configuration
.
SCRIPT
;
@Entity
(
value
=
"quests"
,
useDiscriminator
=
false
)
@Entity
(
value
=
"quests"
,
useDiscriminator
=
false
)
public
class
GameMainQuest
{
public
class
GameMainQuest
{
@Id
private
ObjectId
id
;
@Id
private
ObjectId
id
;
@Indexed
@Getter
private
int
ownerUid
;
@Indexed
private
int
ownerUid
;
@Transient
@Getter
private
Player
owner
;
@Transient
private
Player
owner
;
@Transient
@Getter
private
QuestManager
questManager
;
@Getter
private
Map
<
Integer
,
GameQuest
>
childQuests
;
private
Map
<
Integer
,
GameQuest
>
childQuests
;
@Getter
private
int
parentQuestId
;
@Getter
private
int
[]
questVars
;
private
int
parentQuestId
;
//QuestUpdateQuestVarReq is sent in two stages...
private
int
[]
questVars
;
@Getter
private
List
<
Integer
>
questVarsUpdate
;
private
ParentQuestState
state
;
@Getter
private
ParentQuestState
state
;
private
boolean
isFinished
;
@Getter
private
boolean
isFinished
;
List
<
QuestGroupSuite
>
questGroupSuites
;
@Getter
List
<
QuestGroupSuite
>
questGroupSuites
;
@Getter
int
[]
suggestTrackMainQuestList
;
@Getter
private
Map
<
Integer
,
TalkData
>
talks
;
//key is subId
private
Map
<
Integer
,
Position
>
rewindPositions
;
private
Map
<
Integer
,
Position
>
rewindRotations
;
@Deprecated
// Morphia only. Do not use.
@Deprecated
// Morphia only. Do not use.
public
GameMainQuest
()
{}
public
GameMainQuest
()
{}
...
@@ -48,23 +66,26 @@ public class GameMainQuest {
...
@@ -48,23 +66,26 @@ public class GameMainQuest {
public
GameMainQuest
(
Player
player
,
int
parentQuestId
)
{
public
GameMainQuest
(
Player
player
,
int
parentQuestId
)
{
this
.
owner
=
player
;
this
.
owner
=
player
;
this
.
ownerUid
=
player
.
getUid
();
this
.
ownerUid
=
player
.
getUid
();
this
.
questManager
=
player
.
getQuestManager
();
this
.
parentQuestId
=
parentQuestId
;
this
.
parentQuestId
=
parentQuestId
;
this
.
childQuests
=
new
HashMap
<>();
this
.
childQuests
=
new
HashMap
<>();
this
.
questVars
=
new
int
[
5
];
this
.
talks
=
new
HashMap
<>();
//official server always has a list of 5 questVars, with default value 0
this
.
questVars
=
new
int
[]
{
0
,
0
,
0
,
0
,
0
};
this
.
state
=
ParentQuestState
.
PARENT_QUEST_STATE_NONE
;
this
.
state
=
ParentQuestState
.
PARENT_QUEST_STATE_NONE
;
this
.
questGroupSuites
=
new
ArrayList
<>();
this
.
questGroupSuites
=
new
ArrayList
<>();
this
.
rewindPositions
=
new
HashMap
<>();
this
.
rewindRotations
=
new
HashMap
<>();
addAllChildQuests
();
addRewindPoints
();
}
}
public
int
getParentQuestId
()
{
private
void
addAllChildQuests
()
{
return
parentQuestId
;
List
<
Integer
>
subQuestIds
=
Arrays
.
stream
(
GameData
.
getMainQuestDataMap
().
get
(
this
.
parentQuestId
).
getSubQuests
()).
map
(
SubQuestData:
:
getSubId
).
toList
();
for
(
Integer
subQuestId
:
subQuestIds
)
{
QuestData
questConfig
=
GameData
.
getQuestDataMap
().
get
(
subQuestId
);
this
.
childQuests
.
put
(
subQuestId
,
new
GameQuest
(
this
,
questConfig
));
}
}
public
int
getOwnerUid
()
{
return
ownerUid
;
}
public
Player
getOwner
()
{
return
owner
;
}
}
public
void
setOwner
(
Player
player
)
{
public
void
setOwner
(
Player
player
)
{
...
@@ -72,28 +93,33 @@ public class GameMainQuest {
...
@@ -72,28 +93,33 @@ public class GameMainQuest {
this
.
owner
=
player
;
this
.
owner
=
player
;
}
}
public
Map
<
Integer
,
GameQuest
>
getChildQuests
(
)
{
public
int
getQuestVar
(
int
i
)
{
return
childQuests
;
return
questVars
[
i
]
;
}
}
public
void
setQuestVar
(
int
i
,
int
value
)
{
public
GameQuest
getChildQuestById
(
int
id
)
{
int
previousValue
=
this
.
questVars
[
i
];
return
this
.
getChildQuests
().
get
(
id
);
this
.
questVars
[
i
]
=
value
;
Grasscutter
.
getLogger
().
debug
(
"questVar {} value changed from {} to {}"
,
i
,
previousValue
,
value
);
}
}
public
int
[]
getQuestVars
()
{
public
void
incQuestVar
(
int
i
,
int
inc
)
{
return
questVars
;
int
previousValue
=
this
.
questVars
[
i
];
this
.
questVars
[
i
]
+=
inc
;
Grasscutter
.
getLogger
().
debug
(
"questVar {} value incremented from {} to {}"
,
i
,
previousValue
,
previousValue
+
inc
);
}
}
public
ParentQuestState
getState
()
{
public
void
decQuestVar
(
int
i
,
int
dec
)
{
return
state
;
int
previousValue
=
this
.
questVars
[
i
];
this
.
questVars
[
i
]
-=
dec
;
Grasscutter
.
getLogger
().
debug
(
"questVar {} value decremented from {} to {}"
,
i
,
previousValue
,
previousValue
-
dec
);
}
}
public
boolean
isFinished
()
{
return
isFinished
;
}
public
List
<
QuestGroupSuite
>
getQuestGroupSuites
()
{
public
GameQuest
getChildQuestById
(
int
id
)
{
return
questGroupSuites
;
return
this
.
getChildQuests
().
get
(
id
);
}
public
GameQuest
getChildQuestByOrder
(
int
order
)
{
return
this
.
getChildQuests
().
values
().
stream
().
filter
(
p
->
p
.
getQuestData
().
getOrder
()
==
order
).
toList
().
get
(
0
);
}
}
public
void
finish
()
{
public
void
finish
()
{
...
@@ -120,7 +146,191 @@ public class GameMainQuest {
...
@@ -120,7 +146,191 @@ public class GameMainQuest {
// handoff main quest
// handoff main quest
if
(
mainQuestData
.
getSuggestTrackMainQuestList
()
!=
null
){
if
(
mainQuestData
.
getSuggestTrackMainQuestList
()
!=
null
){
Arrays
.
stream
(
mainQuestData
.
getSuggestTrackMainQuestList
())
Arrays
.
stream
(
mainQuestData
.
getSuggestTrackMainQuestList
())
.
forEach
(
getOwner
().
getQuestManager
()::
startMainQuest
);
.
forEach
(
getQuestManager
()::
startMainQuest
);
}
}
//TODO
public
void
fail
()
{}
public
void
cancel
()
{}
// Rewinds to the last finished/unfinished rewind quest, and returns the avatar rewind position (if it exists)
public
List
<
Position
>
rewind
()
{
if
(
this
.
questManager
==
null
)
{
this
.
questManager
=
getOwner
().
getQuestManager
();
}
List
<
GameQuest
>
sortedByOrder
=
new
ArrayList
<>(
getChildQuests
().
values
().
stream
().
filter
(
q
->
q
.
getQuestData
().
isRewind
()).
toList
());
sortedByOrder
.
sort
((
a
,
b
)
->
{
if
(
a
==
b
){
return
0
;
}
return
a
.
getQuestData
().
getOrder
()
>
b
.
getQuestData
().
getOrder
()
?
1
:
-
1
;});
boolean
didRewind
=
false
;
for
(
GameQuest
quest
:
sortedByOrder
)
{
int
i
=
sortedByOrder
.
indexOf
(
quest
);
if
(
i
==
sortedByOrder
.
size
())
{
didRewind
=
quest
.
rewind
(
null
);
}
else
{
didRewind
=
quest
.
rewind
(
sortedByOrder
.
get
(
i
+
1
));
}
if
(
didRewind
)
{
break
;
}
}
List
<
GameQuest
>
rewindQuests
=
getChildQuests
().
values
().
stream
()
.
filter
(
p
->
(
p
.
getState
()
==
QuestState
.
QUEST_STATE_UNFINISHED
||
p
.
getState
()
==
QuestState
.
QUEST_STATE_FINISHED
)
&&
p
.
getQuestData
().
isRewind
()).
toList
();
for
(
GameQuest
quest
:
rewindQuests
)
{
if
(
rewindPositions
.
containsKey
(
quest
.
getSubQuestId
()))
{
List
<
Position
>
posAndRot
=
new
ArrayList
<>();
posAndRot
.
add
(
0
,
rewindPositions
.
get
(
quest
.
getSubQuestId
()));
posAndRot
.
add
(
1
,
rewindRotations
.
get
(
quest
.
getSubQuestId
()));
return
posAndRot
;
}
}
return
null
;
}
public
void
addRewindPoints
()
{
Bindings
bindings
=
ScriptLoader
.
getEngine
().
createBindings
();
CompiledScript
cs
=
ScriptLoader
.
getScriptByPath
(
SCRIPT
(
"Quest/Share/Q"
+
getParentQuestId
()
+
"ShareConfig."
+
ScriptLoader
.
getScriptType
()));
if
(
cs
==
null
)
{
Grasscutter
.
getLogger
().
error
(
"Couldn't find Q"
+
getParentQuestId
()
+
"ShareConfig."
+
ScriptLoader
.
getScriptType
());
return
;
}
// Eval script
try
{
cs
.
eval
(
bindings
);
var
rewindDataMap
=
ScriptLoader
.
getSerializer
().
toMap
(
RewindData
.
class
,
bindings
.
get
(
"rewind_data"
));
for
(
String
subId
:
rewindDataMap
.
keySet
())
{
RewindData
questRewind
=
rewindDataMap
.
get
(
subId
);
if
(
questRewind
!=
null
)
{
RewindData
.
AvatarData
avatarData
=
questRewind
.
getAvatar
();
if
(
avatarData
!=
null
)
{
String
avatarPos
=
avatarData
.
getPos
();
QuestData
.
Guide
guide
=
GameData
.
getQuestDataMap
().
get
(
Integer
.
valueOf
(
subId
)).
getGuide
();
if
(
guide
!=
null
)
{
int
sceneId
=
guide
.
getGuideScene
();
ScriptSceneData
fullGlobals
=
GameData
.
getScriptSceneDataMap
().
get
(
"flat.luas.scenes.full_globals.lua.json"
);
if
(
fullGlobals
!=
null
)
{
ScriptSceneData
.
ScriptObject
dummyPointScript
=
fullGlobals
.
getScriptObjectList
().
get
(
sceneId
+
"/scene"
+
sceneId
+
"_dummy_points.lua"
);
if
(
dummyPointScript
!=
null
)
{
Map
<
String
,
List
<
Float
>>
dummyPointMap
=
dummyPointScript
.
getDummyPoints
();
if
(
dummyPointMap
!=
null
)
{
List
<
Float
>
avatarPosPos
=
dummyPointMap
.
get
(
avatarPos
+
".pos"
);
if
(
avatarPosPos
!=
null
)
{
Position
pos
=
new
Position
(
avatarPosPos
.
get
(
0
),
avatarPosPos
.
get
(
1
),
avatarPosPos
.
get
(
2
));
List
<
Float
>
avatarPosRot
=
dummyPointMap
.
get
(
avatarPos
+
".rot"
);
Position
rot
=
new
Position
(
avatarPosRot
.
get
(
0
),
avatarPosRot
.
get
(
1
),
avatarPosRot
.
get
(
2
));
rewindPositions
.
put
(
Integer
.
valueOf
(
subId
),
pos
);
rewindRotations
.
put
(
Integer
.
valueOf
(
subId
),
rot
);
Grasscutter
.
getLogger
().
debug
(
"Succesfully loaded rewind position for subQuest {}"
,
subId
);
}
}
}
}
}
}
}
}
}
catch
(
ScriptException
e
)
{
Grasscutter
.
getLogger
().
error
(
"An error occurred while loading rewind positions"
);
}
}
public
void
tryAcceptSubQuests
(
QuestTrigger
condType
,
String
paramStr
,
int
...
params
)
{
try
{
List
<
GameQuest
>
subQuestsWithCond
=
getChildQuests
().
values
().
stream
()
.
filter
(
p
->
p
.
getState
()
==
QuestState
.
QUEST_STATE_UNSTARTED
)
.
filter
(
p
->
p
.
getQuestData
().
getAcceptCond
().
stream
().
anyMatch
(
q
->
q
.
getType
()
==
condType
))
.
toList
();
for
(
GameQuest
subQuestWithCond
:
subQuestsWithCond
)
{
List
<
QuestData
.
QuestCondition
>
acceptCond
=
subQuestWithCond
.
getQuestData
().
getAcceptCond
();
int
[]
accept
=
new
int
[
acceptCond
.
size
()];
for
(
int
i
=
0
;
i
<
subQuestWithCond
.
getQuestData
().
getAcceptCond
().
size
();
i
++)
{
QuestData
.
QuestCondition
condition
=
acceptCond
.
get
(
i
);
boolean
result
=
this
.
getOwner
().
getServer
().
getQuestSystem
().
triggerCondition
(
subQuestWithCond
,
condition
,
paramStr
,
params
);
accept
[
i
]
=
result
?
1
:
0
;
}
boolean
shouldAccept
=
LogicType
.
calculate
(
subQuestWithCond
.
getQuestData
().
getAcceptCondComb
(),
accept
);
if
(
shouldAccept
)
{
subQuestWithCond
.
start
();
getQuestManager
().
getAddToQuestListUpdateNotify
().
add
(
subQuestWithCond
);
}
}
this
.
save
();
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
error
(
"An error occurred while trying to accept quest."
,
e
);
}
}
public
void
tryFailSubQuests
(
QuestTrigger
condType
,
String
paramStr
,
int
...
params
)
{
try
{
List
<
GameQuest
>
subQuestsWithCond
=
getChildQuests
().
values
().
stream
()
.
filter
(
p
->
p
.
getState
()
==
QuestState
.
QUEST_STATE_UNFINISHED
)
.
filter
(
p
->
p
.
getQuestData
().
getFailCond
().
stream
().
anyMatch
(
q
->
q
.
getType
()
==
condType
))
.
toList
();
for
(
GameQuest
subQuestWithCond
:
subQuestsWithCond
)
{
List
<
QuestData
.
QuestCondition
>
failCond
=
subQuestWithCond
.
getQuestData
().
getFailCond
();
int
[]
fail
=
new
int
[
failCond
.
size
()];
for
(
int
i
=
0
;
i
<
subQuestWithCond
.
getQuestData
().
getFailCond
().
size
();
i
++)
{
QuestData
.
QuestCondition
condition
=
failCond
.
get
(
i
);
boolean
result
=
this
.
getOwner
().
getServer
().
getQuestSystem
().
triggerContent
(
subQuestWithCond
,
condition
,
paramStr
,
params
);
fail
[
i
]
=
result
?
1
:
0
;
}
boolean
shouldFail
=
LogicType
.
calculate
(
subQuestWithCond
.
getQuestData
().
getFailCondComb
(),
fail
);
if
(
shouldFail
)
{
subQuestWithCond
.
fail
();
getQuestManager
().
getAddToQuestListUpdateNotify
().
add
(
subQuestWithCond
);
}
}
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
error
(
"An error occurred while trying to fail quest."
,
e
);
}
}
public
void
tryFinishSubQuests
(
QuestTrigger
condType
,
String
paramStr
,
int
...
params
)
{
try
{
List
<
GameQuest
>
subQuestsWithCond
=
getChildQuests
().
values
().
stream
()
//There are subQuests with no acceptCond, but can be finished (example: 35104)
.
filter
(
p
->
p
.
getState
()
==
QuestState
.
QUEST_STATE_UNFINISHED
&&
p
.
getQuestData
().
getAcceptCond
()
!=
null
)
.
filter
(
p
->
p
.
getQuestData
().
getFinishCond
().
stream
().
anyMatch
(
q
->
q
.
getType
()
==
condType
))
.
toList
();
for
(
GameQuest
subQuestWithCond
:
subQuestsWithCond
)
{
List
<
QuestData
.
QuestCondition
>
finishCond
=
subQuestWithCond
.
getQuestData
().
getFinishCond
();
int
[]
finish
=
new
int
[
finishCond
.
size
()];
for
(
int
i
=
0
;
i
<
subQuestWithCond
.
getQuestData
().
getFinishCond
().
size
();
i
++)
{
QuestData
.
QuestCondition
condition
=
finishCond
.
get
(
i
);
boolean
result
=
this
.
getOwner
().
getServer
().
getQuestSystem
().
triggerContent
(
subQuestWithCond
,
condition
,
paramStr
,
params
);
finish
[
i
]
=
result
?
1
:
0
;
}
boolean
shouldFinish
=
LogicType
.
calculate
(
subQuestWithCond
.
getQuestData
().
getFinishCondComb
(),
finish
);
if
(
shouldFinish
)
{
subQuestWithCond
.
finish
();
getQuestManager
().
getAddToQuestListUpdateNotify
().
add
(
subQuestWithCond
);
}
}
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
debug
(
"An error occurred while trying to finish quest."
,
e
);
}
}
}
}
...
@@ -131,24 +341,30 @@ public class GameMainQuest {
...
@@ -131,24 +341,30 @@ public class GameMainQuest {
public
ParentQuest
toProto
()
{
public
ParentQuest
toProto
()
{
ParentQuest
.
Builder
proto
=
ParentQuest
.
newBuilder
()
ParentQuest
.
Builder
proto
=
ParentQuest
.
newBuilder
()
.
setParentQuestId
(
getParentQuestId
())
.
setParentQuestId
(
getParentQuestId
())
.
setIsFinished
(
isFinished
())
.
setIsFinished
(
isFinished
());
.
setParentQuestState
(
getState
().
getValue
());
/**
if ParentQuestState is NONE, official server does not send ParentQuestState nor childQuestList!!!
might need more sniffing...
sending childQuestList without ParentQuestState set causes the game to hang on login
*/
if
(
getState
()
!=
ParentQuestState
.
PARENT_QUEST_STATE_NONE
)
{
proto
.
setParentQuestState
(
getState
().
getValue
());
for
(
GameQuest
quest
:
this
.
getChildQuests
().
values
())
{
for
(
GameQuest
quest
:
this
.
getChildQuests
().
values
())
{
if
(
quest
.
getState
()
!=
QuestState
.
QUEST_STATE_UNSTARTED
)
{
ChildQuest
childQuest
=
ChildQuest
.
newBuilder
()
ChildQuest
childQuest
=
ChildQuest
.
newBuilder
()
.
setQuestId
(
quest
.
getQuestId
())
.
setQuestId
(
quest
.
get
Sub
QuestId
())
.
setState
(
quest
.
getState
().
getValue
())
.
setState
(
quest
.
getState
().
getValue
())
.
build
();
.
build
();
proto
.
addChildQuestList
(
childQuest
);
proto
.
addChildQuestList
(
childQuest
);
}
}
}
if
(
getQuestVars
()
!=
null
)
{
}
for
(
int
i
:
getQuestVars
())
{
for
(
int
i
:
getQuestVars
())
{
proto
.
addQuestVar
(
i
);
proto
.
addQuestVar
(
i
);
}
}
}
return
proto
.
build
();
return
proto
.
build
();
}
}
}
}
src/main/java/emu/grasscutter/game/quest/GameQuest.java
View file @
8050f0cc
...
@@ -4,51 +4,84 @@ import dev.morphia.annotations.Entity;
...
@@ -4,51 +4,84 @@ import dev.morphia.annotations.Entity;
import
dev.morphia.annotations.Transient
;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.binout.MainQuestData
;
import
emu.grasscutter.data.binout.MainQuestData.SubQuestData
;
import
emu.grasscutter.data.excels.ChapterData
;
import
emu.grasscutter.data.excels.ChapterData
;
import
emu.grasscutter.data.excels.QuestData
;
import
emu.grasscutter.data.excels.QuestData
;
import
emu.grasscutter.data.excels.
QuestData.QuestCondition
;
import
emu.grasscutter.data.excels.
TriggerExcelConfigData
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.quest.enums.LogicType
;
import
emu.grasscutter.game.quest.enums.QuestState
;
import
emu.grasscutter.game.quest.enums.QuestState
;
import
emu.grasscutter.game.quest.enums.QuestTrigger
;
import
emu.grasscutter.game.quest.enums.QuestTrigger
;
import
emu.grasscutter.net.proto.ChapterStateOuterClass
;
import
emu.grasscutter.net.proto.ChapterStateOuterClass
;
import
emu.grasscutter.net.proto.QuestOuterClass.Quest
;
import
emu.grasscutter.net.proto.QuestOuterClass.Quest
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
emu.grasscutter.server.packet.send.PacketChapterStateNotify
;
import
emu.grasscutter.server.packet.send.PacketChapterStateNotify
;
import
emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify
;
import
emu.grasscutter.utils.Utils
;
import
emu.grasscutter.utils.Utils
;
import
lombok.Getter
;
import
lombok.Setter
;
import
javax.script.Bindings
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
@Entity
@Entity
public
class
GameQuest
{
public
class
GameQuest
{
@Transient
private
GameMainQuest
mainQuest
;
@Transient
@Getter
@Setter
private
GameMainQuest
mainQuest
;
@Transient
private
QuestData
questData
;
@Transient
@Getter
private
QuestData
questData
;
private
int
questId
;
@Getter
private
int
subQuestId
;
private
int
mainQuestId
;
@Getter
private
int
mainQuestId
;
@Getter
@Setter
private
QuestState
state
;
private
QuestState
state
;
private
int
startTime
;
@Getter
@Setter
private
int
startTime
;
private
int
acceptTime
;
@Getter
@Setter
private
int
acceptTime
;
private
int
finishTime
;
@Getter
@Setter
private
int
finishTime
;
private
int
[]
finishProgressList
;
@Getter
private
int
[]
finishProgressList
;
private
int
[]
failProgressList
;
@Getter
private
int
[]
failProgressList
;
@Transient
@Getter
private
Map
<
String
,
TriggerExcelConfigData
>
triggerData
;
@Getter
private
Map
<
String
,
Boolean
>
triggers
;
private
transient
Bindings
bindings
;
@Deprecated
// Morphia only. Do not use.
@Deprecated
// Morphia only. Do not use.
public
GameQuest
()
{}
public
GameQuest
()
{}
public
GameQuest
(
GameMainQuest
mainQuest
,
QuestData
questData
)
{
public
GameQuest
(
GameMainQuest
mainQuest
,
QuestData
questData
)
{
this
.
mainQuest
=
mainQuest
;
this
.
mainQuest
=
mainQuest
;
this
.
q
uestId
=
questData
.
getId
();
this
.
subQ
uestId
=
questData
.
getId
();
this
.
mainQuestId
=
questData
.
getMainId
();
this
.
mainQuestId
=
questData
.
getMainId
();
this
.
questData
=
questData
;
this
.
questData
=
questData
;
this
.
state
=
QuestState
.
QUEST_STATE_UNSTARTED
;
this
.
triggerData
=
new
HashMap
<>();
this
.
triggers
=
new
HashMap
<>();
}
public
void
start
()
{
this
.
acceptTime
=
Utils
.
getCurrentSeconds
();
this
.
acceptTime
=
Utils
.
getCurrentSeconds
();
this
.
startTime
=
this
.
acceptTime
;
this
.
startTime
=
this
.
acceptTime
;
this
.
state
=
QuestState
.
QUEST_STATE_UNFINISHED
;
this
.
state
=
QuestState
.
QUEST_STATE_UNFINISHED
;
List
<
QuestData
.
QuestCondition
>
triggerCond
=
questData
.
getFinishCond
().
stream
()
.
filter
(
p
->
p
.
getType
()
==
QuestTrigger
.
QUEST_CONTENT_TRIGGER_FIRE
).
toList
();
if
(
triggerCond
.
size
()
>
0
)
{
for
(
QuestData
.
QuestCondition
cond
:
triggerCond
)
{
TriggerExcelConfigData
newTrigger
=
GameData
.
getTriggerExcelConfigDataMap
().
get
(
cond
.
getParam
()[
0
]);
if
(
newTrigger
!=
null
)
{
if
(
this
.
triggerData
==
null
)
{
this
.
triggerData
=
new
HashMap
<>();
}
triggerData
.
put
(
newTrigger
.
getTriggerName
(),
newTrigger
);
triggers
.
put
(
newTrigger
.
getTriggerName
(),
false
);
SceneGroup
group
=
SceneGroup
.
of
(
newTrigger
.
getGroupId
()).
load
(
newTrigger
.
getSceneId
());
getOwner
().
getWorld
().
getSceneById
(
newTrigger
.
getSceneId
()).
loadTriggerFromGroup
(
group
,
newTrigger
.
getTriggerName
());
}
}
}
if
(
questData
.
getFinishCond
()
!=
null
&&
questData
.
get
Accept
Cond
().
size
()
!=
0
)
{
if
(
questData
.
getFinishCond
()
!=
null
&&
questData
.
get
Finish
Cond
().
size
()
!=
0
)
{
this
.
finishProgressList
=
new
int
[
questData
.
getFinishCond
().
size
()];
this
.
finishProgressList
=
new
int
[
questData
.
getFinishCond
().
size
()];
}
}
...
@@ -56,95 +89,46 @@ public class GameQuest {
...
@@ -56,95 +89,46 @@ public class GameQuest {
this
.
failProgressList
=
new
int
[
questData
.
getFailCond
().
size
()];
this
.
failProgressList
=
new
int
[
questData
.
getFailCond
().
size
()];
}
}
this
.
mainQuest
.
getChildQuests
().
put
(
this
.
questId
,
this
);
getQuestData
().
getBeginExec
().
forEach
(
e
->
getOwner
().
getServer
().
getQuestSystem
().
triggerExec
(
this
,
e
,
e
.
getParam
()));
this
.
getData
().
getBeginExec
().
forEach
(
e
->
getOwner
().
getServer
().
getQuestSystem
().
triggerExec
(
this
,
e
,
e
.
getParam
()));
this
.
getOwner
().
getQuestManager
().
triggerEvent
(
QuestTrigger
.
QUEST_CONTENT_QUEST_STATE_EQUAL
,
this
.
questId
,
this
.
state
.
getValue
());
if
(
ChapterData
.
beginQuestChapterMap
.
containsKey
(
q
uestId
))
{
if
(
ChapterData
.
beginQuestChapterMap
.
containsKey
(
subQ
uestId
)){
mainQuest
.
getOwner
().
sendPacket
(
new
PacketChapterStateNotify
(
mainQuest
.
getOwner
().
sendPacket
(
new
PacketChapterStateNotify
(
ChapterData
.
beginQuestChapterMap
.
get
(
q
uestId
).
getId
(),
ChapterData
.
beginQuestChapterMap
.
get
(
subQ
uestId
).
getId
(),
ChapterStateOuterClass
.
ChapterState
.
CHAPTER_STATE_BEGIN
ChapterStateOuterClass
.
ChapterState
.
CHAPTER_STATE_BEGIN
));
));
}
}
Grasscutter
.
getLogger
().
debug
(
"Quest {} is started"
,
questId
);
//Some subQuests and talks become active when some other subQuests are unfinished (even from different MainQuests)
}
this
.
getOwner
().
getQuestManager
().
triggerEvent
(
QuestTrigger
.
QUEST_CONTENT_QUEST_STATE_EQUAL
,
this
.
getSubQuestId
(),
this
.
getState
().
getValue
(),
0
,
0
,
0
);
this
.
getOwner
().
getQuestManager
().
triggerEvent
(
QuestTrigger
.
QUEST_COND_STATE_EQUAL
,
this
.
getSubQuestId
(),
this
.
getState
().
getValue
(),
0
,
0
,
0
);
public
GameMainQuest
getMainQuest
()
{
Grasscutter
.
getLogger
().
debug
(
"Quest {} is started"
,
subQuestId
);
return
mainQuest
;
}
}
public
void
setMainQuest
(
GameMainQuest
mainQuest
)
{
public
String
getTriggerNameById
(
int
id
)
{
this
.
mainQuest
=
mainQuest
;
TriggerExcelConfigData
trigger
=
GameData
.
getTriggerExcelConfigDataMap
().
get
(
id
);
if
(
trigger
!=
null
)
{
String
triggerName
=
trigger
.
getTriggerName
();
return
triggerName
;
}
}
//return empty string if can't find trigger
public
Player
getOwner
()
{
return
""
;
return
getMainQuest
().
getOwner
();
}
}
public
int
getQuestId
()
{
public
Player
getOwner
()
{
return
questId
;
return
this
.
getMainQuest
().
getOwner
();
}
public
int
getMainQuestId
()
{
return
mainQuestId
;
}
public
QuestData
getData
()
{
return
questData
;
}
}
public
void
setConfig
(
QuestData
config
)
{
public
void
setConfig
(
QuestData
config
)
{
if
(
this
.
get
QuestId
()
!=
config
.
getId
())
return
;
if
(
getSub
QuestId
()
!=
config
.
getId
())
return
;
this
.
questData
=
config
;
this
.
questData
=
config
;
}
}
public
QuestState
getState
()
{
return
state
;
}
public
void
setState
(
QuestState
state
)
{
this
.
state
=
state
;
}
public
int
getStartTime
()
{
return
startTime
;
}
public
void
setStartTime
(
int
startTime
)
{
this
.
startTime
=
startTime
;
}
public
int
getAcceptTime
()
{
return
acceptTime
;
}
public
void
setAcceptTime
(
int
acceptTime
)
{
this
.
acceptTime
=
acceptTime
;
}
public
int
getFinishTime
()
{
return
finishTime
;
}
public
void
setFinishTime
(
int
finishTime
)
{
this
.
finishTime
=
finishTime
;
}
public
int
[]
getFinishProgressList
()
{
return
finishProgressList
;
}
public
void
setFinishProgress
(
int
index
,
int
value
)
{
public
void
setFinishProgress
(
int
index
,
int
value
)
{
finishProgressList
[
index
]
=
value
;
finishProgressList
[
index
]
=
value
;
}
}
public
int
[]
getFailProgressList
()
{
return
failProgressList
;
}
public
void
setFailProgress
(
int
index
,
int
value
)
{
public
void
setFailProgress
(
int
index
,
int
value
)
{
failProgressList
[
index
]
=
value
;
failProgressList
[
index
]
=
value
;
}
}
...
@@ -153,100 +137,84 @@ public class GameQuest {
...
@@ -153,100 +137,84 @@ public class GameQuest {
this
.
state
=
QuestState
.
QUEST_STATE_FINISHED
;
this
.
state
=
QuestState
.
QUEST_STATE_FINISHED
;
this
.
finishTime
=
Utils
.
getCurrentSeconds
();
this
.
finishTime
=
Utils
.
getCurrentSeconds
();
if
(
this
.
getFinishProgressList
()
!=
null
)
{
if
(
getFinishProgressList
()
!=
null
)
{
for
(
int
i
=
0
;
i
<
getFinishProgressList
().
length
;
i
++)
{
Arrays
.
fill
(
getFinishProgressList
(),
1
);
getFinishProgressList
()[
i
]
=
1
;
}
}
}
this
.
getOwner
().
getSession
().
send
(
new
PacketQuestProgressUpdateNotify
(
this
));
getOwner
().
getSession
().
send
(
new
PacketQuestProgressUpdateNotify
(
this
));
this
.
getOwner
().
getSession
().
send
(
new
PacketQuestListUpdateNotify
(
this
));
if
(
this
.
getData
().
finishParent
())
{
// This quest finishes the questline - the main quest will also save the quest to db so we dont have to call save() here
this
.
getMainQuest
().
finish
();
}
else
{
// Try and accept other quests if possible
this
.
tryAcceptQuestLine
();
this
.
save
();
}
this
.
getData
().
getFinishExec
().
forEach
(
e
->
getOwner
().
getServer
().
getQuestSystem
().
triggerExec
(
this
,
e
,
e
.
getParam
()));
if
(
getQuestData
().
finishParent
())
{
// This quest finishes the questline - the main quest will also save the quest to db, so we don't have to call save() here
getMainQuest
().
finish
();
}
this
.
getOwner
().
getQuestManager
().
triggerEvent
(
QuestTrigger
.
QUEST_CONTENT_QUEST_STATE_EQUAL
,
this
.
questId
,
this
.
state
.
getValue
());
getQuestData
().
getFinishExec
().
forEach
(
e
->
getOwner
().
getServer
().
getQuestSystem
().
triggerExec
(
this
,
e
,
e
.
getParam
()));
//Some subQuests have conditions that subQuests are finished (even from different MainQuests)
getOwner
().
getQuestManager
().
triggerEvent
(
QuestTrigger
.
QUEST_CONTENT_QUEST_STATE_EQUAL
,
this
.
subQuestId
,
this
.
state
.
getValue
(),
0
,
0
,
0
);
getOwner
().
getQuestManager
().
triggerEvent
(
QuestTrigger
.
QUEST_COND_STATE_EQUAL
,
this
.
subQuestId
,
this
.
state
.
getValue
(),
0
,
0
,
0
);
if
(
ChapterData
.
endQuestChapterMap
.
containsKey
(
q
uestId
))
{
if
(
ChapterData
.
endQuestChapterMap
.
containsKey
(
subQ
uestId
)){
mainQuest
.
getOwner
().
sendPacket
(
new
PacketChapterStateNotify
(
mainQuest
.
getOwner
().
sendPacket
(
new
PacketChapterStateNotify
(
ChapterData
.
endQuestChapterMap
.
get
(
q
uestId
).
getId
(),
ChapterData
.
endQuestChapterMap
.
get
(
subQ
uestId
).
getId
(),
ChapterStateOuterClass
.
ChapterState
.
CHAPTER_STATE_END
ChapterStateOuterClass
.
ChapterState
.
CHAPTER_STATE_END
));
));
}
}
Grasscutter
.
getLogger
().
debug
(
"Quest {} is finished"
,
q
uestId
);
Grasscutter
.
getLogger
().
debug
(
"Quest {} is finished"
,
subQ
uestId
);
}
}
public
boolean
tryAcceptQuestLine
()
{
//TODO
try
{
public
void
fail
()
{
MainQuestData
questConfig
=
GameData
.
getMainQuestDataMap
().
get
(
this
.
getMainQuestId
());
this
.
state
=
QuestState
.
QUEST_STATE_FAILED
;
this
.
finishTime
=
Utils
.
getCurrentSeconds
();
for
(
SubQuestData
subQuest
:
questConfig
.
getSubQuests
())
{
GameQuest
quest
=
getMainQuest
().
getChildQuestById
(
subQuest
.
getSubId
());
if
(
quest
==
null
)
{
QuestData
questData
=
GameData
.
getQuestDataMap
().
get
(
subQuest
.
getSubId
());
if
(
questData
==
null
||
questData
.
getAcceptCond
()
==
null
if
(
getFailProgressList
()
!=
null
)
{
||
questData
.
getAcceptCond
().
size
()
==
0
)
{
Arrays
.
fill
(
getFailProgressList
(),
1
);
continue
;
}
}
int
[]
accept
=
new
int
[
questData
.
getAcceptCond
().
size
()]
;
getOwner
().
getSession
().
send
(
new
PacketQuestProgressUpdateNotify
(
this
))
;
// TODO
getQuestData
().
getFailExec
().
forEach
(
e
->
getOwner
().
getServer
().
getQuestSystem
().
triggerExec
(
this
,
e
,
e
.
getParam
()));
for
(
int
i
=
0
;
i
<
questData
.
getAcceptCond
().
size
();
i
++)
{
//Some subQuests have conditions that subQuests fail (even from different MainQuests)
QuestCondition
condition
=
questData
.
getAcceptCond
().
get
(
i
);
getOwner
().
getQuestManager
().
triggerEvent
(
QuestTrigger
.
QUEST_CONTENT_QUEST_STATE_EQUAL
,
this
.
subQuestId
,
this
.
state
.
getValue
(),
0
,
0
,
0
);
boolean
result
=
getOwner
().
getServer
().
getQuestSystem
().
triggerCondition
(
this
,
condition
,
getOwner
().
getQuestManager
().
triggerEvent
(
QuestTrigger
.
QUEST_COND_STATE_EQUAL
,
this
.
subQuestId
,
this
.
state
.
getValue
(),
0
,
0
,
0
);
condition
.
getParamStr
(),
condition
.
getParam
());
accept
[
i
]
=
result
?
1
:
0
;
}
boolean
shouldAccept
=
LogicType
.
calculate
(
questData
.
getAcceptCondComb
(),
accept
);
if
(
shouldAccept
)
{
this
.
getOwner
().
getQuestManager
().
addQuest
(
questData
.
getId
());
}
}
// Return true if ParentQuest should rewind to this childQuest
public
boolean
rewind
(
GameQuest
nextRewind
)
{
if
(
questData
.
isRewind
())
{
if
(
nextRewind
==
null
)
{
return
true
;}
// if the next isRewind subQuest is none or unstarted, reset all subQuests with order higher than this one, and restart this quest
if
(
nextRewind
.
getState
()
==
QuestState
.
QUEST_STATE_NONE
||
nextRewind
.
getState
()
==
QuestState
.
QUEST_STATE_UNSTARTED
)
{
getMainQuest
().
getChildQuests
().
values
().
stream
().
filter
(
p
->
p
.
getQuestData
().
getOrder
()
>
this
.
getQuestData
().
getOrder
()).
forEach
(
q
->
q
.
setState
(
QuestState
.
QUEST_STATE_UNSTARTED
));
this
.
start
();
return
true
;
}
}
}
}
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
error
(
"An error occurred while trying to accept quest."
,
e
);
}
return
false
;
return
false
;
}
}
public
void
save
()
{
public
void
save
()
{
getMainQuest
().
save
();
getMainQuest
().
save
();
}
}
public
Quest
toProto
()
{
public
Quest
toProto
()
{
Quest
.
Builder
proto
=
Quest
.
newBuilder
()
Quest
.
Builder
proto
=
Quest
.
newBuilder
()
.
setQuestId
(
this
.
getQuestId
())
.
setQuestId
(
get
Sub
QuestId
())
.
setState
(
this
.
getState
().
getValue
())
.
setState
(
getState
().
getValue
())
.
setParentQuestId
(
this
.
getMainQuestId
())
.
setParentQuestId
(
getMainQuestId
())
.
setStartTime
(
this
.
getStartTime
())
.
setStartTime
(
getStartTime
())
.
setStartGameTime
(
438
)
.
setStartGameTime
(
438
)
.
setAcceptTime
(
this
.
getAcceptTime
());
.
setAcceptTime
(
getAcceptTime
());
if
(
this
.
getFinishProgressList
()
!=
null
)
{
if
(
getFinishProgressList
()
!=
null
)
{
for
(
int
i
:
this
.
getFinishProgressList
())
{
for
(
int
i
:
getFinishProgressList
())
{
proto
.
addFinishProgressList
(
i
);
proto
.
addFinishProgressList
(
i
);
}
}
}
}
if
(
this
.
getFailProgressList
()
!=
null
)
{
if
(
getFailProgressList
()
!=
null
)
{
for
(
int
i
:
this
.
getFailProgressList
())
{
for
(
int
i
:
getFailProgressList
())
{
proto
.
addFailProgressList
(
i
);
proto
.
addFailProgressList
(
i
);
}
}
}
}
...
...
src/main/java/emu/grasscutter/game/quest/QuestManager.java
View file @
8050f0cc
package
emu.grasscutter.game.quest
;
package
emu.grasscutter.game.quest
;
import
java.beans.Transient
;
import
java.util.*
;
import
java.util.*
;
import
java.util.function.Consumer
;
import
java.util.function.Consumer
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
...
@@ -17,23 +18,118 @@ import emu.grasscutter.game.quest.enums.QuestTrigger;
...
@@ -17,23 +18,118 @@ import emu.grasscutter.game.quest.enums.QuestTrigger;
import
emu.grasscutter.game.quest.enums.LogicType
;
import
emu.grasscutter.game.quest.enums.LogicType
;
import
emu.grasscutter.game.quest.enums.QuestState
;
import
emu.grasscutter.game.quest.enums.QuestState
;
import
emu.grasscutter.server.packet.send.*
;
import
emu.grasscutter.server.packet.send.*
;
import
emu.grasscutter.utils.Position
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
import
jdk.jshell.spi.ExecutionControl
;
import
lombok.Getter
;
public
class
QuestManager
extends
BasePlayerManager
{
public
class
QuestManager
extends
BasePlayerManager
{
private
final
Int2ObjectMap
<
GameMainQuest
>
quests
;
@Getter
private
final
Player
player
;
@Getter
private
Map
<
Integer
,
Integer
>
questGlobalVariables
;
@Getter
private
final
Int2ObjectMap
<
GameMainQuest
>
mainQuests
;
@Getter
private
List
<
GameQuest
>
addToQuestListUpdateNotify
;
/*
On SetPlayerBornDataReq, the server sends FinishedParentQuestNotify, with this exact
parentQuestList. Captured on Game version 2.7
Note: quest 40063 is already set to finished, with childQuest 4006406's state set to 3
*/
private
static
Set
<
Integer
>
newPlayerMainQuests
=
Set
.
of
(
303
,
318
,
348
,
349
,
350
,
351
,
416
,
500
,
501
,
502
,
503
,
504
,
505
,
506
,
507
,
508
,
509
,
20000
,
20507
,
20509
,
21004
,
21005
,
21010
,
21011
,
21016
,
21017
,
21020
,
21021
,
21025
,
40063
,
70121
,
70124
,
70511
,
71010
,
71012
,
71013
,
71015
,
71016
,
71017
,
71555
);
/*
On SetPlayerBornDataReq, the server sends ServerCondMeetQuestListUpdateNotify, with this exact
addQuestIdList. Captured on Game version 2.7
Total of 161...
*/
/*
private static Set<Integer> newPlayerServerCondMeetQuestListUpdateNotify = Set.of(3100101, 7104405, 2201601,
7100801, 1907002, 7293301, 7193801, 7293401, 7193901, 7091001, 7190501, 7090901, 7190401, 7090801, 7190301,
7195301, 7294801, 7195201, 7293001, 7094001, 7193501, 7293501, 7194001, 7293701, 7194201, 7194301, 7293801,
7194901, 7194101, 7195001, 7294501, 7294101, 7194601, 7294301, 7194801, 7091301, 7290301, 2102401, 7216801,
7190201, 7090701, 7093801, 7193301, 7292801, 7227828, 7093901, 7193401, 7292901, 7093701, 7193201, 7292701,
7082402, 7093601, 7292601, 7193101, 2102301, 7093501, 7292501, 7193001, 7093401, 7292401, 7192901, 7093301,
7292301, 7192801, 7294201, 7194701, 2100301, 7093201, 7212402, 7292201, 7192701, 7280001, 7293901, 7194401,
7093101, 7212302, 7292101, 7192601, 7093001, 7292001, 7192501, 7216001, 7195101, 7294601, 2100900, 7092901,
7291901, 7192401, 7092801, 7291801, 7192301, 2101501, 7092701, 7291701, 7192201, 7106401, 2100716, 7091801,
7290801, 7191301, 7293201, 7193701, 7094201, 7294001, 7194501, 2102290, 7227829, 7193601, 7094101, 7091401,
7290401, 7190901, 7106605, 7291601, 7192101, 7092601, 7291501, 7192001, 7092501, 7291401, 7191901, 7092401,
7291301, 7191801, 7092301, 7211402, 7291201, 7191701, 7092201, 7291101, 7191601, 7092101, 7291001, 7191501,
7092001, 7290901, 7191401, 7091901, 7290701, 7191201, 7091701, 7290601, 7191101, 7091601, 7290501, 7191001,
7091501, 7290201, 7190701, 7091201, 7190601, 7091101, 7190101, 7090601, 7090501, 7090401, 7010701, 7090301,
7090201, 7010103, 7090101
);
*/
public
QuestManager
(
Player
player
)
{
public
QuestManager
(
Player
player
)
{
super
(
player
);
super
(
player
);
this
.
quests
=
new
Int2ObjectOpenHashMap
<>();
this
.
player
=
player
;
this
.
questGlobalVariables
=
player
.
getQuestGlobalVariables
();
this
.
mainQuests
=
new
Int2ObjectOpenHashMap
<>();
this
.
addToQuestListUpdateNotify
=
new
ArrayList
<>();
}
public
void
onNewPlayerCreate
()
{
List
<
GameMainQuest
>
newQuests
=
this
.
addMultMainQuests
(
newPlayerMainQuests
);
//getPlayer().sendPacket(new PacketServerCondMeetQuestListUpdateNotify(newPlayerServerCondMeetQuestListUpdateNotify));
getPlayer
().
sendPacket
(
new
PacketFinishedParentQuestUpdateNotify
(
newQuests
));
}
public
void
onLogin
()
{
List
<
GameMainQuest
>
activeQuests
=
getActiveMainQuests
();
for
(
GameMainQuest
quest
:
activeQuests
)
{
List
<
Position
>
rewindPos
=
quest
.
rewind
();
// <pos, rotation>
if
(
rewindPos
!=
null
)
{
getPlayer
().
getPosition
().
set
(
rewindPos
.
get
(
0
));
getPlayer
().
getRotation
().
set
(
rewindPos
.
get
(
1
));
}
}
}
private
List
<
GameMainQuest
>
addMultMainQuests
(
Set
<
Integer
>
mainQuestIds
)
{
List
<
GameMainQuest
>
newQuests
=
new
ArrayList
<>();
for
(
Integer
id
:
mainQuestIds
)
{
getMainQuests
().
put
(
id
.
intValue
(),
new
GameMainQuest
(
this
.
player
,
id
));
getMainQuestById
(
id
).
save
();
newQuests
.
add
(
getMainQuestById
(
id
));
}
return
newQuests
;
}
/*
Looking through mainQuests 72201-72208 and 72174, we can infer that a questGlobalVar's default value is 0
*/
public
Integer
getQuestGlobalVarValue
(
Integer
variable
)
{
return
this
.
questGlobalVariables
.
getOrDefault
(
variable
,
0
);
}
}
public
Int2ObjectMap
<
GameMainQuest
>
getQuests
()
{
public
void
setQuestGlobalVarValue
(
Integer
variable
,
Integer
value
)
{
return
quests
;
Integer
previousValue
=
this
.
questGlobalVariables
.
put
(
variable
,
value
);
Grasscutter
.
getLogger
().
debug
(
"Changed questGlobalVar {} value from {} to {}"
,
variable
,
previousValue
==
null
?
0
:
previousValue
,
value
);
}
public
void
incQuestGlobalVarValue
(
Integer
variable
,
Integer
inc
)
{
//
Integer
previousValue
=
this
.
questGlobalVariables
.
getOrDefault
(
variable
,
0
);
this
.
questGlobalVariables
.
put
(
variable
,
previousValue
+
inc
);
Grasscutter
.
getLogger
().
debug
(
"Incremented questGlobalVar {} value from {} to {}"
,
variable
,
previousValue
,
previousValue
+
inc
);
}
//In MainQuest 998, dec is passed as a positive integer
public
void
decQuestGlobalVarValue
(
Integer
variable
,
Integer
dec
)
{
//
Integer
previousValue
=
this
.
questGlobalVariables
.
getOrDefault
(
variable
,
0
);
this
.
questGlobalVariables
.
put
(
variable
,
previousValue
-
dec
);
Grasscutter
.
getLogger
().
debug
(
"Decremented questGlobalVar {} value from {} to {}"
,
variable
,
previousValue
,
previousValue
-
dec
);
}
}
public
GameMainQuest
getMainQuestById
(
int
mainQuestId
)
{
public
GameMainQuest
getMainQuestById
(
int
mainQuestId
)
{
return
getQuests
().
get
(
mainQuestId
);
return
get
Main
Quests
().
get
(
mainQuestId
);
}
}
public
GameQuest
getQuestById
(
int
questId
)
{
public
GameQuest
getQuestById
(
int
questId
)
{
...
@@ -42,7 +138,7 @@ public class QuestManager extends BasePlayerManager {
...
@@ -42,7 +138,7 @@ public class QuestManager extends BasePlayerManager {
return
null
;
return
null
;
}
}
GameMainQuest
mainQuest
=
getQuests
().
get
(
questConfig
.
getMainId
());
GameMainQuest
mainQuest
=
get
Main
Quests
().
get
(
questConfig
.
getMainId
());
if
(
mainQuest
==
null
)
{
if
(
mainQuest
==
null
)
{
return
null
;
return
null
;
...
@@ -52,7 +148,7 @@ public class QuestManager extends BasePlayerManager {
...
@@ -52,7 +148,7 @@ public class QuestManager extends BasePlayerManager {
}
}
public
void
forEachQuest
(
Consumer
<
GameQuest
>
callback
)
{
public
void
forEachQuest
(
Consumer
<
GameQuest
>
callback
)
{
for
(
GameMainQuest
mainQuest
:
getQuests
().
values
())
{
for
(
GameMainQuest
mainQuest
:
get
Main
Quests
().
values
())
{
for
(
GameQuest
quest
:
mainQuest
.
getChildQuests
().
values
())
{
for
(
GameQuest
quest
:
mainQuest
.
getChildQuests
().
values
())
{
callback
.
accept
(
quest
);
callback
.
accept
(
quest
);
}
}
...
@@ -60,14 +156,14 @@ public class QuestManager extends BasePlayerManager {
...
@@ -60,14 +156,14 @@ public class QuestManager extends BasePlayerManager {
}
}
public
void
forEachMainQuest
(
Consumer
<
GameMainQuest
>
callback
)
{
public
void
forEachMainQuest
(
Consumer
<
GameMainQuest
>
callback
)
{
for
(
GameMainQuest
mainQuest
:
getQuests
().
values
())
{
for
(
GameMainQuest
mainQuest
:
get
Main
Quests
().
values
())
{
callback
.
accept
(
mainQuest
);
callback
.
accept
(
mainQuest
);
}
}
}
}
// TODO
// TODO
public
void
forEachActiveQuest
(
Consumer
<
GameQuest
>
callback
)
{
public
void
forEachActiveQuest
(
Consumer
<
GameQuest
>
callback
)
{
for
(
GameMainQuest
mainQuest
:
getQuests
().
values
())
{
for
(
GameMainQuest
mainQuest
:
get
Main
Quests
().
values
())
{
for
(
GameQuest
quest
:
mainQuest
.
getChildQuests
().
values
())
{
for
(
GameQuest
quest
:
mainQuest
.
getChildQuests
().
values
())
{
if
(
quest
.
getState
()
!=
QuestState
.
QUEST_STATE_FINISHED
)
{
if
(
quest
.
getState
()
!=
QuestState
.
QUEST_STATE_FINISHED
)
{
callback
.
accept
(
quest
);
callback
.
accept
(
quest
);
...
@@ -78,7 +174,7 @@ public class QuestManager extends BasePlayerManager {
...
@@ -78,7 +174,7 @@ public class QuestManager extends BasePlayerManager {
public
GameMainQuest
addMainQuest
(
QuestData
questConfig
)
{
public
GameMainQuest
addMainQuest
(
QuestData
questConfig
)
{
GameMainQuest
mainQuest
=
new
GameMainQuest
(
getPlayer
(),
questConfig
.
getMainId
());
GameMainQuest
mainQuest
=
new
GameMainQuest
(
getPlayer
(),
questConfig
.
getMainId
());
get
Quests
().
put
(
mainQuest
.
getParentQuestId
(),
mainQuest
);
getMain
Quests
().
put
(
mainQuest
.
getParentQuestId
(),
mainQuest
);
getPlayer
().
sendPacket
(
new
PacketFinishedParentQuestUpdateNotify
(
mainQuest
));
getPlayer
().
sendPacket
(
new
PacketFinishedParentQuestUpdateNotify
(
mainQuest
));
...
@@ -102,18 +198,16 @@ public class QuestManager extends BasePlayerManager {
...
@@ -102,18 +198,16 @@ public class QuestManager extends BasePlayerManager {
// Sub quest
// Sub quest
GameQuest
quest
=
mainQuest
.
getChildQuestById
(
questId
);
GameQuest
quest
=
mainQuest
.
getChildQuestById
(
questId
);
if
(
quest
!=
null
)
{
// Forcefully start
return
null
;
quest
.
start
();
}
// Create
quest
=
new
GameQuest
(
mainQuest
,
questConfig
);
// Save main quest
// Save main quest
mainQuest
.
save
();
mainQuest
.
save
();
// Send packet
// Send packet
getPlayer
().
sendPacket
(
new
PacketQuestListUpdateNotify
(
quest
));
getPlayer
().
sendPacket
(
new
PacketQuestListUpdateNotify
(
mainQuest
.
getChildQuests
().
values
().
stream
()
.
filter
(
p
->
p
.
getState
()
!=
QuestState
.
QUEST_STATE_UNSTARTED
)
.
toList
()));
return
quest
;
return
quest
;
}
}
...
@@ -133,55 +227,81 @@ public class QuestManager extends BasePlayerManager {
...
@@ -133,55 +227,81 @@ public class QuestManager extends BasePlayerManager {
triggerEvent
(
condType
,
""
,
params
);
triggerEvent
(
condType
,
""
,
params
);
}
}
//TODO
public
void
triggerEvent
(
QuestTrigger
condType
,
String
paramStr
,
int
...
params
)
{
public
void
triggerEvent
(
QuestTrigger
condType
,
String
paramStr
,
int
...
params
)
{
Grasscutter
.
getLogger
().
debug
(
"Trigger Event {}, {}, {}"
,
condType
,
paramStr
,
params
);
Grasscutter
.
getLogger
().
debug
(
"Trigger Event {}, {}, {}"
,
condType
,
paramStr
,
params
);
Set
<
GameQuest
>
changedQuests
=
new
HashSet
<>();
List
<
GameMainQuest
>
checkMainQuests
=
this
.
getMainQuests
().
values
().
stream
()
.
filter
(
i
->
i
.
getState
()
!=
ParentQuestState
.
PARENT_QUEST_STATE_FINISHED
)
this
.
forEachActiveQuest
(
quest
->
{
.
toList
();
QuestData
data
=
quest
.
getData
();
switch
(
condType
){
//accept Conds
for
(
int
i
=
0
;
i
<
data
.
getFinishCond
().
size
();
i
++)
{
case
QUEST_COND_STATE_EQUAL:
if
(
quest
.
getFinishProgressList
()
==
null
case
QUEST_COND_STATE_NOT_EQUAL:
||
quest
.
getFinishProgressList
().
length
==
0
case
QUEST_COND_COMPLETE_TALK:
||
quest
.
getFinishProgressList
()[
i
]
==
1
)
{
case
QUEST_COND_LUA_NOTIFY:
continue
;
case
QUEST_COND_QUEST_VAR_EQUAL:
}
case
QUEST_COND_QUEST_VAR_GREATER:
case
QUEST_COND_QUEST_VAR_LESS:
QuestCondition
condition
=
data
.
getFinishCond
().
get
(
i
);
case
QUEST_COND_PLAYER_LEVEL_EQUAL_GREATER:
case
QUEST_COND_QUEST_GLOBAL_VAR_EQUAL:
if
(
condition
.
getType
()
!=
condType
)
{
case
QUEST_COND_QUEST_GLOBAL_VAR_GREATER:
continue
;
case
QUEST_COND_QUEST_GLOBAL_VAR_LESS:
}
for
(
GameMainQuest
mainquest
:
checkMainQuests
)
{
mainquest
.
tryAcceptSubQuests
(
condType
,
paramStr
,
params
);
boolean
result
=
getPlayer
().
getServer
().
getQuestSystem
().
triggerContent
(
quest
,
condition
,
paramStr
,
params
);
}
break
;
if
(
result
)
{
quest
.
getFinishProgressList
()[
i
]
=
1
;
//fail Conds
case
QUEST_CONTENT_NOT_FINISH_PLOT:
changedQuests
.
add
(
quest
);
for
(
GameMainQuest
mainquest
:
checkMainQuests
)
{
}
mainquest
.
tryFailSubQuests
(
condType
,
paramStr
,
params
);
}
break
;
//finish Conds
case
QUEST_CONTENT_COMPLETE_TALK:
case
QUEST_CONTENT_FINISH_PLOT:
case
QUEST_CONTENT_COMPLETE_ANY_TALK:
case
QUEST_CONTENT_LUA_NOTIFY:
case
QUEST_CONTENT_QUEST_VAR_EQUAL:
case
QUEST_CONTENT_QUEST_VAR_GREATER:
case
QUEST_CONTENT_QUEST_VAR_LESS:
case
QUEST_CONTENT_ENTER_DUNGEON:
case
QUEST_CONTENT_ENTER_ROOM:
case
QUEST_CONTENT_INTERACT_GADGET:
case
QUEST_CONTENT_TRIGGER_FIRE:
case
QUEST_CONTENT_UNLOCK_TRANS_POINT:
for
(
GameMainQuest
mainQuest
:
checkMainQuests
)
{
mainQuest
.
tryFinishSubQuests
(
condType
,
paramStr
,
params
);
}
break
;
//finish Or Fail Conds
case
QUEST_CONTENT_GAME_TIME_TICK:
case
QUEST_CONTENT_QUEST_STATE_EQUAL:
case
QUEST_CONTENT_ADD_QUEST_PROGRESS:
case
QUEST_CONTENT_LEAVE_SCENE:
for
(
GameMainQuest
mainQuest
:
checkMainQuests
)
{
mainQuest
.
tryFailSubQuests
(
condType
,
paramStr
,
params
);
mainQuest
.
tryFinishSubQuests
(
condType
,
paramStr
,
params
);
}
break
;
//QUEST_EXEC are handled directly by each subQuest
//Unused
case
QUEST_CONTENT_QUEST_STATE_NOT_EQUAL:
case
QUEST_COND_PLAYER_CHOOSE_MALE:
default
:
Grasscutter
.
getLogger
().
error
(
"Unhandled QuestTrigger {}"
,
condType
);
}
if
(
this
.
addToQuestListUpdateNotify
.
size
()
!=
0
){
this
.
getPlayer
().
getSession
().
send
(
new
PacketQuestListUpdateNotify
(
this
.
addToQuestListUpdateNotify
));
this
.
addToQuestListUpdateNotify
.
clear
();
}
}
});
for
(
GameQuest
quest
:
changedQuests
)
{
LogicType
logicType
=
quest
.
getData
().
getFailCondComb
();
int
[]
progress
=
quest
.
getFinishProgressList
();
// Handle logical comb
boolean
finish
=
LogicType
.
calculate
(
logicType
,
progress
);
// Finish
if
(
finish
)
{
quest
.
finish
();
}
else
{
getPlayer
().
sendPacket
(
new
PacketQuestProgressUpdateNotify
(
quest
));
quest
.
save
();
}
}
}
}
public
List
<
QuestGroupSuite
>
getSceneGroupSuite
(
int
sceneId
)
{
public
List
<
QuestGroupSuite
>
getSceneGroupSuite
(
int
sceneId
)
{
return
getQuests
().
values
().
stream
()
return
get
Main
Quests
().
values
().
stream
()
.
filter
(
i
->
i
.
getState
()
!=
ParentQuestState
.
PARENT_QUEST_STATE_FINISHED
)
.
filter
(
i
->
i
.
getState
()
!=
ParentQuestState
.
PARENT_QUEST_STATE_FINISHED
)
.
map
(
GameMainQuest:
:
getQuestGroupSuites
)
.
map
(
GameMainQuest:
:
getQuestGroupSuites
)
.
filter
(
Objects:
:
nonNull
)
.
filter
(
Objects:
:
nonNull
)
...
@@ -197,10 +317,14 @@ public class QuestManager extends BasePlayerManager {
...
@@ -197,10 +317,14 @@ public class QuestManager extends BasePlayerManager {
for
(
GameQuest
quest
:
mainQuest
.
getChildQuests
().
values
())
{
for
(
GameQuest
quest
:
mainQuest
.
getChildQuests
().
values
())
{
quest
.
setMainQuest
(
mainQuest
);
quest
.
setMainQuest
(
mainQuest
);
quest
.
setConfig
(
GameData
.
getQuestDataMap
().
get
(
quest
.
getQuestId
()));
quest
.
setConfig
(
GameData
.
getQuestDataMap
().
get
(
quest
.
get
Sub
QuestId
()));
}
}
this
.
getQuests
().
put
(
mainQuest
.
getParentQuestId
(),
mainQuest
);
this
.
get
Main
Quests
().
put
(
mainQuest
.
getParentQuestId
(),
mainQuest
);
}
}
}
}
public
List
<
GameMainQuest
>
getActiveMainQuests
()
{
return
getMainQuests
().
values
().
stream
().
filter
(
p
->
!
p
.
isFinished
()).
toList
();
}
}
}
src/main/java/emu/grasscutter/game/quest/conditions/ConditionLuaNotify.java
View file @
8050f0cc
...
@@ -8,7 +8,7 @@ import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
...
@@ -8,7 +8,7 @@ import emu.grasscutter.game.quest.handlers.QuestBaseHandler;
@QuestValue
(
QuestTrigger
.
QUEST_COND_LUA_NOTIFY
)
@QuestValue
(
QuestTrigger
.
QUEST_COND_LUA_NOTIFY
)
public
class
ConditionLuaNotify
extends
QuestBaseHandler
{
public
class
ConditionLuaNotify
extends
QuestBaseHandler
{
//Wrong implementation. Example: 7010226 has no paramStr
@Override
@Override
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
return
condition
.
getParam
()[
0
]
==
Integer
.
parseInt
(
paramStr
);
return
condition
.
getParam
()[
0
]
==
Integer
.
parseInt
(
paramStr
);
...
...
src/main/java/emu/grasscutter/game/quest/conditions/ConditionStateEqual.java
View file @
8050f0cc
package
emu.grasscutter.game.quest.conditions
;
package
emu.grasscutter.game.quest.conditions
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.quest.QuestValue
;
import
emu.grasscutter.game.quest.QuestValue
;
import
emu.grasscutter.data.excels.QuestData.QuestCondition
;
import
emu.grasscutter.data.excels.QuestData.QuestCondition
;
import
emu.grasscutter.game.quest.GameQuest
;
import
emu.grasscutter.game.quest.GameQuest
;
...
@@ -11,13 +12,16 @@ public class ConditionStateEqual extends QuestBaseHandler {
...
@@ -11,13 +12,16 @@ public class ConditionStateEqual extends QuestBaseHandler {
@Override
@Override
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
GameQuest
checkQuest
=
quest
.
getOwner
().
getQuestManager
().
getQuestById
(
p
aram
s
[
0
]);
GameQuest
checkQuest
=
quest
.
getOwner
().
getQuestManager
().
getQuestById
(
condition
.
getP
aram
()
[
0
]);
if
(
checkQuest
==
null
)
{
if
(
checkQuest
!=
null
)
{
/*
return
checkQuest
.
getState
().
getValue
()
==
params
[
1
];
Will spam the console
}
//Grasscutter.getLogger().debug("Warning: quest {} hasn't been started yet!", condition.getParam()[0]);
*/
return
false
;
return
false
;
}
}
return
checkQuest
.
getState
().
getValue
()
==
condition
.
getParam
()[
1
];
}
}
}
src/main/java/emu/grasscutter/game/quest/content/ContentAddQuestProgress.java
View file @
8050f0cc
...
@@ -11,7 +11,12 @@ public class ContentAddQuestProgress extends QuestBaseHandler {
...
@@ -11,7 +11,12 @@ public class ContentAddQuestProgress extends QuestBaseHandler {
@Override
@Override
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
return
condition
.
getParam
()[
0
]
==
params
[
0
];
/*
//paramStr is a lua group, params[0] may also be a lua group!
questid = xxxxxx lua group = xxxxxxyy
count seems relevant only for lua group
*/
return
condition
.
getParam
()[
0
]
==
params
[
0
];
//missing params[1], paramStr, and count
}
}
}
}
src/main/java/emu/grasscutter/game/quest/content/ContentCompleteTalk.java
View file @
8050f0cc
package
emu.grasscutter.game.quest.content
;
package
emu.grasscutter.game.quest.content
;
import
emu.grasscutter.data.binout.MainQuestData
;
import
emu.grasscutter.game.quest.GameMainQuest
;
import
emu.grasscutter.game.quest.GameQuest
;
import
emu.grasscutter.game.quest.QuestValue
;
import
emu.grasscutter.game.quest.QuestValue
;
import
emu.grasscutter.data.excels.QuestData.QuestCondition
;
import
emu.grasscutter.data.excels.QuestData.QuestCondition
;
import
emu.grasscutter.game.quest.GameQuest
;
import
emu.grasscutter.game.quest.enums.QuestTrigger
;
import
emu.grasscutter.game.quest.enums.QuestTrigger
;
import
emu.grasscutter.game.quest.handlers.QuestBaseHandler
;
import
emu.grasscutter.game.quest.handlers.QuestBaseHandler
;
...
@@ -11,7 +13,9 @@ public class ContentCompleteTalk extends QuestBaseHandler {
...
@@ -11,7 +13,9 @@ public class ContentCompleteTalk extends QuestBaseHandler {
@Override
@Override
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
return
condition
.
getParam
()[
0
]
==
params
[
0
];
GameMainQuest
checkMainQuest
=
quest
.
getOwner
().
getQuestManager
().
getMainQuestById
(
params
[
0
]/
100
);
if
(
checkMainQuest
==
null
)
{
return
false
;}
MainQuestData
.
TalkData
talkData
=
checkMainQuest
.
getTalks
().
get
(
Integer
.
valueOf
(
params
[
0
]));
return
talkData
==
null
||
condition
.
getParamStr
().
contains
(
paramStr
)
||
checkMainQuest
.
getChildQuestById
(
params
[
0
])
!=
null
;
}
}
}
}
src/main/java/emu/grasscutter/game/quest/content/ContentEnterDungeon.java
View file @
8050f0cc
...
@@ -11,7 +11,7 @@ public class ContentEnterDungeon extends QuestBaseHandler {
...
@@ -11,7 +11,7 @@ public class ContentEnterDungeon extends QuestBaseHandler {
@Override
@Override
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
return
condition
.
getParam
()[
0
]
==
params
[
0
];
return
condition
.
getParam
()[
0
]
==
params
[
0
];
//missing params[1]
}
}
}
}
src/main/java/emu/grasscutter/game/quest/content/ContentFinishPlot.java
View file @
8050f0cc
package
emu.grasscutter.game.quest.content
;
package
emu.grasscutter.game.quest.content
;
import
emu.grasscutter.data.binout.MainQuestData
;
import
emu.grasscutter.game.quest.GameMainQuest
;
import
emu.grasscutter.game.quest.QuestValue
;
import
emu.grasscutter.game.quest.QuestValue
;
import
emu.grasscutter.data.excels.QuestData.QuestCondition
;
import
emu.grasscutter.data.excels.QuestData.QuestCondition
;
import
emu.grasscutter.game.quest.GameQuest
;
import
emu.grasscutter.game.quest.GameQuest
;
...
@@ -11,7 +13,9 @@ public class ContentFinishPlot extends QuestBaseHandler {
...
@@ -11,7 +13,9 @@ public class ContentFinishPlot extends QuestBaseHandler {
@Override
@Override
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
return
condition
.
getParam
()[
0
]
==
params
[
0
];
MainQuestData
.
TalkData
talkData
=
quest
.
getMainQuest
().
getTalks
().
get
(
Integer
.
valueOf
(
params
[
0
]));
GameQuest
subQuest
=
quest
.
getMainQuest
().
getChildQuestById
(
params
[
0
]);
return
talkData
!=
null
||
subQuest
!=
null
;
}
}
}
}
src/main/java/emu/grasscutter/game/quest/content/ContentQuestStateEqual.java
View file @
8050f0cc
...
@@ -11,13 +11,9 @@ public class ContentQuestStateEqual extends QuestBaseHandler {
...
@@ -11,13 +11,9 @@ public class ContentQuestStateEqual extends QuestBaseHandler {
@Override
@Override
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
public
boolean
execute
(
GameQuest
quest
,
QuestCondition
condition
,
String
paramStr
,
int
...
params
)
{
GameQuest
checkQuest
=
quest
.
getOwner
().
getQuestManager
().
getQuestById
(
params
[
0
]);
GameQuest
checkQuest
=
quest
.
getOwner
().
getQuestManager
().
getQuestById
(
condition
.
getParam
()[
0
]);
if
(
checkQuest
==
null
)
{
return
false
;}
if
(
checkQuest
!=
null
)
{
return
checkQuest
.
getState
().
getValue
()
==
params
[
1
];
return
checkQuest
.
getState
().
getValue
()
==
params
[
1
];
}
}
return
false
;
}
}
}
src/main/java/emu/grasscutter/game/quest/enums/QuestState.java
View file @
8050f0cc
...
@@ -5,7 +5,14 @@ public enum QuestState {
...
@@ -5,7 +5,14 @@ public enum QuestState {
QUEST_STATE_UNSTARTED
(
1
),
QUEST_STATE_UNSTARTED
(
1
),
QUEST_STATE_UNFINISHED
(
2
),
QUEST_STATE_UNFINISHED
(
2
),
QUEST_STATE_FINISHED
(
3
),
QUEST_STATE_FINISHED
(
3
),
QUEST_STATE_FAILED
(
4
);
QUEST_STATE_FAILED
(
4
),
// Used by lua
NONE
(
0
),
UNSTARTED
(
1
),
UNFINISHED
(
2
),
FINISHED
(
3
),
FAILED
(
4
);
private
final
int
value
;
private
final
int
value
;
...
...
src/main/java/emu/grasscutter/scripts/SceneScriptManager.java
View file @
8050f0cc
...
@@ -92,6 +92,7 @@ public class SceneScriptManager {
...
@@ -92,6 +92,7 @@ public class SceneScriptManager {
}
}
public
void
registerTrigger
(
SceneTrigger
trigger
)
{
public
void
registerTrigger
(
SceneTrigger
trigger
)
{
getTriggersByEvent
(
trigger
.
event
).
add
(
trigger
);
getTriggersByEvent
(
trigger
.
event
).
add
(
trigger
);
Grasscutter
.
getLogger
().
debug
(
"Registered trigger {}"
,
trigger
.
name
);
}
}
public
void
deregisterTrigger
(
List
<
SceneTrigger
>
triggers
)
{
public
void
deregisterTrigger
(
List
<
SceneTrigger
>
triggers
)
{
triggers
.
forEach
(
this
::
deregisterTrigger
);
triggers
.
forEach
(
this
::
deregisterTrigger
);
...
@@ -122,6 +123,7 @@ public class SceneScriptManager {
...
@@ -122,6 +123,7 @@ public class SceneScriptManager {
public
void
registerRegion
(
EntityRegion
region
)
{
public
void
registerRegion
(
EntityRegion
region
)
{
regions
.
put
(
region
.
getId
(),
region
);
regions
.
put
(
region
.
getId
(),
region
);
Grasscutter
.
getLogger
().
debug
(
"Registered region {} from group {}"
,
region
.
getMetaRegion
().
config_id
,
region
.
getGroupId
());
}
}
public
void
registerRegionInGroupSuite
(
SceneGroup
group
,
SceneSuite
suite
){
public
void
registerRegionInGroupSuite
(
SceneGroup
group
,
SceneSuite
suite
){
suite
.
sceneRegions
.
stream
().
map
(
region
->
new
EntityRegion
(
this
.
getScene
(),
region
))
suite
.
sceneRegions
.
stream
().
map
(
region
->
new
EntityRegion
(
this
.
getScene
(),
region
))
...
@@ -195,9 +197,30 @@ public class SceneScriptManager {
...
@@ -195,9 +197,30 @@ public class SceneScriptManager {
.
filter
(
e
->
e
.
getEntityType
()
==
EntityType
.
Avatar
.
getValue
()
&&
region
.
getMetaRegion
().
contains
(
e
.
getPosition
()))
.
filter
(
e
->
e
.
getEntityType
()
==
EntityType
.
Avatar
.
getValue
()
&&
region
.
getMetaRegion
().
contains
(
e
.
getPosition
()))
.
forEach
(
region:
:
addEntity
);
.
forEach
(
region:
:
addEntity
);
var
players
=
region
.
getScene
().
getPlayers
();
int
targetID
=
0
;
if
(
players
.
size
()
>
0
)
targetID
=
players
.
get
(
0
).
getUid
();
if
(
region
.
hasNewEntities
())
{
if
(
region
.
hasNewEntities
())
{
Grasscutter
.
getLogger
().
trace
(
"Call EVENT_ENTER_REGION_{}"
,
region
.
getMetaRegion
().
config_id
);
callEvent
(
EventType
.
EVENT_ENTER_REGION
,
new
ScriptArgs
(
region
.
getConfigId
())
callEvent
(
EventType
.
EVENT_ENTER_REGION
,
new
ScriptArgs
(
region
.
getConfigId
())
.
setSourceEntityId
(
region
.
getId
())
.
setSourceEntityId
(
region
.
getId
())
.
setTargetEntityId
(
targetID
)
);
region
.
resetNewEntities
();
}
for
(
int
entityId
:
region
.
getEntities
())
{
if
(!
region
.
getMetaRegion
().
contains
(
getScene
().
getEntityById
(
entityId
).
getPosition
()))
{
region
.
removeEntity
(
entityId
);
}
}
if
(
region
.
entityLeave
())
{
callEvent
(
EventType
.
EVENT_LEAVE_REGION
,
new
ScriptArgs
(
region
.
getConfigId
())
.
setSourceEntityId
(
region
.
getId
())
.
setTargetEntityId
(
region
.
getFirstEntityId
())
.
setTargetEntityId
(
region
.
getFirstEntityId
())
);
);
...
@@ -286,22 +309,34 @@ public class SceneScriptManager {
...
@@ -286,22 +309,34 @@ public class SceneScriptManager {
}
}
private
void
realCallEvent
(
int
eventType
,
ScriptArgs
params
)
{
private
void
realCallEvent
(
int
eventType
,
ScriptArgs
params
)
{
try
{
try
{
ScriptLoader
.
getScriptLib
().
setSceneScriptManager
(
this
);
Set
<
SceneTrigger
>
relevantTriggers
=
new
HashSet
<>();
for
(
SceneTrigger
trigger
:
this
.
getTriggersByEvent
(
eventType
))
{
if
(
eventType
==
EventType
.
EVENT_ENTER_REGION
||
eventType
==
EventType
.
EVENT_LEAVE_REGION
)
{
try
{
List
<
SceneTrigger
>
relevantTriggersList
=
this
.
getTriggersByEvent
(
eventType
).
stream
()
.
filter
(
p
->
p
.
condition
.
contains
(
String
.
valueOf
(
params
.
param1
))).
toList
();
relevantTriggers
=
new
HashSet
<>(
relevantTriggersList
);
}
else
{
relevantTriggers
=
this
.
getTriggersByEvent
(
eventType
);}
for
(
SceneTrigger
trigger
:
relevantTriggers
)
{
try
{
ScriptLoader
.
getScriptLib
().
setCurrentGroup
(
trigger
.
currentGroup
);
ScriptLoader
.
getScriptLib
().
setCurrentGroup
(
trigger
.
currentGroup
);
LuaValue
ret
=
this
.
callScriptFunc
(
trigger
.
condition
,
trigger
.
currentGroup
,
params
);
LuaValue
ret
=
callScriptFunc
(
trigger
.
condition
,
trigger
.
currentGroup
,
params
);
Grasscutter
.
getLogger
().
trace
(
"Call Condition Trigger {}, [{},{},{}]"
,
trigger
.
condition
,
params
.
param1
,
params
.
source_eid
,
params
.
target_eid
);
Grasscutter
.
getLogger
().
trace
(
"Call Condition Trigger {}"
,
trigger
.
condition
);
if
(
ret
.
isboolean
()
&&
ret
.
checkboolean
())
{
if
(
ret
.
isboolean
()
&&
ret
.
checkboolean
())
{
// the SetGroupVariableValueByGroup in tower need the param to record the first stage time
// the SetGroupVariableValueByGroup in tower need the param to record the first stage time
callScriptFunc
(
trigger
.
action
,
trigger
.
currentGroup
,
params
);
this
.
callScriptFunc
(
trigger
.
action
,
trigger
.
currentGroup
,
params
);
Grasscutter
.
getLogger
().
trace
(
"Call Action Trigger {}"
,
trigger
.
action
);
Grasscutter
.
getLogger
().
trace
(
"Call Action Trigger {}"
,
trigger
.
action
);
}
if
(
trigger
.
event
==
EventType
.
EVENT_ENTER_REGION
)
{
//TODO some ret may not bool
EntityRegion
region
=
this
.
regions
.
values
().
stream
().
filter
(
p
->
p
.
getConfigId
()
==
params
.
param1
).
toList
().
get
(
0
);
getScene
().
getPlayers
().
forEach
(
p
->
p
.
onEnterRegion
(
region
.
getMetaRegion
()));
}
else
if
(
trigger
.
event
==
EventType
.
EVENT_LEAVE_REGION
)
{
EntityRegion
region
=
this
.
regions
.
values
().
stream
().
filter
(
p
->
p
.
getConfigId
()
==
params
.
param1
).
toList
().
get
(
0
);
getScene
().
getPlayers
().
forEach
(
p
->
p
.
onLeaveRegion
(
region
.
getMetaRegion
()));
}
deregisterTrigger
(
trigger
);
}
else
{
Grasscutter
.
getLogger
().
debug
(
"Condition Trigger {} returned {}"
,
trigger
.
condition
,
ret
);
}
//TODO some ret do not bool
}
finally
{
}
finally
{
ScriptLoader
.
getScriptLib
().
removeCurrentGroup
();
ScriptLoader
.
getScriptLib
().
removeCurrentGroup
();
}
}
...
...
src/main/java/emu/grasscutter/scripts/data/SceneRegion.java
View file @
8050f0cc
...
@@ -26,7 +26,8 @@ public class SceneRegion {
...
@@ -26,7 +26,8 @@ public class SceneRegion {
var
x
=
Math
.
pow
(
pos
.
getX
()
-
position
.
getX
(),
2
);
var
x
=
Math
.
pow
(
pos
.
getX
()
-
position
.
getX
(),
2
);
var
y
=
Math
.
pow
(
pos
.
getY
()
-
position
.
getY
(),
2
);
var
y
=
Math
.
pow
(
pos
.
getY
()
-
position
.
getY
(),
2
);
var
z
=
Math
.
pow
(
pos
.
getZ
()
-
position
.
getZ
(),
2
);
var
z
=
Math
.
pow
(
pos
.
getZ
()
-
position
.
getZ
(),
2
);
return
x
+
y
+
z
<=
(
radius
^
2
);
// ^ means XOR in java!
return
x
+
y
+
z
<=
(
radius
*
radius
);
}
}
return
false
;
return
false
;
}
}
...
...
src/main/java/emu/grasscutter/scripts/serializer/LuaSerializer.java
View file @
8050f0cc
...
@@ -30,6 +30,54 @@ public class LuaSerializer implements Serializer {
...
@@ -30,6 +30,54 @@ public class LuaSerializer implements Serializer {
return
serialize
(
type
,
(
LuaTable
)
obj
);
return
serialize
(
type
,
(
LuaTable
)
obj
);
}
}
@Override
public
<
T
>
Map
<
String
,
T
>
toMap
(
Class
<
T
>
type
,
Object
obj
)
{
return
serializeMap
(
type
,
(
LuaTable
)
obj
);
}
private
<
T
>
Map
<
String
,
T
>
serializeMap
(
Class
<
T
>
type
,
LuaTable
table
)
{
Map
<
String
,
T
>
map
=
new
HashMap
<>();
if
(
table
==
null
)
{
return
map
;
}
try
{
LuaValue
[]
keys
=
table
.
keys
();
for
(
LuaValue
k
:
keys
)
{
try
{
LuaValue
keyValue
=
table
.
get
(
k
);
T
object
=
null
;
if
(
keyValue
.
istable
())
{
object
=
serialize
(
type
,
keyValue
.
checktable
());
}
else
if
(
keyValue
.
isint
())
{
object
=
(
T
)
(
Integer
)
keyValue
.
toint
();
}
else
if
(
keyValue
.
isnumber
())
{
object
=
(
T
)
(
Float
)
keyValue
.
tofloat
();
// terrible...
}
else
if
(
keyValue
.
isstring
())
{
object
=
(
T
)
keyValue
.
tojstring
();
}
else
if
(
keyValue
.
isboolean
())
{
object
=
(
T
)
(
Boolean
)
keyValue
.
toboolean
();
}
else
{
object
=
(
T
)
keyValue
;
}
if
(
object
!=
null
)
{
map
.
put
(
String
.
valueOf
(
k
),
object
);
}
}
catch
(
Exception
ex
)
{
}
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
map
;
}
public
<
T
>
List
<
T
>
serializeList
(
Class
<
T
>
type
,
LuaTable
table
)
{
public
<
T
>
List
<
T
>
serializeList
(
Class
<
T
>
type
,
LuaTable
table
)
{
List
<
T
>
list
=
new
ArrayList
<>();
List
<
T
>
list
=
new
ArrayList
<>();
...
...
src/main/java/emu/grasscutter/scripts/serializer/Serializer.java
View file @
8050f0cc
package
emu.grasscutter.scripts.serializer
;
package
emu.grasscutter.scripts.serializer
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
org.luaj.vm2.LuaTable
;
public
interface
Serializer
{
public
interface
Serializer
{
public
<
T
>
List
<
T
>
toList
(
Class
<
T
>
type
,
Object
obj
);
public
<
T
>
List
<
T
>
toList
(
Class
<
T
>
type
,
Object
obj
);
public
<
T
>
T
toObject
(
Class
<
T
>
type
,
Object
obj
);
public
<
T
>
T
toObject
(
Class
<
T
>
type
,
Object
obj
);
public
<
T
>
Map
<
String
,
T
>
toMap
(
Class
<
T
>
type
,
Object
obj
);
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerAddQuestContentProgressReq.java
View file @
8050f0cc
package
emu.grasscutter.server.packet.recv
;
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.excels.QuestData
;
import
emu.grasscutter.game.quest.GameQuest
;
import
emu.grasscutter.game.quest.enums.QuestTrigger
;
import
emu.grasscutter.game.quest.enums.QuestTrigger
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketHandler
;
...
@@ -7,6 +10,9 @@ import emu.grasscutter.net.packet.PacketOpcodes;
...
@@ -7,6 +10,9 @@ import emu.grasscutter.net.packet.PacketOpcodes;
import
emu.grasscutter.net.proto.AddQuestContentProgressReqOuterClass
;
import
emu.grasscutter.net.proto.AddQuestContentProgressReqOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketAddQuestContentProgressRsp
;
import
emu.grasscutter.server.packet.send.PacketAddQuestContentProgressRsp
;
import
emu.grasscutter.data.excels.QuestData.QuestCondition
;
import
java.util.List
;
import
java.util.stream.Stream
;
@Opcodes
(
PacketOpcodes
.
AddQuestContentProgressReq
)
@Opcodes
(
PacketOpcodes
.
AddQuestContentProgressReq
)
public
class
HandlerAddQuestContentProgressReq
extends
PacketHandler
{
public
class
HandlerAddQuestContentProgressReq
extends
PacketHandler
{
...
@@ -14,9 +20,14 @@ public class HandlerAddQuestContentProgressReq extends PacketHandler {
...
@@ -14,9 +20,14 @@ public class HandlerAddQuestContentProgressReq extends PacketHandler {
@Override
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
var
req
=
AddQuestContentProgressReqOuterClass
.
AddQuestContentProgressReq
.
parseFrom
(
payload
);
var
req
=
AddQuestContentProgressReqOuterClass
.
AddQuestContentProgressReq
.
parseFrom
(
payload
);
//Find all conditions in quest that are the same as the given one
session
.
getPlayer
().
getQuestManager
().
triggerEvent
(
QuestTrigger
.
getContentTriggerByValue
(
req
.
getContentType
()),
req
.
getParam
());
Stream
<
QuestCondition
>
finishCond
=
GameData
.
getQuestDataMap
().
get
(
req
.
getParam
()).
getFinishCond
().
stream
();
Stream
<
QuestCondition
>
acceptCond
=
GameData
.
getQuestDataMap
().
get
(
req
.
getParam
()).
getAcceptCond
().
stream
();
Stream
<
QuestCondition
>
failCond
=
GameData
.
getQuestDataMap
().
get
(
req
.
getParam
()).
getFailCond
().
stream
();
List
<
QuestCondition
>
allCondMatch
=
Stream
.
concat
(
Stream
.
concat
(
acceptCond
,
failCond
),
finishCond
).
filter
(
p
->
p
.
getType
().
getValue
()
==
req
.
getContentType
()).
toList
();
for
(
QuestCondition
cond
:
allCondMatch
)
{
session
.
getPlayer
().
getQuestManager
().
triggerEvent
(
QuestTrigger
.
getContentTriggerByValue
(
req
.
getContentType
()),
cond
.
getParam
());
}
session
.
send
(
new
PacketAddQuestContentProgressRsp
(
req
.
getContentType
()));
session
.
send
(
new
PacketAddQuestContentProgressRsp
(
req
.
getContentType
()));
}
}
...
...
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