Fix salvaging items

This commit is contained in:
Melledy 2024-02-07 18:19:28 -08:00
parent bb2850385d
commit 5ed029dccb
6 changed files with 125 additions and 30 deletions

View File

@ -18,6 +18,11 @@ public final class SellItemCsReqOuterClass {
public static final class SellItemCsReq extends ProtoMessage<SellItemCsReq> implements Cloneable {
private static final long serialVersionUID = 0L;
/**
* <code>optional bool to_material = 1;</code>
*/
private boolean toMaterial;
/**
* <code>optional .ItemCostList item_cost_list = 8;</code>
*/
@ -33,12 +38,49 @@ public final class SellItemCsReqOuterClass {
return new SellItemCsReq();
}
/**
* <code>optional bool to_material = 1;</code>
* @return whether the toMaterial field is set
*/
public boolean hasToMaterial() {
return (bitField0_ & 0x00000001) != 0;
}
/**
* <code>optional bool to_material = 1;</code>
* @return this
*/
public SellItemCsReq clearToMaterial() {
bitField0_ &= ~0x00000001;
toMaterial = false;
return this;
}
/**
* <code>optional bool to_material = 1;</code>
* @return the toMaterial
*/
public boolean getToMaterial() {
return toMaterial;
}
/**
* <code>optional bool to_material = 1;</code>
* @param value the toMaterial to set
* @return this
*/
public SellItemCsReq setToMaterial(final boolean value) {
bitField0_ |= 0x00000001;
toMaterial = value;
return this;
}
/**
* <code>optional .ItemCostList item_cost_list = 8;</code>
* @return whether the itemCostList field is set
*/
public boolean hasItemCostList() {
return (bitField0_ & 0x00000001) != 0;
return (bitField0_ & 0x00000002) != 0;
}
/**
@ -46,7 +88,7 @@ public final class SellItemCsReqOuterClass {
* @return this
*/
public SellItemCsReq clearItemCostList() {
bitField0_ &= ~0x00000001;
bitField0_ &= ~0x00000002;
itemCostList.clear();
return this;
}
@ -75,7 +117,7 @@ public final class SellItemCsReqOuterClass {
* @return internal storage object for modifications
*/
public ItemCostListOuterClass.ItemCostList getMutableItemCostList() {
bitField0_ |= 0x00000001;
bitField0_ |= 0x00000002;
return itemCostList;
}
@ -85,7 +127,7 @@ public final class SellItemCsReqOuterClass {
* @return this
*/
public SellItemCsReq setItemCostList(final ItemCostListOuterClass.ItemCostList value) {
bitField0_ |= 0x00000001;
bitField0_ |= 0x00000002;
itemCostList.copyFrom(value);
return this;
}
@ -95,6 +137,7 @@ public final class SellItemCsReqOuterClass {
cachedSize = other.cachedSize;
if ((bitField0_ | other.bitField0_) != 0) {
bitField0_ = other.bitField0_;
toMaterial = other.toMaterial;
itemCostList.copyFrom(other.itemCostList);
}
return this;
@ -106,6 +149,9 @@ public final class SellItemCsReqOuterClass {
return this;
}
cachedSize = -1;
if (other.hasToMaterial()) {
setToMaterial(other.toMaterial);
}
if (other.hasItemCostList()) {
getMutableItemCostList().mergeFrom(other.itemCostList);
}
@ -119,6 +165,7 @@ public final class SellItemCsReqOuterClass {
}
cachedSize = -1;
bitField0_ = 0;
toMaterial = false;
itemCostList.clear();
return this;
}
@ -144,12 +191,17 @@ public final class SellItemCsReqOuterClass {
}
SellItemCsReq other = (SellItemCsReq) o;
return bitField0_ == other.bitField0_
&& (!hasToMaterial() || toMaterial == other.toMaterial)
&& (!hasItemCostList() || itemCostList.equals(other.itemCostList));
}
@Override
public void writeTo(final ProtoSink output) throws IOException {
if ((bitField0_ & 0x00000001) != 0) {
output.writeRawByte((byte) 8);
output.writeBoolNoTag(toMaterial);
}
if ((bitField0_ & 0x00000002) != 0) {
output.writeRawByte((byte) 66);
output.writeMessageNoTag(itemCostList);
}
@ -159,6 +211,9 @@ public final class SellItemCsReqOuterClass {
protected int computeSerializedSize() {
int size = 0;
if ((bitField0_ & 0x00000001) != 0) {
size += 2;
}
if ((bitField0_ & 0x00000002) != 0) {
size += 1 + ProtoSink.computeMessageSizeNoTag(itemCostList);
}
return size;
@ -171,10 +226,19 @@ public final class SellItemCsReqOuterClass {
int tag = input.readTag();
while (true) {
switch (tag) {
case 8: {
// toMaterial
toMaterial = input.readBool();
bitField0_ |= 0x00000001;
tag = input.readTag();
if (tag != 66) {
break;
}
}
case 66: {
// itemCostList
input.readMessage(itemCostList);
bitField0_ |= 0x00000001;
bitField0_ |= 0x00000002;
tag = input.readTag();
if (tag != 0) {
break;
@ -198,6 +262,9 @@ public final class SellItemCsReqOuterClass {
public void writeTo(final JsonSink output) throws IOException {
output.beginObject();
if ((bitField0_ & 0x00000001) != 0) {
output.writeBool(FieldNames.toMaterial, toMaterial);
}
if ((bitField0_ & 0x00000002) != 0) {
output.writeMessage(FieldNames.itemCostList, itemCostList);
}
output.endObject();
@ -210,12 +277,24 @@ public final class SellItemCsReqOuterClass {
}
while (!input.isAtEnd()) {
switch (input.readFieldHash()) {
case 278998210:
case 2058461803: {
if (input.isAtField(FieldNames.toMaterial)) {
if (!input.trySkipNullValue()) {
toMaterial = input.readBool();
bitField0_ |= 0x00000001;
}
} else {
input.skipUnknownField();
}
break;
}
case 203506238:
case -1124889692: {
if (input.isAtField(FieldNames.itemCostList)) {
if (!input.trySkipNullValue()) {
input.readMessage(itemCostList);
bitField0_ |= 0x00000001;
bitField0_ |= 0x00000002;
}
} else {
input.skipUnknownField();
@ -274,6 +353,8 @@ public final class SellItemCsReqOuterClass {
* Contains name constants used for serializing JSON
*/
static class FieldNames {
static final FieldName toMaterial = FieldName.forField("toMaterial", "to_material");
static final FieldName itemCostList = FieldName.forField("itemCostList", "item_cost_list");
}
}

View File

@ -32,6 +32,7 @@ public class GameConstants {
public static final int MATERIAL_HCOIN_ID = 1; // Material id for jades. DO NOT CHANGE
public static final int MATERIAL_COIN_ID = 2; // Material id for credits. DO NOT CHANGE
public static final int TRAILBLAZER_EXP_ID = 22;
public static final int RELIC_REMAINS_ID = 235;
public static final int INVENTORY_MAX_EQUIPMENT = 1500;
public static final int INVENTORY_MAX_RELIC = 1500;

View File

@ -313,26 +313,31 @@ public class Inventory extends BasePlayerManager {
List<GameItem> results = new ArrayList<GameItem>(items.size());
for (ItemParam param : items) {
// Check param type
if (param.getId() == GameConstants.MATERIAL_COIN_ID) {
// Remove credits
getPlayer().addSCoin(-param.getCount() * multiplier);
} else if (param.getId() == GameConstants.MATERIAL_HCOIN_ID) {
// Remove credits
getPlayer().addHCoin(-param.getCount() * multiplier);
} else if (param.getId() == GameConstants.ROGUE_TALENT_POINT_ITEM_ID) {
// Remove credits
getPlayer().addTalentPoints(-param.getCount() * multiplier);
} else {
// Remove param items
GameItem item = this.getItemByParam(param);
if (item == null) continue;
GameItem result = this.deleteItem(item, param.getCount() * multiplier);
if (result != null) {
results.add(result);
// Remove virtual items first
if (param.getType() == ItemParamType.PILE) {
if (param.getId() == GameConstants.MATERIAL_COIN_ID) {
// Remove credits
getPlayer().addSCoin(-param.getCount() * multiplier);
continue;
} else if (param.getId() == GameConstants.MATERIAL_HCOIN_ID) {
// Remove credits
getPlayer().addHCoin(-param.getCount() * multiplier);
continue;
} else if (param.getId() == GameConstants.ROGUE_TALENT_POINT_ITEM_ID) {
// Remove credits
getPlayer().addTalentPoints(-param.getCount() * multiplier);
continue;
}
}
// Remove param items
GameItem item = this.getItemByParam(param);
if (item == null) continue;
GameItem result = this.deleteItem(item, param.getCount() * multiplier);
if (result != null) {
results.add(result);
}
}
// Send packet (update)

View File

@ -4,12 +4,14 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import emu.lunarcore.GameConstants;
import emu.lunarcore.data.GameData;
import emu.lunarcore.data.GameDepot;
import emu.lunarcore.data.common.ItemParam;
import emu.lunarcore.data.excel.*;
import emu.lunarcore.data.excel.ItemComposeExcel.FormulaType;
import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.enums.ItemRarity;
import emu.lunarcore.game.player.Player;
import emu.lunarcore.server.game.BaseGameService;
import emu.lunarcore.server.game.GameServer;
@ -552,20 +554,26 @@ public class InventoryService extends BaseGameService {
player.sendPacket(new PacketPlayerSyncScNotify(relic));
}
public Int2IntMap sellItems(Player player, List<ItemParam> items) {
public Int2IntMap sellItems(Player player, boolean toMaterials, List<ItemParam> items) {
// Verify items
var returnItems = new Int2IntOpenHashMap();
for (ItemParam param : items) {
// Get item in inventory
GameItem item = player.getInventory().getItemByParam(param);
if (item == null || item.isLocked() || item.getCount() < param.getCount()) {
return null;
}
// Add return items
for (ItemParam ret : item.getExcel().getReturnItemIDList()) {
// Add to return items
returnItems.put(ret.getId(), returnItems.getOrDefault(ret.getId(), 0) + ret.getCount());
if (item.getExcel().getRarity() == ItemRarity.SuperRare && !toMaterials) {
// Relic remains
returnItems.addTo(GameConstants.RELIC_REMAINS_ID, 10);
} else {
// Add basic return items
for (ItemParam ret : item.getExcel().getReturnItemIDList()) {
returnItems.addTo(ret.getId(), ret.getCount());
}
}
}

View File

@ -24,7 +24,7 @@ public class HandlerSellItemCsReq extends PacketHandler {
items.add(new ItemParam(cost));
}
var returnItems = session.getServer().getInventoryService().sellItems(session.getPlayer(), items);
var returnItems = session.getServer().getInventoryService().sellItems(session.getPlayer(), req.getToMaterial(), items);
session.send(new PacketSellItemScRsp(returnItems));
}

View File

@ -127,7 +127,7 @@ public class Utils {
* Add 2 integers without overflowing
*/
public static int safeAdd(int a, int b) {
return safeAdd(a, b, Integer.MAX_VALUE, Integer.MIN_VALUE);
return safeAdd(a, b, Integer.MAX_VALUE, 0);
}
public static int safeAdd(int a, int b, long max, long min) {