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
5eb1d34b
Commit
5eb1d34b
authored
Jun 24, 2022
by
Melledy
Browse files
Implement battle pass triggers/rewards
parent
34f7c6e7
Changes
32
Hide whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/GameConstants.java
View file @
5eb1d34b
...
...
@@ -18,6 +18,10 @@ public final class GameConstants {
public
static
final
int
SERVER_CONSOLE_UID
=
99
;
// The UID of the server console's "player".
public
static
final
int
BATTLE_PASS_MAX_LEVEL
=
50
;
public
static
final
int
BATTLE_PASS_POINT_PER_LEVEL
=
1000
;
public
static
final
int
BATTLE_PASS_LEVEL_PRICE
=
150
;
// Default entity ability hashes.
public
static
final
String
[]
DEFAULT_ABILITY_STRINGS
=
{
"Avatar_DefaultAbility_VisionReplaceDieInvincible"
,
"Avatar_DefaultAbility_AvartarInShaderChange"
,
"Avatar_SprintBS_Invincible"
,
...
...
src/main/java/emu/grasscutter/command/commands/SetBPLevelCommand.java
View file @
5eb1d34b
...
...
@@ -17,7 +17,6 @@ public final class SetBPLevelCommand implements CommandHandler {
int
level
=
Integer
.
parseInt
(
args
.
get
(
0
));
sender
.
getBattlePassManager
().
addPoint
(
level
);
sender
.
getBattlePassManager
().
updateAwardTakenLevel
(
0
);
sender
.
getBattlePassManager
().
addPoints
(
level
);
}
}
src/main/java/emu/grasscutter/data/GameData.java
View file @
5eb1d34b
...
...
@@ -95,8 +95,8 @@ public class GameData {
private
static
final
Int2ObjectMap
<
InvestigationMonsterData
>
investigationMonsterDataMap
=
new
Int2ObjectOpenHashMap
<>();
private
static
final
Int2ObjectMap
<
CityData
>
cityDataMap
=
new
Int2ObjectOpenHashMap
<>();
private
static
final
Int2ObjectMap
<
WeatherData
>
weatherDataMap
=
new
Int2ObjectOpenHashMap
<>();
private
static
final
Int2ObjectMap
<
BattlePassMission
ExcelConfig
Data
>
battlePassMission
ExcelConfig
DataMap
=
new
Int2ObjectOpenHashMap
<>();
private
static
final
Int2ObjectMap
<
BattlePassReward
ExcelConfig
Data
>
battlePassReward
ExcelConfig
DataMap
=
new
Int2ObjectOpenHashMap
<>();
private
static
final
Int2ObjectMap
<
BattlePassMissionData
>
battlePassMissionDataMap
=
new
Int2ObjectOpenHashMap
<>();
private
static
final
Int2ObjectMap
<
BattlePassRewardData
>
battlePassRewardDataMap
=
new
Int2ObjectOpenHashMap
<>();
// Cache
private
static
Map
<
Integer
,
List
<
Integer
>>
fetters
=
new
HashMap
<>();
...
...
@@ -424,11 +424,11 @@ public class GameData {
return
weatherDataMap
;
}
public
static
Int2ObjectMap
<
BattlePassMission
ExcelConfig
Data
>
getBattlePassMission
ExcelConfig
DataMap
()
{
return
battlePassMission
ExcelConfig
DataMap
;
public
static
Int2ObjectMap
<
BattlePassMissionData
>
getBattlePassMissionDataMap
()
{
return
battlePassMissionDataMap
;
}
public
static
Int2ObjectMap
<
BattlePassReward
ExcelConfig
Data
>
getBattlePassReward
ExcelConfig
DataMap
()
{
return
battlePassReward
ExcelConfig
DataMap
;
public
static
Int2ObjectMap
<
BattlePassRewardData
>
getBattlePassRewardDataMap
()
{
return
battlePassRewardDataMap
;
}
}
src/main/java/emu/grasscutter/data/excels/BattlePassMissionData.java
0 → 100644
View file @
5eb1d34b
package
emu.grasscutter.data.excels
;
import
java.util.Arrays
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
emu.grasscutter.data.GameResource
;
import
emu.grasscutter.data.ResourceType
;
import
emu.grasscutter.game.props.BattlePassMissionRefreshType
;
import
emu.grasscutter.game.props.WatcherTriggerType
;
import
emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission.MissionStatus
;
import
lombok.AccessLevel
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.experimental.FieldDefaults
;
@ResourceType
(
name
=
{
"BattlePassMissionExcelConfigData.json"
})
@Getter
public
class
BattlePassMissionData
extends
GameResource
{
private
int
addPoint
;
private
int
id
;
private
int
scheduleId
;
private
int
progress
;
private
TriggerConfig
triggerConfig
;
private
BattlePassMissionRefreshType
refreshType
;
private
transient
Set
<
Integer
>
mainParams
;
@Override
public
int
getId
()
{
return
this
.
id
;
}
public
WatcherTriggerType
getTriggerType
()
{
return
this
.
getTriggerConfig
().
getTriggerType
();
}
public
boolean
isValidRefreshType
()
{
return
getRefreshType
()
==
null
||
getRefreshType
()
==
BattlePassMissionRefreshType
.
BATTLE_PASS_MISSION_REFRESH_CYCLE_CROSS_SCHEDULE
||
getScheduleId
()
==
2701
;
}
@Override
public
void
onLoad
()
{
if
(
this
.
getTriggerConfig
()
!=
null
&&
getTriggerConfig
().
getParamList
()[
0
].
length
()
>
0
)
{
this
.
mainParams
=
Arrays
.
stream
(
getTriggerConfig
().
getParamList
()[
0
].
split
(
"[:;,]"
)).
map
(
Integer:
:
parseInt
).
collect
(
Collectors
.
toSet
());
}
}
@Getter
public
static
class
TriggerConfig
{
private
WatcherTriggerType
triggerType
;
private
String
[]
paramList
;
}
public
emu
.
grasscutter
.
net
.
proto
.
BattlePassMissionOuterClass
.
BattlePassMission
toProto
()
{
var
protoBuilder
=
emu
.
grasscutter
.
net
.
proto
.
BattlePassMissionOuterClass
.
BattlePassMission
.
newBuilder
();
protoBuilder
.
setMissionId
(
getId
())
.
setTotalProgress
(
this
.
getProgress
())
.
setRewardBattlePassPoint
(
this
.
getAddPoint
())
.
setMissionStatus
(
MissionStatus
.
MISSION_STATUS_UNFINISHED
)
.
setMissionType
(
this
.
getRefreshType
()
==
null
?
0
:
this
.
getRefreshType
().
getValue
());
return
protoBuilder
.
build
();
}
}
src/main/java/emu/grasscutter/data/excels/BattlePassMissionExcelConfigData.java
deleted
100644 → 0
View file @
34f7c6e7
package
emu.grasscutter.data.excels
;
import
emu.grasscutter.data.GameResource
;
import
emu.grasscutter.data.ResourceType
;
import
lombok.AccessLevel
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.experimental.FieldDefaults
;
@ResourceType
(
name
=
{
"BattlePassMissionExcelConfigData.json"
})
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
@Getter
@Setter
public
class
BattlePassMissionExcelConfigData
extends
GameResource
{
private
int
addPoint
;
private
int
id
;
private
int
progress
;
private
String
refreshType
;
@Override
public
void
onLoad
()
{
}
@Override
public
int
getId
()
{
return
this
.
id
;
}
}
src/main/java/emu/grasscutter/data/excels/BattlePassReward
ExcelConfig
Data.java
→
src/main/java/emu/grasscutter/data/excels/BattlePassRewardData.java
View file @
5eb1d34b
...
...
@@ -9,8 +9,7 @@ import java.util.List;
@ResourceType
(
name
=
"BattlePassRewardExcelConfigData.json"
)
@Getter
@Setter
public
class
BattlePassRewardExcelConfigData
extends
GameResource
{
public
class
BattlePassRewardData
extends
GameResource
{
private
int
indexId
;
private
int
level
;
private
List
<
Integer
>
freeRewardIdList
;
...
...
@@ -23,5 +22,6 @@ public class BattlePassRewardExcelConfigData extends GameResource {
@Override
public
void
onLoad
()
{
}
}
src/main/java/emu/grasscutter/database/DatabaseHelper.java
View file @
5eb1d34b
...
...
@@ -131,6 +131,7 @@ public final class DatabaseHelper {
DatabaseManager
.
getGameDatabase
().
getCollection
(
"gachas"
).
deleteMany
(
eq
(
"ownerId"
,
player
.
getUid
()));
DatabaseManager
.
getGameDatabase
().
getCollection
(
"items"
).
deleteMany
(
eq
(
"ownerId"
,
player
.
getUid
()));
DatabaseManager
.
getGameDatabase
().
getCollection
(
"quests"
).
deleteMany
(
eq
(
"ownerUid"
,
player
.
getUid
()));
DatabaseManager
.
getGameDatabase
().
getCollection
(
"battlepass"
).
deleteMany
(
eq
(
"ownerUid"
,
player
.
getUid
()));
// Delete friendships.
// Here, we need to make sure to not only delete the deleted account's friendships,
...
...
src/main/java/emu/grasscutter/game/battlepass/BattlePassManager.java
View file @
5eb1d34b
package
emu.grasscutter.game.battlepass
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
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.GameConstants
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.common.ItemParamData
;
import
emu.grasscutter.data.excels.BattlePassRewardData
;
import
emu.grasscutter.data.excels.RewardData
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.props.BattlePassMissionStatus
;
import
emu.grasscutter.game.props.WatcherTriggerType
;
import
emu.grasscutter.net.proto.BattlePassCycleOuterClass.BattlePassCycle
;
import
emu.grasscutter.net.proto.BattlePassRewardTagOuterClass.BattlePassRewardTag
;
import
emu.grasscutter.net.proto.BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus
;
import
emu.grasscutter.net.proto.BattlePassRewardTakeOptionOuterClass.BattlePassRewardTakeOption
;
import
emu.grasscutter.net.proto.BattlePassScheduleOuterClass.BattlePassSchedule
;
import
emu.grasscutter.server.packet.send.PacketBattlePassCurScheduleUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketBattlePassMissionUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketTakeBattlePassRewardRsp
;
@Entity
(
value
=
"battlepass"
,
useDiscriminator
=
false
)
public
class
BattlePassManager
{
...
...
@@ -17,7 +37,13 @@ public class BattlePassManager {
@Indexed
private
int
ownerUid
;
private
int
point
;
private
int
awardTakenLevel
;
private
int
level
;
private
boolean
viewed
;
private
boolean
paid
;
private
Map
<
Integer
,
BattlePassMission
>
missions
;
private
Map
<
Integer
,
BattlePassReward
>
takenRewards
;
@Deprecated
// Morphia only
public
BattlePassManager
()
{}
...
...
@@ -40,25 +66,215 @@ public class BattlePassManager {
}
public
int
getPoint
()
{
return
point
;
return
this
.
point
;
}
public
int
getLevel
()
{
return
this
.
level
;
}
public
int
getAwardTakenLevel
()
{
return
awardTakenLevel
;
public
boolean
isViewed
()
{
return
viewed
;
}
public
void
updateViewed
()
{
this
.
viewed
=
true
;
}
public
void
addPoint
(
int
point
){
this
.
point
+=
point
;
public
boolean
isPaid
()
{
return
paid
;
}
public
void
addPoints
(
int
point
){
this
.
addPointsDirectly
(
point
);
player
.
getSession
().
send
(
new
PacketBattlePassCurScheduleUpdateNotify
(
player
.
getSession
().
getPlayer
()));
this
.
save
();
}
public
void
updateAwardTakenLevel
(
int
level
){
this
.
awardTakenLevel
=
level
;
player
.
getSession
().
send
(
new
PacketBattlePassCurScheduleUpdateNotify
(
player
.
getSession
().
getPlayer
()));
this
.
save
();
public
void
addPointsDirectly
(
int
point
)
{
this
.
point
+=
point
;
if
(
this
.
point
>=
GameConstants
.
BATTLE_PASS_POINT_PER_LEVEL
&&
this
.
getLevel
()
<
GameConstants
.
BATTLE_PASS_MAX_LEVEL
)
{
int
levelups
=
(
int
)
Math
.
floor
((
float
)
this
.
point
/
GameConstants
.
BATTLE_PASS_POINT_PER_LEVEL
);
// Make sure player cant go above max BP level
levelups
=
Math
.
min
(
levelups
,
GameConstants
.
BATTLE_PASS_MAX_LEVEL
-
levelups
);
// Set new points after level up
this
.
point
=
this
.
point
-
(
levelups
*
GameConstants
.
BATTLE_PASS_POINT_PER_LEVEL
);
this
.
level
+=
levelups
;
}
}
public
Map
<
Integer
,
BattlePassMission
>
getMissions
()
{
if
(
this
.
missions
==
null
)
this
.
missions
=
new
HashMap
<>();
return
this
.
missions
;
}
// Will return a new empty mission if the mission id is not found
public
BattlePassMission
loadMissionById
(
int
id
)
{
return
getMissions
().
computeIfAbsent
(
id
,
i
->
new
BattlePassMission
(
i
));
}
public
boolean
hasMission
(
int
id
)
{
return
getMissions
().
containsKey
(
id
);
}
public
Map
<
Integer
,
BattlePassReward
>
getTakenRewards
()
{
if
(
this
.
takenRewards
==
null
)
this
.
takenRewards
=
new
HashMap
<>();
return
this
.
takenRewards
;
}
// Mission triggers
public
void
triggerMission
(
WatcherTriggerType
triggerType
)
{
getPlayer
().
getServer
().
getBattlePassMissionManager
().
triggerMission
(
getPlayer
(),
triggerType
);
}
public
void
triggerMission
(
WatcherTriggerType
triggerType
,
int
param
,
int
progress
)
{
getPlayer
().
getServer
().
getBattlePassMissionManager
().
triggerMission
(
getPlayer
(),
triggerType
,
param
,
progress
);
}
// Handlers
public
void
takeMissionPoint
(
List
<
Integer
>
missionIdList
)
{
// Obvious exploit check
if
(
missionIdList
.
size
()
>
GameData
.
getBattlePassMissionDataMap
().
size
())
{
return
;
}
List
<
BattlePassMission
>
updatedMissions
=
new
ArrayList
<>(
missionIdList
.
size
());
for
(
int
id
:
missionIdList
)
{
// Skip if we dont have this mission
if
(!
this
.
hasMission
(
id
))
{
continue
;
}
BattlePassMission
mission
=
this
.
loadMissionById
(
id
);
if
(
mission
.
getData
()
==
null
)
{
this
.
getMissions
().
remove
(
mission
.
getId
());
continue
;
}
// Take reward
if
(
mission
.
getStatus
()
==
BattlePassMissionStatus
.
MISSION_STATUS_FINISHED
)
{
this
.
addPointsDirectly
(
mission
.
getData
().
getAddPoint
());
mission
.
setStatus
(
BattlePassMissionStatus
.
MISSION_STATUS_POINT_TAKEN
);
updatedMissions
.
add
(
mission
);
}
}
if
(
updatedMissions
.
size
()
>
0
)
{
// Save to db
this
.
save
();
// Packet
getPlayer
().
sendPacket
(
new
PacketBattlePassMissionUpdateNotify
(
updatedMissions
));
getPlayer
().
sendPacket
(
new
PacketBattlePassCurScheduleUpdateNotify
(
getPlayer
()));
}
}
public
void
takeReward
(
List
<
BattlePassRewardTakeOption
>
takeOptionList
)
{
List
<
BattlePassRewardTag
>
rewardList
=
new
ArrayList
<>();
for
(
BattlePassRewardTakeOption
option
:
takeOptionList
)
{
// Duplicate check
if
(
option
.
getTag
().
getRewardId
()
==
0
||
getTakenRewards
().
containsKey
(
option
.
getTag
().
getRewardId
()))
{
continue
;
}
// Level check
if
(
option
.
getTag
().
getLevel
()
>
this
.
getLevel
())
{
continue
;
}
BattlePassRewardData
rewardData
=
GameData
.
getBattlePassRewardDataMap
().
get
(
option
.
getTag
().
getLevel
());
// Sanity check with excel data
if
(
rewardData
.
getFreeRewardIdList
().
contains
(
option
.
getTag
().
getRewardId
()))
{
rewardList
.
add
(
option
.
getTag
());
}
else
if
(
this
.
isPaid
()
&&
rewardData
.
getPaidRewardIdList
().
contains
(
option
.
getTag
().
getRewardId
()))
{
rewardList
.
add
(
option
.
getTag
());
}
}
// Get rewards
List
<
ItemParamData
>
rewardItems
=
null
;
if
(
rewardList
.
size
()
>
0
)
{
rewardItems
=
new
ArrayList
<>();
for
(
BattlePassRewardTag
tag
:
rewardList
)
{
RewardData
reward
=
GameData
.
getRewardDataMap
().
get
(
tag
.
getRewardId
());
if
(
reward
==
null
)
continue
;
BattlePassReward
bpReward
=
new
BattlePassReward
(
tag
.
getLevel
(),
tag
.
getRewardId
(),
tag
.
getUnlockStatus
()
==
BattlePassUnlockStatus
.
BATTLE_PASS_UNLOCK_STATUS_PAID
);
this
.
getTakenRewards
().
put
(
bpReward
.
getRewardId
(),
bpReward
);
rewardItems
.
addAll
(
reward
.
getRewardItemList
());
}
// Save to db
this
.
save
();
// Add items and send battle pass schedule packet
getPlayer
().
getInventory
().
addItemParamDatas
(
rewardItems
);
getPlayer
().
sendPacket
(
new
PacketBattlePassCurScheduleUpdateNotify
(
getPlayer
()));
}
getPlayer
().
sendPacket
(
new
PacketTakeBattlePassRewardRsp
(
takeOptionList
,
rewardItems
));
}
public
int
buyLevels
(
int
buyLevel
)
{
int
boughtLevels
=
Math
.
min
(
buyLevel
,
GameConstants
.
BATTLE_PASS_MAX_LEVEL
-
buyLevel
);
if
(
boughtLevels
>
0
)
{
int
price
=
GameConstants
.
BATTLE_PASS_LEVEL_PRICE
*
boughtLevels
;
if
(
getPlayer
().
getPrimogems
()
<
price
)
{
return
0
;
}
this
.
level
+=
boughtLevels
;
this
.
save
();
getPlayer
().
sendPacket
(
new
PacketBattlePassCurScheduleUpdateNotify
(
getPlayer
()));
}
return
boughtLevels
;
}
public
void
resetDailyMissions
()
{
// TODO
}
public
void
resetWeeklyMissions
()
{
// TODO
}
//
public
BattlePassSchedule
getScheduleProto
()
{
BattlePassSchedule
.
Builder
schedule
=
BattlePassSchedule
.
newBuilder
()
.
setScheduleId
(
2700
)
.
setLevel
(
this
.
getLevel
())
.
setPoint
(
this
.
getPoint
())
.
setBeginTime
(
0
)
.
setEndTime
(
2059483200
)
.
setIsViewed
(
this
.
isViewed
())
.
setUnlockStatus
(
this
.
isPaid
()
?
BattlePassUnlockStatus
.
BATTLE_PASS_UNLOCK_STATUS_PAID
:
BattlePassUnlockStatus
.
BATTLE_PASS_UNLOCK_STATUS_FREE
)
.
setCurCyclePoints
(
0
)
.
setCurCycle
(
BattlePassCycle
.
newBuilder
().
setBeginTime
(
0
).
setEndTime
(
2059483200
).
setCycleIdx
(
3
));
for
(
BattlePassReward
reward
:
getTakenRewards
().
values
())
{
schedule
.
addRewardTakenList
(
reward
.
toProto
());
}
return
schedule
.
build
();
}
public
void
save
()
{
DatabaseHelper
.
saveBattlePass
(
this
);
}
...
...
src/main/java/emu/grasscutter/game/battlepass/BattlePassMission.java
0 → 100644
View file @
5eb1d34b
package
emu.grasscutter.game.battlepass
;
import
dev.morphia.annotations.Entity
;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.excels.BattlePassMissionData
;
import
emu.grasscutter.game.props.BattlePassMissionStatus
;
@Entity
public
class
BattlePassMission
{
private
int
id
;
private
int
progress
;
private
BattlePassMissionStatus
status
;
@Transient
private
BattlePassMissionData
data
;
@Deprecated
// Morphia only
public
BattlePassMission
()
{}
public
BattlePassMission
(
int
id
)
{
this
.
id
=
id
;
}
public
int
getId
()
{
return
id
;
}
public
BattlePassMissionData
getData
()
{
if
(
this
.
data
==
null
)
{
this
.
data
=
GameData
.
getBattlePassMissionDataMap
().
get
(
getId
());
}
return
this
.
data
;
}
public
int
getProgress
()
{
return
progress
;
}
public
void
addProgress
(
int
addProgress
,
int
maxProgress
)
{
this
.
progress
=
Math
.
min
(
addProgress
+
this
.
progress
,
maxProgress
);
}
public
BattlePassMissionStatus
getStatus
()
{
if
(
status
==
null
)
status
=
BattlePassMissionStatus
.
MISSION_STATUS_UNFINISHED
;
return
status
;
}
public
void
setStatus
(
BattlePassMissionStatus
status
)
{
this
.
status
=
status
;
}
public
boolean
isFinshed
()
{
return
getStatus
().
getValue
()
>=
2
;
}
public
emu
.
grasscutter
.
net
.
proto
.
BattlePassMissionOuterClass
.
BattlePassMission
toProto
()
{
var
protoBuilder
=
emu
.
grasscutter
.
net
.
proto
.
BattlePassMissionOuterClass
.
BattlePassMission
.
newBuilder
();
protoBuilder
.
setMissionId
(
getId
())
.
setCurProgress
(
getProgress
())
.
setTotalProgress
(
getData
().
getProgress
())
.
setRewardBattlePassPoint
(
getData
().
getAddPoint
())
.
setMissionStatus
(
getStatus
().
getMissionStatus
())
.
setMissionType
(
getData
().
getRefreshType
()
==
null
?
0
:
getData
().
getRefreshType
().
getValue
());
return
protoBuilder
.
build
();
}
}
src/main/java/emu/grasscutter/game/battlepass/BattlePassMissionManager.java
0 → 100644
View file @
5eb1d34b
package
emu.grasscutter.game.battlepass
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.excels.BattlePassMissionData
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.BattlePassMissionRefreshType
;
import
emu.grasscutter.game.props.BattlePassMissionStatus
;
import
emu.grasscutter.game.props.WatcherTriggerType
;
import
emu.grasscutter.server.game.GameServer
;
import
emu.grasscutter.server.packet.send.PacketBattlePassMissionUpdateNotify
;
public
class
BattlePassMissionManager
{
private
final
GameServer
server
;
private
final
Map
<
WatcherTriggerType
,
List
<
BattlePassMissionData
>>
cachedTriggers
;
// BP Mission manager for the server, contains cached triggers so we dont have to load it for each player
public
BattlePassMissionManager
(
GameServer
server
)
{
this
.
server
=
server
;
this
.
cachedTriggers
=
new
HashMap
<>();
for
(
BattlePassMissionData
missionData
:
GameData
.
getBattlePassMissionDataMap
().
values
())
{
if
(
missionData
.
isValidRefreshType
())
{
List
<
BattlePassMissionData
>
triggerList
=
getTriggers
().
computeIfAbsent
(
missionData
.
getTriggerType
(),
e
->
new
ArrayList
<>());
triggerList
.
add
(
missionData
);
}
}
}
public
GameServer
getServer
()
{
return
server
;
}
private
Map
<
WatcherTriggerType
,
List
<
BattlePassMissionData
>>
getTriggers
()
{
return
cachedTriggers
;
}
public
void
triggerMission
(
Player
player
,
WatcherTriggerType
triggerType
)
{
triggerMission
(
player
,
triggerType
,
0
,
1
);
}
public
void
triggerMission
(
Player
player
,
WatcherTriggerType
triggerType
,
int
param
,
int
progress
)
{
List
<
BattlePassMissionData
>
triggerList
=
getTriggers
().
get
(
triggerType
);
if
(
triggerList
==
null
||
triggerList
.
isEmpty
())
return
;
for
(
BattlePassMissionData
data
:
triggerList
)
{
// Skip params check if param == 0
if
(
param
!=
0
)
{
if
(!
data
.
getMainParams
().
contains
(
param
))
{
continue
;
}
}
// Get mission from player, if it doesnt exist, then we make one
BattlePassMission
mission
=
player
.
getBattlePassManager
().
loadMissionById
(
data
.
getId
());
if
(
mission
.
isFinshed
())
continue
;
// Add progress
mission
.
addProgress
(
progress
,
data
.
getProgress
());
if
(
mission
.
getProgress
()
>=
data
.
getProgress
())
{
mission
.
setStatus
(
BattlePassMissionStatus
.
MISSION_STATUS_FINISHED
);
}
// Save to db
player
.
getBattlePassManager
().
save
();
// Packet
player
.
sendPacket
(
new
PacketBattlePassMissionUpdateNotify
(
mission
));
}
}
}
src/main/java/emu/grasscutter/game/battlepass/BattlePassReward.java
0 → 100644
View file @
5eb1d34b
package
emu.grasscutter.game.battlepass
;
import
dev.morphia.annotations.Entity
;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.excels.BattlePassMissionData
;
import
emu.grasscutter.data.excels.BattlePassRewardData
;
import
emu.grasscutter.game.props.BattlePassMissionStatus
;
import
emu.grasscutter.net.proto.BattlePassRewardTagOuterClass.BattlePassRewardTag
;
import
emu.grasscutter.net.proto.BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus
;
@Entity
public
class
BattlePassReward
{
private
int
level
;
private
int
rewardId
;
private
boolean
paid
;
@Transient
private
BattlePassMissionData
data
;
@Deprecated
// Morphia only
public
BattlePassReward
()
{}
public
BattlePassReward
(
int
level
,
int
rewardId
,
boolean
paid
)
{
this
.
level
=
level
;
this
.
rewardId
=
rewardId
;
this
.
paid
=
paid
;
}
public
int
getLevel
()
{
return
level
;
}
public
int
getRewardId
()
{
return
rewardId
;
}
public
boolean
isPaid
()
{
return
paid
;
}
public
BattlePassRewardTag
toProto
()
{
var
protoBuilder
=
BattlePassRewardTag
.
newBuilder
();
protoBuilder
.
setLevel
(
this
.
getLevel
())
.
setRewardId
(
this
.
getRewardId
())
.
setUnlockStatus
(
this
.
isPaid
()
?
BattlePassUnlockStatus
.
BATTLE_PASS_UNLOCK_STATUS_PAID
:
BattlePassUnlockStatus
.
BATTLE_PASS_UNLOCK_STATUS_FREE
);
return
protoBuilder
.
build
();
}
}
src/main/java/emu/grasscutter/game/dungeons/challenge/DungeonChallenge.java
View file @
5eb1d34b
...
...
@@ -11,6 +11,7 @@ import emu.grasscutter.game.inventory.GameItem;
import
emu.grasscutter.game.inventory.ItemType
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.props.WatcherTriggerType
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq
;
import
emu.grasscutter.scripts.constants.EventType
;
...
...
@@ -98,6 +99,8 @@ public class DungeonChallenge extends WorldChallenge {
getScene
().
getDungeonSettleObservers
().
forEach
(
o
->
o
.
onDungeonSettle
(
getScene
()));
getScene
().
getScriptManager
().
callEvent
(
EventType
.
EVENT_DUNGEON_SETTLE
,
new
ScriptArgs
(
this
.
isSuccess
()
?
1
:
0
));
// Battle pass trigger
this
.
getScene
().
getPlayers
().
forEach
(
p
->
p
.
getBattlePassManager
().
triggerMission
(
WatcherTriggerType
.
TRIGGER_FINISH_DUNGEON
));
}
}
...
...
src/main/java/emu/grasscutter/game/entity/EntityMonster.java
View file @
5eb1d34b
...
...
@@ -8,6 +8,7 @@ import emu.grasscutter.game.player.Player;
import
emu.grasscutter.game.props.EntityIdType
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.props.WatcherTriggerType
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo
;
import
emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair
;
...
...
@@ -154,6 +155,8 @@ public class EntityMonster extends GameEntity {
getScene
().
getScriptManager
().
callEvent
(
EventType
.
EVENT_ANY_MONSTER_DIE
,
new
ScriptArgs
().
setParam1
(
this
.
getConfigId
()));
}
}
// Battle Pass trigger
getScene
().
getPlayers
().
forEach
(
p
->
p
.
getBattlePassManager
().
triggerMission
(
WatcherTriggerType
.
TRIGGER_MONSTER_DIE
,
this
.
getMonsterId
(),
1
));
}
public
void
recalcStats
()
{
...
...
src/main/java/emu/grasscutter/game/gacha/GachaManager.java
View file @
5eb1d34b
...
...
@@ -27,6 +27,7 @@ import emu.grasscutter.game.inventory.Inventory;
import
emu.grasscutter.game.inventory.ItemType
;
import
emu.grasscutter.game.inventory.MaterialType
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.WatcherTriggerType
;
import
emu.grasscutter.net.proto.GachaItemOuterClass.GachaItem
;
import
emu.grasscutter.net.proto.GachaTransferItemOuterClass.GachaTransferItem
;
import
emu.grasscutter.net.proto.GetGachaInfoRspOuterClass.GetGachaInfoRsp
;
...
...
@@ -372,9 +373,12 @@ public class GachaManager {
if
(
starglitter
>
0
)
{
inventory
.
addItem
(
starglitterId
,
starglitter
);
}
// Packets
player
.
sendPacket
(
new
PacketDoGachaRsp
(
banner
,
list
,
gachaInfo
));
// Battle Pass trigger
player
.
getBattlePassManager
().
triggerMission
(
WatcherTriggerType
.
TRIGGER_GACHA_NUM
,
0
,
times
);
}
private
synchronized
void
startWatcher
(
GameServer
server
)
{
...
...
src/main/java/emu/grasscutter/game/inventory/Inventory.java
View file @
5eb1d34b
...
...
@@ -18,6 +18,7 @@ import emu.grasscutter.game.avatar.Avatar;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.props.WatcherTriggerType
;
import
emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam
;
import
emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketItemAddHintNotify
;
...
...
@@ -95,6 +96,7 @@ public class Inventory implements Iterable<GameItem> {
GameItem
result
=
putItem
(
item
);
if
(
result
!=
null
)
{
getPlayer
().
getBattlePassManager
().
triggerMission
(
WatcherTriggerType
.
TRIGGER_OBTAIN_MATERIAL_NUM
,
result
.
getItemId
(),
result
.
getCount
());
getPlayer
().
sendPacket
(
new
PacketStoreItemChangeNotify
(
result
));
return
true
;
}
...
...
@@ -131,7 +133,9 @@ public class Inventory implements Iterable<GameItem> {
for
(
GameItem
item
:
items
)
{
GameItem
result
=
putItem
(
item
);
if
(
result
!=
null
)
{
getPlayer
().
getBattlePassManager
().
triggerMission
(
WatcherTriggerType
.
TRIGGER_OBTAIN_MATERIAL_NUM
,
result
.
getItemId
(),
result
.
getCount
());
changedItems
.
add
(
result
);
}
}
...
...
@@ -368,7 +372,7 @@ public class Inventory implements Iterable<GameItem> {
if
(
count
<=
0
||
item
==
null
)
{
return
false
;
}
if
(
item
.
getItemData
().
isEquip
())
{
item
.
setCount
(
0
);
}
else
{
...
...
@@ -389,6 +393,10 @@ public class Inventory implements Iterable<GameItem> {
getPlayer
().
sendPacket
(
new
PacketStoreItemChangeNotify
(
item
));
}
// Battle pass trigger
int
removeCount
=
Math
.
min
(
count
,
item
.
getCount
());
getPlayer
().
getBattlePassManager
().
triggerMission
(
WatcherTriggerType
.
TRIGGER_COST_MATERIAL
,
item
.
getItemId
(),
removeCount
);
// Update in db
item
.
save
();
...
...
src/main/java/emu/grasscutter/game/managers/ResinManager.java
View file @
5eb1d34b
...
...
@@ -2,6 +2,7 @@ package emu.grasscutter.game.managers;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.props.WatcherTriggerType
;
import
emu.grasscutter.server.packet.send.PacketPlayerPropNotify
;
import
emu.grasscutter.server.packet.send.PacketResinChangeNotify
;
import
emu.grasscutter.utils.Utils
;
...
...
@@ -45,7 +46,10 @@ public class ResinManager {
// Send packets.
this
.
player
.
sendPacket
(
new
PacketPlayerPropNotify
(
this
.
player
,
PlayerProperty
.
PROP_PLAYER_RESIN
));
this
.
player
.
sendPacket
(
new
PacketResinChangeNotify
(
this
.
player
));
// Battle Pass trigger
this
.
player
.
getBattlePassManager
().
triggerMission
(
WatcherTriggerType
.
TRIGGER_COST_MATERIAL
,
106
,
amount
);
// Resin item id = 106
return
true
;
}
...
...
src/main/java/emu/grasscutter/game/managers/forging/ForgingManager.java
View file @
5eb1d34b
...
...
@@ -16,6 +16,7 @@ import emu.grasscutter.game.inventory.GameItem;
import
emu.grasscutter.game.inventory.ItemType
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.props.WatcherTriggerType
;
import
emu.grasscutter.net.proto.ForgeStartReqOuterClass
;
import
emu.grasscutter.net.proto.ForgeQueueDataOuterClass.ForgeQueueData
;
import
emu.grasscutter.net.proto.ForgeQueueManipulateReqOuterClass.ForgeQueueManipulateReq
;
...
...
@@ -195,6 +196,9 @@ public class ForgingManager {
GameItem
addItem
=
new
GameItem
(
resultItemData
,
data
.
getResultItemCount
()
*
finished
);
this
.
player
.
getInventory
().
addItem
(
addItem
);
// Battle pass trigger handler
this
.
player
.
getBattlePassManager
().
triggerMission
(
WatcherTriggerType
.
TRIGGER_DO_FORGE
,
0
,
finished
);
// Replace active forge with a new one for the unfinished items, if there are any.
if
(
unfinished
>
0
)
{
...
...
src/main/java/emu/grasscutter/game/player/Player.java
View file @
5eb1d34b
...
...
@@ -42,6 +42,7 @@ import emu.grasscutter.game.props.ActionReason;
import
emu.grasscutter.game.props.ClimateType
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.props.SceneType
;
import
emu.grasscutter.game.props.WatcherTriggerType
;
import
emu.grasscutter.game.quest.QuestManager
;
import
emu.grasscutter.game.shop.ShopLimit
;
import
emu.grasscutter.game.tower.TowerData
;
...
...
@@ -1268,6 +1269,7 @@ public class Player {
public
void
loadBattlePassManager
()
{
if
(
this
.
battlePassManager
!=
null
)
return
;
this
.
battlePassManager
=
DatabaseHelper
.
loadBattlePass
(
this
);
this
.
battlePassManager
.
getMissions
().
values
().
removeIf
(
mission
->
mission
.
getData
()
==
null
);
}
public
AbilityManager
getAbilityManager
()
{
...
...
@@ -1425,6 +1427,9 @@ public class Player {
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.
// Battle Pass trigger
this
.
getBattlePassManager
().
triggerMission
(
WatcherTriggerType
.
TRIGGER_LOGIN
);
this
.
furnitureManager
.
onLogin
();
// Home
home
=
GameHome
.
getByUid
(
getUid
());
...
...
src/main/java/emu/grasscutter/game/props/BattlePassMissionRefreshType.java
0 → 100644
View file @
5eb1d34b
package
emu.grasscutter.game.props
;
public
enum
BattlePassMissionRefreshType
{
BATTLE_PASS_MISSION_REFRESH_DAILY
(
0
),
BATTLE_PASS_MISSION_REFRESH_CYCLE_CROSS_SCHEDULE
(
1
),
// Weekly
BATTLE_PASS_MISSION_REFRESH_SCHEDULE
(
2
),
// Per BP
BATTLE_PASS_MISSION_REFRESH_CYCLE
(
1
);
// Event?
private
final
int
value
;
BattlePassMissionRefreshType
(
int
value
)
{
this
.
value
=
value
;
}
public
int
getValue
()
{
return
value
;
}
}
src/main/java/emu/grasscutter/game/props/BattlePassMissionStatus.java
0 → 100644
View file @
5eb1d34b
package
emu.grasscutter.game.props
;
import
emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission.MissionStatus
;
public
enum
BattlePassMissionStatus
{
MISSION_STATUS_INVALID
(
0
,
MissionStatus
.
MISSION_STATUS_INVALID
),
MISSION_STATUS_UNFINISHED
(
1
,
MissionStatus
.
MISSION_STATUS_UNFINISHED
),
MISSION_STATUS_FINISHED
(
2
,
MissionStatus
.
MISSION_STATUS_FINISHED
),
MISSION_STATUS_POINT_TAKEN
(
3
,
MissionStatus
.
MISSION_STATUS_POINT_TAKEN
);
private
final
int
value
;
private
final
MissionStatus
missionStatus
;
BattlePassMissionStatus
(
int
value
,
MissionStatus
missionStatus
)
{
this
.
value
=
value
;
this
.
missionStatus
=
missionStatus
;
// In case proto enum values change later
}
public
int
getValue
()
{
return
value
;
}
public
MissionStatus
getMissionStatus
()
{
return
missionStatus
;
}
}
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