mirror of
https://github.com/Melledy/Nebula.git
synced 2026-09-19 17:19:58 +02:00
Implement sending gifts
This commit is contained in:
@@ -28,6 +28,9 @@ public class GameData {
|
|||||||
@Getter private static DataTable<TalentGroupDef> TalentGroupDataTable = new DataTable<>();
|
@Getter private static DataTable<TalentGroupDef> TalentGroupDataTable = new DataTable<>();
|
||||||
@Getter private static DataTable<TalentDef> TalentDataTable = new DataTable<>();
|
@Getter private static DataTable<TalentDef> TalentDataTable = new DataTable<>();
|
||||||
|
|
||||||
|
@Getter private static DataTable<AffinityLevelDef> AffinityLevelDataTable = new DataTable<>();
|
||||||
|
@Getter private static DataTable<AffinityGiftDef> AffinityGiftDataTable = new DataTable<>();
|
||||||
|
|
||||||
@Getter private static DataTable<CharGemDef> CharGemDataTable = new DataTable<>();
|
@Getter private static DataTable<CharGemDef> CharGemDataTable = new DataTable<>();
|
||||||
@Getter private static DataTable<CharGemSlotControlDef> CharGemSlotControlDataTable = new DataTable<>();
|
@Getter private static DataTable<CharGemSlotControlDef> CharGemSlotControlDataTable = new DataTable<>();
|
||||||
@Getter private static DataTable<CharGemAttrGroupDef> CharGemAttrGroupDataTable = new DataTable<>();
|
@Getter private static DataTable<CharGemAttrGroupDef> CharGemAttrGroupDataTable = new DataTable<>();
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package emu.nebula.data.resources;
|
||||||
|
|
||||||
|
import emu.nebula.data.BaseDef;
|
||||||
|
import emu.nebula.data.ResourceType;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ResourceType(name = "AffinityGift.json")
|
||||||
|
public class AffinityGiftDef extends BaseDef {
|
||||||
|
private int Id;
|
||||||
|
private int BaseAffinity;
|
||||||
|
private int[] Tags;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package emu.nebula.data.resources;
|
||||||
|
|
||||||
|
import emu.nebula.data.BaseDef;
|
||||||
|
import emu.nebula.data.ResourceType;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ResourceType(name = "AffinityLevel.json")
|
||||||
|
public class AffinityLevelDef extends BaseDef {
|
||||||
|
private int AffinityLevel;
|
||||||
|
private int NeedExp;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return AffinityLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@ public class CharacterDef extends BaseDef {
|
|||||||
|
|
||||||
private int[] GemSlots;
|
private int[] GemSlots;
|
||||||
|
|
||||||
|
private transient CharacterDesDef des;
|
||||||
private transient ElementType elementType;
|
private transient ElementType elementType;
|
||||||
private transient List<ChatDef> chats;
|
private transient List<ChatDef> chats;
|
||||||
|
|
||||||
@@ -38,6 +39,10 @@ public class CharacterDef extends BaseDef {
|
|||||||
public int getId() {
|
public int getId() {
|
||||||
return Id;
|
return Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setDes(CharacterDesDef des) {
|
||||||
|
this.des = des;
|
||||||
|
}
|
||||||
|
|
||||||
public int getSkillsUpgradeGroup(int index) {
|
public int getSkillsUpgradeGroup(int index) {
|
||||||
if (index < 0 || index >= this.SkillsUpgradeGroup.length) {
|
if (index < 0 || index >= this.SkillsUpgradeGroup.length) {
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package emu.nebula.data.resources;
|
||||||
|
|
||||||
|
import emu.nebula.data.BaseDef;
|
||||||
|
import emu.nebula.data.GameData;
|
||||||
|
import emu.nebula.data.ResourceType;
|
||||||
|
import emu.nebula.data.ResourceType.LoadPriority;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ResourceType(name = "CharacterDes.json", loadPriority = LoadPriority.LOW)
|
||||||
|
public class CharacterDesDef extends BaseDef {
|
||||||
|
private int Id;
|
||||||
|
private int[] Tag;
|
||||||
|
private IntOpenHashSet PreferTags;
|
||||||
|
private IntOpenHashSet HateTags;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPreferGift(AffinityGiftDef gift) {
|
||||||
|
if (this.getPreferTags() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < gift.getTags().length; i++) {
|
||||||
|
int tag = gift.getTags()[i];
|
||||||
|
if (this.getPreferTags().contains(tag)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHateGift(AffinityGiftDef gift) {
|
||||||
|
if (this.getHateTags() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < gift.getTags().length; i++) {
|
||||||
|
int tag = gift.getTags()[i];
|
||||||
|
if (this.getHateTags().contains(tag)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
var character = GameData.getCharacterDataTable().get(this.getId());
|
||||||
|
if (character != null) {
|
||||||
|
character.setDes(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,6 +53,8 @@ public class GameCharacter implements GameDatabaseObject {
|
|||||||
private int advance;
|
private int advance;
|
||||||
private int level;
|
private int level;
|
||||||
private int exp;
|
private int exp;
|
||||||
|
private int affinityLevel;
|
||||||
|
private int affinityExp;
|
||||||
private int skin;
|
private int skin;
|
||||||
private int[] skills;
|
private int[] skills;
|
||||||
private Bitset talents;
|
private Bitset talents;
|
||||||
@@ -378,6 +380,87 @@ public class GameCharacter implements GameDatabaseObject {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Affinity
|
||||||
|
|
||||||
|
public int getMaxAffinityExp() {
|
||||||
|
var data = GameData.getAffinityLevelDataTable().get(this.affinityLevel + 1);
|
||||||
|
return data != null ? data.getNeedExp() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAffinityExp(int amount) {
|
||||||
|
// Setup
|
||||||
|
int expRequired = this.getMaxAffinityExp();
|
||||||
|
|
||||||
|
// Add exp
|
||||||
|
this.affinityExp += amount;
|
||||||
|
|
||||||
|
// Check for level ups
|
||||||
|
while (this.affinityExp >= expRequired && expRequired > 0) {
|
||||||
|
this.affinityLevel += 1;
|
||||||
|
this.affinityExp -= expRequired;
|
||||||
|
|
||||||
|
expRequired = this.getMaxAffinityExp();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp exp
|
||||||
|
if (expRequired <= 0) {
|
||||||
|
this.affinityExp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save to database
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerChangeInfo sendGift(ItemParamMap items) {
|
||||||
|
// Verify that the player has the items
|
||||||
|
if (!this.getPlayer().getInventory().hasItems(items)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Caluclate amount of exp to gain
|
||||||
|
var charDescription = this.getData().getDes();
|
||||||
|
int exp = 0;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (var item : items) {
|
||||||
|
// Get data
|
||||||
|
var gift = GameData.getAffinityGiftDataTable().get(item.getIntKey());
|
||||||
|
if (gift == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate amount
|
||||||
|
double amount = gift.getBaseAffinity() * item.getIntValue();
|
||||||
|
|
||||||
|
if (charDescription.isPreferGift(gift)) {
|
||||||
|
amount = amount * 1.5D;
|
||||||
|
} else if (charDescription.isHateGift(gift)) {
|
||||||
|
amount = amount * 0.8D;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add
|
||||||
|
exp += (int) amount;
|
||||||
|
count += item.getIntValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
if (exp <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add affinity exp
|
||||||
|
this.addAffinityExp(exp);
|
||||||
|
|
||||||
|
// Trigger quest
|
||||||
|
this.getPlayer().triggerQuest(QuestCondType.GiftGiveTotal, count);
|
||||||
|
|
||||||
|
// Remove items
|
||||||
|
var change = this.getPlayer().getInventory().removeItems(items);
|
||||||
|
|
||||||
|
// Success
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
// Gems
|
// Gems
|
||||||
|
|
||||||
public boolean hasGemPreset(int index) {
|
public boolean hasGemPreset(int index) {
|
||||||
@@ -662,6 +745,8 @@ public class GameCharacter implements GameDatabaseObject {
|
|||||||
.setLevel(this.getLevel())
|
.setLevel(this.getLevel())
|
||||||
.setSkin(this.getSkin())
|
.setSkin(this.getSkin())
|
||||||
.setAdvance(this.getAdvance())
|
.setAdvance(this.getAdvance())
|
||||||
|
.setAffinityLevel(this.getAffinityLevel())
|
||||||
|
.setAffinityExp(this.getAffinityExp())
|
||||||
.setTalentNodes(this.getTalents().toByteArray())
|
.setTalentNodes(this.getTalents().toByteArray())
|
||||||
.addAllSkillLvs(this.getSkills())
|
.addAllSkillLvs(this.getSkills())
|
||||||
.setCreateTime(this.getCreateTime());
|
.setCreateTime(this.getCreateTime());
|
||||||
@@ -705,6 +790,7 @@ public class GameCharacter implements GameDatabaseObject {
|
|||||||
.setId(this.getCharId())
|
.setId(this.getCharId())
|
||||||
.setAdvance(this.getAdvance())
|
.setAdvance(this.getAdvance())
|
||||||
.setLevel(this.getLevel())
|
.setLevel(this.getLevel())
|
||||||
|
.setAffinityLevel(this.getAffinityLevel())
|
||||||
.setTalentNodes(this.getTalents().toByteArray())
|
.setTalentNodes(this.getTalents().toByteArray())
|
||||||
.addAllSkillLvs(this.getSkills());
|
.addAllSkillLvs(this.getSkills());
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package emu.nebula.server.handlers;
|
||||||
|
|
||||||
|
import emu.nebula.net.NetHandler;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.proto.CharAffinityGiftSend.CharAffinityGiftSendReq;
|
||||||
|
import emu.nebula.proto.CharAffinityGiftSend.CharAffinityGiftSendResp;
|
||||||
|
import emu.nebula.net.HandlerId;
|
||||||
|
import emu.nebula.game.inventory.ItemParamMap;
|
||||||
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
|
@HandlerId(NetMsgId.char_affinity_gift_send_req)
|
||||||
|
public class HandlerCharAffinityGiftSendReq extends NetHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
|
// Parse request
|
||||||
|
var req = CharAffinityGiftSendReq.parseFrom(message);
|
||||||
|
|
||||||
|
// Get character
|
||||||
|
var character = session.getPlayer().getCharacters().getCharacterById(req.getCharId());
|
||||||
|
if (character == null) {
|
||||||
|
return session.encodeMsg(NetMsgId.char_affinity_gift_send_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse item templates
|
||||||
|
var items = ItemParamMap.fromTemplates(req.getItems());
|
||||||
|
|
||||||
|
// Send gifts
|
||||||
|
var change = character.sendGift(items);
|
||||||
|
|
||||||
|
if (change == null) {
|
||||||
|
return session.encodeMsg(NetMsgId.char_affinity_gift_send_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build response
|
||||||
|
var rsp = CharAffinityGiftSendResp.newInstance()
|
||||||
|
.setChange(change.toProto());
|
||||||
|
|
||||||
|
rsp.getMutableInfo()
|
||||||
|
.setCharId(character.getCharId())
|
||||||
|
.setAffinityLevel(character.getAffinityLevel())
|
||||||
|
.setAffinityExp(character.getAffinityExp());
|
||||||
|
|
||||||
|
// Encode and send
|
||||||
|
return session.encodeMsg(NetMsgId.char_affinity_gift_send_succeed_ack, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user