mirror of
https://github.com/Melledy/Nebula.git
synced 2025-12-12 20:34:36 +01:00
Implement tutorial levels
This commit is contained in:
@@ -87,6 +87,9 @@ public class GameData {
|
||||
@Getter private static DataTable<DailyQuestDef> DailyQuestDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<DailyQuestActiveDef> DailyQuestActiveDataTable = new DataTable<>();
|
||||
|
||||
// Tutorial
|
||||
@Getter private static DataTable<TutorialLevelDef> TutorialLevelDataTable = new DataTable<>();
|
||||
|
||||
// Star tower
|
||||
@Getter private static DataTable<StarTowerDef> StarTowerDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<StarTowerStageDef> StarTowerStageDataTable = new DataTable<>();
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "TutorialLevel.json")
|
||||
public class TutorialLevelDef extends BaseDef {
|
||||
private int Id;
|
||||
private int WorldClass;
|
||||
private int Item1;
|
||||
private int Qty1;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import emu.nebula.Nebula;
|
||||
import emu.nebula.game.gacha.GachaModule;
|
||||
import emu.nebula.game.player.PlayerModule;
|
||||
import emu.nebula.game.scoreboss.ScoreBossModule;
|
||||
import emu.nebula.game.tutorial.TutorialModule;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
@@ -25,6 +26,7 @@ public class GameContext implements Runnable {
|
||||
// Modules
|
||||
private final PlayerModule playerModule;
|
||||
private final GachaModule gachaModule;
|
||||
private final TutorialModule tutorialModule;
|
||||
private final ScoreBossModule scoreBossModule;
|
||||
|
||||
// Game loop
|
||||
@@ -39,6 +41,7 @@ public class GameContext implements Runnable {
|
||||
// Setup game modules
|
||||
this.playerModule = new PlayerModule(this);
|
||||
this.gachaModule = new GachaModule(this);
|
||||
this.tutorialModule = new TutorialModule(this);
|
||||
this.scoreBossModule = new ScoreBossModule(this);
|
||||
|
||||
// Run game loop
|
||||
|
||||
@@ -8,6 +8,7 @@ import dev.morphia.annotations.Id;
|
||||
import emu.nebula.Nebula;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.database.GameDatabaseObject;
|
||||
import emu.nebula.game.tutorial.TutorialLevelLog;
|
||||
import emu.nebula.game.vampire.VampireSurvivorLog;
|
||||
import emu.nebula.proto.PlayerData.PlayerInfo;
|
||||
import emu.nebula.proto.Public.CharGemInstance;
|
||||
@@ -48,6 +49,9 @@ public class PlayerProgress extends PlayerManager implements GameDatabaseObject
|
||||
|
||||
// Fate cards
|
||||
private IntSet fateCards;
|
||||
|
||||
// Tutorial
|
||||
private Map<Integer, TutorialLevelLog> tutorialLog;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public PlayerProgress() {
|
||||
@@ -74,8 +78,13 @@ public class PlayerProgress extends PlayerManager implements GameDatabaseObject
|
||||
// Vampire Survivor
|
||||
this.vampireLog = new HashMap<>();
|
||||
this.vampireTalents = new Bitset();
|
||||
|
||||
// Fate cards
|
||||
this.fateCards = new IntOpenHashSet();
|
||||
|
||||
// Tutorials
|
||||
this.tutorialLog = new HashMap<>();
|
||||
|
||||
// Save to database
|
||||
this.save();
|
||||
}
|
||||
@@ -219,5 +228,10 @@ public class PlayerProgress extends PlayerManager implements GameDatabaseObject
|
||||
vsProto.addRecords(log.toProto());
|
||||
}
|
||||
}
|
||||
|
||||
// Tutorials
|
||||
for (var tutorial : this.getTutorialLog().values()) {
|
||||
proto.addTutorialLevels(tutorial.toProto());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
36
src/main/java/emu/nebula/game/tutorial/TutorialLevelLog.java
Normal file
36
src/main/java/emu/nebula/game/tutorial/TutorialLevelLog.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package emu.nebula.game.tutorial;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.nebula.proto.Public.TutorialLevel;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Entity(useDiscriminator = false)
|
||||
public class TutorialLevelLog {
|
||||
private int id;
|
||||
private boolean claimed;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public TutorialLevelLog() {
|
||||
|
||||
}
|
||||
|
||||
public TutorialLevelLog(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setClaimed(boolean value) {
|
||||
this.claimed = value;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public TutorialLevel toProto() {
|
||||
var proto = TutorialLevel.newInstance()
|
||||
.setLevelId(this.getId())
|
||||
.setPassed(true)
|
||||
.setRewardReceived(this.isClaimed());
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
63
src/main/java/emu/nebula/game/tutorial/TutorialModule.java
Normal file
63
src/main/java/emu/nebula/game/tutorial/TutorialModule.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package emu.nebula.game.tutorial;
|
||||
|
||||
import emu.nebula.Nebula;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.game.GameContext;
|
||||
import emu.nebula.game.GameContextModule;
|
||||
import emu.nebula.game.player.Player;
|
||||
import emu.nebula.game.player.PlayerChangeInfo;
|
||||
|
||||
public class TutorialModule extends GameContextModule {
|
||||
|
||||
public TutorialModule(GameContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public boolean settle(Player player, int id) {
|
||||
// Check if the tutorial was completed
|
||||
if (player.getProgress().getTutorialLog().containsKey(id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get data
|
||||
var data = GameData.getTutorialLevelDataTable().get(id);
|
||||
if (data == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create log
|
||||
var log = new TutorialLevelLog(id);
|
||||
|
||||
// Add to progress tutorial map
|
||||
player.getProgress().getTutorialLog().put(id, log);
|
||||
|
||||
// Save to database
|
||||
Nebula.getGameDatabase().update(player.getProgress(), player.getUid(), "tutorialLog." + log.getId(), log);
|
||||
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
public PlayerChangeInfo recvReward(Player player, int id) {
|
||||
// Get tutorial log
|
||||
var log = player.getProgress().getTutorialLog().get(id);
|
||||
if (log == null || log.isClaimed()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get data
|
||||
var data = GameData.getTutorialLevelDataTable().get(id);
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Set claim state
|
||||
log.setClaimed(true);
|
||||
|
||||
// Save to database
|
||||
Nebula.getGameDatabase().update(player.getProgress(), player.getUid(), "tutorialLog." + log.getId(), log);
|
||||
|
||||
// Add reward item
|
||||
return player.getInventory().addItem(data.getItem1(), data.getQty1());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.Public.UI32;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.Nebula;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.tutorial_level_reward_receive_req)
|
||||
public class HandlerTutorialLevelRewardReceiveReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = UI32.parseFrom(message);
|
||||
|
||||
// Get rewards
|
||||
var change = Nebula.getGameContext().getTutorialModule().recvReward(session.getPlayer(), req.getValue());
|
||||
|
||||
if (change == null) {
|
||||
return session.encodeMsg(NetMsgId.tutorial_level_reward_receive_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.tutorial_level_reward_receive_succeed_ack, change.toProto());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package emu.nebula.server.handlers;
|
||||
|
||||
import emu.nebula.net.NetHandler;
|
||||
import emu.nebula.net.NetMsgId;
|
||||
import emu.nebula.proto.Public.UI32;
|
||||
import emu.nebula.net.HandlerId;
|
||||
import emu.nebula.Nebula;
|
||||
import emu.nebula.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.tutorial_level_settle_req)
|
||||
public class HandlerTutorialLevelSettleReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = UI32.parseFrom(message);
|
||||
|
||||
// Settle
|
||||
boolean success = Nebula.getGameContext().getTutorialModule().settle(session.getPlayer(), req.getValue());
|
||||
|
||||
if (success == false) {
|
||||
return session.encodeMsg(NetMsgId.tutorial_level_settle_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.tutorial_level_settle_succeed_ack);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user