mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2024-11-23 12:29:52 +00:00
feat: implement teapot suite (#2344)
* feat: implement teapot suite * fix: home animals, check respawn, etc * fix: NPE and cancel summon events * fix: forgot to send eventId also
This commit is contained in:
parent
83602f78ae
commit
fc42f665a7
@ -36,21 +36,21 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
int getEntityIdList(int index);
|
||||
|
||||
/**
|
||||
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code>
|
||||
* @return The enum numeric value on the wire for cAKDDMKAIMD.
|
||||
* <code>.HomePlantFieldStatus status = 7;</code>
|
||||
* @return The enum numeric value on the wire for status.
|
||||
*/
|
||||
int getCAKDDMKAIMDValue();
|
||||
int getStatusValue();
|
||||
/**
|
||||
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code>
|
||||
* @return The cAKDDMKAIMD.
|
||||
* <code>.HomePlantFieldStatus status = 7;</code>
|
||||
* @return The status.
|
||||
*/
|
||||
emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus getCAKDDMKAIMD();
|
||||
emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus getStatus();
|
||||
|
||||
/**
|
||||
* <code>uint32 JHFNDBIHLNB = 8;</code>
|
||||
* @return The jHFNDBIHLNB.
|
||||
* <code>uint32 seed_id = 8;</code>
|
||||
* @return The seedId.
|
||||
*/
|
||||
int getJHFNDBIHLNB();
|
||||
int getSeedId();
|
||||
|
||||
/**
|
||||
* <code>fixed32 end_time = 14;</code>
|
||||
@ -59,10 +59,10 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
int getEndTime();
|
||||
|
||||
/**
|
||||
* <code>uint32 KHFGOPCOAGM = 3;</code>
|
||||
* @return The kHFGOPCOAGM.
|
||||
* <code>uint32 gather_point_type = 3;</code>
|
||||
* @return The gatherPointType.
|
||||
*/
|
||||
int getKHFGOPCOAGM();
|
||||
int getGatherPointType();
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
@ -82,7 +82,7 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
}
|
||||
private HomePlantSubFieldData() {
|
||||
entityIdList_ = emptyIntList();
|
||||
cAKDDMKAIMD_ = 0;
|
||||
status_ = 0;
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
@ -118,7 +118,7 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
break;
|
||||
case 24: {
|
||||
|
||||
kHFGOPCOAGM_ = input.readUInt32();
|
||||
gatherPointType_ = input.readUInt32();
|
||||
break;
|
||||
}
|
||||
case 48: {
|
||||
@ -145,12 +145,12 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
case 56: {
|
||||
int rawValue = input.readEnum();
|
||||
|
||||
cAKDDMKAIMD_ = rawValue;
|
||||
status_ = rawValue;
|
||||
break;
|
||||
}
|
||||
case 64: {
|
||||
|
||||
jHFNDBIHLNB_ = input.readUInt32();
|
||||
seedId_ = input.readUInt32();
|
||||
break;
|
||||
}
|
||||
case 117: {
|
||||
@ -221,34 +221,34 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
}
|
||||
private int entityIdListMemoizedSerializedSize = -1;
|
||||
|
||||
public static final int CAKDDMKAIMD_FIELD_NUMBER = 7;
|
||||
private int cAKDDMKAIMD_;
|
||||
public static final int STATUS_FIELD_NUMBER = 7;
|
||||
private int status_;
|
||||
/**
|
||||
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code>
|
||||
* @return The enum numeric value on the wire for cAKDDMKAIMD.
|
||||
* <code>.HomePlantFieldStatus status = 7;</code>
|
||||
* @return The enum numeric value on the wire for status.
|
||||
*/
|
||||
@java.lang.Override public int getCAKDDMKAIMDValue() {
|
||||
return cAKDDMKAIMD_;
|
||||
@java.lang.Override public int getStatusValue() {
|
||||
return status_;
|
||||
}
|
||||
/**
|
||||
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code>
|
||||
* @return The cAKDDMKAIMD.
|
||||
* <code>.HomePlantFieldStatus status = 7;</code>
|
||||
* @return The status.
|
||||
*/
|
||||
@java.lang.Override public emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus getCAKDDMKAIMD() {
|
||||
@java.lang.Override public emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus getStatus() {
|
||||
@SuppressWarnings("deprecation")
|
||||
emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus result = emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.valueOf(cAKDDMKAIMD_);
|
||||
emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus result = emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.valueOf(status_);
|
||||
return result == null ? emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.UNRECOGNIZED : result;
|
||||
}
|
||||
|
||||
public static final int JHFNDBIHLNB_FIELD_NUMBER = 8;
|
||||
private int jHFNDBIHLNB_;
|
||||
public static final int SEED_ID_FIELD_NUMBER = 8;
|
||||
private int seedId_;
|
||||
/**
|
||||
* <code>uint32 JHFNDBIHLNB = 8;</code>
|
||||
* @return The jHFNDBIHLNB.
|
||||
* <code>uint32 seed_id = 8;</code>
|
||||
* @return The seedId.
|
||||
*/
|
||||
@java.lang.Override
|
||||
public int getJHFNDBIHLNB() {
|
||||
return jHFNDBIHLNB_;
|
||||
public int getSeedId() {
|
||||
return seedId_;
|
||||
}
|
||||
|
||||
public static final int END_TIME_FIELD_NUMBER = 14;
|
||||
@ -262,15 +262,15 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
return endTime_;
|
||||
}
|
||||
|
||||
public static final int KHFGOPCOAGM_FIELD_NUMBER = 3;
|
||||
private int kHFGOPCOAGM_;
|
||||
public static final int GATHER_POINT_TYPE_FIELD_NUMBER = 3;
|
||||
private int gatherPointType_;
|
||||
/**
|
||||
* <code>uint32 KHFGOPCOAGM = 3;</code>
|
||||
* @return The kHFGOPCOAGM.
|
||||
* <code>uint32 gather_point_type = 3;</code>
|
||||
* @return The gatherPointType.
|
||||
*/
|
||||
@java.lang.Override
|
||||
public int getKHFGOPCOAGM() {
|
||||
return kHFGOPCOAGM_;
|
||||
public int getGatherPointType() {
|
||||
return gatherPointType_;
|
||||
}
|
||||
|
||||
private byte memoizedIsInitialized = -1;
|
||||
@ -288,8 +288,8 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||
throws java.io.IOException {
|
||||
getSerializedSize();
|
||||
if (kHFGOPCOAGM_ != 0) {
|
||||
output.writeUInt32(3, kHFGOPCOAGM_);
|
||||
if (gatherPointType_ != 0) {
|
||||
output.writeUInt32(3, gatherPointType_);
|
||||
}
|
||||
if (getEntityIdListList().size() > 0) {
|
||||
output.writeUInt32NoTag(50);
|
||||
@ -298,11 +298,11 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
for (int i = 0; i < entityIdList_.size(); i++) {
|
||||
output.writeUInt32NoTag(entityIdList_.getInt(i));
|
||||
}
|
||||
if (cAKDDMKAIMD_ != emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.HOME_FIELD_STATUE_NONE.getNumber()) {
|
||||
output.writeEnum(7, cAKDDMKAIMD_);
|
||||
if (status_ != emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.HOME_FIELD_STATUE_NONE.getNumber()) {
|
||||
output.writeEnum(7, status_);
|
||||
}
|
||||
if (jHFNDBIHLNB_ != 0) {
|
||||
output.writeUInt32(8, jHFNDBIHLNB_);
|
||||
if (seedId_ != 0) {
|
||||
output.writeUInt32(8, seedId_);
|
||||
}
|
||||
if (endTime_ != 0) {
|
||||
output.writeFixed32(14, endTime_);
|
||||
@ -316,9 +316,9 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
if (size != -1) return size;
|
||||
|
||||
size = 0;
|
||||
if (kHFGOPCOAGM_ != 0) {
|
||||
if (gatherPointType_ != 0) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeUInt32Size(3, kHFGOPCOAGM_);
|
||||
.computeUInt32Size(3, gatherPointType_);
|
||||
}
|
||||
{
|
||||
int dataSize = 0;
|
||||
@ -334,13 +334,13 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
}
|
||||
entityIdListMemoizedSerializedSize = dataSize;
|
||||
}
|
||||
if (cAKDDMKAIMD_ != emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.HOME_FIELD_STATUE_NONE.getNumber()) {
|
||||
if (status_ != emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.HOME_FIELD_STATUE_NONE.getNumber()) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeEnumSize(7, cAKDDMKAIMD_);
|
||||
.computeEnumSize(7, status_);
|
||||
}
|
||||
if (jHFNDBIHLNB_ != 0) {
|
||||
if (seedId_ != 0) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeUInt32Size(8, jHFNDBIHLNB_);
|
||||
.computeUInt32Size(8, seedId_);
|
||||
}
|
||||
if (endTime_ != 0) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
@ -363,13 +363,13 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
|
||||
if (!getEntityIdListList()
|
||||
.equals(other.getEntityIdListList())) return false;
|
||||
if (cAKDDMKAIMD_ != other.cAKDDMKAIMD_) return false;
|
||||
if (getJHFNDBIHLNB()
|
||||
!= other.getJHFNDBIHLNB()) return false;
|
||||
if (status_ != other.status_) return false;
|
||||
if (getSeedId()
|
||||
!= other.getSeedId()) return false;
|
||||
if (getEndTime()
|
||||
!= other.getEndTime()) return false;
|
||||
if (getKHFGOPCOAGM()
|
||||
!= other.getKHFGOPCOAGM()) return false;
|
||||
if (getGatherPointType()
|
||||
!= other.getGatherPointType()) return false;
|
||||
if (!unknownFields.equals(other.unknownFields)) return false;
|
||||
return true;
|
||||
}
|
||||
@ -385,14 +385,14 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
hash = (37 * hash) + ENTITY_ID_LIST_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getEntityIdListList().hashCode();
|
||||
}
|
||||
hash = (37 * hash) + CAKDDMKAIMD_FIELD_NUMBER;
|
||||
hash = (53 * hash) + cAKDDMKAIMD_;
|
||||
hash = (37 * hash) + JHFNDBIHLNB_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getJHFNDBIHLNB();
|
||||
hash = (37 * hash) + STATUS_FIELD_NUMBER;
|
||||
hash = (53 * hash) + status_;
|
||||
hash = (37 * hash) + SEED_ID_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getSeedId();
|
||||
hash = (37 * hash) + END_TIME_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getEndTime();
|
||||
hash = (37 * hash) + KHFGOPCOAGM_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getKHFGOPCOAGM();
|
||||
hash = (37 * hash) + GATHER_POINT_TYPE_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getGatherPointType();
|
||||
hash = (29 * hash) + unknownFields.hashCode();
|
||||
memoizedHashCode = hash;
|
||||
return hash;
|
||||
@ -532,13 +532,13 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
super.clear();
|
||||
entityIdList_ = emptyIntList();
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
cAKDDMKAIMD_ = 0;
|
||||
status_ = 0;
|
||||
|
||||
jHFNDBIHLNB_ = 0;
|
||||
seedId_ = 0;
|
||||
|
||||
endTime_ = 0;
|
||||
|
||||
kHFGOPCOAGM_ = 0;
|
||||
gatherPointType_ = 0;
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -572,10 +572,10 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
}
|
||||
result.entityIdList_ = entityIdList_;
|
||||
result.cAKDDMKAIMD_ = cAKDDMKAIMD_;
|
||||
result.jHFNDBIHLNB_ = jHFNDBIHLNB_;
|
||||
result.status_ = status_;
|
||||
result.seedId_ = seedId_;
|
||||
result.endTime_ = endTime_;
|
||||
result.kHFGOPCOAGM_ = kHFGOPCOAGM_;
|
||||
result.gatherPointType_ = gatherPointType_;
|
||||
onBuilt();
|
||||
return result;
|
||||
}
|
||||
@ -634,17 +634,17 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
}
|
||||
onChanged();
|
||||
}
|
||||
if (other.cAKDDMKAIMD_ != 0) {
|
||||
setCAKDDMKAIMDValue(other.getCAKDDMKAIMDValue());
|
||||
if (other.status_ != 0) {
|
||||
setStatusValue(other.getStatusValue());
|
||||
}
|
||||
if (other.getJHFNDBIHLNB() != 0) {
|
||||
setJHFNDBIHLNB(other.getJHFNDBIHLNB());
|
||||
if (other.getSeedId() != 0) {
|
||||
setSeedId(other.getSeedId());
|
||||
}
|
||||
if (other.getEndTime() != 0) {
|
||||
setEndTime(other.getEndTime());
|
||||
}
|
||||
if (other.getKHFGOPCOAGM() != 0) {
|
||||
setKHFGOPCOAGM(other.getKHFGOPCOAGM());
|
||||
if (other.getGatherPointType() != 0) {
|
||||
setGatherPointType(other.getGatherPointType());
|
||||
}
|
||||
this.mergeUnknownFields(other.unknownFields);
|
||||
onChanged();
|
||||
@ -755,87 +755,87 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
return this;
|
||||
}
|
||||
|
||||
private int cAKDDMKAIMD_ = 0;
|
||||
private int status_ = 0;
|
||||
/**
|
||||
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code>
|
||||
* @return The enum numeric value on the wire for cAKDDMKAIMD.
|
||||
* <code>.HomePlantFieldStatus status = 7;</code>
|
||||
* @return The enum numeric value on the wire for status.
|
||||
*/
|
||||
@java.lang.Override public int getCAKDDMKAIMDValue() {
|
||||
return cAKDDMKAIMD_;
|
||||
@java.lang.Override public int getStatusValue() {
|
||||
return status_;
|
||||
}
|
||||
/**
|
||||
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code>
|
||||
* @param value The enum numeric value on the wire for cAKDDMKAIMD to set.
|
||||
* <code>.HomePlantFieldStatus status = 7;</code>
|
||||
* @param value The enum numeric value on the wire for status to set.
|
||||
* @return This builder for chaining.
|
||||
*/
|
||||
public Builder setCAKDDMKAIMDValue(int value) {
|
||||
public Builder setStatusValue(int value) {
|
||||
|
||||
cAKDDMKAIMD_ = value;
|
||||
status_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code>
|
||||
* @return The cAKDDMKAIMD.
|
||||
* <code>.HomePlantFieldStatus status = 7;</code>
|
||||
* @return The status.
|
||||
*/
|
||||
@java.lang.Override
|
||||
public emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus getCAKDDMKAIMD() {
|
||||
public emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus getStatus() {
|
||||
@SuppressWarnings("deprecation")
|
||||
emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus result = emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.valueOf(cAKDDMKAIMD_);
|
||||
emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus result = emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.valueOf(status_);
|
||||
return result == null ? emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.UNRECOGNIZED : result;
|
||||
}
|
||||
/**
|
||||
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code>
|
||||
* @param value The cAKDDMKAIMD to set.
|
||||
* <code>.HomePlantFieldStatus status = 7;</code>
|
||||
* @param value The status to set.
|
||||
* @return This builder for chaining.
|
||||
*/
|
||||
public Builder setCAKDDMKAIMD(emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus value) {
|
||||
public Builder setStatus(emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
cAKDDMKAIMD_ = value.getNumber();
|
||||
status_ = value.getNumber();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code>
|
||||
* <code>.HomePlantFieldStatus status = 7;</code>
|
||||
* @return This builder for chaining.
|
||||
*/
|
||||
public Builder clearCAKDDMKAIMD() {
|
||||
public Builder clearStatus() {
|
||||
|
||||
cAKDDMKAIMD_ = 0;
|
||||
status_ = 0;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
private int jHFNDBIHLNB_ ;
|
||||
private int seedId_ ;
|
||||
/**
|
||||
* <code>uint32 JHFNDBIHLNB = 8;</code>
|
||||
* @return The jHFNDBIHLNB.
|
||||
* <code>uint32 seed_id = 8;</code>
|
||||
* @return The seedId.
|
||||
*/
|
||||
@java.lang.Override
|
||||
public int getJHFNDBIHLNB() {
|
||||
return jHFNDBIHLNB_;
|
||||
public int getSeedId() {
|
||||
return seedId_;
|
||||
}
|
||||
/**
|
||||
* <code>uint32 JHFNDBIHLNB = 8;</code>
|
||||
* @param value The jHFNDBIHLNB to set.
|
||||
* <code>uint32 seed_id = 8;</code>
|
||||
* @param value The seedId to set.
|
||||
* @return This builder for chaining.
|
||||
*/
|
||||
public Builder setJHFNDBIHLNB(int value) {
|
||||
public Builder setSeedId(int value) {
|
||||
|
||||
jHFNDBIHLNB_ = value;
|
||||
seedId_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>uint32 JHFNDBIHLNB = 8;</code>
|
||||
* <code>uint32 seed_id = 8;</code>
|
||||
* @return This builder for chaining.
|
||||
*/
|
||||
public Builder clearJHFNDBIHLNB() {
|
||||
public Builder clearSeedId() {
|
||||
|
||||
jHFNDBIHLNB_ = 0;
|
||||
seedId_ = 0;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
@ -871,33 +871,33 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
return this;
|
||||
}
|
||||
|
||||
private int kHFGOPCOAGM_ ;
|
||||
private int gatherPointType_ ;
|
||||
/**
|
||||
* <code>uint32 KHFGOPCOAGM = 3;</code>
|
||||
* @return The kHFGOPCOAGM.
|
||||
* <code>uint32 gather_point_type = 3;</code>
|
||||
* @return The gatherPointType.
|
||||
*/
|
||||
@java.lang.Override
|
||||
public int getKHFGOPCOAGM() {
|
||||
return kHFGOPCOAGM_;
|
||||
public int getGatherPointType() {
|
||||
return gatherPointType_;
|
||||
}
|
||||
/**
|
||||
* <code>uint32 KHFGOPCOAGM = 3;</code>
|
||||
* @param value The kHFGOPCOAGM to set.
|
||||
* <code>uint32 gather_point_type = 3;</code>
|
||||
* @param value The gatherPointType to set.
|
||||
* @return This builder for chaining.
|
||||
*/
|
||||
public Builder setKHFGOPCOAGM(int value) {
|
||||
public Builder setGatherPointType(int value) {
|
||||
|
||||
kHFGOPCOAGM_ = value;
|
||||
gatherPointType_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>uint32 KHFGOPCOAGM = 3;</code>
|
||||
* <code>uint32 gather_point_type = 3;</code>
|
||||
* @return This builder for chaining.
|
||||
*/
|
||||
public Builder clearKHFGOPCOAGM() {
|
||||
public Builder clearGatherPointType() {
|
||||
|
||||
kHFGOPCOAGM_ = 0;
|
||||
gatherPointType_ = 0;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
@ -969,12 +969,12 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
"\n\033HomePlantSubFieldData.proto\032\032HomePlant" +
|
||||
"FieldStatus.proto\"\227\001\n\025HomePlantSubFieldD" +
|
||||
"ata\022\026\n\016entity_id_list\030\006 \003(\r\022*\n\013CAKDDMKAI" +
|
||||
"MD\030\007 \001(\0162\025.HomePlantFieldStatus\022\023\n\013JHFND" +
|
||||
"BIHLNB\030\010 \001(\r\022\020\n\010end_time\030\016 \001(\007\022\023\n\013KHFGOP" +
|
||||
"COAGM\030\003 \001(\rB\033\n\031emu.grasscutter.net.proto" +
|
||||
"b\006proto3"
|
||||
"FieldStatus.proto\"\224\001\n\025HomePlantSubFieldD" +
|
||||
"ata\022\026\n\016entity_id_list\030\006 \003(\r\022%\n\006status\030\007 " +
|
||||
"\001(\0162\025.HomePlantFieldStatus\022\017\n\007seed_id\030\010 " +
|
||||
"\001(\r\022\020\n\010end_time\030\016 \001(\007\022\031\n\021gather_point_ty" +
|
||||
"pe\030\003 \001(\rB\033\n\031emu.grasscutter.net.protob\006p" +
|
||||
"roto3"
|
||||
};
|
||||
descriptor = com.google.protobuf.Descriptors.FileDescriptor
|
||||
.internalBuildGeneratedFileFrom(descriptorData,
|
||||
@ -986,7 +986,7 @@ public final class HomePlantSubFieldDataOuterClass {
|
||||
internal_static_HomePlantSubFieldData_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
|
||||
internal_static_HomePlantSubFieldData_descriptor,
|
||||
new java.lang.String[] { "EntityIdList", "CAKDDMKAIMD", "JHFNDBIHLNB", "EndTime", "KHFGOPCOAGM", });
|
||||
new java.lang.String[] { "EntityIdList", "Status", "SeedId", "EndTime", "GatherPointType", });
|
||||
emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.getDescriptor();
|
||||
}
|
||||
|
||||
|
@ -286,6 +286,10 @@ public final class GameData {
|
||||
private static final Int2ObjectMap<HomeWorldBgmData> homeWorldBgmDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<HomeWorldEventData> homeWorldEventDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<HomeWorldLevelData> homeWorldLevelDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
@ -0,0 +1,25 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.home.suite.event.SuiteEventType;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@ResourceType(name = "HomeWorldEventExcelConfigData.json")
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
@Getter
|
||||
public class HomeWorldEventData extends GameResource {
|
||||
@SerializedName(value = "id", alternate = {"BBEIIPEFDPE"})
|
||||
int id;
|
||||
@SerializedName(value = "eventType", alternate = {"JOCKIMECHDP"})
|
||||
SuiteEventType eventType;
|
||||
int avatarID;
|
||||
@SerializedName(value = "talkId", alternate = {"IGNJAICDFPD"})
|
||||
int talkId;
|
||||
int rewardID;
|
||||
@SerializedName(value = "suiteId", alternate = {"FEHOKMJPOED"})
|
||||
int suiteId;
|
||||
}
|
@ -10,12 +10,14 @@ import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneEntityDisappearNotify;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class EntityHomeAnimal extends EntityMonster implements Rebornable {
|
||||
private int rebornCDTickCount;
|
||||
private final Position rebornPos;
|
||||
@Getter private final int rebirth;
|
||||
@Getter private final int rebirthCD;
|
||||
private boolean disappeared;
|
||||
private final AtomicBoolean disappeared = new AtomicBoolean();
|
||||
|
||||
public EntityHomeAnimal(Scene scene, HomeWorldAnimalData data, Position pos) {
|
||||
super(scene, GameData.getMonsterDataMap().get(data.getMonsterID()), pos, 1);
|
||||
@ -60,13 +62,13 @@ public class EntityHomeAnimal extends EntityMonster implements Rebornable {
|
||||
new PacketSceneEntityDisappearNotify(
|
||||
this, VisionTypeOuterClass.VisionType.VISION_TYPE_REMOVE));
|
||||
this.rebornCDTickCount = this.getRebornCD();
|
||||
this.disappeared = true;
|
||||
this.disappeared.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reborn() {
|
||||
if (this.disappeared) {
|
||||
this.disappeared = false;
|
||||
if (this.disappeared.get()) {
|
||||
this.disappeared.set(false);
|
||||
this.getPosition().set(this.getRebornPos());
|
||||
this.getScene().broadcastPacket(new PacketSceneEntityAppearNotify(this));
|
||||
}
|
||||
@ -74,6 +76,6 @@ public class EntityHomeAnimal extends EntityMonster implements Rebornable {
|
||||
|
||||
@Override
|
||||
public boolean isInCD() {
|
||||
return this.disappeared;
|
||||
return this.disappeared.get();
|
||||
}
|
||||
}
|
||||
|
@ -12,15 +12,17 @@ import emu.grasscutter.game.props.SceneType;
|
||||
import emu.grasscutter.net.proto.HomeAvatarTalkFinishInfoOuterClass;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Entity(value = "homes", useDiscriminator = false)
|
||||
@Data
|
||||
@ -55,6 +57,7 @@ public class GameHome {
|
||||
Set<Integer> unlockedHomeBgmList;
|
||||
int enterHomeOption;
|
||||
Map<Integer, Set<Integer>> finishedTalkIdMap;
|
||||
Set<Integer> finishedRewardEventIdSet;
|
||||
|
||||
public static GameHome getByUid(Integer uid) {
|
||||
var home = DatabaseHelper.getHomeByUid(uid);
|
||||
@ -62,7 +65,9 @@ public class GameHome {
|
||||
home = GameHome.create(uid);
|
||||
}
|
||||
|
||||
home.reassignIfNull();
|
||||
home.fixMainHouseIfOld();
|
||||
home.syncHomeAvatarCostume();
|
||||
|
||||
return home;
|
||||
}
|
||||
@ -79,9 +84,19 @@ public class GameHome {
|
||||
.mainHouseMap(new ConcurrentHashMap<>())
|
||||
.unlockedHomeBgmList(new HashSet<>())
|
||||
.finishedTalkIdMap(new HashMap<>())
|
||||
.finishedRewardEventIdSet(new HashSet<>())
|
||||
.build();
|
||||
}
|
||||
|
||||
// avoid NPE caused by database remover.
|
||||
private void reassignIfNull() {
|
||||
this.getSceneMap().values().stream()
|
||||
.map(HomeSceneItem::getBlockItems)
|
||||
.map(Map::values)
|
||||
.flatMap(Collection::stream)
|
||||
.forEach(HomeBlockItem::reassignIfNull);
|
||||
}
|
||||
|
||||
// Data fixer.
|
||||
private void fixMainHouseIfOld() {
|
||||
if (this.getMainHouseMap() == null) {
|
||||
@ -97,6 +112,18 @@ public class GameHome {
|
||||
this.save();
|
||||
}
|
||||
|
||||
private void syncHomeAvatarCostume() {
|
||||
Stream.of(this.sceneMap, this.mainHouseMap)
|
||||
.map(ConcurrentHashMap::values)
|
||||
.flatMap(Collection::stream)
|
||||
.map(HomeSceneItem::getBlockItems)
|
||||
.map(Map::values)
|
||||
.flatMap(Collection::stream)
|
||||
.map(HomeBlockItem::getDeployNPCList)
|
||||
.flatMap(Collection::stream)
|
||||
.forEach(npc -> npc.setCostumeId(this.getPlayer().getCostumeFrom(npc.getAvatarId())));
|
||||
}
|
||||
|
||||
public void save() {
|
||||
DatabaseHelper.saveHome(this);
|
||||
}
|
||||
@ -113,12 +140,12 @@ public class GameHome {
|
||||
if (defaultItem != null) {
|
||||
Grasscutter.getLogger()
|
||||
.info("Set player {} home {} to initial setting", ownerUid, sceneId);
|
||||
return HomeSceneItem.parseFrom(defaultItem, sceneId);
|
||||
} else {
|
||||
// Realm res missing bricks account, use default realm data to allow main house
|
||||
defaultItem = GameData.getHomeworldDefaultSaveData().get(2001);
|
||||
return HomeSceneItem.parseFrom(defaultItem, sceneId);
|
||||
}
|
||||
|
||||
return HomeSceneItem.parseFrom(defaultItem, sceneId);
|
||||
});
|
||||
}
|
||||
|
||||
@ -149,6 +176,8 @@ public class GameHome {
|
||||
this.getMainHouseMap().remove(outdoor); // delete main house in current scene.
|
||||
this.getMainHouseItem(outdoor); // put new main house with default arrangement.
|
||||
this.save();
|
||||
|
||||
this.getPlayer().getCurHomeWorld().getModuleManager().refreshMainHouse();
|
||||
}
|
||||
|
||||
public void onOwnerLogin(Player player) {
|
||||
@ -160,6 +189,8 @@ public class GameHome {
|
||||
player.getSession().send(new PacketHomeMarkPointNotify(player));
|
||||
player.getSession().send(new PacketHomeAvatarTalkFinishInfoNotify(player));
|
||||
player.getSession().send(new PacketHomeAllUnlockedBgmIdListNotify(player));
|
||||
player.getSession().send(new PacketHomeAvatarRewardEventNotify(player));
|
||||
player.getSession().send(new PacketHomeAvatarAllFinishRewardNotify(player));
|
||||
checkAccumulatedResources(player);
|
||||
player.getSession().send(new PacketHomeResourceNotify(player));
|
||||
}
|
||||
@ -226,6 +257,20 @@ public class GameHome {
|
||||
.toList();
|
||||
}
|
||||
|
||||
public boolean onClaimAvatarRewards(int eventId) {
|
||||
if (this.finishedRewardEventIdSet == null) {
|
||||
this.finishedRewardEventIdSet = new HashSet<>();
|
||||
}
|
||||
|
||||
var success = this.finishedRewardEventIdSet.add(eventId);
|
||||
this.save();
|
||||
return success;
|
||||
}
|
||||
|
||||
public boolean isRewardEventFinished(int eventId) {
|
||||
return this.finishedRewardEventIdSet != null && this.finishedRewardEventIdSet.contains(eventId);
|
||||
}
|
||||
|
||||
public boolean addUnlockedHomeBgm(int homeBgmId) {
|
||||
if (!getUnlockedHomeBgmList().add(homeBgmId)) return false;
|
||||
|
||||
@ -404,7 +449,7 @@ public class GameHome {
|
||||
newCoin = storedCoin + owedCoin;
|
||||
}
|
||||
// Ensure max is not exceeded
|
||||
storedCoin = (maxCoin >= newCoin) ? newCoin : maxCoin;
|
||||
storedCoin = Math.min(maxCoin, newCoin);
|
||||
}
|
||||
|
||||
// Update fetter exp
|
||||
@ -416,7 +461,7 @@ public class GameHome {
|
||||
newFetter = storedFetterExp + owedFetter;
|
||||
}
|
||||
// Ensure max is not exceeded
|
||||
storedFetterExp = (maxFetter >= newFetter) ? newFetter : maxFetter;
|
||||
storedFetterExp = Math.min(maxFetter, newFetter);
|
||||
}
|
||||
|
||||
save();
|
||||
|
@ -2,6 +2,8 @@ package emu.grasscutter.game.home;
|
||||
|
||||
import dev.morphia.annotations.*;
|
||||
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
|
||||
import emu.grasscutter.game.home.suite.HomeSuiteItem;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.proto.HomeBlockArrangementInfoOuterClass.HomeBlockArrangementInfo;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
@ -19,6 +21,7 @@ public class HomeBlockItem {
|
||||
List<HomeFurnitureItem> persistentFurnitureList;
|
||||
List<HomeAnimalItem> deployAnimalList;
|
||||
List<HomeNPCItem> deployNPCList;
|
||||
List<HomeSuiteItem> suiteList;
|
||||
|
||||
public static HomeBlockItem parseFrom(HomeworldDefaultSaveData.HomeBlock homeBlock) {
|
||||
// create from default setting
|
||||
@ -37,10 +40,11 @@ public class HomeBlockItem {
|
||||
.toList())
|
||||
.deployAnimalList(List.of())
|
||||
.deployNPCList(List.of())
|
||||
.suiteList(List.of())
|
||||
.build();
|
||||
}
|
||||
|
||||
public void update(HomeBlockArrangementInfo homeBlockArrangementInfo) {
|
||||
public void update(HomeBlockArrangementInfo homeBlockArrangementInfo, Player owner) {
|
||||
this.blockId = homeBlockArrangementInfo.getBlockId();
|
||||
|
||||
this.deployFurnitureList =
|
||||
@ -60,8 +64,12 @@ public class HomeBlockItem {
|
||||
|
||||
this.deployNPCList =
|
||||
homeBlockArrangementInfo.getDeployNpcListList().stream()
|
||||
.map(HomeNPCItem::parseFrom)
|
||||
.map(homeNpcData -> HomeNPCItem.parseFrom(homeNpcData, owner))
|
||||
.toList();
|
||||
|
||||
this.suiteList = homeBlockArrangementInfo.getFurnitureSuiteListList().stream()
|
||||
.map(HomeSuiteItem::parseFrom)
|
||||
.toList();
|
||||
}
|
||||
|
||||
public int calComfort() {
|
||||
@ -81,15 +89,16 @@ public class HomeBlockItem {
|
||||
this.persistentFurnitureList.forEach(f -> proto.addPersistentFurnitureList(f.toProto()));
|
||||
this.deployAnimalList.forEach(f -> proto.addDeployAnimalList(f.toProto()));
|
||||
this.deployNPCList.forEach(f -> proto.addDeployNpcList(f.toProto()));
|
||||
this.suiteList.forEach(f -> proto.addFurnitureSuiteList(f.toProto()));
|
||||
|
||||
return proto.build();
|
||||
}
|
||||
|
||||
// TODO add more types (farm field and suite)
|
||||
// TODO implement farm field.
|
||||
public List<? extends HomeMarkPointProtoFactory> getMarkPointProtoFactories() {
|
||||
this.reassignIfNull();
|
||||
|
||||
return Stream.of(this.deployFurnitureList, this.persistentFurnitureList, this.deployNPCList)
|
||||
return Stream.of(this.deployFurnitureList, this.persistentFurnitureList, this.deployNPCList, this.suiteList)
|
||||
.flatMap(Collection::stream)
|
||||
.toList();
|
||||
}
|
||||
@ -107,5 +116,8 @@ public class HomeBlockItem {
|
||||
if (this.deployNPCList == null) {
|
||||
this.deployNPCList = List.of();
|
||||
}
|
||||
if (this.suiteList == null) {
|
||||
this.suiteList = List.of();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
204
src/main/java/emu/grasscutter/game/home/HomeModuleManager.java
Normal file
204
src/main/java/emu/grasscutter/game/home/HomeModuleManager.java
Normal file
@ -0,0 +1,204 @@
|
||||
package emu.grasscutter.game.home;
|
||||
|
||||
import com.github.davidmoten.guavamini.Lists;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.home.suite.event.HomeAvatarRewardEvent;
|
||||
import emu.grasscutter.game.home.suite.event.HomeAvatarSummonEvent;
|
||||
import emu.grasscutter.game.home.suite.event.SuiteEventType;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.proto.HomeAvatarRewardEventNotifyOuterClass;
|
||||
import emu.grasscutter.net.proto.HomeAvatarSummonAllEventNotifyOuterClass;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeAvatarSummonAllEventNotify;
|
||||
import emu.grasscutter.utils.Either;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class HomeModuleManager {
|
||||
final Player homeOwner;
|
||||
final HomeWorld homeWorld;
|
||||
final GameHome home;
|
||||
final int moduleId;
|
||||
final HomeScene outdoor;
|
||||
HomeScene indoor;
|
||||
final List<HomeAvatarRewardEvent> rewardEvents;
|
||||
final List<HomeAvatarSummonEvent> summonEvents;
|
||||
|
||||
public HomeModuleManager(HomeWorld homeWorld) {
|
||||
this.homeOwner = homeWorld.getHost();
|
||||
this.homeWorld = homeWorld;
|
||||
this.home = homeWorld.getHome();
|
||||
this.moduleId = this.homeOwner.getCurrentRealmId();
|
||||
this.outdoor = homeWorld.getSceneById(homeWorld.getActiveOutdoorSceneId());
|
||||
this.refreshMainHouse();
|
||||
this.rewardEvents = Lists.newArrayList();
|
||||
this.summonEvents = Collections.synchronizedList(Lists.newArrayList());
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
this.outdoor.onTick();
|
||||
this.indoor.onTick();
|
||||
this.summonEvents.removeIf(HomeAvatarSummonEvent::isTimeOver);
|
||||
}
|
||||
|
||||
public void refreshMainHouse() {
|
||||
this.indoor = this.homeWorld.getSceneById(this.homeWorld.getActiveIndoorSceneId());
|
||||
}
|
||||
|
||||
public void onUpdateArrangement() {
|
||||
this.fireAllAvatarRewardEvent();
|
||||
this.cancelSummonEventIfAvatarLeave();
|
||||
}
|
||||
|
||||
private void fireAllAvatarRewardEvent() {
|
||||
this.rewardEvents.clear();
|
||||
var allBlockItems = Stream.of(this.getOutdoorSceneItem(), this.getIndoorSceneItem())
|
||||
.map(HomeSceneItem::getBlockItems)
|
||||
.map(Map::values)
|
||||
.flatMap(Collection::stream)
|
||||
.toList();
|
||||
|
||||
var suites = allBlockItems.stream()
|
||||
.map(HomeBlockItem::getSuiteList)
|
||||
.flatMap(Collection::stream)
|
||||
.distinct()
|
||||
.toList();
|
||||
|
||||
allBlockItems.stream()
|
||||
.map(HomeBlockItem::getDeployNPCList)
|
||||
.flatMap(Collection::stream)
|
||||
.forEach(avatar -> {
|
||||
suites.forEach(suite -> {
|
||||
var data = SuiteEventType.HOME_AVATAR_REWARD_EVENT.getEventDataFrom(avatar.getAvatarId(), suite.getSuiteId());
|
||||
if (data == null || this.home.isRewardEventFinished(data.getId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.rewardEvents.add(new HomeAvatarRewardEvent(homeOwner, data.getId(), data.getRewardID(), data.getAvatarID(), data.getSuiteId(), suite.getGuid()));
|
||||
});
|
||||
});
|
||||
|
||||
if (this.summonEvents != null) {
|
||||
var suiteIdList = this.rewardEvents.stream().map(HomeAvatarRewardEvent::getSuiteId).toList();
|
||||
this.summonEvents.removeIf(event -> suiteIdList.contains(event.getSuiteId()));
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelSummonEventIfAvatarLeave() {
|
||||
var avatars = Stream.of(this.getOutdoorSceneItem(), this.getIndoorSceneItem())
|
||||
.map(HomeSceneItem::getBlockItems)
|
||||
.map(Map::values)
|
||||
.flatMap(Collection::stream)
|
||||
.map(HomeBlockItem::getDeployNPCList)
|
||||
.flatMap(Collection::stream)
|
||||
.map(HomeNPCItem::getAvatarId)
|
||||
.toList();
|
||||
|
||||
this.summonEvents.removeIf(event -> !avatars.contains(event.getAvatarId()));
|
||||
}
|
||||
|
||||
public Either<List<GameItem>, Integer> claimAvatarRewards(int eventId) {
|
||||
if (this.rewardEvents.isEmpty()) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_FAIL_VALUE);
|
||||
}
|
||||
|
||||
var event = this.rewardEvents.remove(0);
|
||||
if (event.getEventId() != eventId) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_FAIL_VALUE);
|
||||
}
|
||||
|
||||
if (!this.homeOwner.getHome().onClaimAvatarRewards(eventId)) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_FAIL_VALUE);
|
||||
}
|
||||
|
||||
return Either.left(event.giveRewards());
|
||||
}
|
||||
|
||||
public Either<HomeAvatarSummonEvent, Integer> fireAvatarSummonEvent(Player owner, int avatarId, int guid, int suiteId) {
|
||||
var targetSuite = ((HomeScene) owner.getScene()).getSceneItem().getBlockItems().values().stream()
|
||||
.map(HomeBlockItem::getSuiteList)
|
||||
.flatMap(Collection::stream)
|
||||
.filter(suite -> suite.getGuid() == guid)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (this.isInRewardEvent(avatarId)) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_DUPLICATE_AVATAR_VALUE);
|
||||
}
|
||||
|
||||
if (this.rewardEvents.stream().anyMatch(event -> event.getGuid() == guid)) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_HOME_FURNITURE_GUID_ERROR_VALUE);
|
||||
}
|
||||
|
||||
this.summonEvents.removeIf(event -> event.getGuid() == guid || event.getAvatarId() == avatarId);
|
||||
|
||||
if (targetSuite == null) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_HOME_CLIENT_PARAM_INVALID_VALUE);
|
||||
}
|
||||
|
||||
var eventData = SuiteEventType.HOME_AVATAR_SUMMON_EVENT.getEventDataFrom(avatarId, suiteId);
|
||||
if (eventData == null) {
|
||||
return Either.right(RetcodeOuterClass.Retcode.RET_HOME_CLIENT_PARAM_INVALID_VALUE);
|
||||
}
|
||||
|
||||
var event = new HomeAvatarSummonEvent(owner, eventData.getId(), eventData.getRewardID(), avatarId, suiteId, guid);
|
||||
this.summonEvents.add(event);
|
||||
owner.sendPacket(new PacketHomeAvatarSummonAllEventNotify(owner));
|
||||
return Either.left(event);
|
||||
}
|
||||
|
||||
public void onFinishSummonEvent(int eventId) {
|
||||
this.summonEvents.removeIf(event -> event.getEventId() == eventId);
|
||||
}
|
||||
|
||||
public HomeAvatarRewardEventNotifyOuterClass.HomeAvatarRewardEventNotify toRewardEventProto() {
|
||||
var notify = HomeAvatarRewardEventNotifyOuterClass.HomeAvatarRewardEventNotify.newBuilder();
|
||||
if (!this.rewardEvents.isEmpty()) {
|
||||
notify.setRewardEvent(this.rewardEvents.get(0).toProto()).setIsEventTrigger(true);
|
||||
|
||||
notify.addAllPendingList(this.rewardEvents.subList(1, this.rewardEvents.size()).stream()
|
||||
.map(HomeAvatarRewardEvent::toProto)
|
||||
.toList());
|
||||
}
|
||||
|
||||
return notify.build();
|
||||
}
|
||||
|
||||
public HomeAvatarSummonAllEventNotifyOuterClass.HomeAvatarSummonAllEventNotify toSummonEventProto() {
|
||||
return HomeAvatarSummonAllEventNotifyOuterClass.HomeAvatarSummonAllEventNotify.newBuilder()
|
||||
.addAllSummonEventList(this.summonEvents.stream()
|
||||
.map(HomeAvatarSummonEvent::toProto)
|
||||
.toList())
|
||||
.build();
|
||||
}
|
||||
|
||||
public boolean isInRewardEvent(int avatarId) {
|
||||
return this.rewardEvents.stream().anyMatch(e -> e.getAvatarId() == avatarId);
|
||||
}
|
||||
|
||||
public HomeSceneItem getOutdoorSceneItem() {
|
||||
return this.outdoor.getSceneItem();
|
||||
}
|
||||
|
||||
public HomeSceneItem getIndoorSceneItem() {
|
||||
return this.indoor.getSceneItem();
|
||||
}
|
||||
|
||||
public void onSetModule() {
|
||||
this.outdoor.addEntities(this.getOutdoorSceneItem().getAnimals(this.outdoor));
|
||||
this.indoor.addEntities(this.getIndoorSceneItem().getAnimals(this.indoor));
|
||||
this.fireAllAvatarRewardEvent();
|
||||
}
|
||||
|
||||
public void onRemovedModule() {
|
||||
this.outdoor.getEntities().clear();
|
||||
this.indoor.getEntities().clear();
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package emu.grasscutter.game.home;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.world.Position;
|
||||
import emu.grasscutter.net.proto.HomeMarkPointFurnitureDataOuterClass;
|
||||
import emu.grasscutter.net.proto.HomeMarkPointNPCDataOuterClass;
|
||||
@ -23,11 +24,12 @@ public class HomeNPCItem implements HomeMarkPointProtoFactory {
|
||||
Position spawnRot;
|
||||
int costumeId;
|
||||
|
||||
public static HomeNPCItem parseFrom(HomeNpcDataOuterClass.HomeNpcData homeNpcData) {
|
||||
public static HomeNPCItem parseFrom(HomeNpcDataOuterClass.HomeNpcData homeNpcData, Player owner) {
|
||||
return HomeNPCItem.of()
|
||||
.avatarId(homeNpcData.getAvatarId())
|
||||
.spawnPos(new Position(homeNpcData.getSpawnPos()))
|
||||
.spawnRot(new Position(homeNpcData.getSpawnRot()))
|
||||
.costumeId(owner.getCostumeFrom(homeNpcData.getAvatarId()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
package emu.grasscutter.game.home;
|
||||
|
||||
import emu.grasscutter.data.excels.scene.SceneData;
|
||||
import emu.grasscutter.game.entity.EntityHomeAnimal;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
import emu.grasscutter.game.entity.Rebornable;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.net.proto.VisionTypeOuterClass;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneTimeNotify;
|
||||
|
||||
public class HomeScene extends Scene {
|
||||
@ -40,10 +43,31 @@ public class HomeScene extends Scene {
|
||||
.forEach(gameEntity -> gameEntity.onTick(this.getSceneTimeSeconds()));
|
||||
|
||||
this.finishLoading();
|
||||
this.checkPlayerRespawn();
|
||||
if (this.tickCount++ % 10 == 0) this.broadcastPacket(new PacketSceneTimeNotify(this));
|
||||
}
|
||||
|
||||
public void onEnterEditModeFinish() {
|
||||
this.removeEntities(
|
||||
this.getEntities().values().stream()
|
||||
.filter(gameEntity -> gameEntity instanceof EntityHomeAnimal)
|
||||
.toList(),
|
||||
VisionTypeOuterClass.VisionType.VISION_TYPE_REMOVE);
|
||||
}
|
||||
|
||||
public void onLeaveEditMode() {
|
||||
this.addEntities(this.getSceneItem().getAnimals(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void killEntity(GameEntity target, int attackerId) {
|
||||
if (target instanceof Rebornable rebornable) {
|
||||
rebornable.onAiKillSelf(); // Teapot animals will not die. They will revive!
|
||||
return;
|
||||
}
|
||||
|
||||
super.killEntity(target, attackerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkNpcGroup() {}
|
||||
|
||||
|
@ -6,17 +6,20 @@ import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
|
||||
import emu.grasscutter.game.entity.EntityHomeAnimal;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.world.Position;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.net.proto.HomeSceneArrangementInfoOuterClass.HomeSceneArrangementInfo;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@ -49,14 +52,14 @@ public class HomeSceneItem {
|
||||
.build();
|
||||
}
|
||||
|
||||
public void update(HomeSceneArrangementInfo arrangementInfo) {
|
||||
public void update(HomeSceneArrangementInfo arrangementInfo, Player owner) {
|
||||
for (var blockItem : arrangementInfo.getBlockArrangementInfoListList()) {
|
||||
var block = this.blockItems.get(blockItem.getBlockId());
|
||||
if (block == null) {
|
||||
Grasscutter.getLogger().warn("Could not found the Home Block {}", blockItem.getBlockId());
|
||||
continue;
|
||||
}
|
||||
block.update(blockItem);
|
||||
block.update(blockItem, owner);
|
||||
this.blockItems.put(blockItem.getBlockId(), block);
|
||||
}
|
||||
|
||||
@ -84,17 +87,13 @@ public class HomeSceneItem {
|
||||
}
|
||||
|
||||
@Nullable public Position getTeleportPointPos(int guid) {
|
||||
var pos = new AtomicReference<Position>();
|
||||
|
||||
this.getBlockItems().values().stream()
|
||||
return this.getBlockItems().values().stream()
|
||||
.map(HomeBlockItem::getDeployFurnitureList)
|
||||
.flatMap(Collection::stream)
|
||||
.filter(homeFurnitureItem -> homeFurnitureItem.getGuid() == guid)
|
||||
.map(HomeFurnitureItem::getSpawnPos)
|
||||
.findFirst()
|
||||
.ifPresent(pos::set);
|
||||
|
||||
return pos.get();
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public List<EntityHomeAnimal> getAnimals(Scene scene) {
|
||||
|
@ -8,33 +8,57 @@ import emu.grasscutter.game.world.World;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.proto.ChatInfoOuterClass;
|
||||
import emu.grasscutter.server.game.GameServer;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
import java.util.List;
|
||||
import emu.grasscutter.server.packet.send.PacketDelTeamEntityNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerChatNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerGameTimeNotify;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class HomeWorld extends World {
|
||||
@Getter private final GameHome home;
|
||||
@Getter private HomeModuleManager moduleManager;
|
||||
|
||||
public HomeWorld(GameServer server, Player owner) {
|
||||
super(server, owner);
|
||||
|
||||
this.home = owner.isOnline() ? owner.getHome() : GameHome.getByUid(owner.getUid());
|
||||
server.registerHomeWorld(this);
|
||||
this.refreshModuleManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerScene(Scene scene) {
|
||||
this.addAnimalsToScene((HomeScene) scene);
|
||||
super.registerScene(scene);
|
||||
public boolean onTick() {
|
||||
this.moduleManager.tick();
|
||||
|
||||
if (this.getTickCount() % 10 == 0) {
|
||||
this.getPlayers().forEach(p -> p.sendPacket(new PacketPlayerGameTimeNotify(p)));
|
||||
}
|
||||
|
||||
if (this.isInHome(this.getHost()) && this.getTickCount() % 60 == 0) {
|
||||
this.getHost().updatePlayerGameTime(this.getCurrentWorldTime());
|
||||
}
|
||||
|
||||
this.tickCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregisterScene(Scene scene) {
|
||||
super.deregisterScene(scene);
|
||||
public void refreshModuleManager() {
|
||||
if (this.moduleManager != null) {
|
||||
this.moduleManager.onRemovedModule();
|
||||
}
|
||||
|
||||
this.moduleManager = new HomeModuleManager(this);
|
||||
this.moduleManager.onSetModule();
|
||||
}
|
||||
|
||||
private void addAnimalsToScene(HomeScene scene) {
|
||||
scene.getSceneItem().getAnimals(scene).forEach(scene::addEntity);
|
||||
public int getActiveOutdoorSceneId() {
|
||||
return this.getHost().getCurrentRealmId() + 2000;
|
||||
}
|
||||
|
||||
public int getActiveIndoorSceneId() {
|
||||
return this.getSceneById(this.getActiveOutdoorSceneId()).getSceneItem().getRoomSceneId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -188,6 +212,12 @@ public class HomeWorld extends World {
|
||||
return this.getPlayers().contains(player);
|
||||
}
|
||||
|
||||
public void ifHost(Player hostOrGuest, Consumer<Player> ifHost) {
|
||||
if (this.getHost().equals(hostOrGuest)) {
|
||||
ifHost.accept(hostOrGuest);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendPacketToHostIfOnline(BasePacket basePacket) {
|
||||
if (this.getHost().isOnline()) {
|
||||
this.getHost().sendPacket(basePacket);
|
||||
|
@ -5,10 +5,7 @@ import emu.grasscutter.game.props.EnterReason;
|
||||
import emu.grasscutter.game.world.Position;
|
||||
import emu.grasscutter.game.world.World;
|
||||
import emu.grasscutter.game.world.data.TeleportProperties;
|
||||
import emu.grasscutter.net.proto.EnterTypeOuterClass;
|
||||
import emu.grasscutter.net.proto.OtherPlayerEnterHomeNotifyOuterClass;
|
||||
import emu.grasscutter.net.proto.PlayerApplyEnterHomeResultNotifyOuterClass;
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass;
|
||||
import emu.grasscutter.net.proto.*;
|
||||
import emu.grasscutter.server.event.player.PlayerEnterHomeEvent;
|
||||
import emu.grasscutter.server.event.player.PlayerLeaveHomeEvent;
|
||||
import emu.grasscutter.server.event.player.PlayerTeleportEvent;
|
||||
@ -215,6 +212,7 @@ public class HomeWorldMPSystem extends BaseGameSystem {
|
||||
player.setCurHomeWorld(myHome);
|
||||
myHome.getHome().onOwnerLogin(player);
|
||||
|
||||
player.sendPacket(new PacketPlayerQuitFromHomeNotify(PlayerQuitFromHomeNotifyOuterClass.PlayerQuitFromHomeNotify.QuitReason.BACK_TO_MY_WORLD));
|
||||
player.sendPacket(
|
||||
new PacketPlayerEnterSceneNotify(
|
||||
player,
|
||||
@ -263,6 +261,7 @@ public class HomeWorldMPSystem extends BaseGameSystem {
|
||||
victim.setCurHomeWorld(myHome);
|
||||
myHome.getHome().onOwnerLogin(victim);
|
||||
|
||||
victim.sendPacket(new PacketPlayerQuitFromHomeNotify(PlayerQuitFromHomeNotifyOuterClass.PlayerQuitFromHomeNotify.QuitReason.KICK_BY_HOST));
|
||||
victim.sendPacket(
|
||||
new PacketPlayerEnterSceneNotify(
|
||||
victim,
|
||||
|
@ -0,0 +1,82 @@
|
||||
package emu.grasscutter.game.home.suite;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.grasscutter.game.home.HomeMarkPointProtoFactory;
|
||||
import emu.grasscutter.game.home.SpecialFurnitureType;
|
||||
import emu.grasscutter.game.world.Position;
|
||||
import emu.grasscutter.net.proto.HomeFurnitureSuiteDataOuterClass;
|
||||
import emu.grasscutter.net.proto.HomeMarkPointFurnitureDataOuterClass;
|
||||
import emu.grasscutter.net.proto.HomeMarkPointSuiteDataOuterClass;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Builder(builderMethodName = "of")
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class HomeSuiteItem implements HomeMarkPointProtoFactory {
|
||||
public static final int SUITE_FURNITURE_ID = 377101;
|
||||
int guid;
|
||||
int suiteId;
|
||||
Position pos;
|
||||
List<Integer> includedFurnitureIndexList;
|
||||
boolean isAllowSummon;
|
||||
|
||||
public static HomeSuiteItem parseFrom(HomeFurnitureSuiteDataOuterClass.HomeFurnitureSuiteData data) {
|
||||
return HomeSuiteItem.of()
|
||||
.guid(data.getGuid())
|
||||
.suiteId(data.getSuiteId())
|
||||
.pos(new Position(data.getSpawnPos()))
|
||||
.includedFurnitureIndexList(data.getIncludedFurnitureIndexListList())
|
||||
.isAllowSummon(data.getIsAllowSummon())
|
||||
.build();
|
||||
}
|
||||
|
||||
public HomeFurnitureSuiteDataOuterClass.HomeFurnitureSuiteData toProto() {
|
||||
return HomeFurnitureSuiteDataOuterClass.HomeFurnitureSuiteData.newBuilder()
|
||||
.setSuiteId(this.suiteId)
|
||||
.setGuid(this.guid)
|
||||
.setIsAllowSummon(this.isAllowSummon)
|
||||
.addAllIncludedFurnitureIndexList(this.includedFurnitureIndexList)
|
||||
.setSpawnPos(this.pos.toProto())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public HomeMarkPointFurnitureDataOuterClass.HomeMarkPointFurnitureData toMarkPointProto() {
|
||||
return HomeMarkPointFurnitureDataOuterClass.HomeMarkPointFurnitureData.newBuilder()
|
||||
.setFurnitureId(SUITE_FURNITURE_ID)
|
||||
.setPos(this.pos.toProto())
|
||||
.setFurnitureType(this.getType().getValue())
|
||||
.setGuid(this.guid)
|
||||
.setSuiteData(HomeMarkPointSuiteDataOuterClass.HomeMarkPointSuiteData.newBuilder()
|
||||
.setSuiteId(this.suiteId)
|
||||
.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpecialFurnitureType getType() {
|
||||
return SpecialFurnitureType.FurnitureSuite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
HomeSuiteItem that = (HomeSuiteItem) o;
|
||||
return suiteId == that.suiteId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(suiteId);
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package emu.grasscutter.game.home.suite.event;
|
||||
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public abstract class HomeAvatarEvent {
|
||||
final Player homeOwner;
|
||||
final int eventId;
|
||||
final int rewardId;
|
||||
final int avatarId;
|
||||
final int suiteId;
|
||||
final int guid;
|
||||
final int randomPos;
|
||||
|
||||
public HomeAvatarEvent(Player homeOwner, int eventId, int rewardId, int avatarId, int suiteId, int guid) {
|
||||
this.homeOwner = homeOwner;
|
||||
this.eventId = eventId;
|
||||
this.rewardId = rewardId;
|
||||
this.avatarId = avatarId;
|
||||
this.suiteId = suiteId;
|
||||
this.guid = guid;
|
||||
this.randomPos = this.generateRandomPos();
|
||||
}
|
||||
|
||||
public int generateRandomPos() {
|
||||
return Utils.randomRange(1, 97);
|
||||
}
|
||||
|
||||
public List<GameItem> giveRewards() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
HomeAvatarEvent that = (HomeAvatarEvent) o;
|
||||
return eventId == that.eventId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(eventId);
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package emu.grasscutter.game.home.suite.event;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.net.proto.HomeAvatarRewardEventInfoOuterClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class HomeAvatarRewardEvent extends HomeAvatarEvent {
|
||||
public HomeAvatarRewardEvent(Player homeOwner, int eventId, int rewardId, int avatarId, int suiteId, int guid) {
|
||||
super(homeOwner, eventId, rewardId, avatarId, suiteId, guid);
|
||||
}
|
||||
|
||||
public HomeAvatarRewardEventInfoOuterClass.HomeAvatarRewardEventInfo toProto() {
|
||||
return HomeAvatarRewardEventInfoOuterClass.HomeAvatarRewardEventInfo.newBuilder()
|
||||
.setAvatarId(this.getAvatarId())
|
||||
.setEventId(this.getEventId())
|
||||
.setGuid(this.getGuid())
|
||||
.setSuiteId(this.getSuiteId())
|
||||
.setRandomPosition(this.getRandomPos())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GameItem> giveRewards() {
|
||||
var data = GameData.getRewardDataMap().get(this.getRewardId());
|
||||
if (data == null) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
var rewards = data.getRewardItemList().stream().map(GameItem::new).toList();
|
||||
this.getHomeOwner().getInventory().addItems(rewards, ActionReason.HomeAvatarEventReward);
|
||||
return rewards;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package emu.grasscutter.game.home.suite.event;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.proto.HomeAvatarSummonEventInfoOuterClass;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class HomeAvatarSummonEvent extends HomeAvatarEvent {
|
||||
public static final int TIME_LIMIT_SECS = 240;
|
||||
final int eventOverTime;
|
||||
|
||||
public HomeAvatarSummonEvent(Player homeOwner, int eventId, int rewardId, int avatarId, int suiteId, int guid) {
|
||||
super(homeOwner, eventId, rewardId, avatarId, suiteId, guid);
|
||||
|
||||
this.eventOverTime = Utils.getCurrentSeconds() + TIME_LIMIT_SECS;
|
||||
}
|
||||
|
||||
public HomeAvatarSummonEventInfoOuterClass.HomeAvatarSummonEventInfo toProto() {
|
||||
return HomeAvatarSummonEventInfoOuterClass.HomeAvatarSummonEventInfo.newBuilder()
|
||||
.setAvatarId(this.getAvatarId())
|
||||
.setEventId(this.getEventId())
|
||||
.setGuid(this.getGuid())
|
||||
.setSuitId(this.getSuiteId())
|
||||
.setRandomPosition(this.getRandomPos())
|
||||
.setEventOverTime(this.eventOverTime)
|
||||
.build();
|
||||
}
|
||||
|
||||
public boolean isTimeOver() {
|
||||
return Utils.getCurrentSeconds() > this.eventOverTime;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.game.home.suite.event;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.HomeWorldEventData;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public enum SuiteEventType {
|
||||
HOME_AVATAR_REWARD_EVENT,
|
||||
HOME_AVATAR_SUMMON_EVENT;
|
||||
|
||||
@Nullable
|
||||
public HomeWorldEventData getEventDataFrom(int avatarId, int suiteId) {
|
||||
return GameData.getHomeWorldEventDataMap().values().stream()
|
||||
.filter(data -> data.getEventType() == this && data.getAvatarID() == avatarId && data.getSuiteId() == suiteId)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
@ -950,6 +950,13 @@ public class Player implements PlayerHook, FieldFetch {
|
||||
this.sendPacket(new PacketAvatarGainCostumeNotify(costumeId));
|
||||
}
|
||||
|
||||
public int getCostumeFrom(int avatarId) {
|
||||
var avatars = this.getAvatars();
|
||||
avatars.loadFromDatabase();
|
||||
var avatar = avatars.getAvatarById(avatarId);
|
||||
return avatar == null ? 0 : avatar.getCostume();
|
||||
}
|
||||
|
||||
public void addPersonalLine(int personalLineId) {
|
||||
this.getPersonalLineList().add(personalLineId);
|
||||
session.getPlayer().getQuestManager().queueEvent(QuestCond.QUEST_COND_PERSONAL_LINE_UNLOCK, personalLineId);
|
||||
|
@ -177,7 +177,8 @@ public enum ActionReason {
|
||||
ChannellerSlabLoopDungeonFirstPassReward(1090),
|
||||
ChannellerSlabLoopDungeonScoreReward(1091),
|
||||
HomeLimitedShopBuy(1092),
|
||||
HomeCoinCollect(1093);
|
||||
HomeCoinCollect(1093),
|
||||
HomeAvatarEventReward(1100);
|
||||
|
||||
private static final Int2ObjectMap<ActionReason> map = new Int2ObjectOpenHashMap<>();
|
||||
private static final Map<String, ActionReason> stringMap = new HashMap<>();
|
||||
|
@ -39,7 +39,7 @@ public class World implements Iterable<Player> {
|
||||
@Getter private boolean timeLocked;
|
||||
|
||||
private long lastUpdateTime;
|
||||
@Getter private int tickCount = 0;
|
||||
@Getter protected int tickCount = 0;
|
||||
@Getter private boolean isPaused = false;
|
||||
@Getter private long currentWorldTime;
|
||||
|
||||
|
@ -0,0 +1,30 @@
|
||||
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.HomeAvatarRewardEventGetReqOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeAvatarAllFinishRewardNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeAvatarRewardEventGetRsp;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeAvatarRewardEventNotify;
|
||||
|
||||
@Opcodes(PacketOpcodes.HomeAvatarRewardEventGetReq)
|
||||
public class HandlerHomeAvatarRewardEventGetReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
var req = HomeAvatarRewardEventGetReqOuterClass.HomeAvatarRewardEventGetReq.parseFrom(payload);
|
||||
|
||||
var player = session.getPlayer();
|
||||
var rewardsOrError = player.getCurHomeWorld().getModuleManager().claimAvatarRewards(req.getEventId());
|
||||
session.send(new PacketHomeAvatarRewardEventNotify(player));
|
||||
session.send(new PacketHomeAvatarAllFinishRewardNotify(player));
|
||||
|
||||
session.send(
|
||||
rewardsOrError.map(
|
||||
gameItems -> new PacketHomeAvatarRewardEventGetRsp(req.getEventId(), gameItems),
|
||||
integer -> new PacketHomeAvatarRewardEventGetRsp(req.getEventId(), integer)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
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.HomeAvatarSummonEventReqOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeAvatarSummonEventRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.HomeAvatarSummonEventReq)
|
||||
public class HandlerHomeAvatarSummonEventReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
var req = HomeAvatarSummonEventReqOuterClass.HomeAvatarSummonEventReq.parseFrom(payload);
|
||||
var moduleManager = session.getPlayer().getCurHomeWorld().getModuleManager();
|
||||
var eventOrError = moduleManager.fireAvatarSummonEvent(session.getPlayer(), req.getAvatarId(), req.getGuid(), req.getSuitId());
|
||||
session.send(eventOrError.map(PacketHomeAvatarSummonEventRsp::new, PacketHomeAvatarSummonEventRsp::new));
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
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.HomeAvatarSummonFinishReqOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeAvatarSummonAllEventNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeAvatarSummonFinishRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.HomeAvatarSummonFinishReq)
|
||||
public class HandlerHomeAvatarSummonFinishReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
var req = HomeAvatarSummonFinishReqOuterClass.HomeAvatarSummonFinishReq.parseFrom(payload);
|
||||
var player = session.getPlayer();
|
||||
player.getCurHomeWorld().getModuleManager().onFinishSummonEvent(req.getEventId());
|
||||
session.send(new PacketHomeAvatarSummonAllEventNotify(session.getPlayer()));
|
||||
session.send(new PacketHomeAvatarSummonFinishRsp(req.getEventId()));
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.home.HomeScene;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
@ -31,14 +32,8 @@ public class HandlerHomeChangeEditModeReq extends PacketHandler {
|
||||
session.send(new PacketHomeComfortInfoNotify(session.getPlayer()));
|
||||
|
||||
if (!req.getIsEnterEditMode()) {
|
||||
var scene = session.getPlayer().getScene();
|
||||
scene.addEntities(
|
||||
session
|
||||
.getPlayer()
|
||||
.getCurHomeWorld()
|
||||
.getHome()
|
||||
.getHomeSceneItem(scene.getId())
|
||||
.getAnimals(scene));
|
||||
var scene = (HomeScene) session.getPlayer().getScene();
|
||||
scene.onLeaveEditMode();
|
||||
}
|
||||
|
||||
session.send(new PacketHomeChangeEditModeRsp(req.getIsEnterEditMode()));
|
||||
|
@ -1,7 +1,5 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.world.Position;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
@ -19,9 +17,10 @@ public class HandlerHomeChangeModuleReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
HomeChangeModuleReqOuterClass.HomeChangeModuleReq req =
|
||||
HomeChangeModuleReqOuterClass.HomeChangeModuleReq.parseFrom(payload);
|
||||
HomeChangeModuleReqOuterClass.HomeChangeModuleReq.parseFrom(payload);
|
||||
|
||||
if (!session.getPlayer().getCurHomeWorld().getGuests().isEmpty()) {
|
||||
var homeWorld = session.getPlayer().getCurHomeWorld();
|
||||
if (!homeWorld.getGuests().isEmpty()) {
|
||||
session.send(new PacketHomeChangeModuleRsp());
|
||||
return;
|
||||
}
|
||||
@ -33,13 +32,10 @@ public class HandlerHomeChangeModuleReq extends PacketHandler {
|
||||
session.send(new PacketHomeComfortInfoNotify(session.getPlayer()));
|
||||
|
||||
int realmId = 2000 + req.getTargetModuleId();
|
||||
var scene = homeWorld.getSceneById(realmId);
|
||||
var pos = scene.getScriptManager().getConfig().born_pos;
|
||||
|
||||
Scene scene = session.getPlayer().getWorld().getSceneById(realmId);
|
||||
Position pos = scene.getScriptManager().getConfig().born_pos;
|
||||
|
||||
session
|
||||
.getPlayer()
|
||||
.getWorld()
|
||||
.transferPlayerToScene(session.getPlayer(), realmId, TeleportType.WAYPOINT, pos);
|
||||
homeWorld.transferPlayerToScene(session.getPlayer(), realmId, TeleportType.WAYPOINT, pos);
|
||||
homeWorld.refreshModuleManager();
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.entity.EntityHomeAnimal;
|
||||
import emu.grasscutter.game.home.HomeScene;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.VisionTypeOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeEnterEditModeFinishRsp;
|
||||
|
||||
@ -17,12 +16,8 @@ public class HandlerHomeEnterEditModeFinishReq extends PacketHandler {
|
||||
* This packet is about the edit mode
|
||||
*/
|
||||
|
||||
var scene = session.getPlayer().getScene();
|
||||
scene.removeEntities(
|
||||
scene.getEntities().values().stream()
|
||||
.filter(gameEntity -> gameEntity instanceof EntityHomeAnimal)
|
||||
.toList(),
|
||||
VisionTypeOuterClass.VisionType.VISION_TYPE_REMOVE);
|
||||
var scene = (HomeScene) session.getPlayer().getScene();
|
||||
scene.onEnterEditModeFinish();
|
||||
|
||||
session.send(new PacketHomeEnterEditModeFinishRsp());
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.*;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.OtherPlayerEnterHomeNotifyOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
@ -16,16 +18,20 @@ public class HandlerHomeSceneInitFinishReq extends PacketHandler {
|
||||
session.getPlayer().setHasSentInitPacketInHome(true);
|
||||
|
||||
if (curHomeWorld.getHost().isOnline()
|
||||
&& !curHomeWorld.getHost().equals(session.getPlayer())) {
|
||||
&& !curHomeWorld.getHost().equals(session.getPlayer())) {
|
||||
curHomeWorld
|
||||
.getHost()
|
||||
.sendPacket(
|
||||
new PacketOtherPlayerEnterOrLeaveHomeNotify(
|
||||
session.getPlayer(),
|
||||
OtherPlayerEnterHomeNotifyOuterClass.OtherPlayerEnterHomeNotify.Reason.ENTER));
|
||||
.getHost()
|
||||
.sendPacket(
|
||||
new PacketOtherPlayerEnterOrLeaveHomeNotify(
|
||||
session.getPlayer(),
|
||||
OtherPlayerEnterHomeNotifyOuterClass.OtherPlayerEnterHomeNotify.Reason.ENTER));
|
||||
}
|
||||
}
|
||||
|
||||
curHomeWorld.ifHost(session.getPlayer(), player -> {
|
||||
player.sendPacket(new PacketHomeAvatarRewardEventNotify(player));
|
||||
player.sendPacket(new PacketHomeAvatarSummonAllEventNotify(player));
|
||||
});
|
||||
session.send(new PacketHomeMarkPointNotify(session.getPlayer()));
|
||||
|
||||
session.send(new PacketHomeSceneInitFinishRsp());
|
||||
|
@ -5,10 +5,7 @@ import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.HomeUpdateArrangementInfoReqOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeAvatarTalkFinishInfoNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeBasicInfoNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeMarkPointNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketHomeUpdateArrangementInfoRsp;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
|
||||
@Opcodes(PacketOpcodes.HomeUpdateArrangementInfoReq)
|
||||
public class HandlerHomeUpdateArrangementInfoReq extends PacketHandler {
|
||||
@ -22,14 +19,17 @@ public class HandlerHomeUpdateArrangementInfoReq extends PacketHandler {
|
||||
session.getPlayer().getHome().getHomeSceneItem(session.getPlayer().getSceneId());
|
||||
|
||||
var roomSceneId = homeScene.getRoomSceneId();
|
||||
homeScene.update(req.getSceneArrangementInfo());
|
||||
homeScene.update(req.getSceneArrangementInfo(), session.getPlayer());
|
||||
if (roomSceneId != homeScene.getRoomSceneId()) {
|
||||
session.getPlayer().getHome().onMainHouseChanged();
|
||||
}
|
||||
|
||||
session.getPlayer().getCurHomeWorld().getModuleManager().onUpdateArrangement();
|
||||
session.send(new PacketHomeAvatarRewardEventNotify(session.getPlayer()));
|
||||
session.send(
|
||||
new PacketHomeBasicInfoNotify(session.getPlayer(), session.getPlayer().isInEditMode()));
|
||||
session.send(new PacketHomeAvatarTalkFinishInfoNotify(session.getPlayer()));
|
||||
session.send(new PacketHomeAvatarSummonAllEventNotify(session.getPlayer()));
|
||||
session.send(new PacketHomeMarkPointNotify(session.getPlayer()));
|
||||
|
||||
session.getPlayer().getHome().save();
|
||||
|
@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.HomeAvatarAllFinishRewardNotifyOuterClass;
|
||||
|
||||
public class PacketHomeAvatarAllFinishRewardNotify extends BasePacket {
|
||||
public PacketHomeAvatarAllFinishRewardNotify(Player player) {
|
||||
super(PacketOpcodes.HomeAvatarAllFinishRewardNotify);
|
||||
|
||||
var list = player.getHome().getFinishedRewardEventIdSet();
|
||||
if (list != null) {
|
||||
this.setData(HomeAvatarAllFinishRewardNotifyOuterClass.HomeAvatarAllFinishRewardNotify.newBuilder()
|
||||
.addAllEventIdList(player.getHome().getFinishedRewardEventIdSet()));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.HomeAvatarRewardEventGetRspOuterClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PacketHomeAvatarRewardEventGetRsp extends BasePacket {
|
||||
public PacketHomeAvatarRewardEventGetRsp(int eventId, List<GameItem> rewards) {
|
||||
super(PacketOpcodes.HomeAvatarRewardEventGetRsp);
|
||||
|
||||
this.setData(HomeAvatarRewardEventGetRspOuterClass.HomeAvatarRewardEventGetRsp.newBuilder()
|
||||
.setEventId(eventId)
|
||||
.addAllItemList(rewards.stream().map(GameItem::toItemParam).toList()));
|
||||
}
|
||||
|
||||
public PacketHomeAvatarRewardEventGetRsp(int eventId, int retcode) {
|
||||
super(PacketOpcodes.HomeAvatarRewardEventGetRsp);
|
||||
|
||||
this.setData(HomeAvatarRewardEventGetRspOuterClass.HomeAvatarRewardEventGetRsp.newBuilder()
|
||||
.setEventId(eventId)
|
||||
.setRetcode(retcode));
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
|
||||
public class PacketHomeAvatarRewardEventNotify extends BasePacket {
|
||||
public PacketHomeAvatarRewardEventNotify(Player homeOwner) {
|
||||
super(PacketOpcodes.HomeAvatarRewardEventNotify);
|
||||
this.setData(homeOwner.getCurHomeWorld().getModuleManager().toRewardEventProto());
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
|
||||
public class PacketHomeAvatarSummonAllEventNotify extends BasePacket {
|
||||
public PacketHomeAvatarSummonAllEventNotify(Player homeOwner) {
|
||||
super(PacketOpcodes.HomeAvatarSummonAllEventNotify);
|
||||
this.setData(homeOwner.getCurHomeWorld().getModuleManager().toSummonEventProto());
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.home.suite.event.HomeAvatarSummonEvent;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.HomeAvatarSummonEventRspOuterClass;
|
||||
|
||||
public class PacketHomeAvatarSummonEventRsp extends BasePacket {
|
||||
public PacketHomeAvatarSummonEventRsp(HomeAvatarSummonEvent event) {
|
||||
super(PacketOpcodes.HomeAvatarSummonEventRsp);
|
||||
|
||||
this.setData(HomeAvatarSummonEventRspOuterClass.HomeAvatarSummonEventRsp.newBuilder()
|
||||
.setEventId(event.getEventId()));
|
||||
}
|
||||
|
||||
public PacketHomeAvatarSummonEventRsp(int retcode) {
|
||||
super(PacketOpcodes.HomeAvatarSummonEventRsp);
|
||||
|
||||
this.setData(HomeAvatarSummonEventRspOuterClass.HomeAvatarSummonEventRsp.newBuilder()
|
||||
.setRetcode(retcode));
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.HomeAvatarSummonFinishRspOuterClass;
|
||||
|
||||
public class PacketHomeAvatarSummonFinishRsp extends BasePacket {
|
||||
public PacketHomeAvatarSummonFinishRsp(int eventId) {
|
||||
super(PacketOpcodes.HomeAvatarSummonFinishRsp);
|
||||
|
||||
this.setData(HomeAvatarSummonFinishRspOuterClass.HomeAvatarSummonFinishRsp.newBuilder()
|
||||
.setEventId(eventId));
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.PlayerQuitFromHomeNotifyOuterClass;
|
||||
|
||||
public class PacketPlayerQuitFromHomeNotify extends BasePacket {
|
||||
public PacketPlayerQuitFromHomeNotify(PlayerQuitFromHomeNotifyOuterClass.PlayerQuitFromHomeNotify.QuitReason reason) {
|
||||
super(PacketOpcodes.PlayerQuitFromHomeNotify);
|
||||
|
||||
this.setData(PlayerQuitFromHomeNotifyOuterClass.PlayerQuitFromHomeNotify.newBuilder()
|
||||
.setReason(reason));
|
||||
}
|
||||
}
|
153
src/main/java/emu/grasscutter/utils/Either.java
Normal file
153
src/main/java/emu/grasscutter/utils/Either.java
Normal file
@ -0,0 +1,153 @@
|
||||
package emu.grasscutter.utils;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class Either<L, R> {
|
||||
private static final class Left<L, R> extends Either<L, R> {
|
||||
private final L value;
|
||||
|
||||
public Left(L value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U, V> Either<U, V> mapBoth(Function<? super L, ? extends U> f1, Function<? super R, ? extends V> f2) {
|
||||
return new Left<>(f1.apply(this.value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T map(Function<? super L, ? extends T> l, Function<? super R, ? extends T> r) {
|
||||
return l.apply(this.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Either<L, R> ifLeft(Consumer<? super L> consumer) {
|
||||
consumer.accept(this.value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Either<L, R> ifRight(Consumer<? super R> consumer) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<L> left() {
|
||||
return Optional.of(this.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<R> right() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Left[" + this.value + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Left<?, ?> left = (Left<?, ?>) o;
|
||||
return Objects.equals(value, left.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(value);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Right<L, R> extends Either<L, R> {
|
||||
private final R value;
|
||||
|
||||
public Right(R value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U, V> Either<U, V> mapBoth(Function<? super L, ? extends U> f1, Function<? super R, ? extends V> f2) {
|
||||
return new Right<>(f2.apply(this.value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T map(Function<? super L, ? extends T> l, Function<? super R, ? extends T> r) {
|
||||
return r.apply(this.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Either<L, R> ifLeft(Consumer<? super L> consumer) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Either<L, R> ifRight(Consumer<? super R> consumer) {
|
||||
consumer.accept(this.value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<L> left() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<R> right() {
|
||||
return Optional.of(this.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Right[" + this.value + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Right<?, ?> right = (Right<?, ?>) o;
|
||||
return Objects.equals(value, right.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(value);
|
||||
}
|
||||
}
|
||||
|
||||
private Either() {
|
||||
}
|
||||
|
||||
public abstract <U, V> Either<U, V> mapBoth(Function<? super L, ? extends U> f1, Function<? super R, ? extends V> f2);
|
||||
|
||||
public abstract <T> T map(Function<? super L, ? extends T> l, Function<? super R, ? extends T> r);
|
||||
|
||||
public abstract Either<L, R> ifLeft(Consumer<? super L> consumer);
|
||||
|
||||
public abstract Either<L, R> ifRight(Consumer<? super R> consumer);
|
||||
|
||||
public abstract Optional<L> left();
|
||||
|
||||
public abstract Optional<R> right();
|
||||
|
||||
public <T> Either<T, R> mapLeft(Function<? super L, ? extends T> l) {
|
||||
return map(t -> left(l.apply(t)), Either::right);
|
||||
}
|
||||
|
||||
public <T> Either<L, T> mapRight(Function<? super R, ? extends T> l) {
|
||||
return map(Either::left, t -> right(l.apply(t)));
|
||||
}
|
||||
|
||||
public static <L, R> Either<L, R> left(L value) {
|
||||
return new Left<>(value);
|
||||
}
|
||||
|
||||
public static <L, R> Either<L, R> right(R value) {
|
||||
return new Right<>(value);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user