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
e9d7d5d5
Commit
e9d7d5d5
authored
May 11, 2022
by
Melledy
Browse files
Implement quests
parent
54cf45a7
Changes
27
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/command/commands/QuestCommand.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.command.commands
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.command.Command
;
import
emu.grasscutter.command.CommandHandler
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.quest.GameQuest
;
import
java.util.List
;
import
static
emu
.
grasscutter
.
utils
.
Language
.
translate
;
@Command
(
label
=
"quest"
,
usage
=
"quest <add|finish> [quest id]"
,
permission
=
"player.quest"
,
permissionTargeted
=
"player.quest.others"
,
description
=
"commands.quest.description"
)
public
final
class
QuestCommand
implements
CommandHandler
{
@Override
public
void
execute
(
Player
sender
,
Player
targetPlayer
,
List
<
String
>
args
)
{
if
(
targetPlayer
==
null
)
{
CommandHandler
.
sendMessage
(
sender
,
translate
(
sender
,
"commands.execution.need_target"
));
return
;
}
if
(
args
.
size
()
!=
2
)
{
CommandHandler
.
sendMessage
(
sender
,
translate
(
sender
,
"commands.quest.usage"
));
return
;
}
String
cmd
=
args
.
get
(
0
).
toLowerCase
();
int
questId
;
try
{
questId
=
Integer
.
parseInt
(
args
.
get
(
1
));
}
catch
(
Exception
e
)
{
CommandHandler
.
sendMessage
(
sender
,
translate
(
sender
,
"commands.quest.invalid_id"
));
return
;
}
switch
(
cmd
)
{
case
"add"
->
{
GameQuest
quest
=
sender
.
getQuestManager
().
addQuest
(
questId
);
if
(
quest
!=
null
)
{
CommandHandler
.
sendMessage
(
sender
,
translate
(
sender
,
"commands.quest.added"
,
questId
));
return
;
}
CommandHandler
.
sendMessage
(
sender
,
translate
(
sender
,
"commands.quest.not_found"
));
}
case
"finish"
->
{
GameQuest
quest
=
sender
.
getQuestManager
().
getQuestById
(
questId
);
if
(
quest
==
null
)
{
CommandHandler
.
sendMessage
(
sender
,
translate
(
sender
,
"commands.quest.not_found"
));
return
;
}
quest
.
finish
();
CommandHandler
.
sendMessage
(
sender
,
translate
(
sender
,
"commands.quest.finished"
,
questId
));
}
default
->
{
CommandHandler
.
sendMessage
(
sender
,
translate
(
sender
,
"commands.quest.usage"
));
}
}
}
}
src/main/java/emu/grasscutter/data/GameData.java
View file @
e9d7d5d5
...
...
@@ -12,6 +12,7 @@ import emu.grasscutter.data.custom.AbilityEmbryoEntry;
import
emu.grasscutter.data.custom.AbilityModifier
;
import
emu.grasscutter.data.custom.AbilityModifierEntry
;
import
emu.grasscutter.data.custom.OpenConfigEntry
;
import
emu.grasscutter.data.custom.QuestConfig
;
import
emu.grasscutter.data.custom.ScenePointEntry
;
import
emu.grasscutter.data.def.*
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap
;
...
...
@@ -27,6 +28,7 @@ public class GameData {
private
static
final
Map
<
String
,
AbilityModifierEntry
>
abilityModifiers
=
new
HashMap
<>();
private
static
final
Map
<
String
,
OpenConfigEntry
>
openConfigEntries
=
new
HashMap
<>();
private
static
final
Map
<
String
,
ScenePointEntry
>
scenePointEntries
=
new
HashMap
<>();
private
static
final
Int2ObjectMap
<
QuestConfig
>
questConfigs
=
new
Int2ObjectOpenHashMap
<>();
// ExcelConfigs
private
static
final
Int2ObjectMap
<
PlayerLevelData
>
playerLevelDataMap
=
new
Int2ObjectOpenHashMap
<>();
...
...
@@ -122,6 +124,10 @@ public class GameData {
return
getScenePointEntries
().
get
(
sceneId
+
"_"
+
pointId
);
}
public
static
Int2ObjectMap
<
QuestConfig
>
getQuestConfigs
()
{
return
questConfigs
;
}
public
static
Int2ObjectMap
<
AvatarData
>
getAvatarDataMap
()
{
return
avatarDataMap
;
}
...
...
src/main/java/emu/grasscutter/data/ResourceLoader.java
View file @
e9d7d5d5
...
...
@@ -24,6 +24,9 @@ import emu.grasscutter.data.custom.AbilityModifier.AbilityModifierAction;
import
emu.grasscutter.data.custom.AbilityModifier.AbilityModifierActionType
;
import
emu.grasscutter.data.custom.AbilityModifierEntry
;
import
emu.grasscutter.data.custom.OpenConfigEntry
;
import
emu.grasscutter.data.custom.QuestConfig
;
import
emu.grasscutter.data.custom.QuestConfigData
;
import
emu.grasscutter.data.custom.QuestConfigData.SubQuestConfigData
;
import
emu.grasscutter.data.custom.ScenePointEntry
;
import
emu.grasscutter.game.world.SpawnDataEntry
;
import
emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry
;
...
...
@@ -57,8 +60,9 @@ public class ResourceLoader {
loadResources
();
// Process into depots
GameDepot
.
load
();
// Load spawn data
// Load spawn data
and quests
loadSpawnData
();
loadQuests
();
// Load scene points - must be done AFTER resources are loaded
loadScenePoints
();
// Custom - TODO move this somewhere else
...
...
@@ -397,6 +401,34 @@ public class ResourceLoader {
}
}
private
static
void
loadQuests
()
{
File
folder
=
new
File
(
Grasscutter
.
getConfig
().
RESOURCE_FOLDER
+
"BinOutput/Quest/"
);
if
(!
folder
.
exists
())
{
return
;
}
for
(
File
file
:
folder
.
listFiles
())
{
QuestConfigData
mainQuest
=
null
;
try
(
FileReader
fileReader
=
new
FileReader
(
file
))
{
mainQuest
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
QuestConfigData
.
class
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
continue
;
}
if
(
mainQuest
.
getSubQuests
()
!=
null
)
{
for
(
SubQuestConfigData
subQuest
:
mainQuest
.
getSubQuests
())
{
QuestConfig
quest
=
new
QuestConfig
(
mainQuest
,
subQuest
);
GameData
.
getQuestConfigs
().
put
(
quest
.
getId
(),
quest
);
}
}
}
Grasscutter
.
getLogger
().
info
(
"Loaded "
+
GameData
.
getQuestConfigs
().
size
()
+
" Quest Configs"
);
}
// BinOutput configs
private
static
class
AvatarConfig
{
...
...
src/main/java/emu/grasscutter/data/custom/QuestConfig.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.data.custom
;
import
emu.grasscutter.data.custom.QuestConfigData.SubQuestConfigData
;
public
class
QuestConfig
{
private
final
QuestConfigData
mainQuest
;
private
final
SubQuestConfigData
subQuest
;
public
QuestConfig
(
QuestConfigData
mainQuest
,
SubQuestConfigData
subQuest
)
{
this
.
mainQuest
=
mainQuest
;
this
.
subQuest
=
subQuest
;
}
public
int
getId
()
{
return
subQuest
.
getSubId
();
}
public
QuestConfigData
getMainQuest
()
{
return
mainQuest
;
}
public
SubQuestConfigData
getSubQuest
()
{
return
subQuest
;
}
}
src/main/java/emu/grasscutter/data/custom/QuestConfigData.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.data.custom
;
import
emu.grasscutter.game.quest.enums.LogicType
;
import
emu.grasscutter.game.quest.enums.QuestCondType
;
import
emu.grasscutter.game.quest.enums.QuestType
;
public
class
QuestConfigData
{
private
int
id
;
private
int
series
;
private
QuestType
type
;
private
long
titleTextMapHash
;
private
int
[]
suggestTrackMainQuestList
;
private
int
[]
rewardIdList
;
private
SubQuestConfigData
[]
subQuests
;
public
int
getId
()
{
return
id
;
}
public
int
getSeries
()
{
return
series
;
}
public
QuestType
getType
()
{
return
type
;
}
public
long
getTitleTextMapHash
()
{
return
titleTextMapHash
;
}
public
int
[]
getSuggestTrackMainQuestList
()
{
return
suggestTrackMainQuestList
;
}
public
int
[]
getRewardIdList
()
{
return
rewardIdList
;
}
public
SubQuestConfigData
[]
getSubQuests
()
{
return
subQuests
;
}
public
class
SubQuestConfigData
{
private
int
subId
;
private
int
mainId
;
private
LogicType
acceptCondComb
;
private
QuestCondition
[]
acceptCond
;
private
LogicType
finishCondComb
;
private
QuestCondition
[]
finishCond
;
private
LogicType
failCondComb
;
private
QuestCondition
[]
failCond
;
public
int
getSubId
()
{
return
subId
;
}
public
int
getMainId
()
{
return
mainId
;
}
public
LogicType
getAcceptCondComb
()
{
return
acceptCondComb
;
}
public
QuestCondition
[]
getAcceptCond
()
{
return
acceptCond
;
}
public
LogicType
getFinishCondComb
()
{
return
finishCondComb
;
}
public
QuestCondition
[]
getFinishCond
()
{
return
finishCond
;
}
public
LogicType
getFailCondComb
()
{
return
failCondComb
;
}
public
QuestCondition
[]
getFailCond
()
{
return
failCond
;
}
}
public
class
QuestCondition
{
private
QuestCondType
type
;
private
int
[]
param
;
public
QuestCondType
getType
()
{
return
type
;
}
public
int
[]
getParam
()
{
return
param
;
}
}
}
src/main/java/emu/grasscutter/database/DatabaseHelper.java
View file @
e9d7d5d5
...
...
@@ -15,6 +15,7 @@ import emu.grasscutter.game.gacha.GachaRecord;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.mail.Mail
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.quest.GameMainQuest
;
import
static
com
.
mongodb
.
client
.
model
.
Filters
.
eq
;
...
...
@@ -111,6 +112,8 @@ public final class DatabaseHelper {
DatabaseManager
.
getDatabase
().
getCollection
(
"gachas"
).
deleteMany
(
eq
(
"ownerId"
,
target
.
getPlayerUid
()));
// Delete GameItem.class data
DatabaseManager
.
getDatabase
().
getCollection
(
"items"
).
deleteMany
(
eq
(
"ownerId"
,
target
.
getPlayerUid
()));
// Delete GameMainQuest.class data
DatabaseManager
.
getDatabase
().
getCollection
(
"quests"
).
deleteMany
(
eq
(
"ownerUid"
,
target
.
getPlayerUid
()));
// Delete friendships.
// Here, we need to make sure to not only delete the deleted account's friendships,
...
...
@@ -260,4 +263,16 @@ public final class DatabaseHelper {
DeleteResult
result
=
DatabaseManager
.
getDatastore
().
delete
(
mail
);
return
result
.
wasAcknowledged
();
}
public
static
List
<
GameMainQuest
>
getAllQuests
(
Player
player
)
{
return
DatabaseManager
.
getDatastore
().
find
(
GameMainQuest
.
class
).
filter
(
Filters
.
eq
(
"ownerUid"
,
player
.
getUid
())).
stream
().
toList
();
}
public
static
void
saveQuest
(
GameMainQuest
quest
)
{
DatabaseManager
.
getDatastore
().
save
(
quest
);
}
public
static
boolean
deleteQuest
(
GameMainQuest
quest
)
{
return
DatabaseManager
.
getDatastore
().
delete
(
quest
).
wasAcknowledged
();
}
}
src/main/java/emu/grasscutter/database/DatabaseManager.java
View file @
e9d7d5d5
...
...
@@ -20,6 +20,8 @@ import emu.grasscutter.game.gacha.GachaRecord;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.mail.Mail
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.quest.GameMainQuest
;
import
emu.grasscutter.game.quest.GameQuest
;
public
final
class
DatabaseManager
{
...
...
@@ -30,7 +32,8 @@ public final class DatabaseManager {
private
static
Datastore
dispatchDatastore
;
private
static
final
Class
<?>[]
mappedClasses
=
new
Class
<?>[]
{
DatabaseCounter
.
class
,
Account
.
class
,
Player
.
class
,
Avatar
.
class
,
GameItem
.
class
,
Friendship
.
class
,
GachaRecord
.
class
,
Mail
.
class
DatabaseCounter
.
class
,
Account
.
class
,
Player
.
class
,
Avatar
.
class
,
GameItem
.
class
,
Friendship
.
class
,
GachaRecord
.
class
,
Mail
.
class
,
GameMainQuest
.
class
};
public
static
Datastore
getDatastore
()
{
...
...
src/main/java/emu/grasscutter/game/player/Player.java
View file @
e9d7d5d5
...
...
@@ -29,6 +29,9 @@ 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.quest.GameMainQuest
;
import
emu.grasscutter.game.quest.GameQuest
;
import
emu.grasscutter.game.quest.QuestManager
;
import
emu.grasscutter.game.shop.ShopLimit
;
import
emu.grasscutter.game.managers.MapMarkManager.*
;
import
emu.grasscutter.game.tower.TowerManager
;
...
...
@@ -91,6 +94,7 @@ public class Player {
@Transient
private
MailHandler
mailHandler
;
@Transient
private
MessageHandler
messageHandler
;
@Transient
private
AbilityManager
abilityManager
;
@Transient
private
QuestManager
questManager
;
@Transient
private
SotSManager
sotsManager
;
...
...
@@ -145,6 +149,7 @@ public class Player {
this
.
mailHandler
=
new
MailHandler
(
this
);
this
.
towerManager
=
new
TowerManager
(
this
);
this
.
abilityManager
=
new
AbilityManager
(
this
);
this
.
setQuestManager
(
new
QuestManager
(
this
));
this
.
pos
=
new
Position
();
this
.
rotation
=
new
Position
();
this
.
properties
=
new
HashMap
<>();
...
...
@@ -409,6 +414,14 @@ public class Player {
return
towerManager
;
}
public
QuestManager
getQuestManager
()
{
return
questManager
;
}
public
void
setQuestManager
(
QuestManager
questManager
)
{
this
.
questManager
=
questManager
;
}
public
PlayerGachaInfo
getGachaInfo
()
{
return
gachaInfo
;
}
...
...
@@ -883,10 +896,8 @@ public class Player {
}
public
void
sendPacket
(
BasePacket
packet
)
{
if
(
this
.
hasSentAvatarDataNotify
)
{
this
.
getSession
().
send
(
packet
);
}
}
public
OnlinePlayerInfo
getOnlinePlayerInfo
()
{
OnlinePlayerInfo
.
Builder
onlineInfo
=
OnlinePlayerInfo
.
newBuilder
()
...
...
@@ -1118,6 +1129,22 @@ public class Player {
this
.
getFriendsList
().
loadFromDatabase
();
this
.
getMailHandler
().
loadFromDatabase
();
this
.
getQuestManager
().
loadFromDatabase
();
// Quest - Commented out because a problem is caused if you log out while this quest is active
/*
if (getQuestManager().getMainQuestById(351) == null) {
GameQuest quest = getQuestManager().addQuest(35104);
if (quest != null) {
quest.finish();
}
getQuestManager().addQuest(35101);
this.setSceneId(3);
this.getPos().set(GameConstants.START_POSITION);
}
*/
// Create world
World
world
=
new
World
(
this
);
...
...
@@ -1138,6 +1165,9 @@ public class Player {
session
.
send
(
new
PacketStoreWeightLimitNotify
());
session
.
send
(
new
PacketPlayerStoreNotify
(
this
));
session
.
send
(
new
PacketAvatarDataNotify
(
this
));
session
.
send
(
new
PacketFinishedParentQuestNotify
(
this
));
session
.
send
(
new
PacketQuestListNotify
(
this
));
session
.
send
(
new
PacketServerCondMeetQuestListUpdateNotify
(
this
));
getTodayMoonCard
();
// The timer works at 0:0, some users log in after that, use this method to check if they have received a reward today or not. If not, send the reward.
...
...
src/main/java/emu/grasscutter/game/quest/GameMainQuest.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.game.quest
;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.bson.types.ObjectId
;
import
dev.morphia.annotations.Entity
;
import
dev.morphia.annotations.Id
;
import
dev.morphia.annotations.Indexed
;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.custom.QuestConfig
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.quest.enums.ParentQuestState
;
import
emu.grasscutter.game.quest.enums.QuestState
;
import
emu.grasscutter.net.proto.ChildQuestOuterClass.ChildQuest
;
import
emu.grasscutter.net.proto.ParentQuestOuterClass.ParentQuest
;
import
emu.grasscutter.net.proto.QuestOuterClass.Quest
;
import
emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify
;
import
emu.grasscutter.utils.Utils
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
@Entity
(
value
=
"quests"
,
useDiscriminator
=
false
)
public
class
GameMainQuest
{
@Id
private
ObjectId
id
;
@Indexed
private
int
ownerUid
;
@Transient
private
Player
owner
;
private
Map
<
Integer
,
GameQuest
>
childQuests
;
private
int
parentQuestId
;
private
int
[]
questVars
;
private
ParentQuestState
state
;
private
boolean
isFinished
;
@Deprecated
// Morphia only. Do not use.
public
GameMainQuest
()
{}
public
GameMainQuest
(
Player
player
,
int
parentQuestId
)
{
this
.
owner
=
player
;
this
.
ownerUid
=
player
.
getUid
();
this
.
parentQuestId
=
parentQuestId
;
this
.
childQuests
=
new
HashMap
<>();
this
.
questVars
=
new
int
[
5
];
this
.
state
=
ParentQuestState
.
PARENT_QUEST_STATE_NONE
;
}
public
int
getParentQuestId
()
{
return
parentQuestId
;
}
public
int
getOwnerUid
()
{
return
ownerUid
;
}
public
Player
getOwner
()
{
return
owner
;
}
public
void
setOwner
(
Player
player
)
{
if
(
player
.
getUid
()
!=
this
.
getOwnerUid
())
return
;
this
.
owner
=
player
;
}
public
Map
<
Integer
,
GameQuest
>
getChildQuests
()
{
return
childQuests
;
}
public
GameQuest
getChildQuestById
(
int
id
)
{
return
this
.
getChildQuests
().
get
(
id
);
}
public
int
[]
getQuestVars
()
{
return
questVars
;
}
public
ParentQuestState
getState
()
{
return
state
;
}
public
boolean
isFinished
()
{
return
isFinished
;
}
public
void
finish
()
{
this
.
isFinished
=
true
;
this
.
state
=
ParentQuestState
.
PARENT_QUEST_STATE_FINISHED
;
this
.
getOwner
().
getSession
().
send
(
new
PacketFinishedParentQuestUpdateNotify
(
this
));
}
public
void
save
()
{
DatabaseHelper
.
saveQuest
(
this
);
}
public
ParentQuest
toProto
()
{
ParentQuest
.
Builder
proto
=
ParentQuest
.
newBuilder
()
.
setParentQuestId
(
getParentQuestId
())
.
setIsFinished
(
isFinished
())
.
setParentQuestState
(
getState
().
getValue
());
for
(
GameQuest
quest
:
this
.
getChildQuests
().
values
())
{
ChildQuest
childQuest
=
ChildQuest
.
newBuilder
()
.
setQuestId
(
quest
.
getQuestId
())
.
setState
(
quest
.
getState
().
getValue
())
.
build
();
proto
.
addChildQuestList
(
childQuest
);
}
if
(
getQuestVars
()
!=
null
)
{
for
(
int
i
:
getQuestVars
())
{
proto
.
addQuestVar
(
i
);
}
}
return
proto
.
build
();
}
}
src/main/java/emu/grasscutter/game/quest/GameQuest.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.game.quest
;
import
dev.morphia.annotations.Entity
;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.data.custom.QuestConfig
;
import
emu.grasscutter.data.custom.QuestConfigData.SubQuestConfigData
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.quest.enums.QuestState
;
import
emu.grasscutter.net.proto.QuestOuterClass.Quest
;
import
emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify
;
import
emu.grasscutter.utils.Utils
;
@Entity
public
class
GameQuest
{
@Transient
private
GameMainQuest
mainQuest
;
@Transient
private
QuestConfig
config
;
private
int
questId
;
private
int
mainQuestId
;
private
QuestState
state
;
private
int
startTime
;
private
int
acceptTime
;
private
int
finishTime
;
private
int
[]
finishProgressList
;
private
int
[]
failProgressList
;
@Deprecated
// Morphia only. Do not use.
public
GameQuest
()
{}
public
GameQuest
(
GameMainQuest
mainQuest
,
QuestConfig
config
)
{
this
.
mainQuest
=
mainQuest
;
this
.
questId
=
config
.
getId
();
this
.
mainQuestId
=
config
.
getMainQuest
().
getId
();
this
.
config
=
config
;
this
.
acceptTime
=
Utils
.
getCurrentSeconds
();
this
.
startTime
=
this
.
acceptTime
;
this
.
state
=
QuestState
.
QUEST_STATE_UNFINISHED
;
if
(
config
.
getSubQuest
().
getFinishCond
()
!=
null
)
{
this
.
finishProgressList
=
new
int
[
config
.
getSubQuest
().
getFinishCond
().
length
];
}
if
(
config
.
getSubQuest
().
getFailCond
()
!=
null
)
{
this
.
failProgressList
=
new
int
[
config
.
getSubQuest
().
getFailCond
().
length
];
}
this
.
mainQuest
.
getChildQuests
().
put
(
this
.
questId
,
this
);
}
public
GameMainQuest
getMainQuest
()
{
return
mainQuest
;
}
public
void
setMainQuest
(
GameMainQuest
mainQuest
)
{
this
.
mainQuest
=
mainQuest
;
}
public
Player
getOwner
()
{
return
getMainQuest
().
getOwner
();
}
public
int
getQuestId
()
{
return
questId
;
}
public
int
getMainQuestId
()
{
return
mainQuestId
;
}
public
QuestConfig
getConfig
()
{
return
config
;
}
public
void
setConfig
(
QuestConfig
config
)
{
if
(
this
.
getQuestId
()
!=
config
.
getId
())
return
;
this
.
config
=
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
)
{
finishProgressList
[
index
]
=
value
;
}
public
int
[]
getFailProgressList
()
{
return
failProgressList
;
}
public
void
setFailProgress
(
int
index
,
int
value
)
{
failProgressList
[
index
]
=
value
;
}
public
void
finish
()
{
this
.
state
=
QuestState
.
QUEST_STATE_FINISHED
;
this
.
finishTime
=
Utils
.
getCurrentSeconds
();
if
(
this
.
getFinishProgressList
()
!=
null
)
{
for
(
int
i
=
0
;
i
<
getFinishProgressList
().
length
;
i
++)
{
getFinishProgressList
()[
i
]
=
1
;
}
}
this
.
getOwner
().
getSession
().
send
(
new
PacketQuestProgressUpdateNotify
(
this
));
// Finish main quest if all child quests are done
this
.
tryFinishMainQuest
();
this
.
save
();
}
public
boolean
tryFinishMainQuest
()
{
try
{
SubQuestConfigData
subQuestData
=
getConfig
().
getMainQuest
().
getSubQuests
()[
getConfig
().
getMainQuest
().
getSubQuests
().
length
-
1
];
if
(
subQuestData
.
getSubId
()
==
this
.
getQuestId
())
{
getMainQuest
().
finish
();
return
true
;
}
}
catch
(
Exception
e
)
{
}
return
false
;
}
public
void
save
()
{
getMainQuest
().
save
();
}
public
Quest
toProto
()
{
Quest
.
Builder
proto
=
Quest
.
newBuilder
()
.
setQuestId
(
this
.
getQuestId
())
.
setState
(
this
.
getState
().
getValue
())
.
setParentQuestId
(
this
.
getMainQuestId
())
.
setStartTime
(
this
.
getStartTime
())
.
setStartGameTime
(
438
)
.
setAcceptTime
(
this
.
getAcceptTime
());
if
(
this
.
getFinishProgressList
()
!=
null
)
{
for
(
int
i
:
this
.
getFinishProgressList
())
{
proto
.
addFinishProgressList
(
i
);
}
}
if
(
this
.
getFailProgressList
()
!=
null
)
{
for
(
int
i
:
this
.
getFailProgressList
())
{
proto
.
addFailProgressList
(
i
);
}
}
return
proto
.
build
();
}
}
src/main/java/emu/grasscutter/game/quest/QuestManager.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.game.quest
;
import
java.util.List
;
import
java.util.function.Consumer
;
import
java.util.function.Function
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.custom.QuestConfig
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.quest.enums.QuestState
;
import
emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketServerCondMeetQuestListUpdateNotify
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
public
class
QuestManager
{
private
final
Player
player
;
private
final
Int2ObjectMap
<
GameMainQuest
>
quests
;
public
QuestManager
(
Player
player
)
{
this
.
player
=
player
;
this
.
quests
=
new
Int2ObjectOpenHashMap
<>();
}
public
Player
getPlayer
()
{
return
player
;
}
public
Int2ObjectMap
<
GameMainQuest
>
getQuests
()
{
return
quests
;
}
public
GameMainQuest
getMainQuestById
(
int
mainQuestId
)
{
return
getQuests
().
get
(
mainQuestId
);
}
public
GameQuest
getQuestById
(
int
questId
)
{
QuestConfig
questConfig
=
GameData
.
getQuestConfigs
().
get
(
questId
);
if
(
questConfig
==
null
)
{
return
null
;
}
GameMainQuest
mainQuest
=
getQuests
().
get
(
questConfig
.
getMainQuest
().
getId
());
if
(
mainQuest
==
null
)
{
return
null
;
}
return
mainQuest
.
getChildQuests
().
get
(
questId
);
}
public
void
forEachQuest
(
Consumer
<
GameQuest
>
callback
)
{
for
(
GameMainQuest
mainQuest
:
getQuests
().
values
())
{
for
(
GameQuest
quest
:
mainQuest
.
getChildQuests
().
values
())
{
callback
.
accept
(
quest
);
}
}
}
public
GameMainQuest
addMainQuest
(
QuestConfig
questConfig
)
{
GameMainQuest
mainQuest
=
new
GameMainQuest
(
getPlayer
(),
questConfig
.
getMainQuest
().
getId
());
getQuests
().
put
(
mainQuest
.
getParentQuestId
(),
mainQuest
);
getPlayer
().
sendPacket
(
new
PacketFinishedParentQuestUpdateNotify
(
mainQuest
));
return
mainQuest
;
}
public
GameQuest
addQuest
(
int
questId
)
{
QuestConfig
questConfig
=
GameData
.
getQuestConfigs
().
get
(
questId
);
if
(
questConfig
==
null
)
{
return
null
;
}
// Main quest
GameMainQuest
mainQuest
=
this
.
getMainQuestById
(
questConfig
.
getMainQuest
().
getId
());
// Create main quest if it doesnt exist
if
(
mainQuest
==
null
)
{
mainQuest
=
addMainQuest
(
questConfig
);
}
// Sub quest
GameQuest
quest
=
mainQuest
.
getChildQuestById
(
questId
);
if
(
quest
!=
null
)
{
return
null
;
}
// Create
quest
=
new
GameQuest
(
mainQuest
,
questConfig
);
// Save main quest
mainQuest
.
save
();
// Send packet
getPlayer
().
sendPacket
(
new
PacketServerCondMeetQuestListUpdateNotify
(
quest
));
getPlayer
().
sendPacket
(
new
PacketQuestListUpdateNotify
(
quest
));
return
quest
;
}
public
void
loadFromDatabase
()
{
List
<
GameMainQuest
>
quests
=
DatabaseHelper
.
getAllQuests
(
getPlayer
());
for
(
GameMainQuest
mainQuest
:
quests
)
{
mainQuest
.
setOwner
(
this
.
getPlayer
());
for
(
GameQuest
quest
:
mainQuest
.
getChildQuests
().
values
())
{
quest
.
setMainQuest
(
mainQuest
);
quest
.
setConfig
(
GameData
.
getQuestConfigs
().
get
(
quest
.
getQuestId
()));
}
this
.
getQuests
().
put
(
mainQuest
.
getParentQuestId
(),
mainQuest
);
}
}
}
src/main/java/emu/grasscutter/game/quest/enums/LogicType.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.game.quest.enums
;
public
enum
LogicType
{
LOGIC_NONE
(
0
),
LOGIC_AND
(
1
),
LOGIC_OR
(
2
),
LOGIC_NOT
(
3
),
LOGIC_A_AND_ETCOR
(
4
),
LOGIC_A_AND_B_AND_ETCOR
(
5
),
LOGIC_A_OR_ETCAND
(
6
),
LOGIC_A_OR_B_OR_ETCAND
(
7
),
LOGIC_A_AND_B_OR_ETCAND
(
8
);
private
final
int
value
;
LogicType
(
int
id
)
{
this
.
value
=
id
;
}
public
int
getValue
()
{
return
value
;
}
}
src/main/java/emu/grasscutter/game/quest/enums/ParentQuestState.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.game.quest.enums
;
public
enum
ParentQuestState
{
PARENT_QUEST_STATE_NONE
(
0
),
PARENT_QUEST_STATE_FINISHED
(
1
),
PARENT_QUEST_STATE_FAILED
(
2
),
PARENT_QUEST_STATE_CANCELED
(
3
);
private
final
int
value
;
ParentQuestState
(
int
id
)
{
this
.
value
=
id
;
}
public
int
getValue
()
{
return
value
;
}
}
src/main/java/emu/grasscutter/game/quest/enums/QuestCondType.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.game.quest.enums
;
public
enum
QuestCondType
{
QUEST_COND_NONE
(
0
),
QUEST_COND_STATE_EQUAL
(
1
),
QUEST_COND_STATE_NOT_EQUAL
(
2
),
QUEST_COND_PACK_HAVE_ITEM
(
3
),
QUEST_COND_AVATAR_ELEMENT_EQUAL
(
4
),
QUEST_COND_AVATAR_ELEMENT_NOT_EQUAL
(
5
),
QUEST_COND_AVATAR_CAN_CHANGE_ELEMENT
(
6
),
QUEST_COND_CITY_LEVEL_EQUAL_GREATER
(
7
),
QUEST_COND_ITEM_NUM_LESS_THAN
(
8
),
QUEST_COND_DAILY_TASK_START
(
9
),
QUEST_COND_OPEN_STATE_EQUAL
(
10
),
QUEST_COND_DAILY_TASK_OPEN
(
11
),
QUEST_COND_DAILY_TASK_REWARD_CAN_GET
(
12
),
QUEST_COND_DAILY_TASK_REWARD_RECEIVED
(
13
),
QUEST_COND_PLAYER_LEVEL_REWARD_CAN_GET
(
14
),
QUEST_COND_EXPLORATION_REWARD_CAN_GET
(
15
),
QUEST_COND_IS_WORLD_OWNER
(
16
),
QUEST_COND_PLAYER_LEVEL_EQUAL_GREATER
(
17
),
QUEST_COND_SCENE_AREA_UNLOCKED
(
18
),
QUEST_COND_ITEM_GIVING_ACTIVED
(
19
),
QUEST_COND_ITEM_GIVING_FINISHED
(
20
),
QUEST_COND_IS_DAYTIME
(
21
),
QUEST_COND_CURRENT_AVATAR
(
22
),
QUEST_COND_CURRENT_AREA
(
23
),
QUEST_COND_QUEST_VAR_EQUAL
(
24
),
QUEST_COND_QUEST_VAR_GREATER
(
25
),
QUEST_COND_QUEST_VAR_LESS
(
26
),
QUEST_COND_FORGE_HAVE_FINISH
(
27
),
QUEST_COND_DAILY_TASK_IN_PROGRESS
(
28
),
QUEST_COND_DAILY_TASK_FINISHED
(
29
),
QUEST_COND_ACTIVITY_COND
(
30
),
QUEST_COND_ACTIVITY_OPEN
(
31
),
QUEST_COND_DAILY_TASK_VAR_GT
(
32
),
QUEST_COND_DAILY_TASK_VAR_EQ
(
33
),
QUEST_COND_DAILY_TASK_VAR_LT
(
34
),
QUEST_COND_BARGAIN_ITEM_GT
(
35
),
QUEST_COND_BARGAIN_ITEM_EQ
(
36
),
QUEST_COND_BARGAIN_ITEM_LT
(
37
),
QUEST_COND_COMPLETE_TALK
(
38
),
QUEST_COND_NOT_HAVE_BLOSSOM_TALK
(
39
),
QUEST_COND_IS_CUR_BLOSSOM_TALK
(
40
),
QUEST_COND_QUEST_NOT_RECEIVE
(
41
),
QUEST_COND_QUEST_SERVER_COND_VALID
(
42
),
QUEST_COND_ACTIVITY_CLIENT_COND
(
43
),
QUEST_COND_QUEST_GLOBAL_VAR_EQUAL
(
44
),
QUEST_COND_QUEST_GLOBAL_VAR_GREATER
(
45
),
QUEST_COND_QUEST_GLOBAL_VAR_LESS
(
46
),
QUEST_COND_PERSONAL_LINE_UNLOCK
(
47
),
QUEST_COND_CITY_REPUTATION_REQUEST
(
48
),
QUEST_COND_MAIN_COOP_START
(
49
),
QUEST_COND_MAIN_COOP_ENTER_SAVE_POINT
(
50
),
QUEST_COND_CITY_REPUTATION_LEVEL
(
51
),
QUEST_COND_CITY_REPUTATION_UNLOCK
(
52
),
QUEST_COND_LUA_NOTIFY
(
53
),
QUEST_COND_CUR_CLIMATE
(
54
),
QUEST_COND_ACTIVITY_END
(
55
),
QUEST_COND_COOP_POINT_RUNNING
(
56
),
QUEST_COND_GADGET_TALK_STATE_EQUAL
(
57
),
QUEST_COND_AVATAR_FETTER_GT
(
58
),
QUEST_COND_AVATAR_FETTER_EQ
(
59
),
QUEST_COND_AVATAR_FETTER_LT
(
60
),
QUEST_COND_NEW_HOMEWORLD_MOUDLE_UNLOCK
(
61
),
QUEST_COND_NEW_HOMEWORLD_LEVEL_REWARD
(
62
),
QUEST_COND_NEW_HOMEWORLD_MAKE_FINISH
(
63
),
QUEST_COND_HOMEWORLD_NPC_EVENT
(
64
),
QUEST_COND_TIME_VAR_GT_EQ
(
65
),
QUEST_COND_TIME_VAR_PASS_DAY
(
66
),
QUEST_COND_HOMEWORLD_NPC_NEW_TALK
(
67
),
QUEST_COND_PLAYER_CHOOSE_MALE
(
68
),
QUEST_COND_HISTORY_GOT_ANY_ITEM
(
69
),
QUEST_COND_LEARNED_RECIPE
(
70
),
QUEST_COND_LUNARITE_REGION_UNLOCKED
(
71
),
QUEST_COND_LUNARITE_HAS_REGION_HINT_COUNT
(
72
),
QUEST_COND_LUNARITE_COLLECT_FINISH
(
73
),
QUEST_COND_LUNARITE_MARK_ALL_FINISH
(
74
),
QUEST_COND_NEW_HOMEWORLD_SHOP_ITEM
(
75
),
QUEST_COND_SCENE_POINT_UNLOCK
(
76
),
QUEST_COND_SCENE_LEVEL_TAG_EQ
(
77
);
private
final
int
value
;
QuestCondType
(
int
id
)
{
this
.
value
=
id
;
}
public
int
getValue
()
{
return
value
;
}
}
src/main/java/emu/grasscutter/game/quest/enums/QuestExecType.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.game.quest.enums
;
public
enum
QuestExecType
{
QUEST_EXEC_NONE
(
0
),
QUEST_EXEC_DEL_PACK_ITEM
(
1
),
QUEST_EXEC_UNLOCK_POINT
(
2
),
QUEST_EXEC_UNLOCK_AREA
(
3
),
QUEST_EXEC_UNLOCK_FORCE
(
4
),
QUEST_EXEC_LOCK_FORCE
(
5
),
QUEST_EXEC_CHANGE_AVATAR_ELEMET
(
6
),
QUEST_EXEC_REFRESH_GROUP_MONSTER
(
7
),
QUEST_EXEC_SET_IS_FLYABLE
(
8
),
QUEST_EXEC_SET_IS_WEATHER_LOCKED
(
9
),
QUEST_EXEC_SET_IS_GAME_TIME_LOCKED
(
10
),
QUEST_EXEC_SET_IS_TRANSFERABLE
(
11
),
QUEST_EXEC_GRANT_TRIAL_AVATAR
(
12
),
QUEST_EXEC_OPEN_BORED
(
13
),
QUEST_EXEC_ROLLBACK_QUEST
(
14
),
QUEST_EXEC_NOTIFY_GROUP_LUA
(
15
),
QUEST_EXEC_SET_OPEN_STATE
(
16
),
QUEST_EXEC_LOCK_POINT
(
17
),
QUEST_EXEC_DEL_PACK_ITEM_BATCH
(
18
),
QUEST_EXEC_REFRESH_GROUP_SUITE
(
19
),
QUEST_EXEC_REMOVE_TRIAL_AVATAR
(
20
),
QUEST_EXEC_SET_GAME_TIME
(
21
),
QUEST_EXEC_SET_WEATHER_GADGET
(
22
),
QUEST_EXEC_ADD_QUEST_PROGRESS
(
23
),
QUEST_EXEC_NOTIFY_DAILY_TASK
(
24
),
QUEST_EXEC_CREATE_PATTERN_GROUP
(
25
),
QUEST_EXEC_REMOVE_PATTERN_GROUP
(
26
),
QUEST_EXEC_REFRESH_GROUP_SUITE_RANDOM
(
27
),
QUEST_EXEC_ACTIVE_ITEM_GIVING
(
28
),
QUEST_EXEC_DEL_ALL_SPECIFIC_PACK_ITEM
(
29
),
QUEST_EXEC_ROLLBACK_PARENT_QUEST
(
30
),
QUEST_EXEC_LOCK_AVATAR_TEAM
(
31
),
QUEST_EXEC_UNLOCK_AVATAR_TEAM
(
32
),
QUEST_EXEC_UPDATE_PARENT_QUEST_REWARD_INDEX
(
33
),
QUEST_EXEC_SET_DAILY_TASK_VAR
(
34
),
QUEST_EXEC_INC_DAILY_TASK_VAR
(
35
),
QUEST_EXEC_DEC_DAILY_TASK_VAR
(
36
),
QUEST_EXEC_ACTIVE_ACTIVITY_COND_STATE
(
37
),
QUEST_EXEC_INACTIVE_ACTIVITY_COND_STATE
(
38
),
QUEST_EXEC_ADD_CUR_AVATAR_ENERGY
(
39
),
QUEST_EXEC_START_BARGAIN
(
41
),
QUEST_EXEC_STOP_BARGAIN
(
42
),
QUEST_EXEC_SET_QUEST_GLOBAL_VAR
(
43
),
QUEST_EXEC_INC_QUEST_GLOBAL_VAR
(
44
),
QUEST_EXEC_DEC_QUEST_GLOBAL_VAR
(
45
),
QUEST_EXEC_REGISTER_DYNAMIC_GROUP
(
46
),
QUEST_EXEC_UNREGISTER_DYNAMIC_GROUP
(
47
),
QUEST_EXEC_SET_QUEST_VAR
(
48
),
QUEST_EXEC_INC_QUEST_VAR
(
49
),
QUEST_EXEC_DEC_QUEST_VAR
(
50
),
QUEST_EXEC_RANDOM_QUEST_VAR
(
51
),
QUEST_EXEC_ACTIVATE_SCANNING_PIC
(
52
),
QUEST_EXEC_RELOAD_SCENE_TAG
(
53
),
QUEST_EXEC_REGISTER_DYNAMIC_GROUP_ONLY
(
54
),
QUEST_EXEC_CHANGE_SKILL_DEPOT
(
55
),
QUEST_EXEC_ADD_SCENE_TAG
(
56
),
QUEST_EXEC_DEL_SCENE_TAG
(
57
),
QUEST_EXEC_INIT_TIME_VAR
(
58
),
QUEST_EXEC_CLEAR_TIME_VAR
(
59
),
QUEST_EXEC_MODIFY_CLIMATE_AREA
(
60
),
QUEST_EXEC_GRANT_TRIAL_AVATAR_AND_LOCK_TEAM
(
61
),
QUEST_EXEC_CHANGE_MAP_AREA_STATE
(
62
),
QUEST_EXEC_DEACTIVE_ITEM_GIVING
(
63
),
QUEST_EXEC_CHANGE_SCENE_LEVEL_TAG
(
64
),
QUEST_EXEC_UNLOCK_PLAYER_WORLD_SCENE
(
65
),
QUEST_EXEC_LOCK_PLAYER_WORLD_SCENE
(
66
),
QUEST_EXEC_FAIL_MAINCOOP
(
67
),
QUEST_EXEC_MODIFY_WEATHER_AREA
(
68
);
private
final
int
value
;
QuestExecType
(
int
id
)
{
this
.
value
=
id
;
}
public
int
getValue
()
{
return
value
;
}
}
src/main/java/emu/grasscutter/game/quest/enums/QuestGuideType.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.game.quest.enums
;
public
enum
QuestGuideType
{
QUEST_GUIDE_NONE
(
0
),
QUEST_GUIDE_LOCATION
(
1
),
QUEST_GUIDE_NPC
(
2
);
private
final
int
value
;
QuestGuideType
(
int
id
)
{
this
.
value
=
id
;
}
public
int
getValue
()
{
return
value
;
}
}
src/main/java/emu/grasscutter/game/quest/enums/QuestShowType.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.game.quest.enums
;
public
enum
QuestShowType
{
QUEST_SHOW
(
0
),
QUEST_HIDDEN
(
1
);
private
final
int
value
;
QuestShowType
(
int
id
)
{
this
.
value
=
id
;
}
public
int
getValue
()
{
return
value
;
}
}
src/main/java/emu/grasscutter/game/quest/enums/QuestState.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.game.quest.enums
;
public
enum
QuestState
{
QUEST_STATE_NONE
(
0
),
QUEST_STATE_UNSTARTED
(
1
),
QUEST_STATE_UNFINISHED
(
2
),
QUEST_STATE_FINISHED
(
3
),
QUEST_STATE_FAILED
(
4
);
private
final
int
value
;
QuestState
(
int
id
)
{
this
.
value
=
id
;
}
public
int
getValue
()
{
return
value
;
}
}
src/main/java/emu/grasscutter/game/quest/enums/QuestType.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.game.quest.enums
;
public
enum
QuestType
{
AQ
(
0
),
FQ
(
1
),
LQ
(
2
),
EQ
(
3
),
DQ
(
4
),
IQ
(
5
),
VQ
(
6
),
WQ
(
7
);
private
final
int
value
;
QuestType
(
int
id
)
{
this
.
value
=
id
;
}
public
int
getValue
()
{
return
value
;
}
}
src/main/java/emu/grasscutter/game/quest/enums/ShowQuestGuideType.java
0 → 100644
View file @
e9d7d5d5
package
emu.grasscutter.game.quest.enums
;
public
enum
ShowQuestGuideType
{
QUEST_GUIDE_ITEM_ENABLE
(
0
),
QUEST_GUIDE_ITEM_DISABLE
(
1
),
QUEST_GUIDE_ITEM_MOVE_HIDE
(
2
);
private
final
int
value
;
ShowQuestGuideType
(
int
id
)
{
this
.
value
=
id
;
}
public
int
getValue
()
{
return
value
;
}
}
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