mirror of
https://github.com/Melledy/Nebula.git
synced 2026-11-04 21:36:51 +01:00
Implement monolith research quests
This commit is contained in:
1 parent
2424496472
commit
b302871630
16 files changed
+1024
-35
No files matched your search
@@ -21,7 +21,7 @@ Latest nightly compiled server jar: [Nightly](https://nightly.link/Melledy/Nebul
|
||||
- Commissions
|
||||
- Heartlink
|
||||
- Achievements
|
||||
- Monoliths (research quests not implemented)
|
||||
- Monoliths
|
||||
- Bounty Trials
|
||||
- Menance Arena
|
||||
- Proving Grounds
|
||||
|
||||
@@ -4,7 +4,6 @@ import emu.nebula.data.custom.CharGemAttrGroupDef;
|
||||
import emu.nebula.data.resources.*;
|
||||
import lombok.Getter;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class GameData {
|
||||
// ===== Characters =====
|
||||
@Getter private static DataTable<CharacterDef> CharacterDataTable = new DataTable<>();
|
||||
@@ -117,6 +116,7 @@ public class GameData {
|
||||
@Getter private static DataTable<StarTowerFloorExpDef> StarTowerFloorExpDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<StarTowerTeamExpDef> StarTowerTeamExpDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<StarTowerEventDef> StarTowerEventDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<StarTowerQuestDef> StarTowerQuestDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<StarTowerBuildRankDef> StarTowerBuildRankDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<StarTowerBookPotentialRewardDef> StarTowerBookPotentialRewardDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<SubNoteSkillPromoteGroupDef> SubNoteSkillPromoteGroupDataTable = new DataTable<>();
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package emu.nebula.data.custom;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import emu.nebula.data.ResourceType.LoadPriority;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "StarTowerQuestParam.json", useInternal = true, loadPriority = LoadPriority.LOW)
|
||||
public class StarTowerQuestParamDef extends BaseDef {
|
||||
private int Id;
|
||||
|
||||
private int CompleteCond;
|
||||
private int Aim;
|
||||
|
||||
private int Param1;
|
||||
private int ParamCond1;
|
||||
private int Param2;
|
||||
private int ParamCond2;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
var quest = GameData.getStarTowerQuestDataTable().get(this.Id);
|
||||
if (quest == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
quest.setParams(this);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import lombok.Getter;
|
||||
public class StarTowerBuildRankDef extends BaseDef {
|
||||
private int Id;
|
||||
private int MinGrade;
|
||||
private int Level;
|
||||
private int Rarity;
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import emu.nebula.data.custom.StarTowerQuestParamDef;
|
||||
import emu.nebula.game.quest.QuestData;
|
||||
import emu.nebula.game.quest.QuestType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "StarTowerQuest.json")
|
||||
public class StarTowerQuestDef extends BaseDef implements QuestData {
|
||||
private int Id;
|
||||
private String Title;
|
||||
private int TowerQuestType; // 1 = Core, 2 = Normal
|
||||
private int[] PreTowerQuestIds;
|
||||
|
||||
// Rewards
|
||||
private int Reward1;
|
||||
private int RewardQty1;
|
||||
private int Reward2;
|
||||
private int RewardQty2;
|
||||
|
||||
// Custom params (loaded from defs/StarTowerQuestParam.json)
|
||||
private transient int completeCond;
|
||||
private transient int aim;
|
||||
private transient int param1;
|
||||
private transient int paramCond1;
|
||||
private transient int param2;
|
||||
private transient int paramCond2;
|
||||
private transient int[] condParams;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQuestType() {
|
||||
return QuestType.Tower;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCompleteCond() {
|
||||
return this.completeCond;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getCompleteCondParams() {
|
||||
if (this.condParams == null) {
|
||||
this.condParams = new int[] { 1, 0, 0 };
|
||||
}
|
||||
|
||||
return this.condParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the generated condition params from the internal defs file.
|
||||
*/
|
||||
public void setParams(StarTowerQuestParamDef params) {
|
||||
this.completeCond = params.getCompleteCond();
|
||||
this.aim = params.getAim();
|
||||
this.param1 = params.getParam1();
|
||||
this.paramCond1 = params.getParamCond1();
|
||||
this.param2 = params.getParam2();
|
||||
this.paramCond2 = params.getParamCond2();
|
||||
|
||||
this.condParams = new int[] { this.aim, this.param1, this.param2 };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Quests without prerequisites have no array in the data file
|
||||
if (this.PreTowerQuestIds == null) {
|
||||
this.PreTowerQuestIds = new int[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,62 @@ public class GameQuest {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes condition data from a resource definition while preserving progress.
|
||||
*/
|
||||
public boolean refreshData(QuestData data) {
|
||||
int oldCond = this.cond;
|
||||
int oldMax = this.maxProgress;
|
||||
int oldParam = this.param;
|
||||
|
||||
this.cond = data.getCompleteCond();
|
||||
|
||||
int[] params = data.getCompleteCondParams();
|
||||
this.maxProgress = params.length > 0 ? params[0] : 0;
|
||||
this.param = params.length > 1 ? params[1] : 0;
|
||||
|
||||
return oldCond != this.cond || oldMax != this.maxProgress || oldParam != this.param;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds progress without applying condition/param checks.
|
||||
* Used by quest systems that perform their own matching.
|
||||
*/
|
||||
public boolean addProgress(int progress) {
|
||||
if (this.isComplete() || progress <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int newProgress = Math.min(this.curProgress + progress, this.maxProgress);
|
||||
|
||||
if (newProgress == this.curProgress) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.curProgress = newProgress;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Directly sets quest progress
|
||||
*/
|
||||
public boolean setProgress(int progress) {
|
||||
if (this.isComplete() || progress < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int newProgress = Math.min(progress, this.maxProgress);
|
||||
|
||||
if (newProgress == this.curProgress) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.curProgress = newProgress;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean trigger(int condition, int progress, int param1, int param2) {
|
||||
// Sanity check
|
||||
if (this.isComplete()) {
|
||||
|
||||
@@ -60,6 +60,8 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
|
||||
this.list = new HashMap<>();
|
||||
this.levelRewards = new Bitset();
|
||||
|
||||
this.initStarTowerQuests();
|
||||
|
||||
this.resetDailyQuests(true);
|
||||
|
||||
this.save();
|
||||
@@ -71,7 +73,34 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
|
||||
}
|
||||
|
||||
public synchronized GameQuest addQuest(GameQuest quest) {
|
||||
// Add to quest list
|
||||
this.list.put(quest.getKey(), quest);
|
||||
|
||||
// Star Tower growth-node quests can complete retroactively if the player
|
||||
// already unlocked the required node(s) before the quest was added
|
||||
if (quest.getType() == QuestType.Tower) {
|
||||
var data = GameData.getStarTowerQuestDataTable().get(quest.getId());
|
||||
int cond = data != null ? data.getCompleteCond() : 0;
|
||||
|
||||
if (cond == QuestCondition.TowerGrowthSpecificNote.getValue() || cond == QuestCondition.TowerGrowthWithSpecificNote.getValue()) {
|
||||
var manager = this.getPlayer().getStarTowerManager();
|
||||
int progress = 0;
|
||||
|
||||
if (data.getParam1() != 0 && manager.hasGrowthNode(data.getParam1())) {
|
||||
progress++;
|
||||
}
|
||||
|
||||
if (data.getParam2() != 0 && manager.hasGrowthNode(data.getParam2())) {
|
||||
progress++;
|
||||
}
|
||||
|
||||
if (progress > 0) {
|
||||
quest.setProgress(progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return quest
|
||||
return quest;
|
||||
}
|
||||
|
||||
@@ -146,14 +175,39 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
|
||||
// Get quest from entry
|
||||
var quest = entry.getValue();
|
||||
|
||||
// Try to trigger quest
|
||||
boolean result = quest.trigger(condition, progress, param1, param2);
|
||||
|
||||
// Skip if quest progress wasn't changed
|
||||
if (!result) {
|
||||
// Skip completed quests
|
||||
if (quest.isComplete()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Star Tower quests use their own generated params and matching rules
|
||||
// TODO clean this code up to look nice
|
||||
if (quest.getType() == QuestType.Tower) {
|
||||
// Get quest data
|
||||
var data = GameData.getStarTowerQuestDataTable().get(quest.getId());
|
||||
if (data == null || data.getCompleteCond() != condition) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check params
|
||||
if (!StarTowerQuestHelper.matches(data, param1, param2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add progress
|
||||
if (!quest.addProgress(progress)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Now we try to trigger regular daily/weekly quests
|
||||
boolean result = quest.trigger(condition, progress, param1, param2);
|
||||
|
||||
// Skip if quest progress wasn't changed
|
||||
if (!result) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Sync quest with player client
|
||||
this.syncQuest(quest);
|
||||
|
||||
@@ -176,6 +230,132 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
|
||||
);
|
||||
}
|
||||
|
||||
// Star Tower quests
|
||||
|
||||
/**
|
||||
* Adds all currently unlocked Star Tower quests.
|
||||
* Returns true if any quest was added or refreshed.
|
||||
*/
|
||||
public synchronized boolean initStarTowerQuests() {
|
||||
boolean changed = false;
|
||||
|
||||
for (var data : GameData.getStarTowerQuestDataTable()) {
|
||||
// Only add quests whose prerequisites have been claimed
|
||||
if (!StarTowerQuestHelper.isUnlocked(this, data)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get existing quest
|
||||
var quest = this.getList().get(data.getQuestKey());
|
||||
|
||||
if (quest == null) {
|
||||
this.addQuest(new GameQuest(data));
|
||||
changed = true;
|
||||
} else if (quest.refreshData(data)) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds quests that became available after a prerequisite was claimed.
|
||||
*/
|
||||
public synchronized void unlockStarTowerQuests() {
|
||||
boolean changed = false;
|
||||
|
||||
for (var data : GameData.getStarTowerQuestDataTable()) {
|
||||
// Skip quests that already exist
|
||||
if (this.getList().containsKey(data.getQuestKey())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only add quests whose prerequisites have been claimed
|
||||
if (!StarTowerQuestHelper.isUnlocked(this, data)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add quest and sync it with the client
|
||||
var quest = this.addQuest(new GameQuest(data));
|
||||
|
||||
// Syncs quest with client
|
||||
this.syncQuest(quest);
|
||||
|
||||
// Set changed flag
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Persist new quests
|
||||
if (changed) {
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized PlayerChangeInfo receiveStarTowerQuestReward(int questId) {
|
||||
// Get received quests
|
||||
var claimList = new ArrayList<GameQuest>();
|
||||
|
||||
if (questId > 0) {
|
||||
// Claim specific quest
|
||||
var quest = this.getQuest(QuestType.Tower, questId);
|
||||
|
||||
if (quest != null && quest.canClaim()) {
|
||||
claimList.add(quest);
|
||||
}
|
||||
} else {
|
||||
// Claim all
|
||||
for (var quest : this.getQuests()) {
|
||||
if (quest.getType() != QuestType.Tower) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!quest.canClaim()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
claimList.add(quest);
|
||||
}
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if (claimList.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create change info
|
||||
var change = new PlayerChangeInfo();
|
||||
|
||||
// Claim
|
||||
for (var quest : claimList) {
|
||||
// Get data
|
||||
var data = GameData.getStarTowerQuestDataTable().get(quest.getId());
|
||||
|
||||
if (data != null) {
|
||||
// Add rewards
|
||||
if (data.getReward1() > 0 && data.getRewardQty1() > 0) {
|
||||
this.getPlayer().getInventory().addItem(data.getReward1(), data.getRewardQty1(), change);
|
||||
}
|
||||
|
||||
if (data.getReward2() > 0 && data.getRewardQty2() > 0) {
|
||||
this.getPlayer().getInventory().addItem(data.getReward2(), data.getRewardQty2(), change);
|
||||
}
|
||||
}
|
||||
|
||||
// Set claimed
|
||||
quest.setClaimed(true);
|
||||
|
||||
// Update in database
|
||||
Nebula.getGameDatabase().update(this, this.getUid(), "list." + quest.getKey(), quest);
|
||||
}
|
||||
|
||||
// Unlock newly available quests
|
||||
this.unlockStarTowerQuests();
|
||||
|
||||
// Success
|
||||
return change.setSuccess(true);
|
||||
}
|
||||
|
||||
// Daily quests
|
||||
|
||||
public synchronized int getDailyActivity() {
|
||||
@@ -525,11 +705,23 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
|
||||
|
||||
// Fix quest lists
|
||||
if (this.getList() == null) {
|
||||
// Create quest list
|
||||
this.list = new HashMap<>();
|
||||
|
||||
// Add missing Star Tower quests and refresh their condition data
|
||||
// We do not need to save here because QuestManager::resetDailyQuests will save to the database
|
||||
this.initStarTowerQuests();
|
||||
|
||||
// Reset daily quests
|
||||
this.resetDailyQuests(true);
|
||||
|
||||
// QuestManager::resetDailyQuests will save to the database, so we dont need to set the shouldSave flag
|
||||
shouldSave = false;
|
||||
} else {
|
||||
// Add missing Star Tower quests and refresh their condition data
|
||||
if (this.initStarTowerQuests()) {
|
||||
shouldSave = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Save to database
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package emu.nebula.game.quest;
|
||||
|
||||
import emu.nebula.data.resources.StarTowerQuestDef;
|
||||
import emu.nebula.game.achievement.AchievementParamCond;
|
||||
|
||||
// TODO clean up and merge with other quest helpers
|
||||
public class StarTowerQuestHelper {
|
||||
|
||||
/**
|
||||
* Checks if all prerequisite quests for the specified quest have been claimed.
|
||||
*/
|
||||
public static boolean isUnlocked(QuestManager manager, StarTowerQuestDef data) {
|
||||
for (int preId : data.getPreTowerQuestIds()) {
|
||||
var quest = manager.getQuest(QuestType.Tower, preId);
|
||||
|
||||
if (quest == null || !quest.isClaimed()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a trigger payload matches the quest's generated params.
|
||||
*/
|
||||
public static boolean matches(StarTowerQuestDef data, int param1, int param2) {
|
||||
// Growth node quests can require one or two specific nodes.
|
||||
// The trigger payload puts the unlocked node id in param1.
|
||||
if (data.getCompleteCond() == QuestCondition.TowerGrowthWithSpecificNote.getValue()) {
|
||||
boolean matchesFirst = data.getParam1() != 0 && param1 == data.getParam1();
|
||||
boolean matchesSecond = data.getParam2() != 0 && param1 == data.getParam2();
|
||||
|
||||
return matchesFirst || matchesSecond;
|
||||
}
|
||||
|
||||
return matchesParam(data.getParam1(), data.getParamCond1(), param1) && matchesParam(data.getParam2(), data.getParamCond2(), param2);
|
||||
}
|
||||
|
||||
private static boolean matchesParam(int param, int cond, int value) {
|
||||
// A param of zero is a wildcard, matching the existing GameQuest behavior
|
||||
if (param == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return AchievementParamCond.getByValue(cond).test(param, value);
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import emu.nebula.game.formation.Formation;
|
||||
import emu.nebula.game.inventory.ItemParamMap;
|
||||
import emu.nebula.game.player.Player;
|
||||
import emu.nebula.game.player.PlayerChangeInfo;
|
||||
import emu.nebula.game.quest.QuestCondition;
|
||||
import emu.nebula.game.tower.cases.StarTowerBaseCase;
|
||||
import emu.nebula.game.tower.cases.StarTowerDoorCase;
|
||||
import emu.nebula.game.tower.cases.StarTowerHawkerCase;
|
||||
@@ -463,9 +464,11 @@ public class StarTowerGame {
|
||||
// Add to new infos
|
||||
this.getNewInfos().add(id, count);
|
||||
|
||||
// Achievment
|
||||
// Achievement + Star Tower quests (Musical Notes).
|
||||
// The quest treats param1 as a wildcard, so passing the item id keeps
|
||||
// the per-note achievements working while counting every sub-note.
|
||||
if (count > 0) {
|
||||
this.getAchievementManager().trigger(AchievementCondition.TowerItemsGet, count, id, 0);
|
||||
this.getPlayer().trigger(QuestCondition.TowerItemsGet, count, id);
|
||||
}
|
||||
}
|
||||
case Res -> {
|
||||
@@ -866,15 +869,7 @@ public class StarTowerGame {
|
||||
int tickets = this.getModifiers().calculateTickets();
|
||||
rewards.add(12, tickets);
|
||||
|
||||
// (Custom) Add research materials since tower quests are not implemented yet
|
||||
int research = 50 + (Utils.randomRange(this.getDifficulty() - 1, this.getDifficulty() * 2) * 10);
|
||||
rewards.add(51, research);
|
||||
|
||||
// Add to inventory
|
||||
var change = this.getPlayer().getInventory().addItem(51, research);
|
||||
|
||||
// Set proto data
|
||||
settle.setChange(change.toProto());
|
||||
rewards.toItemTemplateStream().forEach(settle::addTowerRewards);
|
||||
|
||||
// Save tower tickets
|
||||
@@ -920,10 +915,10 @@ public class StarTowerGame {
|
||||
// Set new secondary skills
|
||||
this.secondarySkills = newSecondarySkills;
|
||||
|
||||
// Achievement trigger
|
||||
// Achievement + Star Tower quests
|
||||
if (newSecondaryCount > 0) {
|
||||
this.getAchievementManager().trigger(
|
||||
AchievementCondition.TowerSpecificSecondarySkillActivateTotal,
|
||||
this.getPlayer().trigger(
|
||||
QuestCondition.TowerSpecificSecondarySkillActivateTotal,
|
||||
newSecondaryCount
|
||||
);
|
||||
}
|
||||
|
||||
@@ -102,6 +102,10 @@ public class StarTowerManager extends PlayerManager {
|
||||
this.getProgress().getStarTowerGrowth()
|
||||
);
|
||||
|
||||
// Star Tower quests
|
||||
this.getPlayer().trigger(QuestCondition.TowerGrowthSpecificNote, 1, data.getId());
|
||||
this.getPlayer().trigger(QuestCondition.TowerGrowthWithSpecificNote, 1, data.getId());
|
||||
|
||||
// Remove items
|
||||
return getPlayer().getInventory().removeItem(data.getItemId1(), data.getItemQty1());
|
||||
}
|
||||
@@ -147,6 +151,14 @@ public class StarTowerManager extends PlayerManager {
|
||||
"starTowerGrowth",
|
||||
this.getProgress().getStarTowerGrowth()
|
||||
);
|
||||
|
||||
// Star Tower quests
|
||||
for (int i = 0; i < unlocked.size(); i++) {
|
||||
int nodeId = unlocked.getInt(i);
|
||||
|
||||
this.getPlayer().trigger(QuestCondition.TowerGrowthSpecificNote, 1, nodeId);
|
||||
this.getPlayer().trigger(QuestCondition.TowerGrowthWithSpecificNote, 1, nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
// Set unlocked list
|
||||
@@ -190,6 +202,17 @@ public class StarTowerManager extends PlayerManager {
|
||||
rank.getRarity(),
|
||||
0
|
||||
);
|
||||
|
||||
// Star Tower quests use the record's rating level, not its rarity.
|
||||
// NOTE: This must stay on the quest manager directly. Condition 504 is also
|
||||
// used by the build-rarity achievements (param1 = rarity), so routing this
|
||||
// through Player::trigger would feed them the level instead of the rarity.
|
||||
this.getPlayer().getQuestManager().trigger(
|
||||
QuestCondition.TowerBuildSpecificScoreWithTotal.getValue(),
|
||||
1,
|
||||
rank.getLevel(),
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,6 +438,7 @@ public class StarTowerManager extends PlayerManager {
|
||||
|
||||
// Trigger quest
|
||||
this.getPlayer().trigger(QuestCondition.TowerEnterFloor, 1);
|
||||
this.getPlayer().trigger(QuestCondition.TowerEnterTotal, 1);
|
||||
|
||||
// Success
|
||||
return change.setExtraData(this.game);
|
||||
@@ -439,6 +463,18 @@ public class StarTowerManager extends PlayerManager {
|
||||
// Add star tower history
|
||||
this.getPlayer().getProgress().addStarTowerLog(game.getId());
|
||||
|
||||
// Star Tower quests (group + difficulty)
|
||||
// NOTE: This must stay on the quest manager directly. Condition 506 is also
|
||||
// used by the "Monolith Conqueror" achievements, but they interpret the
|
||||
// params as (difficulty, 0) instead of (groupId, difficulty), so routing
|
||||
// this through Player::trigger would corrupt them.
|
||||
this.getPlayer().getQuestManager().trigger(
|
||||
QuestCondition.TowerClearSpecificGroupIdAndDifficulty.getValue(),
|
||||
1,
|
||||
game.getData().getGroupId(),
|
||||
game.getDifficulty()
|
||||
);
|
||||
|
||||
// Achievement conditions
|
||||
var achievements = this.getPlayer().getAchievementManager();
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import emu.nebula.GameConstants;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.game.inventory.ItemParamMap;
|
||||
import emu.nebula.game.player.PlayerChangeInfo;
|
||||
import emu.nebula.game.quest.QuestCondition;
|
||||
import emu.nebula.game.tower.room.RoomType;
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
|
||||
@@ -162,6 +163,9 @@ public class StarTowerBattleCase extends StarTowerBaseCase {
|
||||
// Bonus sub note chance (Note of Surprise)
|
||||
if (Utils.randomChance(this.getModifiers().getBonusSubNoteChance())) {
|
||||
subNotes += this.getModifiers().getBonusSubNotes();
|
||||
|
||||
// Star Tower quests
|
||||
this.getGame().getPlayer().trigger(QuestCondition.TowerSpecificNoteActivateTotal, 1);
|
||||
}
|
||||
|
||||
// Regular sub note drops
|
||||
|
||||
@@ -5,8 +5,8 @@ import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.game.achievement.AchievementCondition;
|
||||
import emu.nebula.game.player.PlayerChangeInfo;
|
||||
import emu.nebula.game.quest.QuestCondition;
|
||||
import emu.nebula.game.tower.StarTowerShopGoods;
|
||||
import emu.nebula.proto.PublicStarTower.HawkerCaseData;
|
||||
import emu.nebula.proto.PublicStarTower.HawkerGoods;
|
||||
@@ -176,8 +176,8 @@ public class StarTowerHawkerCase extends StarTowerBaseCase {
|
||||
// Set change info
|
||||
rsp.setChange(change.toProto());
|
||||
|
||||
// Achievement
|
||||
this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificShopReRollTotal, 1);
|
||||
// Achievement + Star Tower quests
|
||||
this.getGame().getPlayer().trigger(QuestCondition.TowerSpecificShopReRollTotal, 1);
|
||||
}
|
||||
|
||||
private void buy(int sid, StarTowerInteractResp rsp) {
|
||||
@@ -214,11 +214,11 @@ public class StarTowerHawkerCase extends StarTowerBaseCase {
|
||||
// Remove coins
|
||||
this.getGame().addItem(GameConstants.TOWER_COIN_ITEM_ID, -price, change);
|
||||
|
||||
// Achievements
|
||||
this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificDifficultyShopBuyTimes, 1);
|
||||
// Achievement + Star Tower quests
|
||||
this.getGame().getPlayer().trigger(QuestCondition.TowerSpecificDifficultyShopBuyTimes, 1);
|
||||
|
||||
if (goods.hasDiscount()) {
|
||||
this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificShopBuyDiscountTotal, 1);
|
||||
this.getGame().getPlayer().trigger(QuestCondition.TowerSpecificShopBuyDiscountTotal, 1);
|
||||
}
|
||||
|
||||
// Set change info
|
||||
|
||||
@@ -3,7 +3,7 @@ package emu.nebula.game.tower.cases;
|
||||
import java.util.List;
|
||||
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.game.achievement.AchievementCondition;
|
||||
import emu.nebula.game.quest.QuestCondition;
|
||||
import emu.nebula.game.tower.StarTowerGame;
|
||||
import emu.nebula.game.tower.StarTowerPotentialInfo;
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
@@ -118,8 +118,8 @@ public class StarTowerPotentialCase extends StarTowerBaseCase {
|
||||
|
||||
rsp.setChange(change.toProto());
|
||||
|
||||
// Achievement
|
||||
this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificPotentialReRollTotal, 1);
|
||||
// Achievement + Star Tower quests
|
||||
this.getGame().getPlayer().trigger(QuestCondition.TowerSpecificPotentialReRollTotal, 1);
|
||||
}
|
||||
|
||||
private void select(int index, StarTowerInteractResp rsp) {
|
||||
@@ -152,12 +152,12 @@ public class StarTowerPotentialCase extends StarTowerBaseCase {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.getGame().getPotentials().containsKey(charId)) {
|
||||
if (this.getGame().getPotentials().containsKey(potential.getId())) {
|
||||
// Enhancing potentials
|
||||
this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificPotentialLuckyTotal, 1);
|
||||
this.getGame().getPlayer().trigger(QuestCondition.TowerSpecificPotentialLuckyTotal, 1);
|
||||
} else {
|
||||
// Adding new potential
|
||||
this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificPotentialBonusTotal, 1);
|
||||
this.getGame().getPlayer().trigger(QuestCondition.TowerSpecificPotentialBonusTotal, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package emu.nebula.game.tower.cases;
|
||||
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.game.achievement.AchievementCondition;
|
||||
import emu.nebula.game.quest.QuestCondition;
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
|
||||
@@ -76,8 +76,8 @@ public class StarTowerStrengthenMachineCase extends StarTowerBaseCase {
|
||||
// Increment price
|
||||
this.increasePrice();
|
||||
|
||||
// Achievement
|
||||
this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificDifficultyStrengthenMachineTotal, 1);
|
||||
// Trigger quests + achievements
|
||||
this.getGame().getPlayer().trigger(QuestCondition.TowerSpecificDifficultyStrengthenMachineTotal, 1, 0);
|
||||
}
|
||||
|
||||
// Set success result
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
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.net.GameSession;
|
||||
|
||||
@HandlerId(NetMsgId.quest_tower_reward_receive_req)
|
||||
public class HandlerQuestTowerRewardReceiveReq extends NetHandler {
|
||||
|
||||
@Override
|
||||
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||
// Parse request
|
||||
var req = UI32.parseFrom(message);
|
||||
|
||||
// Receive rewards
|
||||
var change = session.getPlayer().getQuestManager().receiveStarTowerQuestReward(req.getValue());
|
||||
|
||||
if (change == null) {
|
||||
return session.encodeMsg(NetMsgId.quest_tower_reward_receive_failed_ack);
|
||||
}
|
||||
|
||||
// Encode and send
|
||||
return session.encodeMsg(NetMsgId.quest_tower_reward_receive_succeed_ack, change.toProto());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,515 @@
|
||||
[
|
||||
{
|
||||
"Id": 100,
|
||||
"CompleteCond": 515,
|
||||
"Aim": 1,
|
||||
"Param1": 10101,
|
||||
"ParamCond1": 0,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 200,
|
||||
"CompleteCond": 515,
|
||||
"Aim": 1,
|
||||
"Param1": 10301,
|
||||
"ParamCond1": 0,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 300,
|
||||
"CompleteCond": 527,
|
||||
"Aim": 2,
|
||||
"Param1": 10601,
|
||||
"ParamCond1": 0,
|
||||
"Param2": 10602,
|
||||
"ParamCond2": 0
|
||||
},
|
||||
{
|
||||
"Id": 400,
|
||||
"CompleteCond": 515,
|
||||
"Aim": 1,
|
||||
"Param1": 10901,
|
||||
"ParamCond1": 0,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 500,
|
||||
"CompleteCond": 527,
|
||||
"Aim": 2,
|
||||
"Param1": 20301,
|
||||
"ParamCond1": 0,
|
||||
"Param2": 20302,
|
||||
"ParamCond2": 0
|
||||
},
|
||||
{
|
||||
"Id": 600,
|
||||
"CompleteCond": 515,
|
||||
"Aim": 1,
|
||||
"Param1": 20601,
|
||||
"ParamCond1": 0,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 700,
|
||||
"CompleteCond": 527,
|
||||
"Aim": 2,
|
||||
"Param1": 20901,
|
||||
"ParamCond1": 0,
|
||||
"Param2": 20902,
|
||||
"ParamCond2": 0
|
||||
},
|
||||
{
|
||||
"Id": 800,
|
||||
"CompleteCond": 515,
|
||||
"Aim": 1,
|
||||
"Param1": 30301,
|
||||
"ParamCond1": 0,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 900,
|
||||
"CompleteCond": 515,
|
||||
"Aim": 1,
|
||||
"Param1": 30601,
|
||||
"ParamCond1": 0,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 1000,
|
||||
"CompleteCond": 515,
|
||||
"Aim": 1,
|
||||
"Param1": 30901,
|
||||
"ParamCond1": 0,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 1100,
|
||||
"CompleteCond": 515,
|
||||
"Aim": 1,
|
||||
"Param1": 40401,
|
||||
"ParamCond1": 0,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 101,
|
||||
"CompleteCond": 510,
|
||||
"Aim": 1,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 102,
|
||||
"CompleteCond": 506,
|
||||
"Aim": 1,
|
||||
"Param1": 2,
|
||||
"ParamCond1": 0,
|
||||
"Param2": 1,
|
||||
"ParamCond2": 4
|
||||
},
|
||||
{
|
||||
"Id": 103,
|
||||
"CompleteCond": 506,
|
||||
"Aim": 1,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 2,
|
||||
"ParamCond2": 4
|
||||
},
|
||||
{
|
||||
"Id": 201,
|
||||
"CompleteCond": 506,
|
||||
"Aim": 2,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 2,
|
||||
"ParamCond2": 4
|
||||
},
|
||||
{
|
||||
"Id": 202,
|
||||
"CompleteCond": 514,
|
||||
"Aim": 10,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 203,
|
||||
"CompleteCond": 513,
|
||||
"Aim": 30,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 301,
|
||||
"CompleteCond": 504,
|
||||
"Aim": 1,
|
||||
"Param1": 5,
|
||||
"ParamCond1": 4,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 302,
|
||||
"CompleteCond": 513,
|
||||
"Aim": 80,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 303,
|
||||
"CompleteCond": 517,
|
||||
"Aim": 10,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 401,
|
||||
"CompleteCond": 506,
|
||||
"Aim": 1,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 3,
|
||||
"ParamCond2": 4
|
||||
},
|
||||
{
|
||||
"Id": 402,
|
||||
"CompleteCond": 514,
|
||||
"Aim": 20,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 403,
|
||||
"CompleteCond": 522,
|
||||
"Aim": 6,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 501,
|
||||
"CompleteCond": 535,
|
||||
"Aim": 8,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 502,
|
||||
"CompleteCond": 504,
|
||||
"Aim": 1,
|
||||
"Param1": 10,
|
||||
"ParamCond1": 4,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 503,
|
||||
"CompleteCond": 513,
|
||||
"Aim": 150,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 504,
|
||||
"CompleteCond": 536,
|
||||
"Aim": 10,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 505,
|
||||
"CompleteCond": 517,
|
||||
"Aim": 20,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 601,
|
||||
"CompleteCond": 506,
|
||||
"Aim": 1,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 4,
|
||||
"ParamCond2": 4
|
||||
},
|
||||
{
|
||||
"Id": 602,
|
||||
"CompleteCond": 514,
|
||||
"Aim": 50,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 603,
|
||||
"CompleteCond": 522,
|
||||
"Aim": 20,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 605,
|
||||
"CompleteCond": 531,
|
||||
"Aim": 3,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 701,
|
||||
"CompleteCond": 533,
|
||||
"Aim": 3,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 702,
|
||||
"CompleteCond": 504,
|
||||
"Aim": 1,
|
||||
"Param1": 20,
|
||||
"ParamCond1": 4,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 703,
|
||||
"CompleteCond": 513,
|
||||
"Aim": 500,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 704,
|
||||
"CompleteCond": 536,
|
||||
"Aim": 25,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 705,
|
||||
"CompleteCond": 517,
|
||||
"Aim": 30,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 801,
|
||||
"CompleteCond": 506,
|
||||
"Aim": 5,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 4,
|
||||
"ParamCond2": 4
|
||||
},
|
||||
{
|
||||
"Id": 802,
|
||||
"CompleteCond": 514,
|
||||
"Aim": 100,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 803,
|
||||
"CompleteCond": 522,
|
||||
"Aim": 80,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 804,
|
||||
"CompleteCond": 529,
|
||||
"Aim": 20,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 901,
|
||||
"CompleteCond": 506,
|
||||
"Aim": 2,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 5,
|
||||
"ParamCond2": 4
|
||||
},
|
||||
{
|
||||
"Id": 902,
|
||||
"CompleteCond": 504,
|
||||
"Aim": 1,
|
||||
"Param1": 25,
|
||||
"ParamCond1": 4,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 903,
|
||||
"CompleteCond": 513,
|
||||
"Aim": 2000,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 904,
|
||||
"CompleteCond": 536,
|
||||
"Aim": 50,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 905,
|
||||
"CompleteCond": 517,
|
||||
"Aim": 40,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 906,
|
||||
"CompleteCond": 530,
|
||||
"Aim": 10,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 1001,
|
||||
"CompleteCond": 506,
|
||||
"Aim": 2,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 6,
|
||||
"ParamCond2": 4
|
||||
},
|
||||
{
|
||||
"Id": 1002,
|
||||
"CompleteCond": 514,
|
||||
"Aim": 200,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 1003,
|
||||
"CompleteCond": 522,
|
||||
"Aim": 150,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 1004,
|
||||
"CompleteCond": 533,
|
||||
"Aim": 10,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 1005,
|
||||
"CompleteCond": 534,
|
||||
"Aim": 5,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 1101,
|
||||
"CompleteCond": 506,
|
||||
"Aim": 3,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 8,
|
||||
"ParamCond2": 4
|
||||
},
|
||||
{
|
||||
"Id": 1102,
|
||||
"CompleteCond": 513,
|
||||
"Aim": 3000,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 1103,
|
||||
"CompleteCond": 504,
|
||||
"Aim": 1,
|
||||
"Param1": 31,
|
||||
"ParamCond1": 4,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 1104,
|
||||
"CompleteCond": 536,
|
||||
"Aim": 80,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
},
|
||||
{
|
||||
"Id": 1105,
|
||||
"CompleteCond": 533,
|
||||
"Aim": 30,
|
||||
"Param1": 0,
|
||||
"ParamCond1": 1,
|
||||
"Param2": 0,
|
||||
"ParamCond2": 1
|
||||
}
|
||||
]
|
||||
Reference in new issue
Block a user