mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-22 20:04:56 +01:00
Implement Resin (#1257)
* Basic resin usage/refresh. * Honor resin config, move some logic to logon. * Add resin usage to DungeonChallenge * Make fragile and transient resin usable. * Get resin cost from dungeon excel. * Add ability to unlock combine diagrams. * Refactor CombineManager to use Inventory.payItems, enabling crafting of condensed resin. * Refactor ForgingManager to use Inventory.payItems, to prepare for eventually forging Mystic Enhancement Ores using resin. * Remove comment * Check resin usage in addResin
This commit is contained in:
@@ -15,6 +15,7 @@ import emu.grasscutter.data.excels.ItemData;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.inventory.ItemType;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.net.proto.ForgeStartReqOuterClass;
|
||||
import emu.grasscutter.net.proto.ForgeQueueDataOuterClass.ForgeQueueData;
|
||||
import emu.grasscutter.net.proto.ForgeQueueManipulateReqOuterClass.ForgeQueueManipulateReq;
|
||||
@@ -147,38 +148,16 @@ public class ForgingManager {
|
||||
|
||||
ForgeData forgeData = GameData.getForgeDataMap().get(req.getForgeId());
|
||||
|
||||
// Check if we have enough of each material.
|
||||
for (var material : forgeData.getMaterialItems()) {
|
||||
if (material.getItemId() == 0) {
|
||||
continue;
|
||||
}
|
||||
// Check if we have enough of each material and consume.
|
||||
List<ItemParamData> material = new ArrayList<>(forgeData.getMaterialItems());
|
||||
material.add(new ItemParamData(202, forgeData.getScoinCost()));
|
||||
|
||||
int currentCount = this.player.getInventory().getInventoryTab(ItemType.ITEM_MATERIAL).getItemById(material.getItemId()).getCount();
|
||||
boolean success = player.getInventory().payItems(material.toArray(new ItemParamData[0]), req.getForgeCount(), ActionReason.ForgeCost);
|
||||
|
||||
if (currentCount < material.getCount() * req.getForgeCount()) {
|
||||
this.player.sendPacket(new PacketForgeStartRsp(Retcode.RET_FORGE_POINT_NOT_ENOUGH)); //ToDo: Probably the wrong return code.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we have enough Mora.
|
||||
if (this.player.getMora() < forgeData.getScoinCost() * req.getForgeCount()) {
|
||||
if (!success) {
|
||||
this.player.sendPacket(new PacketForgeStartRsp(Retcode.RET_FORGE_POINT_NOT_ENOUGH)); //ToDo: Probably the wrong return code.
|
||||
return;
|
||||
}
|
||||
|
||||
// Consume material and Mora.
|
||||
for (var material : forgeData.getMaterialItems()) {
|
||||
if (material.getItemId() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GameItem item = this.player.getInventory().getInventoryTab(ItemType.ITEM_MATERIAL).getItemById(material.getItemId());
|
||||
this.player.getInventory().removeItem(item, material.getCount() * req.getForgeCount());
|
||||
}
|
||||
|
||||
this.player.setMora(this.player.getMora() - forgeData.getScoinCost() * req.getForgeCount());
|
||||
|
||||
// Create and add active forge.
|
||||
ActiveForgeData activeForge = new ActiveForgeData();
|
||||
activeForge.setForgeId(req.getForgeId());
|
||||
|
||||
@@ -856,6 +856,27 @@ public class InventoryManager {
|
||||
// Unlock.
|
||||
useSuccess = player.getForgingManager().unlockForgingBlueprint(useItem);
|
||||
}
|
||||
// Handle combine diagrams.
|
||||
if (useItem.getItemData().getItemUse().get(0).getUseOp().equals("ITEM_USE_UNLOCK_COMBINE")) {
|
||||
// Unlock.
|
||||
useSuccess = player.getServer().getCombineManger().unlockCombineDiagram(player, useItem);
|
||||
}
|
||||
break;
|
||||
case MATERIAL_CONSUME_BATCH_USE:
|
||||
// Make sure we have usage data for this material.
|
||||
if (useItem.getItemData().getItemUse() == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle fragile/transient resin.
|
||||
if (useItem.getItemId() == 107009 || useItem.getItemId() == 107012){
|
||||
// Add resin to the inventory.
|
||||
ItemData resinItemData = GameData.getItemDataMap().get(106);
|
||||
player.getInventory().addItem(new GameItem(resinItemData, 60 * count), ActionReason.PlayerUseItem);
|
||||
|
||||
// Set used amount.
|
||||
used = count;
|
||||
}
|
||||
break;
|
||||
case MATERIAL_CHEST:
|
||||
List<ShopChestTable> shopChestTableList = player.getServer().getShopManager().getShopChestData();
|
||||
|
||||
143
src/main/java/emu/grasscutter/game/managers/ResinManager.java
Normal file
143
src/main/java/emu/grasscutter/game/managers/ResinManager.java
Normal file
@@ -0,0 +1,143 @@
|
||||
package emu.grasscutter.game.managers;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerPropNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketResinChangeNotify;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
|
||||
import static emu.grasscutter.Configuration.GAME_OPTIONS;
|
||||
|
||||
public class ResinManager {
|
||||
private final Player player;
|
||||
|
||||
public ResinManager(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Change resin.
|
||||
********************/
|
||||
public synchronized boolean useResin(int amount) {
|
||||
// Check if resin enabled.
|
||||
if (!GAME_OPTIONS.resinOptions.resinUsage) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int currentResin = this.player.getProperty(PlayerProperty.PROP_PLAYER_RESIN);
|
||||
|
||||
// Check if the player has sufficient resin.
|
||||
if (currentResin < amount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Deduct the resin from the player.
|
||||
int newResin = currentResin - amount;
|
||||
this.player.setProperty(PlayerProperty.PROP_PLAYER_RESIN, newResin);
|
||||
|
||||
// Check if this has taken the player under the recharge cap,
|
||||
// starting the recharging process.
|
||||
if (this.player.getNextResinRefresh() == 0 && newResin < GAME_OPTIONS.resinOptions.cap) {
|
||||
int currentTime = Utils.getCurrentSeconds();
|
||||
this.player.setNextResinRefresh(currentTime + GAME_OPTIONS.resinOptions.rechargeTime);
|
||||
}
|
||||
|
||||
// Send packets.
|
||||
this.player.sendPacket(new PacketPlayerPropNotify(this.player, PlayerProperty.PROP_PLAYER_RESIN));
|
||||
this.player.sendPacket(new PacketResinChangeNotify(this.player));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized void addResin(int amount) {
|
||||
// Check if resin enabled.
|
||||
if (!GAME_OPTIONS.resinOptions.resinUsage) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add resin.
|
||||
int currentResin = this.player.getProperty(PlayerProperty.PROP_PLAYER_RESIN);
|
||||
int newResin = currentResin + amount;
|
||||
this.player.setProperty(PlayerProperty.PROP_PLAYER_RESIN, newResin);
|
||||
|
||||
// Stop recharging if player is now at or over the cap.
|
||||
if (newResin >= GAME_OPTIONS.resinOptions.cap) {
|
||||
this.player.setNextResinRefresh(0);
|
||||
}
|
||||
|
||||
// Send packets.
|
||||
this.player.sendPacket(new PacketPlayerPropNotify(this.player, PlayerProperty.PROP_PLAYER_RESIN));
|
||||
this.player.sendPacket(new PacketResinChangeNotify(this.player));
|
||||
}
|
||||
|
||||
/********************
|
||||
* Recharge resin.
|
||||
********************/
|
||||
public synchronized void rechargeResin() {
|
||||
// Check if resin enabled.
|
||||
if (!GAME_OPTIONS.resinOptions.resinUsage) {
|
||||
return;
|
||||
}
|
||||
|
||||
int currentResin = this.player.getProperty(PlayerProperty.PROP_PLAYER_RESIN);
|
||||
int currentTime = Utils.getCurrentSeconds();
|
||||
|
||||
// Make sure we are currently in "recharging mode".
|
||||
// This is denoted by Player.nextResinRefresh being greater than 0.
|
||||
if (this.player.getNextResinRefresh() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine if we actually need to recharge yet.
|
||||
if (currentTime < this.player.getNextResinRefresh()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate how much resin we need to refill and update player.
|
||||
// Note that this can be more than one in case the player
|
||||
// logged off with uncapped resin and is now logging in again.
|
||||
int recharge = 1 + (int)((currentTime - this.player.getNextResinRefresh()) / GAME_OPTIONS.resinOptions.rechargeTime);
|
||||
int newResin = Math.min(GAME_OPTIONS.resinOptions.cap, currentResin + recharge);
|
||||
int resinChange = newResin - currentResin;
|
||||
|
||||
this.player.setProperty(PlayerProperty.PROP_PLAYER_RESIN, newResin);
|
||||
|
||||
// Calculate next recharge time.
|
||||
// Set to zero to disable recharge (because on/over cap.)
|
||||
if (newResin >= GAME_OPTIONS.resinOptions.cap) {
|
||||
this.player.setNextResinRefresh(0);
|
||||
}
|
||||
else {
|
||||
int nextRecharge = this.player.getNextResinRefresh() + resinChange * GAME_OPTIONS.resinOptions.rechargeTime;
|
||||
this.player.setNextResinRefresh(nextRecharge);
|
||||
}
|
||||
|
||||
// Send packets.
|
||||
this.player.sendPacket(new PacketPlayerPropNotify(this.player, PlayerProperty.PROP_PLAYER_RESIN));
|
||||
this.player.sendPacket(new PacketResinChangeNotify(this.player));
|
||||
}
|
||||
|
||||
/********************
|
||||
* Player login.
|
||||
********************/
|
||||
public synchronized void onPlayerLogin() {
|
||||
// If resin usage is disabled, set resin to cap.
|
||||
if (!GAME_OPTIONS.resinOptions.resinUsage) {
|
||||
this.player.setProperty(PlayerProperty.PROP_PLAYER_RESIN, GAME_OPTIONS.resinOptions.cap);
|
||||
this.player.setNextResinRefresh(0);
|
||||
}
|
||||
|
||||
// In case server administrators change the resin cap while players are capped,
|
||||
// we need to restart recharging here.
|
||||
int currentResin = this.player.getProperty(PlayerProperty.PROP_PLAYER_RESIN);
|
||||
int currentTime = Utils.getCurrentSeconds();
|
||||
|
||||
if (currentResin < GAME_OPTIONS.resinOptions.cap && this.player.getNextResinRefresh() == 0) {
|
||||
this.player.setNextResinRefresh(currentTime + GAME_OPTIONS.resinOptions.rechargeTime);
|
||||
}
|
||||
|
||||
// Send initial notifications on logon.
|
||||
this.player.sendPacket(new PacketPlayerPropNotify(this.player, PlayerProperty.PROP_PLAYER_RESIN));
|
||||
this.player.sendPacket(new PacketResinChangeNotify(this.player));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user