mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-16 08:56:04 +01:00
[BREAKING] Item Usage Overhaul
-De-hardcode elemental orb values -De-hardcode exp items -Change ShopChest format (temporary, drop system overhaul will replace it entirely) -Food healing actually uses Ability data for real HP amounts
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseAcceptQuest extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_ACCEPT_QUEST;
|
||||
}
|
||||
|
||||
public ItemUseAcceptQuest(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return (params.player.getQuestManager().addQuest(this.i) != null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.data.common.ItemUseData;
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseAction {
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_NONE;
|
||||
}
|
||||
|
||||
public static ItemUseAction fromItemUseData(ItemUseData data) {
|
||||
var useParam = data.getUseParam();
|
||||
return switch (data.getUseOp()) {
|
||||
case ITEM_USE_NONE -> null;
|
||||
// Uprade materials - no direct usage
|
||||
case ITEM_USE_ADD_EXP -> new ItemUseAddExp(useParam);
|
||||
case ITEM_USE_ADD_RELIQUARY_EXP -> new ItemUseAddReliquaryExp(useParam);
|
||||
case ITEM_USE_ADD_WEAPON_EXP -> new ItemUseAddWeaponExp(useParam);
|
||||
// Energy pickups
|
||||
case ITEM_USE_ADD_ALL_ENERGY -> new ItemUseAddAllEnergy(useParam);
|
||||
case ITEM_USE_ADD_ELEM_ENERGY -> new ItemUseAddElemEnergy(useParam);
|
||||
// Give items
|
||||
case ITEM_USE_ADD_ITEM -> new ItemUseAddItem(useParam);
|
||||
case ITEM_USE_GAIN_AVATAR -> new ItemUseGainAvatar(useParam);
|
||||
case ITEM_USE_GAIN_COSTUME -> new ItemUseGainCostume(useParam); // TODO - real success/fail
|
||||
case ITEM_USE_GAIN_FLYCLOAK -> new ItemUseGainFlycloak(useParam); // TODO - real success/fail
|
||||
case ITEM_USE_GAIN_NAME_CARD -> new ItemUseGainNameCard(useParam); // TODO
|
||||
case ITEM_USE_CHEST_SELECT_ITEM -> new ItemUseChestSelectItem(useParam);
|
||||
case ITEM_USE_ADD_SELECT_ITEM -> new ItemUseAddSelectItem(useParam);
|
||||
case ITEM_USE_GRANT_SELECT_REWARD -> new ItemUseGrantSelectReward(useParam);
|
||||
case ITEM_USE_COMBINE_ITEM -> new ItemUseCombineItem(useParam);
|
||||
case ITEM_USE_OPEN_RANDOM_CHEST -> new ItemUseOpenRandomChest(useParam);
|
||||
// Food effects
|
||||
case ITEM_USE_RELIVE_AVATAR -> new ItemUseReliveAvatar(useParam); // First action for revival food. Should we worry about race conditions in parallel streams?
|
||||
case ITEM_USE_ADD_CUR_HP -> new ItemUseAddCurHp(useParam);
|
||||
case ITEM_USE_ADD_CUR_STAMINA -> new ItemUseAddCurStamina(useParam);
|
||||
case ITEM_USE_ADD_SERVER_BUFF -> new ItemUseAddServerBuff(useParam);
|
||||
case ITEM_USE_MAKE_GADGET -> new ItemUseMakeGadget(useParam);
|
||||
// Unlock recipes - TODO: allow scheduling packets for after recipe is removed
|
||||
case ITEM_USE_UNLOCK_COMBINE -> new ItemUseUnlockCombine(useParam);
|
||||
case ITEM_USE_UNLOCK_CODEX -> new ItemUseUnlockCodex(useParam); // TODO: No backend for this yet
|
||||
case ITEM_USE_UNLOCK_COOK_RECIPE -> new ItemUseUnlockCookRecipe(useParam);
|
||||
case ITEM_USE_UNLOCK_FORGE -> new ItemUseUnlockForge(useParam);
|
||||
case ITEM_USE_UNLOCK_FURNITURE_FORMULA -> new ItemUseUnlockFurnitureFormula(useParam);
|
||||
case ITEM_USE_UNLOCK_FURNITURE_SUITE -> new ItemUseUnlockFurnitureSuite(useParam);
|
||||
case ITEM_USE_UNLOCK_HOME_MODULE -> new ItemUseUnlockHomeModule(useParam); // No backend for this yet
|
||||
case ITEM_USE_UNLOCK_HOME_BGM -> new ItemUseUnlockHomeBgm(useParam);
|
||||
// Account things
|
||||
case ITEM_USE_ACCEPT_QUEST -> new ItemUseAcceptQuest(useParam);
|
||||
case ITEM_USE_GAIN_CARD_PRODUCT -> new ItemUseGainCardProduct(useParam);
|
||||
case ITEM_USE_UNLOCK_PAID_BATTLE_PASS_NORMAL -> new ItemUseUnlockPaidBattlePassNormal(useParam); // TODO: add paid BP
|
||||
|
||||
// Unused in current resources
|
||||
case ITEM_USE_DEL_SERVER_BUFF -> null;
|
||||
case ITEM_USE_ADD_BIG_TALENT_POINT -> null;
|
||||
case ITEM_USE_GAIN_RESIN_CARD_PRODUCT -> null;
|
||||
case ITEM_USE_TRIGGER_ABILITY -> null;
|
||||
case ITEM_USE_ADD_TREASURE_MAP_BONUS_REGION_FRAGMENT -> null;
|
||||
// Used in current resources but no point yet
|
||||
case ITEM_USE_ADD_PERSIST_STAMINA -> null; // [int amount] one Test item
|
||||
case ITEM_USE_ADD_TEMPORARY_STAMINA -> null; // [int amount] one Test item
|
||||
case ITEM_USE_ADD_DUNGEON_COND_TIME -> null; // [int 1, int 15 or 20] - minigame shards
|
||||
case ITEM_USE_ADD_CHANNELLER_SLAB_BUFF -> null; // [int] minigame buffs
|
||||
case ITEM_USE_ADD_REGIONAL_PLAY_VAR -> null; // [String, int] - coral butterfly effect
|
||||
};
|
||||
}
|
||||
|
||||
public boolean useItem(UseItemParams params) {
|
||||
// An item must return true on at least one of its actions to count as successfully used.
|
||||
// If all of the actions return false, the item will not be consumed from inventory.
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean postUseItem(UseItemParams params) {
|
||||
// This is run after the item has been consumed from inventory.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ElementType;
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseAddAllEnergy extends ItemUseAddEnergy {
|
||||
private float energy = 0f;
|
||||
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_ADD_ALL_ENERGY;
|
||||
}
|
||||
|
||||
public ItemUseAddAllEnergy(String[] useParam) {
|
||||
try {
|
||||
this.energy = Float.parseFloat(useParam[0]);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
public float getAddEnergy(ElementType avatarElement) {
|
||||
return this.energy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseAddCurHp extends ItemUseInt {
|
||||
private String icon;
|
||||
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_ADD_CUR_HP;
|
||||
}
|
||||
|
||||
public ItemUseAddCurHp(String[] useParam) {
|
||||
super(useParam);
|
||||
this.icon = useParam[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return (params.targetAvatar.getAsEntity().heal(params.count * this.i) > 0.01);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseAddCurStamina extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_ADD_CUR_STAMINA;
|
||||
}
|
||||
|
||||
public ItemUseAddCurStamina(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return params.player.getStaminaManager().addCurrentStamina(this.i);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ElementType;
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseAddElemEnergy extends ItemUseAddEnergy {
|
||||
private ElementType element = ElementType.None;
|
||||
private float elemEnergy = 0f;
|
||||
private float otherEnergy = 0f;
|
||||
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_ADD_ELEM_ENERGY;
|
||||
}
|
||||
|
||||
public ItemUseAddElemEnergy(String[] useParam) {
|
||||
try {
|
||||
this.element = ElementType.getTypeByValue(Integer.parseInt(useParam[0]));
|
||||
} catch (Exception ignored) {}
|
||||
try {
|
||||
this.elemEnergy = Float.parseFloat(useParam[1]);
|
||||
} catch (Exception ignored) {}
|
||||
try {
|
||||
this.otherEnergy = Float.parseFloat(useParam[2]);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
public float getAddEnergy(ElementType avatarElement) {
|
||||
return (avatarElement == this.element) ? this.elemEnergy : this.otherEnergy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.data.excels.AvatarSkillDepotData;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.props.ElementType;
|
||||
import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
|
||||
|
||||
public abstract class ItemUseAddEnergy extends ItemUseAction {
|
||||
public abstract float getAddEnergy(ElementType avatarElement);
|
||||
|
||||
public float getAddEnergy(AvatarSkillDepotData depot) {
|
||||
if (depot == null) return 0f;
|
||||
var element = depot.getElementType();
|
||||
if (element == null) return 0f;
|
||||
return this.getAddEnergy(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
var teamManager = params.player.getTeamManager();
|
||||
return switch (params.itemUseTarget) {
|
||||
case ITEM_USE_TARGET_CUR_AVATAR -> {
|
||||
this.addEnergy(teamManager.getCurrentAvatarEntity().getAvatar(), params.count);
|
||||
yield true; // Always consume elem balls
|
||||
}
|
||||
case ITEM_USE_TARGET_CUR_TEAM -> {
|
||||
var activeTeam = teamManager.getActiveTeam();
|
||||
// On-field vs off-field multiplier.
|
||||
// The on-field character gets full amount, off-field characters get less depending on the team size.
|
||||
final float offFieldRatio = switch(activeTeam.size()) {
|
||||
case 2 -> 0.8f;
|
||||
case 3 -> 0.7f;
|
||||
default -> 0.6f;
|
||||
};
|
||||
final int currentCharacterIndex = teamManager.getCurrentCharacterIndex();
|
||||
|
||||
// Add energy to every team member.
|
||||
for (int i = 0; i < activeTeam.size(); i++) {
|
||||
var avatar = activeTeam.get(i).getAvatar();
|
||||
if (i == currentCharacterIndex)
|
||||
this.addEnergy(avatar, params.count);
|
||||
else
|
||||
this.addEnergy(avatar, params.count * offFieldRatio);
|
||||
}
|
||||
|
||||
yield true; // Always consume elem balls
|
||||
}
|
||||
case ITEM_USE_TARGET_SPECIFY_AVATAR, ITEM_USE_TARGET_SPECIFY_ALIVE_AVATAR, ITEM_USE_TARGET_SPECIFY_DEAD_AVATAR ->
|
||||
this.addEnergy(params.targetAvatar, params.count); // Targeted items might care about this
|
||||
case ITEM_USE_TARGET_NONE -> false;
|
||||
};
|
||||
}
|
||||
|
||||
private boolean addEnergy(Avatar avatar, float multiplier) {
|
||||
float energy = this.getAddEnergy(avatar.getSkillDepot()) * multiplier;
|
||||
if (energy < 0.01f)
|
||||
return false;
|
||||
avatar.getAsEntity().addEnergy(energy, PropChangeReason.PROP_CHANGE_REASON_ENERGY_BALL);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
import lombok.Getter;
|
||||
|
||||
public class ItemUseAddExp extends ItemUseAction {
|
||||
@Getter private int exp = 0;
|
||||
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_ADD_EXP;
|
||||
}
|
||||
|
||||
public ItemUseAddExp(String[] useParam) {
|
||||
try {
|
||||
this.exp = Integer.parseInt(useParam[0]);
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseAddItem extends ItemUseInt {
|
||||
private int count = 0;
|
||||
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_ADD_ITEM;
|
||||
}
|
||||
|
||||
public ItemUseAddItem(String[] useParam) {
|
||||
super(useParam);
|
||||
try {
|
||||
this.count = Integer.parseInt(useParam[1]);
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return params.player.getInventory().addItem(this.i, this.count * params.count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
import lombok.Getter;
|
||||
|
||||
public class ItemUseAddReliquaryExp extends ItemUseAction {
|
||||
@Getter private int exp = 0;
|
||||
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_ADD_RELIQUARY_EXP;
|
||||
}
|
||||
|
||||
public ItemUseAddReliquaryExp(String[] useParam) {
|
||||
try {
|
||||
this.exp = Integer.parseInt(useParam[0]);
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseAddSelectItem extends ItemUseSelectItems {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_ADD_SELECT_ITEM;
|
||||
}
|
||||
|
||||
public ItemUseAddSelectItem(String[] useParam) {
|
||||
String[] options = useParam[0].split(",");
|
||||
this.optionItemIds = new int[options.length];
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
try {
|
||||
this.optionItemIds[i] = Integer.parseInt(options[i]);
|
||||
} catch (NumberFormatException ignored) {
|
||||
this.optionItemIds[i] = INVALID;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseAddServerBuff extends ItemUseInt {
|
||||
private int duration = 0;
|
||||
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_ADD_SERVER_BUFF;
|
||||
}
|
||||
|
||||
public ItemUseAddServerBuff(String[] useParam) {
|
||||
super(useParam);
|
||||
try {
|
||||
this.duration = Integer.parseInt(useParam[1]);
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return params.player.getBuffManager().addBuff(this.i, this.duration, params.targetAvatar);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
import lombok.Getter;
|
||||
|
||||
public class ItemUseAddWeaponExp extends ItemUseAction {
|
||||
@Getter private int exp = 0;
|
||||
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_ADD_WEAPON_EXP;
|
||||
}
|
||||
|
||||
public ItemUseAddWeaponExp(String[] useParam) {
|
||||
try {
|
||||
this.exp = Integer.parseInt(useParam[0]);
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseChestSelectItem extends ItemUseSelectItems {
|
||||
private int[] optionItemCounts;
|
||||
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_CHEST_SELECT_ITEM;
|
||||
}
|
||||
|
||||
public ItemUseChestSelectItem(String[] useParam) {
|
||||
String[] options = useParam[0].split(",");
|
||||
this.optionItemIds = new int[options.length];
|
||||
this.optionItemCounts = new int[options.length];
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
String[] optionParts = options[i].split(":");
|
||||
try {
|
||||
this.optionItemIds[i] = Integer.parseInt(optionParts[0]);
|
||||
} catch (NumberFormatException ignored) {
|
||||
this.optionItemIds[i] = INVALID;
|
||||
}
|
||||
try {
|
||||
this.optionItemCounts[i] = Integer.parseInt(optionParts[1]);
|
||||
} catch (NumberFormatException ignored) {
|
||||
this.optionItemCounts[i] = INVALID;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getItemCount(int index) {
|
||||
if ((optionItemCounts == null) || (index < 0) || (index > optionItemCounts.length)) return INVALID;
|
||||
return this.optionItemCounts[index];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseCombineItem extends ItemUseInt {
|
||||
private int resultId = 0;
|
||||
private int resultCount = 1;
|
||||
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_COMBINE_ITEM;
|
||||
}
|
||||
|
||||
public ItemUseCombineItem(String[] useParam) {
|
||||
super(useParam);
|
||||
try {
|
||||
this.resultId = Integer.parseInt(useParam[1]);
|
||||
} catch (NumberFormatException ignored) {}
|
||||
try {
|
||||
this.resultCount = Integer.parseInt(useParam[2]);
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
if (params.count != this.i) return false; // Wrong amount of fragments supplied!
|
||||
return params.player.getInventory().addItem(this.resultId, this.resultCount);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
import emu.grasscutter.game.systems.InventorySystem;
|
||||
|
||||
public class ItemUseGainAvatar extends ItemUseInt {
|
||||
private int level = 1;
|
||||
private int constellation = 0;
|
||||
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_GAIN_AVATAR;
|
||||
}
|
||||
|
||||
public ItemUseGainAvatar(String[] useParam) {
|
||||
super(useParam);
|
||||
try {
|
||||
this.level = Integer.parseInt(useParam[1]);
|
||||
} catch (NumberFormatException ignored) {}
|
||||
try {
|
||||
this.constellation = Integer.parseInt(useParam[2]);
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
int haveConstellation = InventorySystem.checkPlayerAvatarConstellationLevel(params.player, this.i);
|
||||
if (haveConstellation == -2 || haveConstellation >= 6) {
|
||||
return false;
|
||||
} else if (haveConstellation == -1) {
|
||||
var avatar = new Avatar(this.i);
|
||||
avatar.setLevel(this.level);
|
||||
avatar.forceConstellationLevel(this.constellation);
|
||||
avatar.recalcStats();
|
||||
params.player.addAvatar(avatar);
|
||||
return true;
|
||||
} else {
|
||||
int itemId = (this.i % 1000) + 100;
|
||||
return params.player.getInventory().addItem(itemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseGainCardProduct extends ItemUseAction {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_GAIN_CARD_PRODUCT;
|
||||
}
|
||||
|
||||
public ItemUseGainCardProduct(String[] useParam) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return params.player.rechargeMoonCard();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseGainCostume extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_GAIN_COSTUME;
|
||||
}
|
||||
|
||||
public ItemUseGainCostume(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
params.player.getInventory().addItem(this.i); // TODO: Currently this returns false for all virtual items - need to have a proper success/fail
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseGainFlycloak extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_GAIN_FLYCLOAK;
|
||||
}
|
||||
|
||||
public ItemUseGainFlycloak(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
params.player.getInventory().addItem(this.i); // TODO: Currently this returns false for all virtual items - need to have a proper success/fail
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseGainNameCard extends ItemUseAction {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_GAIN_NAME_CARD;
|
||||
}
|
||||
|
||||
public ItemUseGainNameCard(String[] useParam) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return false; // TODO: work out if this is actually used and how to get the namecard id
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseGrantSelectReward extends ItemUseSelectItems {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_ADD_SELECT_ITEM;
|
||||
}
|
||||
|
||||
public ItemUseGrantSelectReward(String[] useParam) {
|
||||
String[] options = useParam[0].split(",");
|
||||
this.optionItemIds = new int[options.length];
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
try {
|
||||
this.optionItemIds[i] = Integer.parseInt(options[i]);
|
||||
} catch (NumberFormatException ignored) {
|
||||
this.optionItemIds[i] = INVALID;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public abstract class ItemUseInt extends ItemUseAction {
|
||||
@Getter protected int i = 0;
|
||||
|
||||
public ItemUseInt(String[] useParam) {
|
||||
try {
|
||||
this.i = Integer.parseInt(useParam[0]);
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.entity.EntityVehicle;
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseMakeGadget extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_MAKE_GADGET;
|
||||
}
|
||||
|
||||
public ItemUseMakeGadget(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
var player = params.player;
|
||||
var scene = player.getScene();
|
||||
var pos = player.getPosition().nearby2d(1f);
|
||||
var rot = player.getRotation().clone();
|
||||
var e = new EntityVehicle(scene, player, this.i, 0, pos, rot);
|
||||
scene.addEntity(e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseOpenRandomChest extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_OPEN_RANDOM_CHEST;
|
||||
}
|
||||
|
||||
public ItemUseOpenRandomChest(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) { // cash shop material bundles
|
||||
var rewardItems = params.player.getServer().getShopSystem().getShopChestData(this.i).stream().map(GameItem::new).toList();
|
||||
if (!rewardItems.isEmpty()) {
|
||||
params.player.getInventory().addItems(rewardItems, ActionReason.Shop);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseReliveAvatar extends ItemUseAction {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_RELIVE_AVATAR;
|
||||
}
|
||||
|
||||
public ItemUseReliveAvatar(String[] useParam) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return params.player.getTeamManager().reviveAvatar(params.targetAvatar);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
|
||||
public abstract class ItemUseSelectItems extends ItemUseAction {
|
||||
protected static final int INVALID = -1;
|
||||
protected int[] optionItemIds;
|
||||
|
||||
protected int getItemId(int index) {
|
||||
if ((optionItemIds == null) || (index < 0) || (index > optionItemIds.length)) return INVALID;
|
||||
return this.optionItemIds[index];
|
||||
}
|
||||
|
||||
protected int getItemCount(int index) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected GameItem getItemStack(int index, int useCount) {
|
||||
int id = this.getItemId(index);
|
||||
int count = this.getItemCount(index);
|
||||
if (id == INVALID || count == INVALID) return null;
|
||||
|
||||
var item = GameData.getItemDataMap().get(id);
|
||||
if (item == null) return null;
|
||||
|
||||
return new GameItem(item, count * useCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
var itemStack = this.getItemStack(params.optionId - 1, params.count);
|
||||
if (itemStack == null) return false;
|
||||
|
||||
return params.player.getInventory().addItem(itemStack, ActionReason.Shop);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseUnlockCodex extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_UNLOCK_CODEX;
|
||||
}
|
||||
|
||||
public ItemUseUnlockCodex(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseUnlockCombine extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_UNLOCK_COMBINE;
|
||||
}
|
||||
|
||||
public ItemUseUnlockCombine(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postUseItem(UseItemParams params) {
|
||||
return params.player.getServer().getCombineSystem().unlockCombineDiagram(params.player, this.i);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseUnlockCookRecipe extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_UNLOCK_COOK_RECIPE;
|
||||
}
|
||||
|
||||
public ItemUseUnlockCookRecipe(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postUseItem(UseItemParams params) {
|
||||
return params.player.getCookingManager().unlockRecipe(this.i);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseUnlockForge extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_UNLOCK_FORGE;
|
||||
}
|
||||
|
||||
public ItemUseUnlockForge(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postUseItem(UseItemParams params) {
|
||||
return params.player.getForgingManager().unlockForgingBlueprint(this.i);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseUnlockFurnitureFormula extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_UNLOCK_FURNITURE_FORMULA;
|
||||
}
|
||||
|
||||
public ItemUseUnlockFurnitureFormula(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postUseItem(UseItemParams params) {
|
||||
return params.player.getFurnitureManager().unlockFurnitureFormula(this.i);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseUnlockFurnitureSuite extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_UNLOCK_FURNITURE_SUITE;
|
||||
}
|
||||
|
||||
public ItemUseUnlockFurnitureSuite(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postUseItem(UseItemParams params) {
|
||||
return params.player.getFurnitureManager().unlockFurnitureSuite(this.i);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseUnlockHomeBgm extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_UNLOCK_HOME_BGM;
|
||||
}
|
||||
|
||||
public ItemUseUnlockHomeBgm(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
params.player.getHome().addUnlockedHomeBgm(this.i);
|
||||
return true; // Probably best to remove the item even if the bgm was already unlocked.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseUnlockHomeModule extends ItemUseInt {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_UNLOCK_HOME_MODULE;
|
||||
}
|
||||
|
||||
public ItemUseUnlockHomeModule(String[] useParam) {
|
||||
super(useParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
|
||||
public class ItemUseUnlockPaidBattlePassNormal extends ItemUseAction {
|
||||
@Override
|
||||
public ItemUseOp getItemUseOp() {
|
||||
return ItemUseOp.ITEM_USE_UNLOCK_PAID_BATTLE_PASS_NORMAL;
|
||||
}
|
||||
|
||||
public ItemUseUnlockPaidBattlePassNormal(String[] useParam) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useItem(UseItemParams params) {
|
||||
// TODO: add paid BP
|
||||
//return params.player.getBattlePassManager().setPaid(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package emu.grasscutter.game.props.ItemUseAction;
|
||||
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ItemUseTarget;
|
||||
|
||||
public class UseItemParams {
|
||||
// Don't want to change 40 method signatures when this gets extended!
|
||||
public Player player;
|
||||
public ItemUseTarget itemUseTarget;
|
||||
public Avatar targetAvatar = null;
|
||||
public int count = 1;
|
||||
public int optionId = 0;
|
||||
public boolean isEnterMpDungeonTeam = false;
|
||||
|
||||
public UseItemParams(Player player, ItemUseTarget itemUseTarget, Avatar targetAvatar, int count, int optionId, boolean isEnterMpDungeonTeam) {
|
||||
this.player = player;
|
||||
this.itemUseTarget = itemUseTarget;
|
||||
this.targetAvatar = targetAvatar;
|
||||
this.count = count;
|
||||
this.optionId = optionId;
|
||||
this.isEnterMpDungeonTeam = isEnterMpDungeonTeam;
|
||||
}
|
||||
|
||||
public UseItemParams(Player player, ItemUseTarget itemUseTarget) {
|
||||
this.player = player;
|
||||
this.itemUseTarget = itemUseTarget;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user