mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-03-13 06:47:26 +08:00
Merge remote-tracking branch 'origin/development' into development
This commit is contained in:
commit
cfccb2d991
@ -404,6 +404,10 @@ public final class GameData {
|
|||||||
private static final Int2ObjectMap<WeaponPromoteData> weaponPromoteDataMap =
|
private static final Int2ObjectMap<WeaponPromoteData> weaponPromoteDataMap =
|
||||||
new Int2ObjectOpenHashMap<>();
|
new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Int2ObjectMap<StatuePromoteData> statuePromoteDataMap =
|
||||||
|
new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private static final Int2ObjectMap<WeatherData> weatherDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<WeatherData> weatherDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
@ -567,6 +571,10 @@ public final class GameData {
|
|||||||
return weaponPromoteDataMap.get((promoteId << 8) + promoteLevel);
|
return weaponPromoteDataMap.get((promoteId << 8) + promoteLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static StatuePromoteData getStatuePromoteData(int cityId, int promoteLevel) {
|
||||||
|
return statuePromoteDataMap.get((cityId << 8) + promoteLevel);
|
||||||
|
}
|
||||||
|
|
||||||
public static ReliquaryLevelData getRelicLevelData(int rankLevel, int level) {
|
public static ReliquaryLevelData getRelicLevelData(int rankLevel, int level) {
|
||||||
return reliquaryLevelDataMap.get((rankLevel << 8) + level);
|
return reliquaryLevelDataMap.get((rankLevel << 8) + level);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@ResourceType(name = "StatuePromoteExcelConfigData.json")
|
||||||
|
public class StatuePromoteData extends GameResource {
|
||||||
|
@Getter @Setter private int level;
|
||||||
|
@Getter @Setter private int cityId;
|
||||||
|
@Getter @Setter private ItemParamData[] costItems;
|
||||||
|
@Getter @Setter private int[] rewardIdList;
|
||||||
|
@Getter @Setter private int stamina;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return (cityId << 8) + level;
|
||||||
|
}
|
||||||
|
}
|
28
src/main/java/emu/grasscutter/game/city/CityInfoData.java
Normal file
28
src/main/java/emu/grasscutter/game/city/CityInfoData.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package emu.grasscutter.game.city;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.Entity;
|
||||||
|
import emu.grasscutter.net.proto.CityInfoOuterClass.CityInfo;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class CityInfoData {
|
||||||
|
@Getter @Setter private int cityId;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
private int level = 1; // level of the city (include level SotS, level Frostbearing Trees, etc.)
|
||||||
|
|
||||||
|
@Getter @Setter private int numCrystal = 0; // number of crystals in the city
|
||||||
|
|
||||||
|
public CityInfoData(int cityId) {
|
||||||
|
this.cityId = cityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CityInfo toProto() {
|
||||||
|
return CityInfo.newBuilder()
|
||||||
|
.setCityId(cityId)
|
||||||
|
.setLevel(level)
|
||||||
|
.setCrystalNum(numCrystal)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
@ -81,7 +81,7 @@ public final class DungeonManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFinishedSuccessfully() {
|
public boolean isFinishedSuccessfully() {
|
||||||
if (passConfigData.getLogicType() == null) return false;
|
if (passConfigData.getConds() == null) return false;
|
||||||
return LogicType.calculate(passConfigData.getLogicType(), finishedConditions);
|
return LogicType.calculate(passConfigData.getLogicType(), finishedConditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,14 +286,18 @@ public final class DungeonManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void finishDungeon() {
|
public void finishDungeon() {
|
||||||
// Mark the dungeon has completed for the players.
|
this.notifyEndDungeon(true);
|
||||||
var dungeonId = this.getDungeonData().getId();
|
this.endDungeon(BaseDungeonResult.DungeonEndReason.COMPLETED);
|
||||||
this.getScene()
|
}
|
||||||
.getPlayers()
|
|
||||||
.forEach(player -> player.getPlayerProgress().markDungeonAsComplete(dungeonId));
|
|
||||||
|
|
||||||
notifyEndDungeon(true);
|
public void quitDungeon() {
|
||||||
endDungeon(BaseDungeonResult.DungeonEndReason.COMPLETED);
|
this.notifyEndDungeon(false);
|
||||||
|
this.endDungeon(BaseDungeonResult.DungeonEndReason.QUIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void failDungeon() {
|
||||||
|
this.notifyEndDungeon(false);
|
||||||
|
this.endDungeon(BaseDungeonResult.DungeonEndReason.FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyEndDungeon(boolean successfully) {
|
public void notifyEndDungeon(boolean successfully) {
|
||||||
@ -301,8 +305,11 @@ public final class DungeonManager {
|
|||||||
.getPlayers()
|
.getPlayers()
|
||||||
.forEach(
|
.forEach(
|
||||||
p -> {
|
p -> {
|
||||||
// Trigger the fail event if needed.
|
// Trigger the fail and success event.
|
||||||
if (!successfully) {
|
if (successfully) {
|
||||||
|
var dungeonId = this.getDungeonData().getId();
|
||||||
|
p.getPlayerProgress().markDungeonAsComplete(dungeonId);
|
||||||
|
} else {
|
||||||
p.getQuestManager()
|
p.getQuestManager()
|
||||||
.queueEvent(QuestContent.QUEST_CONTENT_FAIL_DUNGEON, dungeonData.getId());
|
.queueEvent(QuestContent.QUEST_CONTENT_FAIL_DUNGEON, dungeonData.getId());
|
||||||
}
|
}
|
||||||
@ -317,16 +324,6 @@ public final class DungeonManager {
|
|||||||
.callEvent(new ScriptArgs(0, EventType.EVENT_DUNGEON_SETTLE, successfully ? 1 : 0));
|
.callEvent(new ScriptArgs(0, EventType.EVENT_DUNGEON_SETTLE, successfully ? 1 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void quitDungeon() {
|
|
||||||
notifyEndDungeon(false);
|
|
||||||
endDungeon(BaseDungeonResult.DungeonEndReason.QUIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void failDungeon() {
|
|
||||||
notifyEndDungeon(false);
|
|
||||||
endDungeon(BaseDungeonResult.DungeonEndReason.FAILED);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void endDungeon(BaseDungeonResult.DungeonEndReason endReason) {
|
public void endDungeon(BaseDungeonResult.DungeonEndReason endReason) {
|
||||||
if (scene.getDungeonSettleListeners() != null) {
|
if (scene.getDungeonSettleListeners() != null) {
|
||||||
scene.getDungeonSettleListeners().forEach(o -> o.onDungeonSettle(this, endReason));
|
scene.getDungeonSettleListeners().forEach(o -> o.onDungeonSettle(this, endReason));
|
||||||
|
@ -150,6 +150,7 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
public void updateState(int state) {
|
public void updateState(int state) {
|
||||||
if (state == this.getState()) return; // Don't triggers events
|
if (state == this.getState()) return; // Don't triggers events
|
||||||
|
|
||||||
|
var oldState = this.getState();
|
||||||
this.setState(state);
|
this.setState(state);
|
||||||
ticksSinceChange = getScene().getSceneTimeSeconds();
|
ticksSinceChange = getScene().getSceneTimeSeconds();
|
||||||
this.getScene().broadcastPacket(new PacketGadgetStateNotify(this, state));
|
this.getScene().broadcastPacket(new PacketGadgetStateNotify(this, state));
|
||||||
@ -157,7 +158,11 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
.getScriptManager()
|
.getScriptManager()
|
||||||
.callEvent(
|
.callEvent(
|
||||||
new ScriptArgs(
|
new ScriptArgs(
|
||||||
this.getGroupId(), EventType.EVENT_GADGET_STATE_CHANGE, state, this.getConfigId()));
|
this.getGroupId(),
|
||||||
|
EventType.EVENT_GADGET_STATE_CHANGE,
|
||||||
|
state,
|
||||||
|
this.getConfigId())
|
||||||
|
.setParam3(oldState));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated(forRemoval = true) // Dont use!
|
@Deprecated(forRemoval = true) // Dont use!
|
||||||
|
@ -36,4 +36,9 @@ public class EquipInventoryTab implements InventoryTab {
|
|||||||
public int getMaxCapacity() {
|
public int getMaxCapacity() {
|
||||||
return this.maxCapacity;
|
return this.maxCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCountById(int itemId) {
|
||||||
|
return (int) items.stream().filter(item -> item.getItemId() == itemId).count();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ public class GameItem {
|
|||||||
|
|
||||||
public void checkIsNew(Inventory inventory) {
|
public void checkIsNew(Inventory inventory) {
|
||||||
// display notification when player obtain new item
|
// display notification when player obtain new item
|
||||||
if (inventory.getItemByGuid(this.itemId) == null) {
|
if (inventory.getItemById(this.itemId) == null) {
|
||||||
this.newItem = true;
|
this.newItem = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ import emu.grasscutter.utils.Utils;
|
|||||||
import it.unimi.dsi.fastutil.ints.*;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
import it.unimi.dsi.fastutil.longs.*;
|
import it.unimi.dsi.fastutil.longs.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
||||||
private final Long2ObjectMap<GameItem> store;
|
private final Long2ObjectMap<GameItem> store;
|
||||||
@ -62,6 +64,24 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
|||||||
return this.getItems().get(id);
|
return this.getItems().get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable public InventoryTab getInventoryTabByItemId(int itemId) {
|
||||||
|
val itemData = GameData.getItemDataMap().get(itemId);
|
||||||
|
if (itemData == null || itemData.getItemType() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getInventoryTab(itemData.getItemType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable public GameItem getItemById(int itemId) {
|
||||||
|
val inventoryTab = this.getInventoryTabByItemId(itemId);
|
||||||
|
return inventoryTab != null ? inventoryTab.getItemById(itemId) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getItemCountById(int itemId) {
|
||||||
|
val inventoryTab = this.getInventoryTabByItemId(itemId);
|
||||||
|
return inventoryTab != null ? inventoryTab.getItemCountById(itemId) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean addItem(int itemId) {
|
public boolean addItem(int itemId) {
|
||||||
return addItem(itemId, 1);
|
return addItem(itemId, 1);
|
||||||
}
|
}
|
||||||
@ -562,7 +582,7 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
|||||||
tab = getInventoryTab(item.getItemData().getItemType());
|
tab = getInventoryTab(item.getItemData().getItemType());
|
||||||
}
|
}
|
||||||
|
|
||||||
putItem(item, tab);
|
this.putItem(item, tab);
|
||||||
|
|
||||||
// Equip to a character if possible
|
// Equip to a character if possible
|
||||||
if (item.isEquipped()) {
|
if (item.isEquipped()) {
|
||||||
|
@ -10,4 +10,6 @@ public interface InventoryTab {
|
|||||||
int getSize();
|
int getSize();
|
||||||
|
|
||||||
int getMaxCapacity();
|
int getMaxCapacity();
|
||||||
|
|
||||||
|
int getItemCountById(int itemId);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package emu.grasscutter.game.inventory;
|
|||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
public class MaterialInventoryTab implements InventoryTab {
|
public class MaterialInventoryTab implements InventoryTab {
|
||||||
private final Int2ObjectMap<GameItem> items;
|
private final Int2ObjectMap<GameItem> items;
|
||||||
@ -36,4 +37,10 @@ public class MaterialInventoryTab implements InventoryTab {
|
|||||||
public int getMaxCapacity() {
|
public int getMaxCapacity() {
|
||||||
return this.maxCapacity;
|
return this.maxCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCountById(int itemId) {
|
||||||
|
val item = getItemById(itemId);
|
||||||
|
return item != null ? item.getCount() : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,24 @@ package emu.grasscutter.game.managers;
|
|||||||
|
|
||||||
import ch.qos.logback.classic.Logger;
|
import ch.qos.logback.classic.Logger;
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
|
import emu.grasscutter.data.excels.CityData;
|
||||||
|
import emu.grasscutter.data.excels.RewardData;
|
||||||
|
import emu.grasscutter.game.city.CityInfoData;
|
||||||
import emu.grasscutter.game.entity.EntityAvatar;
|
import emu.grasscutter.game.entity.EntityAvatar;
|
||||||
import emu.grasscutter.game.player.BasePlayerManager;
|
import emu.grasscutter.game.player.BasePlayerManager;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
import emu.grasscutter.game.props.FightProperty;
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
import emu.grasscutter.game.props.PlayerProperty;
|
import emu.grasscutter.game.props.PlayerProperty;
|
||||||
|
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||||
import emu.grasscutter.net.proto.ChangeHpReasonOuterClass.ChangeHpReason;
|
import emu.grasscutter.net.proto.ChangeHpReasonOuterClass.ChangeHpReason;
|
||||||
import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
|
import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
|
||||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropChangeReasonNotify;
|
import emu.grasscutter.server.packet.send.PacketEntityFightPropChangeReasonNotify;
|
||||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketLevelupCityRsp;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketSceneForceUnlockNotify;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
@ -208,4 +217,91 @@ public class SotSManager extends BasePlayerManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CityData getCityByAreaId(int areaId) {
|
||||||
|
return GameData.getCityDataMap().values().stream()
|
||||||
|
.filter(city -> city.getAreaIdVec().contains(areaId))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CityInfoData getCityInfo(int cityId) {
|
||||||
|
if (player.getCityInfoData() == null) player.setCityInfoData(new HashMap<>());
|
||||||
|
var cityInfo = player.getCityInfoData().get(cityId);
|
||||||
|
if (cityInfo == null) {
|
||||||
|
cityInfo = new CityInfoData(cityId);
|
||||||
|
player.getCityInfoData().put(cityId, cityInfo);
|
||||||
|
}
|
||||||
|
return cityInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addCityInfo(CityInfoData cityInfoData) {
|
||||||
|
if (player.getCityInfoData() == null) player.setCityInfoData(new HashMap<>());
|
||||||
|
|
||||||
|
player.getCityInfoData().put(cityInfoData.getCityId(), cityInfoData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void levelUpSotS(int areaId, int sceneId, int itemNum) {
|
||||||
|
if (itemNum <= 0) return;
|
||||||
|
|
||||||
|
// search city by areaId
|
||||||
|
var city = this.getCityByAreaId(areaId);
|
||||||
|
if (city == null) return;
|
||||||
|
var cityId = city.getCityId();
|
||||||
|
|
||||||
|
// check data level up
|
||||||
|
var cityInfo = this.getCityInfo(cityId);
|
||||||
|
var nextStatuePromoteData = GameData.getStatuePromoteData(cityId, cityInfo.getLevel() + 1);
|
||||||
|
if (nextStatuePromoteData == null) return;
|
||||||
|
var nextLevelCrystal = nextStatuePromoteData.getCostItems()[0].getCount();
|
||||||
|
|
||||||
|
// delete item from inventory
|
||||||
|
var itemNumrequired = Math.min(itemNum, nextLevelCrystal - cityInfo.getNumCrystal());
|
||||||
|
player
|
||||||
|
.getInventory()
|
||||||
|
.removeItemById(nextStatuePromoteData.getCostItems()[0].getId(), itemNumrequired);
|
||||||
|
|
||||||
|
// update number oculi
|
||||||
|
cityInfo.setNumCrystal(cityInfo.getNumCrystal() + itemNumrequired);
|
||||||
|
|
||||||
|
// hanble quest
|
||||||
|
if (itemNumrequired >= 1)
|
||||||
|
player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_CITY_LEVEL_UP, cityId, areaId);
|
||||||
|
|
||||||
|
// handle oculi overflow
|
||||||
|
if (cityInfo.getNumCrystal() >= nextLevelCrystal) {
|
||||||
|
cityInfo.setNumCrystal(cityInfo.getNumCrystal() - nextLevelCrystal);
|
||||||
|
cityInfo.setLevel(cityInfo.getLevel() + 1);
|
||||||
|
|
||||||
|
// update max stamina and notify client
|
||||||
|
player.setProperty(
|
||||||
|
PlayerProperty.PROP_MAX_STAMINA,
|
||||||
|
player.getProperty(PlayerProperty.PROP_MAX_STAMINA)
|
||||||
|
+ nextStatuePromoteData.getStamina() * 100,
|
||||||
|
true);
|
||||||
|
|
||||||
|
// Add items to inventory
|
||||||
|
if (nextStatuePromoteData.getRewardIdList() != null) {
|
||||||
|
for (var rewardId : nextStatuePromoteData.getRewardIdList()) {
|
||||||
|
RewardData rewardData = GameData.getRewardDataMap().get(rewardId);
|
||||||
|
if (rewardData == null) continue;
|
||||||
|
|
||||||
|
player
|
||||||
|
.getInventory()
|
||||||
|
.addItemParamDatas(rewardData.getRewardItemList(), ActionReason.CityLevelupReward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unlock forcescene
|
||||||
|
player.sendPacket(new PacketSceneForceUnlockNotify(1, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
// update data
|
||||||
|
this.addCityInfo(cityInfo);
|
||||||
|
|
||||||
|
// Packets
|
||||||
|
player.sendPacket(
|
||||||
|
new PacketLevelupCityRsp(
|
||||||
|
sceneId, cityInfo.getLevel(), cityId, cityInfo.getNumCrystal(), areaId, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -389,6 +389,9 @@ public class StaminaManager extends BasePlayerManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update previous motion state
|
||||||
|
this.previousState = currentState;
|
||||||
|
|
||||||
// Update the current state.
|
// Update the current state.
|
||||||
this.currentState = motionState;
|
this.currentState = motionState;
|
||||||
// logger.trace(currentState + "\t" + (notifyEntityId == currentAvatarEntityId ? "character" : "vehicle"));
|
// logger.trace(currentState + "\t" + (notifyEntityId == currentAvatarEntityId ? "character" : "vehicle"));
|
||||||
@ -417,6 +420,11 @@ public class StaminaManager extends BasePlayerManager {
|
|||||||
// Internal handler
|
// Internal handler
|
||||||
|
|
||||||
private void handleImmediateStamina(GameSession session, @NotNull MotionState motionState) {
|
private void handleImmediateStamina(GameSession session, @NotNull MotionState motionState) {
|
||||||
|
// Don't double dip on sustained stamina start costs
|
||||||
|
if (previousState == currentState) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (motionState) {
|
switch (motionState) {
|
||||||
case MOTION_STATE_CLIMB ->
|
case MOTION_STATE_CLIMB ->
|
||||||
updateStaminaRelative(session, new Consumption(ConsumptionType.CLIMB_START), true);
|
updateStaminaRelative(session, new Consumption(ConsumptionType.CLIMB_START), true);
|
||||||
|
@ -15,6 +15,7 @@ import emu.grasscutter.game.activity.ActivityManager;
|
|||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.game.avatar.AvatarStorage;
|
import emu.grasscutter.game.avatar.AvatarStorage;
|
||||||
import emu.grasscutter.game.battlepass.BattlePassManager;
|
import emu.grasscutter.game.battlepass.BattlePassManager;
|
||||||
|
import emu.grasscutter.game.city.CityInfoData;
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
import emu.grasscutter.game.entity.GameEntity;
|
||||||
import emu.grasscutter.game.expedition.ExpeditionInfo;
|
import emu.grasscutter.game.expedition.ExpeditionInfo;
|
||||||
import emu.grasscutter.game.friends.FriendsList;
|
import emu.grasscutter.game.friends.FriendsList;
|
||||||
@ -28,7 +29,6 @@ import emu.grasscutter.game.mail.MailHandler;
|
|||||||
import emu.grasscutter.game.managers.FurnitureManager;
|
import emu.grasscutter.game.managers.FurnitureManager;
|
||||||
import emu.grasscutter.game.managers.ResinManager;
|
import emu.grasscutter.game.managers.ResinManager;
|
||||||
import emu.grasscutter.game.managers.SatiationManager;
|
import emu.grasscutter.game.managers.SatiationManager;
|
||||||
import emu.grasscutter.game.managers.SotSManager;
|
|
||||||
import emu.grasscutter.game.managers.cooking.ActiveCookCompoundData;
|
import emu.grasscutter.game.managers.cooking.ActiveCookCompoundData;
|
||||||
import emu.grasscutter.game.managers.cooking.CookingCompoundManager;
|
import emu.grasscutter.game.managers.cooking.CookingCompoundManager;
|
||||||
import emu.grasscutter.game.managers.cooking.CookingManager;
|
import emu.grasscutter.game.managers.cooking.CookingManager;
|
||||||
@ -38,6 +38,7 @@ import emu.grasscutter.game.managers.forging.ActiveForgeData;
|
|||||||
import emu.grasscutter.game.managers.forging.ForgingManager;
|
import emu.grasscutter.game.managers.forging.ForgingManager;
|
||||||
import emu.grasscutter.game.managers.mapmark.MapMark;
|
import emu.grasscutter.game.managers.mapmark.MapMark;
|
||||||
import emu.grasscutter.game.managers.mapmark.MapMarksManager;
|
import emu.grasscutter.game.managers.mapmark.MapMarksManager;
|
||||||
|
import emu.grasscutter.game.managers.SotSManager;
|
||||||
import emu.grasscutter.game.managers.stamina.StaminaManager;
|
import emu.grasscutter.game.managers.stamina.StaminaManager;
|
||||||
import emu.grasscutter.game.props.*;
|
import emu.grasscutter.game.props.*;
|
||||||
import emu.grasscutter.game.quest.QuestManager;
|
import emu.grasscutter.game.quest.QuestManager;
|
||||||
@ -221,6 +222,8 @@ public class Player implements PlayerHook, FieldFetch {
|
|||||||
|
|
||||||
@Getter @Setter private ElementType mainCharacterElement = ElementType.None;
|
@Getter @Setter private ElementType mainCharacterElement = ElementType.None;
|
||||||
|
|
||||||
|
@Getter @Setter private Map<Integer, CityInfoData> cityInfoData; // cityId -> CityData
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only!
|
@SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only!
|
||||||
public Player() {
|
public Player() {
|
||||||
@ -267,6 +270,7 @@ public class Player implements PlayerHook, FieldFetch {
|
|||||||
this.chatEmojiIdList = new ArrayList<>();
|
this.chatEmojiIdList = new ArrayList<>();
|
||||||
this.playerProgress = new PlayerProgress();
|
this.playerProgress = new PlayerProgress();
|
||||||
this.activeQuestTimers = new HashSet<>();
|
this.activeQuestTimers = new HashSet<>();
|
||||||
|
this.cityInfoData = new HashMap<>();
|
||||||
|
|
||||||
this.attackResults = new LinkedBlockingQueue<>();
|
this.attackResults = new LinkedBlockingQueue<>();
|
||||||
this.coopRequests = new Int2ObjectOpenHashMap<>();
|
this.coopRequests = new Int2ObjectOpenHashMap<>();
|
||||||
@ -1520,6 +1524,8 @@ public class Player implements PlayerHook, FieldFetch {
|
|||||||
PropChangeReason.PROP_CHANGE_REASON_PLAYER_ADD_EXP));
|
PropChangeReason.PROP_CHANGE_REASON_PLAYER_ADD_EXP));
|
||||||
case PROP_PLAYER_LEVEL -> this.sendPacket(new PacketPlayerPropChangeReasonNotify(this, prop, currentValue, value,
|
case PROP_PLAYER_LEVEL -> this.sendPacket(new PacketPlayerPropChangeReasonNotify(this, prop, currentValue, value,
|
||||||
PropChangeReason.PROP_CHANGE_REASON_LEVELUP));
|
PropChangeReason.PROP_CHANGE_REASON_LEVELUP));
|
||||||
|
case PROP_MAX_STAMINA -> this.sendPacket(new PacketPlayerPropChangeReasonNotify(this, prop, currentValue, value,
|
||||||
|
PropChangeReason.PROP_CHANGE_REASON_CITY_LEVELUP));
|
||||||
|
|
||||||
// TODO: Handle world level changing.
|
// TODO: Handle world level changing.
|
||||||
// case PROP_PLAYER_WORLD_LEVEL -> this.sendPacket(new PacketPlayerPropChangeReasonNotify(this, prop, currentValue, value,
|
// case PROP_PLAYER_WORLD_LEVEL -> this.sendPacket(new PacketPlayerPropChangeReasonNotify(this, prop, currentValue, value,
|
||||||
|
@ -16,6 +16,7 @@ import emu.grasscutter.net.proto.ChildQuestOuterClass.ChildQuest;
|
|||||||
import emu.grasscutter.net.proto.ParentQuestOuterClass.ParentQuest;
|
import emu.grasscutter.net.proto.ParentQuestOuterClass.ParentQuest;
|
||||||
import emu.grasscutter.server.packet.send.*;
|
import emu.grasscutter.server.packet.send.*;
|
||||||
import emu.grasscutter.utils.ConversionUtils;
|
import emu.grasscutter.utils.ConversionUtils;
|
||||||
|
import emu.grasscutter.utils.Utils;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
@ -120,6 +121,15 @@ public class GameMainQuest {
|
|||||||
this.triggerQuestVarAction(i, this.questVars[i]);
|
this.triggerQuestVarAction(i, this.questVars[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void randomQuestVar(int i, int low, int high) {
|
||||||
|
int previousValue = this.questVars[i];
|
||||||
|
this.questVars[i] = Utils.random.nextInt(low, high);
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.debug("questVar {} value randomized from {} to {}", i, previousValue, this.questVars[i]);
|
||||||
|
|
||||||
|
this.triggerQuestVarAction(i, this.questVars[i]);
|
||||||
|
}
|
||||||
|
|
||||||
public void triggerQuestVarAction(int index, int value) {
|
public void triggerQuestVarAction(int index, int value) {
|
||||||
var questManager = this.getQuestManager();
|
var questManager = this.getQuestManager();
|
||||||
questManager.queueEvent(QuestCond.QUEST_COND_QUEST_VAR_EQUAL, index, value);
|
questManager.queueEvent(QuestCond.QUEST_COND_QUEST_VAR_EQUAL, index, value);
|
||||||
|
@ -172,6 +172,8 @@ public class GameQuest {
|
|||||||
this.failProgressList = new int[questData.getFailCond().size()];
|
this.failProgressList = new int[questData.getFailCond().size()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.getMainQuest().getTalks().values().removeIf(talk -> talk.getId() == this.getSubQuestId());
|
||||||
|
|
||||||
this.getOwner().getPlayerProgress().resetCurrentProgress(String.valueOf(this.subQuestId));
|
this.getOwner().getPlayerProgress().resetCurrentProgress(String.valueOf(this.subQuestId));
|
||||||
|
|
||||||
setState(QuestState.QUEST_STATE_UNSTARTED);
|
setState(QuestState.QUEST_STATE_UNSTARTED);
|
||||||
|
@ -282,7 +282,7 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GameMainQuest getMainQuestByTalkId(int talkId) {
|
public GameMainQuest getMainQuestByTalkId(int talkId) {
|
||||||
int mainQuestId = GameData.getQuestTalkMap().getOrDefault(talkId, talkId / 100);
|
var mainQuestId = GameData.getQuestTalkMap().getOrDefault(talkId, 0);
|
||||||
return getMainQuestById(mainQuestId);
|
return getMainQuestById(mainQuestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@ package emu.grasscutter.game.quest.conditions;
|
|||||||
|
|
||||||
import static emu.grasscutter.game.quest.enums.QuestCond.QUEST_COND_COMPLETE_TALK;
|
import static emu.grasscutter.game.quest.enums.QuestCond.QUEST_COND_COMPLETE_TALK;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
|
||||||
import emu.grasscutter.data.GameData;
|
|
||||||
import emu.grasscutter.data.excels.quest.QuestData;
|
import emu.grasscutter.data.excels.quest.QuestData;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.quest.QuestValueCond;
|
import emu.grasscutter.game.quest.QuestValueCond;
|
||||||
@ -20,16 +18,12 @@ public class ConditionCompleteTalk extends BaseCondition {
|
|||||||
String paramStr,
|
String paramStr,
|
||||||
int... params) {
|
int... params) {
|
||||||
val talkId = condition.getParam()[0];
|
val talkId = condition.getParam()[0];
|
||||||
val unknownParam = condition.getParam()[1]; // e.g. 3 for 7081601
|
|
||||||
val checkMainQuest = owner.getQuestManager().getMainQuestByTalkId(talkId);
|
val checkMainQuest = owner.getQuestManager().getMainQuestByTalkId(talkId);
|
||||||
if (checkMainQuest == null
|
if (checkMainQuest == null) {
|
||||||
|| GameData.getMainQuestDataMap().get(checkMainQuest.getParentQuestId()).getTalks()
|
return talkId == params[0];
|
||||||
== null) {
|
|
||||||
Grasscutter.getLogger()
|
|
||||||
.debug("Warning: mainQuest {} hasn't been started yet, or has no talks", talkId / 100);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val talkData = checkMainQuest.getTalks().get(talkId);
|
val talkData = checkMainQuest.getTalks().get(talkId);
|
||||||
return talkData != null || checkMainQuest.getChildQuestById(talkId) != null;
|
return talkData != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@ public class ConditionItemNumLessThan extends BaseCondition {
|
|||||||
String paramStr,
|
String paramStr,
|
||||||
int... params) {
|
int... params) {
|
||||||
val itemId = condition.getParam()[0];
|
val itemId = condition.getParam()[0];
|
||||||
val amount = condition.getParam()[1];
|
val targetAmount = condition.getParam()[1];
|
||||||
val checkItem = owner.getInventory().getItemByGuid(itemId);
|
val amount = owner.getInventory().getItemCountById(itemId);
|
||||||
return checkItem == null || checkItem.getCount() < amount;
|
return amount < targetAmount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,11 @@ public class ConditionPackHaveItem extends BaseCondition {
|
|||||||
String paramStr,
|
String paramStr,
|
||||||
int... params) {
|
int... params) {
|
||||||
val itemId = condition.getParam()[0];
|
val itemId = condition.getParam()[0];
|
||||||
val targetAmount = condition.getParam()[1];
|
var targetAmount = condition.getParam()[1];
|
||||||
val checkItem = owner.getInventory().getItemByGuid(itemId);
|
if (targetAmount == 0) {
|
||||||
return checkItem != null && checkItem.getCount() >= targetAmount;
|
targetAmount = 1;
|
||||||
|
}
|
||||||
|
val amount = owner.getInventory().getItemCountById(itemId);
|
||||||
|
return amount >= targetAmount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,12 @@ public class ContentAddQuestProgress extends BaseContent {
|
|||||||
val currentCount =
|
val currentCount =
|
||||||
quest.getOwner().getPlayerProgress().getCurrentProgress(String.valueOf(progressId));
|
quest.getOwner().getPlayerProgress().getCurrentProgress(String.valueOf(progressId));
|
||||||
|
|
||||||
|
var targetAmount = condition.getCount();
|
||||||
|
if (targetAmount == 0) {
|
||||||
|
targetAmount = 1;
|
||||||
|
}
|
||||||
// if the condition count is 0 I think it is safe to assume that the
|
// if the condition count is 0 I think it is safe to assume that the
|
||||||
// condition count from EXEC only needs to be 1
|
// condition count from EXEC only needs to be 1
|
||||||
return currentCount >= condition.getCount();
|
return currentCount >= targetAmount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,10 @@ package emu.grasscutter.game.quest.content;
|
|||||||
|
|
||||||
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_ANY_TALK;
|
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_ANY_TALK;
|
||||||
|
|
||||||
import emu.grasscutter.data.GameData;
|
|
||||||
import emu.grasscutter.data.excels.quest.QuestData;
|
import emu.grasscutter.data.excels.quest.QuestData;
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
import emu.grasscutter.game.quest.*;
|
||||||
import emu.grasscutter.game.quest.QuestValueContent;
|
import java.util.Arrays;
|
||||||
import java.util.stream.Stream;
|
import lombok.val;
|
||||||
|
|
||||||
@QuestValueContent(QUEST_CONTENT_COMPLETE_ANY_TALK)
|
@QuestValueContent(QUEST_CONTENT_COMPLETE_ANY_TALK)
|
||||||
public class ContentCompleteAnyTalk extends BaseContent {
|
public class ContentCompleteAnyTalk extends BaseContent {
|
||||||
@ -14,10 +13,21 @@ public class ContentCompleteAnyTalk extends BaseContent {
|
|||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
return Stream.of(condition.getParamStr().split(","))
|
var conditionTalk =
|
||||||
.mapToInt(Integer::parseInt)
|
Arrays.stream(condition.getParamStr().split(",")).mapToInt(Integer::parseInt).toArray();
|
||||||
.anyMatch(
|
|
||||||
talkId ->
|
for (var talkId : conditionTalk) {
|
||||||
GameData.getTalkConfigDataMap().get(params[0]) != null && talkId == params[0]);
|
val checkMainQuest = quest.getOwner().getQuestManager().getMainQuestByTalkId(talkId);
|
||||||
|
if (checkMainQuest == null) {
|
||||||
|
if (talkId == params[0]) return true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
val talkData = checkMainQuest.getTalks().get(talkId);
|
||||||
|
if (talkData != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,9 @@ public class ContentCompleteTalk extends BaseContent {
|
|||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
val talkId = condition.getParam()[0];
|
val talkId = condition.getParam()[0];
|
||||||
if (talkId != params[0]) return false;
|
|
||||||
val checkMainQuest = quest.getOwner().getQuestManager().getMainQuestByTalkId(talkId);
|
val checkMainQuest = quest.getOwner().getQuestManager().getMainQuestByTalkId(talkId);
|
||||||
if (checkMainQuest == null) {
|
if (checkMainQuest == null) {
|
||||||
return false;
|
return talkId == params[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
val talkData = checkMainQuest.getTalks().get(talkId);
|
val talkData = checkMainQuest.getTalks().get(talkId);
|
||||||
|
@ -5,12 +5,16 @@ import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_ITEM_L
|
|||||||
import emu.grasscutter.data.excels.quest.QuestData;
|
import emu.grasscutter.data.excels.quest.QuestData;
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
import emu.grasscutter.game.quest.GameQuest;
|
||||||
import emu.grasscutter.game.quest.QuestValueContent;
|
import emu.grasscutter.game.quest.QuestValueContent;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
@QuestValueContent(QUEST_CONTENT_ITEM_LESS_THAN)
|
@QuestValueContent(QUEST_CONTENT_ITEM_LESS_THAN)
|
||||||
public class ContentItemLessThan extends BaseContent {
|
public class ContentItemLessThan extends BaseContent {
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
return condition.getParam()[0] == params[0] && condition.getCount() > params[1];
|
val itemId = condition.getParam()[0];
|
||||||
|
val targetAmount = condition.getParam()[1];
|
||||||
|
val amount = quest.getOwner().getInventory().getItemCountById(itemId);
|
||||||
|
return amount < targetAmount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,11 @@ public class ContentLuaNotify extends BaseContent {
|
|||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
return condition.getParamStr().equals(paramStr)
|
var targetAmount = condition.getCount();
|
||||||
&& condition.getCount()
|
if (targetAmount == 0) {
|
||||||
<= quest.getOwner().getPlayerProgress().getCurrentProgress(paramStr);
|
targetAmount = 1;
|
||||||
|
}
|
||||||
|
return targetAmount
|
||||||
|
<= quest.getOwner().getPlayerProgress().getCurrentProgress(condition.getParamStr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,16 +5,19 @@ import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_OBTAIN
|
|||||||
import emu.grasscutter.data.excels.quest.QuestData;
|
import emu.grasscutter.data.excels.quest.QuestData;
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
import emu.grasscutter.game.quest.GameQuest;
|
||||||
import emu.grasscutter.game.quest.QuestValueContent;
|
import emu.grasscutter.game.quest.QuestValueContent;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
@QuestValueContent(QUEST_CONTENT_OBTAIN_ITEM)
|
@QuestValueContent(QUEST_CONTENT_OBTAIN_ITEM)
|
||||||
public class ContentObtainItem extends BaseContent {
|
public class ContentObtainItem extends BaseContent {
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
var targetCount = condition.getCount();
|
val itemId = condition.getParam()[0];
|
||||||
if (targetCount == 0) {
|
var targetAmount = condition.getCount();
|
||||||
targetCount = 1;
|
if (targetAmount == 0) {
|
||||||
|
targetAmount = 1;
|
||||||
}
|
}
|
||||||
return condition.getParam()[0] == params[0] && targetCount <= params[1];
|
val amount = quest.getOwner().getInventory().getItemCountById(itemId);
|
||||||
|
return amount >= targetAmount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,23 +2,18 @@ package emu.grasscutter.game.quest.content;
|
|||||||
|
|
||||||
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_TRIGGER_FIRE;
|
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_TRIGGER_FIRE;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
|
||||||
import emu.grasscutter.data.excels.quest.QuestData;
|
import emu.grasscutter.data.excels.quest.QuestData;
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
import emu.grasscutter.game.quest.GameQuest;
|
||||||
import emu.grasscutter.game.quest.QuestValueContent;
|
import emu.grasscutter.game.quest.QuestValueContent;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
@QuestValueContent(QUEST_CONTENT_TRIGGER_FIRE)
|
@QuestValueContent(QUEST_CONTENT_TRIGGER_FIRE)
|
||||||
public class ContentTriggerFire extends BaseContent {
|
public class ContentTriggerFire extends BaseContent {
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
if (quest.getTriggers().containsKey(quest.getTriggerNameById(params[0]))) {
|
val triggerId = condition.getParam()[0];
|
||||||
// We don't want to put a new key here
|
val triggerName = quest.getTriggerNameById(triggerId);
|
||||||
return quest.getTriggers().get(quest.getTriggerNameById(params[0]));
|
return quest.getTriggers().getOrDefault(triggerName, false);
|
||||||
} else {
|
|
||||||
Grasscutter.getLogger()
|
|
||||||
.debug("Quest {} doesn't have trigger {} registered.", quest.getSubQuestId(), params[0]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public enum QuestExec implements QuestTrigger {
|
|||||||
QUEST_EXEC_SET_QUEST_VAR(48),
|
QUEST_EXEC_SET_QUEST_VAR(48),
|
||||||
QUEST_EXEC_INC_QUEST_VAR(49),
|
QUEST_EXEC_INC_QUEST_VAR(49),
|
||||||
QUEST_EXEC_DEC_QUEST_VAR(50),
|
QUEST_EXEC_DEC_QUEST_VAR(50),
|
||||||
QUEST_EXEC_RANDOM_QUEST_VAR(51), // missing
|
QUEST_EXEC_RANDOM_QUEST_VAR(51),
|
||||||
QUEST_EXEC_ACTIVATE_SCANNING_PIC(52), // missing, currently unused
|
QUEST_EXEC_ACTIVATE_SCANNING_PIC(52), // missing, currently unused
|
||||||
QUEST_EXEC_RELOAD_SCENE_TAG(53), // missing
|
QUEST_EXEC_RELOAD_SCENE_TAG(53), // missing
|
||||||
QUEST_EXEC_REGISTER_DYNAMIC_GROUP_ONLY(54), // missing
|
QUEST_EXEC_REGISTER_DYNAMIC_GROUP_ONLY(54), // missing
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package emu.grasscutter.game.quest.exec;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.excels.quest.QuestData;
|
||||||
|
import emu.grasscutter.game.quest.GameQuest;
|
||||||
|
import emu.grasscutter.game.quest.QuestValueExec;
|
||||||
|
import emu.grasscutter.game.quest.enums.QuestExec;
|
||||||
|
import emu.grasscutter.game.quest.handlers.QuestExecHandler;
|
||||||
|
|
||||||
|
@QuestValueExec(QuestExec.QUEST_EXEC_RANDOM_QUEST_VAR)
|
||||||
|
public class ExecRandomQuestVar extends QuestExecHandler {
|
||||||
|
@Override
|
||||||
|
public boolean execute(GameQuest quest, QuestData.QuestExecParam condition, String... paramStr) {
|
||||||
|
quest
|
||||||
|
.getMainQuest()
|
||||||
|
.randomQuestVar(
|
||||||
|
Integer.parseInt(paramStr[0]),
|
||||||
|
Integer.parseInt(paramStr[1]),
|
||||||
|
Integer.parseInt(paramStr[2]));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.LevelupCityReqOuterClass.LevelupCityReq;
|
||||||
|
import emu.grasscutter.server.game.GameSession;
|
||||||
|
|
||||||
|
@Opcodes(PacketOpcodes.LevelupCityReq)
|
||||||
|
public class HandlerLevelupCityReq extends PacketHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
|
LevelupCityReq req = LevelupCityReq.parseFrom(payload);
|
||||||
|
|
||||||
|
// Level up city
|
||||||
|
session
|
||||||
|
.getPlayer()
|
||||||
|
.getSotsManager()
|
||||||
|
.levelUpSotS(req.getAreaId(), req.getSceneId(), req.getItemNum());
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,6 @@ package emu.grasscutter.server.packet.send;
|
|||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.CityInfoOuterClass.CityInfo;
|
|
||||||
import emu.grasscutter.net.proto.GetSceneAreaRspOuterClass.GetSceneAreaRsp;
|
import emu.grasscutter.net.proto.GetSceneAreaRspOuterClass.GetSceneAreaRsp;
|
||||||
|
|
||||||
public class PacketGetSceneAreaRsp extends BasePacket {
|
public class PacketGetSceneAreaRsp extends BasePacket {
|
||||||
@ -17,9 +16,9 @@ public class PacketGetSceneAreaRsp extends BasePacket {
|
|||||||
GetSceneAreaRsp.newBuilder()
|
GetSceneAreaRsp.newBuilder()
|
||||||
.setSceneId(sceneId)
|
.setSceneId(sceneId)
|
||||||
.addAllAreaIdList(player.getUnlockedSceneAreas(sceneId))
|
.addAllAreaIdList(player.getUnlockedSceneAreas(sceneId))
|
||||||
.addCityInfoList(CityInfo.newBuilder().setCityId(1).setLevel(1).build())
|
.addCityInfoList(player.getSotsManager().getCityInfo(1).toProto())
|
||||||
.addCityInfoList(CityInfo.newBuilder().setCityId(2).setLevel(1).build())
|
.addCityInfoList(player.getSotsManager().getCityInfo(2).toProto())
|
||||||
.addCityInfoList(CityInfo.newBuilder().setCityId(3).setLevel(1).build())
|
.addCityInfoList(player.getSotsManager().getCityInfo(3).toProto())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
this.setData(p);
|
this.setData(p);
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.CityInfoOuterClass.CityInfo;
|
||||||
|
import emu.grasscutter.net.proto.LevelupCityRspOuterClass.LevelupCityRsp;
|
||||||
|
|
||||||
|
public class PacketLevelupCityRsp extends BasePacket {
|
||||||
|
|
||||||
|
public PacketLevelupCityRsp(
|
||||||
|
int sceneId, int level, int cityId, int crystalNum, int areaId, int retcode) {
|
||||||
|
super(PacketOpcodes.LevelupCityRsp);
|
||||||
|
|
||||||
|
LevelupCityRsp proto =
|
||||||
|
LevelupCityRsp.newBuilder()
|
||||||
|
.setSceneId(sceneId)
|
||||||
|
.setCityInfo(
|
||||||
|
CityInfo.newBuilder()
|
||||||
|
.setCityId(cityId)
|
||||||
|
.setLevel(level)
|
||||||
|
.setCrystalNum(crystalNum)
|
||||||
|
.build())
|
||||||
|
.setAreaId(areaId)
|
||||||
|
.setRetcode(retcode)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.setData(proto);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user