Implement reserve stamina

This commit is contained in:
Melledy
2023-11-13 21:54:29 -08:00
parent 7d9a3671fd
commit dda7e67018
6 changed files with 666 additions and 1 deletions

View File

@@ -0,0 +1,260 @@
// Code generated by protocol buffer compiler. Do not edit!
package emu.lunarcore.proto;
import java.io.IOException;
import us.hebi.quickbuf.FieldName;
import us.hebi.quickbuf.InvalidProtocolBufferException;
import us.hebi.quickbuf.JsonSink;
import us.hebi.quickbuf.JsonSource;
import us.hebi.quickbuf.MessageFactory;
import us.hebi.quickbuf.ProtoMessage;
import us.hebi.quickbuf.ProtoSink;
import us.hebi.quickbuf.ProtoSource;
public final class ReserveStaminaExchangeCsReqOuterClass {
/**
* Protobuf type {@code ReserveStaminaExchangeCsReq}
*/
public static final class ReserveStaminaExchangeCsReq extends ProtoMessage<ReserveStaminaExchangeCsReq> implements Cloneable {
private static final long serialVersionUID = 0L;
/**
* <code>optional uint32 num = 2;</code>
*/
private int num;
private ReserveStaminaExchangeCsReq() {
}
/**
* @return a new empty instance of {@code ReserveStaminaExchangeCsReq}
*/
public static ReserveStaminaExchangeCsReq newInstance() {
return new ReserveStaminaExchangeCsReq();
}
/**
* <code>optional uint32 num = 2;</code>
* @return whether the num field is set
*/
public boolean hasNum() {
return (bitField0_ & 0x00000001) != 0;
}
/**
* <code>optional uint32 num = 2;</code>
* @return this
*/
public ReserveStaminaExchangeCsReq clearNum() {
bitField0_ &= ~0x00000001;
num = 0;
return this;
}
/**
* <code>optional uint32 num = 2;</code>
* @return the num
*/
public int getNum() {
return num;
}
/**
* <code>optional uint32 num = 2;</code>
* @param value the num to set
* @return this
*/
public ReserveStaminaExchangeCsReq setNum(final int value) {
bitField0_ |= 0x00000001;
num = value;
return this;
}
@Override
public ReserveStaminaExchangeCsReq copyFrom(final ReserveStaminaExchangeCsReq other) {
cachedSize = other.cachedSize;
if ((bitField0_ | other.bitField0_) != 0) {
bitField0_ = other.bitField0_;
num = other.num;
}
return this;
}
@Override
public ReserveStaminaExchangeCsReq mergeFrom(final ReserveStaminaExchangeCsReq other) {
if (other.isEmpty()) {
return this;
}
cachedSize = -1;
if (other.hasNum()) {
setNum(other.num);
}
return this;
}
@Override
public ReserveStaminaExchangeCsReq clear() {
if (isEmpty()) {
return this;
}
cachedSize = -1;
bitField0_ = 0;
num = 0;
return this;
}
@Override
public ReserveStaminaExchangeCsReq clearQuick() {
if (isEmpty()) {
return this;
}
cachedSize = -1;
bitField0_ = 0;
return this;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof ReserveStaminaExchangeCsReq)) {
return false;
}
ReserveStaminaExchangeCsReq other = (ReserveStaminaExchangeCsReq) o;
return bitField0_ == other.bitField0_
&& (!hasNum() || num == other.num);
}
@Override
public void writeTo(final ProtoSink output) throws IOException {
if ((bitField0_ & 0x00000001) != 0) {
output.writeRawByte((byte) 16);
output.writeUInt32NoTag(num);
}
}
@Override
protected int computeSerializedSize() {
int size = 0;
if ((bitField0_ & 0x00000001) != 0) {
size += 1 + ProtoSink.computeUInt32SizeNoTag(num);
}
return size;
}
@Override
@SuppressWarnings("fallthrough")
public ReserveStaminaExchangeCsReq mergeFrom(final ProtoSource input) throws IOException {
// Enabled Fall-Through Optimization (QuickBuffers)
int tag = input.readTag();
while (true) {
switch (tag) {
case 16: {
// num
num = input.readUInt32();
bitField0_ |= 0x00000001;
tag = input.readTag();
if (tag != 0) {
break;
}
}
case 0: {
return this;
}
default: {
if (!input.skipField(tag)) {
return this;
}
tag = input.readTag();
break;
}
}
}
}
@Override
public void writeTo(final JsonSink output) throws IOException {
output.beginObject();
if ((bitField0_ & 0x00000001) != 0) {
output.writeUInt32(FieldNames.num, num);
}
output.endObject();
}
@Override
public ReserveStaminaExchangeCsReq mergeFrom(final JsonSource input) throws IOException {
if (!input.beginObject()) {
return this;
}
while (!input.isAtEnd()) {
switch (input.readFieldHash()) {
case 109446: {
if (input.isAtField(FieldNames.num)) {
if (!input.trySkipNullValue()) {
num = input.readUInt32();
bitField0_ |= 0x00000001;
}
} else {
input.skipUnknownField();
}
break;
}
default: {
input.skipUnknownField();
break;
}
}
}
input.endObject();
return this;
}
@Override
public ReserveStaminaExchangeCsReq clone() {
return new ReserveStaminaExchangeCsReq().copyFrom(this);
}
@Override
public boolean isEmpty() {
return ((bitField0_) == 0);
}
public static ReserveStaminaExchangeCsReq parseFrom(final byte[] data) throws
InvalidProtocolBufferException {
return ProtoMessage.mergeFrom(new ReserveStaminaExchangeCsReq(), data).checkInitialized();
}
public static ReserveStaminaExchangeCsReq parseFrom(final ProtoSource input) throws
IOException {
return ProtoMessage.mergeFrom(new ReserveStaminaExchangeCsReq(), input).checkInitialized();
}
public static ReserveStaminaExchangeCsReq parseFrom(final JsonSource input) throws IOException {
return ProtoMessage.mergeFrom(new ReserveStaminaExchangeCsReq(), input).checkInitialized();
}
/**
* @return factory for creating ReserveStaminaExchangeCsReq messages
*/
public static MessageFactory<ReserveStaminaExchangeCsReq> getFactory() {
return ReserveStaminaExchangeCsReqFactory.INSTANCE;
}
private enum ReserveStaminaExchangeCsReqFactory implements MessageFactory<ReserveStaminaExchangeCsReq> {
INSTANCE;
@Override
public ReserveStaminaExchangeCsReq create() {
return ReserveStaminaExchangeCsReq.newInstance();
}
}
/**
* Contains name constants used for serializing JSON
*/
static class FieldNames {
static final FieldName num = FieldName.forField("num");
}
}
}

