mirror of
https://github.com/Melledy/Nebula.git
synced 2026-09-19 09:09:54 +02:00
Implement event story
This commit is contained in:
@@ -189,6 +189,9 @@ public class GameData {
|
|||||||
@Getter private static DataTable<ActivityTaskDef> ActivityTaskDataTable = new DataTable<>();
|
@Getter private static DataTable<ActivityTaskDef> ActivityTaskDataTable = new DataTable<>();
|
||||||
@Getter private static DataTable<ActivityTaskGroupDef> ActivityTaskGroupDataTable = new DataTable<>();
|
@Getter private static DataTable<ActivityTaskGroupDef> ActivityTaskGroupDataTable = new DataTable<>();
|
||||||
|
|
||||||
|
// Activity: Story
|
||||||
|
@Getter private static DataTable<ActivityStoryDef> ActivityStoryDataTable = new DataTable<>();
|
||||||
|
|
||||||
// Activity: Shop
|
// Activity: Shop
|
||||||
@Getter private static DataTable<ActivityShopDef> ActivityShopDataTable = new DataTable<>();
|
@Getter private static DataTable<ActivityShopDef> ActivityShopDataTable = new DataTable<>();
|
||||||
@Getter private static DataTable<ActivityShopControlDef> ActivityShopControlDataTable = new DataTable<>();
|
@Getter private static DataTable<ActivityShopControlDef> ActivityShopControlDataTable = new DataTable<>();
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package emu.nebula.data.resources;
|
||||||
|
|
||||||
|
import emu.nebula.data.BaseDef;
|
||||||
|
import emu.nebula.data.ResourceType;
|
||||||
|
import emu.nebula.game.inventory.ItemParamMap;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ResourceType(name = "ActivityStory.json")
|
||||||
|
public class ActivityStoryDef extends BaseDef {
|
||||||
|
private int Id;
|
||||||
|
private int ChapterId;
|
||||||
|
|
||||||
|
private String FirstCompleteReward;
|
||||||
|
|
||||||
|
private transient ItemParamMap rewards;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
this.rewards = ItemParamMap.fromJsonString(this.FirstCompleteReward);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -137,6 +137,7 @@ public class ActivityManager extends PlayerManager implements GameDatabaseObject
|
|||||||
case Task -> new TaskActivity(this, data);
|
case Task -> new TaskActivity(this, data);
|
||||||
case Shop -> new ShopActivity(this, data);
|
case Shop -> new ShopActivity(this, data);
|
||||||
case TrekkerVersus -> new TrekkerVersusActivity(this, data);
|
case TrekkerVersus -> new TrekkerVersusActivity(this, data);
|
||||||
|
case Story -> new StoryActivity(this, data);
|
||||||
case PenguinCard -> new PenguinCardActivity(this, data);
|
case PenguinCard -> new PenguinCardActivity(this, data);
|
||||||
case Soldier -> new SoldierActivity(this, data);
|
case Soldier -> new SoldierActivity(this, data);
|
||||||
default -> null;
|
default -> null;
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ public class ActivityModule extends GameContextModule {
|
|||||||
|
|
||||||
// Go, My Lady! Training Handbook Plus!
|
// Go, My Lady! Training Handbook Plus!
|
||||||
this.activities.add(1011101);
|
this.activities.add(1011101);
|
||||||
|
this.activities.add(1011102);
|
||||||
this.activities.add(1011103);
|
this.activities.add(1011103);
|
||||||
this.activities.add(1011104);
|
this.activities.add(1011104);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,204 @@
|
|||||||
|
package emu.nebula.game.activity.type;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.Entity;
|
||||||
|
|
||||||
|
import emu.nebula.data.GameData;
|
||||||
|
import emu.nebula.data.resources.ActivityDef;
|
||||||
|
import emu.nebula.game.activity.ActivityManager;
|
||||||
|
import emu.nebula.game.activity.GameActivity;
|
||||||
|
import emu.nebula.game.player.PlayerChangeInfo;
|
||||||
|
import emu.nebula.proto.ActivityDetail.ActivityMsg;
|
||||||
|
import emu.nebula.proto.ActivityStorySettleOuterClass.ActivityStorySettle;
|
||||||
|
import emu.nebula.proto.Public.ActivityStory;
|
||||||
|
import emu.nebula.proto.Public.ActivityStoryChoice;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import us.hebi.quickbuf.RepeatedInt;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Entity
|
||||||
|
public class StoryActivity extends GameActivity {
|
||||||
|
private Map<Integer, ActivityStoryInfo> stories;
|
||||||
|
private IntSet evidences;
|
||||||
|
private long buildId;
|
||||||
|
|
||||||
|
@Deprecated // Morphia only
|
||||||
|
public StoryActivity() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public StoryActivity(ActivityManager manager, ActivityDef data) {
|
||||||
|
super(manager, data);
|
||||||
|
this.stories = new HashMap<>();
|
||||||
|
this.evidences = new IntOpenHashSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getChapterId() {
|
||||||
|
return (int) Math.floor(this.getId() / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply(int storyId, long buildId) {
|
||||||
|
// Check story id
|
||||||
|
var story = GameData.getActivityStoryDataTable().get(storyId);
|
||||||
|
|
||||||
|
if (story == null || story.getChapterId() != this.getChapterId()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set build id
|
||||||
|
if (buildId != 0) {
|
||||||
|
this.buildId = buildId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerChangeInfo settle(Iterable<ActivityStorySettle> list, RepeatedInt evidences) {
|
||||||
|
// Create change info
|
||||||
|
var change = new PlayerChangeInfo();
|
||||||
|
|
||||||
|
// Boolean flag to check if any data was changed/added
|
||||||
|
boolean hasChanged = false;
|
||||||
|
|
||||||
|
// Handle settle info
|
||||||
|
for (var settle : list) {
|
||||||
|
// Get story data
|
||||||
|
var story = GameData.getActivityStoryDataTable().get(settle.getStoryId());
|
||||||
|
|
||||||
|
// Validate story
|
||||||
|
if (story == null || story.getChapterId() != this.getChapterId()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we have already completed this story
|
||||||
|
if (this.getStories().containsKey(story.getId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create story info
|
||||||
|
var info = new ActivityStoryInfo(story.getId());
|
||||||
|
|
||||||
|
for (var option : settle.getMajor()) {
|
||||||
|
info.addMajor(option.getGroup(), option.getChoice());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var option : settle.getPersonality()) {
|
||||||
|
info.addPersonality(option.getGroup(), option.getChoice());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to story log
|
||||||
|
this.stories.put(story.getId(), info);
|
||||||
|
|
||||||
|
// Set changed flag
|
||||||
|
hasChanged = true;
|
||||||
|
|
||||||
|
// Add rewards
|
||||||
|
this.getPlayer().getInventory().addItems(story.getRewards(), change);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add evidences
|
||||||
|
for (int i : evidences) {
|
||||||
|
this.getEvidences().add(i);
|
||||||
|
|
||||||
|
// Set changed flag
|
||||||
|
hasChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save to database if anything has changed
|
||||||
|
if (hasChanged) {
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Success
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proto
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encodeActivityMsg(ActivityMsg msg) {
|
||||||
|
var proto = msg.getMutableStoryChapter()
|
||||||
|
.setBuildId(this.getBuildId());
|
||||||
|
|
||||||
|
for (int i : this.getEvidences()) {
|
||||||
|
proto.addEvidences(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var info : this.getStories().values()) {
|
||||||
|
proto.addStories(info.toProto());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Entity(useDiscriminator = false)
|
||||||
|
public static class ActivityStoryInfo {
|
||||||
|
private int id;
|
||||||
|
private Int2IntMap major;
|
||||||
|
private Int2IntMap personality;
|
||||||
|
|
||||||
|
@Deprecated // Morphia only
|
||||||
|
public ActivityStoryInfo() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActivityStoryInfo(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMajor(int group, int choice) {
|
||||||
|
if (this.major == null) {
|
||||||
|
this.major = new Int2IntOpenHashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.major.put(group, choice);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPersonality(int group, int choice) {
|
||||||
|
if (this.personality == null) {
|
||||||
|
this.personality = new Int2IntOpenHashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.personality.put(group, choice);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proto
|
||||||
|
|
||||||
|
public ActivityStory toProto() {
|
||||||
|
var proto = ActivityStory.newInstance()
|
||||||
|
.setId(this.id);
|
||||||
|
|
||||||
|
if (this.major != null) {
|
||||||
|
for (var entry : this.major.int2IntEntrySet()) {
|
||||||
|
var choice = ActivityStoryChoice.newInstance()
|
||||||
|
.setGroup(entry.getIntKey())
|
||||||
|
.setValue(entry.getIntValue());
|
||||||
|
|
||||||
|
proto.addMajor(choice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.personality != null) {
|
||||||
|
for (var entry : this.personality.int2IntEntrySet()) {
|
||||||
|
var choice = ActivityStoryChoice.newInstance()
|
||||||
|
.setGroup(entry.getIntKey())
|
||||||
|
.setValue(entry.getIntValue());
|
||||||
|
|
||||||
|
proto.addPersonality(choice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return proto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -149,9 +149,11 @@ public class ItemParamMap extends Int2IntLinkedOpenHashMap implements ObjectBidi
|
|||||||
var map = new ItemParamMap();
|
var map = new ItemParamMap();
|
||||||
var json = JsonUtils.decodeMap(jsonString, Integer.class, Integer.class);
|
var json = JsonUtils.decodeMap(jsonString, Integer.class, Integer.class);
|
||||||
|
|
||||||
|
if (json != null) {
|
||||||
for (var entry : json.entrySet()) {
|
for (var entry : json.entrySet()) {
|
||||||
map.add(entry.getKey(), entry.getValue());
|
map.add(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package emu.nebula.server.handlers;
|
||||||
|
|
||||||
|
import emu.nebula.net.NetHandler;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.proto.ActivityStoryApply.ActivityStoryApplyReq;
|
||||||
|
import emu.nebula.net.HandlerId;
|
||||||
|
import emu.nebula.game.activity.type.StoryActivity;
|
||||||
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
|
@HandlerId(NetMsgId.activity_story_apply_req)
|
||||||
|
public class HandlerActivityStoryApplyReq extends NetHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
|
// Parse req
|
||||||
|
var req = ActivityStoryApplyReq.parseFrom(message);
|
||||||
|
|
||||||
|
// Get activity
|
||||||
|
var activity = session.getPlayer().getActivityManager().getActivity(StoryActivity.class, req.getActivityId());
|
||||||
|
|
||||||
|
if (activity == null) {
|
||||||
|
return session.encodeMsg(NetMsgId.activity_story_apply_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply
|
||||||
|
boolean success = activity.apply(req.getStoryId(), req.getBuildId());
|
||||||
|
|
||||||
|
if (success == false) {
|
||||||
|
return session.encodeMsg(NetMsgId.activity_story_apply_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode and send
|
||||||
|
return session.encodeMsg(NetMsgId.activity_story_apply_succeed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package emu.nebula.server.handlers;
|
||||||
|
|
||||||
|
import emu.nebula.net.NetHandler;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.proto.ActivityStorySettleOuterClass.ActivityStorySettleReq;
|
||||||
|
import emu.nebula.net.HandlerId;
|
||||||
|
import emu.nebula.game.activity.type.StoryActivity;
|
||||||
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
|
@HandlerId(NetMsgId.activity_story_settle_req)
|
||||||
|
public class HandlerActivityStorySettleReq extends NetHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
|
// Parse req
|
||||||
|
var req = ActivityStorySettleReq.parseFrom(message);
|
||||||
|
|
||||||
|
// Get activity
|
||||||
|
var activity = session.getPlayer().getActivityManager().getActivity(StoryActivity.class, req.getActivityId());
|
||||||
|
|
||||||
|
if (activity == null) {
|
||||||
|
return session.encodeMsg(NetMsgId.activity_story_settle_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply
|
||||||
|
var change = activity.settle(req.getMutableList(), req.getMutableEvidences());
|
||||||
|
|
||||||
|
if (change == null) {
|
||||||
|
return session.encodeMsg(NetMsgId.activity_story_settle_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle client events for achievements
|
||||||
|
session.getPlayer().getAchievementManager().handleClientEvents(req.getEvents());
|
||||||
|
|
||||||
|
// Encode and send
|
||||||
|
return session.encodeMsg(NetMsgId.activity_story_settle_succeed_ack, change.toProto());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,6 +2,6 @@
|
|||||||
"global": 134,
|
"global": 134,
|
||||||
"kr": 139,
|
"kr": 139,
|
||||||
"jp": 137,
|
"jp": 137,
|
||||||
"tw": 142,
|
"tw": 143,
|
||||||
"cn": 133
|
"cn": 133
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user