View File

@@ -0,0 +1,340 @@
// Code generated by protocol buffer compiler. Do not edit!
package emu.lunarcore.proto;
import java.io.IOException;
import us.hebi.quickbuf.FieldName;
import us.hebi.quickbuf.InvalidProtocolBufferException;
import us.hebi.quickbuf.JsonSink;
import us.hebi.quickbuf.JsonSource;
import us.hebi.quickbuf.MessageFactory;
import us.hebi.quickbuf.ProtoMessage;
import us.hebi.quickbuf.ProtoSink;
import us.hebi.quickbuf.ProtoSource;
public final class ReserveStaminaExchangeScRspOuterClass {
/**
* Protobuf type {@code ReserveStaminaExchangeScRsp}
*/
public static final class ReserveStaminaExchangeScRsp extends ProtoMessage<ReserveStaminaExchangeScRsp> implements Cloneable {
private static final long serialVersionUID = 0L;
/**
* <code>optional uint32 num = 9;</code>
*/
private int num;
/**
* <code>optional uint32 retcode = 13;</code>
*/
private int retcode;
private ReserveStaminaExchangeScRsp() {
}
/**
* @return a new empty instance of {@code ReserveStaminaExchangeScRsp}
*/
public static ReserveStaminaExchangeScRsp newInstance() {
return new ReserveStaminaExchangeScRsp();
}
/**
* <code>optional uint32 num = 9;</code>
* @return whether the num field is set
*/
public boolean hasNum() {
return (bitField0_ & 0x00000001) != 0;
}
/**
* <code>optional uint32 num = 9;</code>
* @return this
*/
public ReserveStaminaExchangeScRsp clearNum() {
bitField0_ &= ~0x00000001;
num = 0;
return this;
}
/**
* <code>optional uint32 num = 9;</code>
* @return the num
*/
public int getNum() {
return num;
}
/**
* <code>optional uint32 num = 9;</code>
* @param value the num to set
* @return this
*/
public ReserveStaminaExchangeScRsp setNum(final int value) {
bitField0_ |= 0x00000001;
num = value;
return this;
}
/**
* <code>optional uint32 retcode = 13;</code>
* @return whether the retcode field is set
*/
public boolean hasRetcode() {
return (bitField0_ & 0x00000002) != 0;
}
/**
* <code>optional uint32 retcode = 13;</code>
* @return this
*/
public ReserveStaminaExchangeScRsp clearRetcode() {
bitField0_ &= ~0x00000002;
retcode = 0;
return this;
}
/**
* <code>optional uint32 retcode = 13;</code>
* @return the retcode
*/
public int getRetcode() {
return retcode;
}
/**
* <code>optional uint32 retcode = 13;</code>
* @param value the retcode to set
* @return this
*/
public ReserveStaminaExchangeScRsp setRetcode(final int value) {
bitField0_ |= 0x00000002;
retcode = value;
return this;
}
@Override
public ReserveStaminaExchangeScRsp copyFrom(final ReserveStaminaExchangeScRsp other) {
cachedSize = other.cachedSize;
if ((bitField0_ | other.bitField0_) != 0) {
bitField0_ = other.bitField0_;
num = other.num;
retcode = other.retcode;
}
return this;
}
@Override
public ReserveStaminaExchangeScRsp mergeFrom(final ReserveStaminaExchangeScRsp other) {
if (other.isEmpty()) {
return this;
}
cachedSize = -1;
if (other.hasNum()) {
setNum(other.num);
}
if (other.hasRetcode()) {
setRetcode(other.retcode);
}
return this;
}
@Override
public ReserveStaminaExchangeScRsp clear() {
if (isEmpty()) {
return this;
}
cachedSize = -1;
bitField0_ = 0;
num = 0;
retcode = 0;
return this;
}
@Override
public ReserveStaminaExchangeScRsp clearQuick() {
if (isEmpty()) {
return this;
}
cachedSize = -1;
bitField0_ = 0;
return this;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof ReserveStaminaExchangeScRsp)) {
return false;
}
ReserveStaminaExchangeScRsp other = (ReserveStaminaExchangeScRsp) o;
return bitField0_ == other.bitField0_
&& (!hasNum() || num == other.num)
&& (!hasRetcode() || retcode == other.retcode);
}
@Override
public void writeTo(final ProtoSink output) throws IOException {
if ((bitField0_ & 0x00000001) != 0) {
output.writeRawByte((byte) 72);
output.writeUInt32NoTag(num);
}
if ((bitField0_ & 0x00000002) != 0) {
output.writeRawByte((byte) 104);
output.writeUInt32NoTag(retcode);
}
}
@Override
protected int computeSerializedSize() {
int size = 0;
if ((bitField0_ & 0x00000001) != 0) {
size += 1 + ProtoSink.computeUInt32SizeNoTag(num);
}
if ((bitField0_ & 0x00000002) != 0) {
size += 1 + ProtoSink.computeUInt32SizeNoTag(retcode);
}
return size;
}
@Override
@SuppressWarnings("fallthrough")
public ReserveStaminaExchangeScRsp mergeFrom(final ProtoSource input) throws IOException {
// Enabled Fall-Through Optimization (QuickBuffers)
int tag = input.readTag();
while (true) {
switch (tag) {
case 72: {
// num
num = input.readUInt32();
bitField0_ |= 0x00000001;
tag = input.readTag();
if (tag != 104) {
break;
}
}
case 104: {
// retcode
retcode = input.readUInt32();
bitField0_ |= 0x00000002;
tag = input.readTag();
if (tag != 0) {
break;
}
}
case 0: {
return this;
}
default: {
if (!input.skipField(tag)) {
return this;
}
tag = input.readTag();
break;
}
}
}
}
@Override
public void writeTo(final JsonSink output) throws IOException {
output.beginObject();
if ((bitField0_ & 0x00000001) != 0) {
output.writeUInt32(FieldNames.num, num);
}
if ((bitField0_ & 0x00000002) != 0) {
output.writeUInt32(FieldNames.retcode, retcode);
}
output.endObject();
}
@Override
public ReserveStaminaExchangeScRsp mergeFrom(final JsonSource input) throws IOException {
if (!input.beginObject()) {
return this;
}
while (!input.isAtEnd()) {
switch (input.readFieldHash()) {
case 109446: {
if (input.isAtField(FieldNames.num)) {
if (!input.trySkipNullValue()) {
num = input.readUInt32();
bitField0_ |= 0x00000001;
}
} else {
input.skipUnknownField();
}
break;
}
case 1097936398: {
if (input.isAtField(FieldNames.retcode)) {
if (!input.trySkipNullValue()) {
retcode = input.readUInt32();
bitField0_ |= 0x00000002;
}
} else {
input.skipUnknownField();
}
break;
}
default: {
input.skipUnknownField();
break;
}
}
}
input.endObject();
return this;
}
@Override
public ReserveStaminaExchangeScRsp clone() {
return new ReserveStaminaExchangeScRsp().copyFrom(this);
}
@Override
public boolean isEmpty() {
return ((bitField0_) == 0);
}
public static ReserveStaminaExchangeScRsp parseFrom(final byte[] data) throws
InvalidProtocolBufferException {
return ProtoMessage.mergeFrom(new ReserveStaminaExchangeScRsp(), data).checkInitialized();
}
public static ReserveStaminaExchangeScRsp parseFrom(final ProtoSource input) throws
IOException {
return ProtoMessage.mergeFrom(new ReserveStaminaExchangeScRsp(), input).checkInitialized();
}
public static ReserveStaminaExchangeScRsp parseFrom(final JsonSource input) throws IOException {
return ProtoMessage.mergeFrom(new ReserveStaminaExchangeScRsp(), input).checkInitialized();
}
/**
* @return factory for creating ReserveStaminaExchangeScRsp messages
*/
public static MessageFactory<ReserveStaminaExchangeScRsp> getFactory() {
return ReserveStaminaExchangeScRspFactory.INSTANCE;
}
private enum ReserveStaminaExchangeScRspFactory implements MessageFactory<ReserveStaminaExchangeScRsp> {
INSTANCE;
@Override
public ReserveStaminaExchangeScRsp create() {
return ReserveStaminaExchangeScRsp.newInstance();
}
}
/**
* Contains name constants used for serializing JSON
*/
static class FieldNames {
static final FieldName num = FieldName.forField("num");
static final FieldName retcode = FieldName.forField("retcode");
}
}
}

View File

@@ -72,6 +72,7 @@ public class Player {
private int talentPoints; // Rogue talent points
private int stamina;
private double staminaReserve;
private long nextStaminaRecover;
private transient Battle battle;
@@ -130,6 +131,7 @@ public class Player {
this.headIcon = 200001;
this.level = 1;
this.stamina = GameConstants.MAX_STAMINA;
this.nextStaminaRecover = System.currentTimeMillis();
this.unlockedHeadIcons = new IntOpenHashSet();
this.lineupManager = new LineupManager(this);
@@ -367,6 +369,20 @@ public class Player {
this.sendPacket(new PacketStaminaInfoScNotify(this));
}
public int exchangeReserveStamina(int amount) {
// Sanity checks
if (amount <= 0 || this.staminaReserve < amount) {
return 0;
}
this.staminaReserve -= amount;
this.stamina += amount;
// Update to client
this.sendPacket(new PacketStaminaInfoScNotify(this));
return amount;
}
private void updateStamina() {
// Get current timestamp
long time = System.currentTimeMillis();
@@ -378,12 +394,17 @@ public class Player {
if (this.stamina < GameConstants.MAX_STAMINA) {
this.stamina += 1;
hasChanged = true;
} else if (this.stamina < GameConstants.MAX_STAMINA_RESERVE) {
double amount = (time - this.nextStaminaRecover) / (18D * 60D * 1000D);
this.staminaReserve = Math.min(this.staminaReserve + amount, GameConstants.MAX_STAMINA_RESERVE);
hasChanged = true;
}
// Calculate next stamina recover time
if (this.stamina >= GameConstants.MAX_STAMINA) {
this.nextStaminaRecover = time;
}
this.nextStaminaRecover += 5 * 60 * 1000;
}

View File

@@ -0,0 +1,21 @@
package emu.lunarcore.server.packet.recv;
import emu.lunarcore.proto.ReserveStaminaExchangeCsReqOuterClass.ReserveStaminaExchangeCsReq;
import emu.lunarcore.server.game.GameSession;
import emu.lunarcore.server.packet.CmdId;
import emu.lunarcore.server.packet.Opcodes;
import emu.lunarcore.server.packet.PacketHandler;
import emu.lunarcore.server.packet.send.PacketReserveStaminaExchangeScRsp;
@Opcodes(CmdId.ReserveStaminaExchangeCsReq)
public class HandlerReserveStaminaExchangeCsReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
var req = ReserveStaminaExchangeCsReq.parseFrom(data);
int exchangedAmount = session.getPlayer().exchangeReserveStamina(req.getNum());
session.send(new PacketReserveStaminaExchangeScRsp(exchangedAmount));
}
}

View File

@@ -0,0 +1,22 @@
package emu.lunarcore.server.packet.send;
import emu.lunarcore.proto.ReserveStaminaExchangeScRspOuterClass.ReserveStaminaExchangeScRsp;
import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CmdId;
public class PacketReserveStaminaExchangeScRsp extends BasePacket {
public PacketReserveStaminaExchangeScRsp(int amount) {
super(CmdId.ReserveStaminaExchangeScRsp);
var data = ReserveStaminaExchangeScRsp.newInstance();
if (amount > 0) {
data.setNum(amount);
} else {
data.setRetcode(1);
}
this.setData(data);
}
}

View File

@@ -12,7 +12,8 @@ public class PacketStaminaInfoScNotify extends BasePacket {
var data = StaminaInfoScNotify.newInstance()
.setNextRecoverTime(player.getNextStaminaRecover() / 1000)
.setStamina(player.getStamina());
.setStamina(player.getStamina())
.setReserveStamina((int) Math.floor(player.getStaminaReserve()));
this.setData(data);
}