Fix most attack/buff avatar techniques not working

This commit is contained in:
Melledy
2023-10-02 23:27:13 -07:00
parent 653047784d
commit 1e165ddde7
11 changed files with 113 additions and 60 deletions

View File

@@ -233,6 +233,6 @@ public class ResourceLoader {
}
// Done
LunarRail.getLogger().info("Loaded " + count + " maze abilities for avatars");
LunarRail.getLogger().info("Loaded " + count + " maze abilities for avatars.");
}
}

View File

@@ -20,37 +20,44 @@ public class SkillAbilityInfo {
// Look for MazeSkill
for (AbilityInfo ability : AbilityList) {
//
List<MazeSkillAction> actionList = null;
// Skip if not a maze skill
if (!ability.getName().contains("MazeSkill")) {
if (ability.getName().contains("MazeSkill")) {
skill = new MazeSkill(avatarExcel);
avatarExcel.setMazeSkill(skill);
actionList = skill.getCastActions();
} else if (ability.getName().contains("NormalAtk")) {
skill = new MazeSkill(avatarExcel);
avatarExcel.setMazeAttack(skill);
actionList = skill.getAttackActions();
} else {
continue;
}
// Create maze skill
skill = new MazeSkill();
// Parse tasks
for (TaskInfo task : ability.getOnStart()) {
parseTask(skill, skill.getCastActions(), task);
parseTask(skill, actionList, task);
}
}
// Set skill for avatar
if (skill != null) {
avatarExcel.setMazeSkill(skill);
return true;
}
return false;
return true;
}
// "Simple" way to parse maze attacks/skills
private void parseTask(MazeSkill skill, List<MazeSkillAction> actionList, TaskInfo task) {
if (task.getType().contains("AddMazeBuff")) {
actionList.add(new MazeSkillAddBuff(task.getID(), 15));
} else if (task.getType().contains("RemoveMazeBuff")) {
actionList.removeIf(action -> action instanceof MazeSkillAddBuff actionAdd && actionAdd.getBuffId() == task.getID());
} else if (task.getType().contains("CreateSummonUnit")) {
} else if (task.getSuccessTaskList() != null) {
for (TaskInfo t : task.getSuccessTaskList()) {
parseTask(skill, skill.getCastActions(), t);
parseTask(skill, actionList, t);
}
} else if (task.getOnAttack() != null) {
if (task.getType().contains("AdventureTriggerAttack")) {

View File

@@ -13,6 +13,7 @@ import emu.lunarcore.game.enums.AvatarBaseType;
import emu.lunarcore.game.enums.DamageType;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
@Getter
@ResourceType(name = {"AvatarConfig.json"})
@@ -35,9 +36,11 @@ public class AvatarExcel extends GameResource {
private transient AvatarPromotionExcel[] promotionData;
private transient List<AvatarSkillTreeExcel> defaultSkillTrees;
private transient String nameKey;
private transient MazeSkill mazeSkill;
private transient int maxSp;
@Setter private transient MazeSkill mazeAttack;
@Setter private transient MazeSkill mazeSkill;
private static Pattern namePattern = Pattern.compile("(?<=Avatar_)(.*?)(?=_Config)");
public AvatarExcel() {
@@ -48,10 +51,6 @@ public class AvatarExcel extends GameResource {
public int getId() {
return AvatarID;
}
public void setMazeSkill(MazeSkill skill) {
this.mazeSkill = skill;
}
public AvatarPromotionExcel getPromotionData(int i) {
return this.promotionData[i];

View File

@@ -58,15 +58,15 @@ public class Battle {
}
public MazeBuff addBuff(int buffId) {
return addBuff(buffId, 0, 0xffffffff);
public MazeBuff addBuff(int buffId, int ownerIndex) {
return addBuff(buffId, ownerIndex, 0xffffffff);
}
public MazeBuff addBuff(int buffId, int ownerId, int waveFlag) {
public MazeBuff addBuff(int buffId, int ownerIndex, int waveFlag) {
MazeBuffExcel excel = GameData.getMazeBuffExcel(buffId, 1);
if (excel == null) return null;
MazeBuff buff = new MazeBuff(excel, ownerId, waveFlag);
MazeBuff buff = new MazeBuff(excel, ownerIndex, waveFlag);
this.buffs.add(buff);
return buff;
@@ -83,11 +83,16 @@ public class Battle {
.setLogicRandomSeed(Utils.randomRange(1, Short.MAX_VALUE))
.setWorldLevel(player.getWorldLevel());
// Init variables
int waveId = 0;
// Add monster waves from stages
for (StageExcel stage : stages) {
// Build monster waves
for (IntList sceneMonsterWave : stage.getMonsterWaves()) {
var wave = SceneMonsterWave.newInstance().setStageId(stage.getId());
var wave = SceneMonsterWave.newInstance()
.setWaveId(++waveId)
.setStageId(stage.getId());
for (int monsterId : sceneMonsterWave) {
var monster = SceneMonster.newInstance().setMonsterId(monsterId);
@@ -115,8 +120,13 @@ public class Battle {
if (avatar.getBuffs().size() > 0) {
for (var buffEntry : avatar.getBuffs().int2LongEntrySet()) {
// Check expiry for buff
if (buffEntry.getLongValue() >= this.timestamp) {
this.addBuff(buffEntry.getIntKey());
if (buffEntry.getLongValue() < this.timestamp) {
continue;
}
MazeBuff buff = this.addBuff(buffEntry.getIntKey(), i);
if (buff != null) {
buff.addTargetIndex(i);
}
}
}

View File

@@ -7,7 +7,6 @@ import emu.lunarcore.data.GameData;
import emu.lunarcore.data.excel.CocoonExcel;
import emu.lunarcore.data.excel.StageExcel;
import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.battle.skills.MazeSkill;
import emu.lunarcore.game.enums.StageType;
import emu.lunarcore.game.player.Player;
import emu.lunarcore.game.scene.entity.EntityMonster;
@@ -32,10 +31,10 @@ public class BattleService extends BaseGameService {
super(server);
}
public void startBattle(Player player, int attackerId, MazeSkill castedSkill, RepeatedInt attackedList) {
public void startBattle(Player player, int attackerId, int attackedGroupId, boolean castedSkill, RepeatedInt attackedList) {
// Sanity check to make sure player isnt in a battle
if (player.isInBattle()) {
player.sendPacket(new PacketSceneCastSkillScRsp(1));
player.sendPacket(new PacketSceneCastSkillScRsp());
return;
}
@@ -68,7 +67,7 @@ public class BattleService extends BaseGameService {
// Give the client an error if no attacked entities detected
if (entities.size() == 0) {
player.sendPacket(new PacketSceneCastSkillScRsp(1));
player.sendPacket(new PacketSceneCastSkillScRsp());
return;
}
@@ -100,7 +99,7 @@ public class BattleService extends BaseGameService {
if (stages.size() == 0) {
// An error has occurred while trying to get stage data
player.sendPacket(new PacketSceneCastSkillScRsp(1));
player.sendPacket(new PacketSceneCastSkillScRsp());
return;
}
@@ -112,26 +111,29 @@ public class BattleService extends BaseGameService {
if (isPlayerCaster) {
GameAvatar avatar = player.getLineupManager().getCurrentLeaderAvatar();
if (avatar != null) {
// Add elemental weakness buff to enemies
MazeBuff buff = battle.addBuff(avatar.getExcel().getDamageType().getEnterBattleBuff());
if (buff != null) {
buff.addDynamicValue("SkillIndex", 1);
// Maze skill attack event
if (castedSkill) { // Dont need to null check maze skill since we already did it in HandlerSceneCastSkillCsReq
avatar.getExcel().getMazeSkill().onAttack(avatar, battle);
} else if (avatar.getExcel().getMazeAttack() != null) {
avatar.getExcel().getMazeAttack().onAttack(avatar, battle);
}
// Maze skill handlers
if (castedSkill != null) {
castedSkill.onAttack(avatar, battle);
// Add elemental weakness buff to enemies
MazeBuff buff = battle.addBuff(avatar.getExcel().getDamageType().getEnterBattleBuff(), player.getLineupManager().getCurrentLeader());
if (buff != null) {
buff.addTargetIndex(player.getLineupManager().getCurrentLeader());
buff.addDynamicValue("SkillIndex", castedSkill ? 2 : 1);
}
}
}
// Set battle and send rsp packet
player.setBattle(battle);
player.sendPacket(new PacketSceneCastSkillScRsp(battle));
player.sendPacket(new PacketSceneCastSkillScRsp(battle, attackedGroupId));
return;
}
// Send packet
player.sendPacket(new PacketSceneCastSkillScRsp(0));
player.sendPacket(new PacketSceneCastSkillScRsp(attackedGroupId));
}
public void startCocoon(Player player, int cocoonId, int worldLevel, int wave) {

View File

@@ -3,6 +3,8 @@ package emu.lunarcore.game.battle;
import emu.lunarcore.data.excel.MazeBuffExcel;
import emu.lunarcore.proto.BattleBuffOuterClass.BattleBuff;
import emu.lunarcore.proto.BattleBuffOuterClass.BattleBuff.DynamicValuesEntry;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.objects.Object2DoubleMap;
import it.unimi.dsi.fastutil.objects.Object2DoubleOpenHashMap;
import lombok.AccessLevel;
@@ -11,18 +13,27 @@ import lombok.Getter;
@Getter
public class MazeBuff {
private MazeBuffExcel excel;
private int ownerEntityId;
private int ownerIndex;
private int waveFlag;
private IntList targetIndex;
@Getter(AccessLevel.NONE)
private Object2DoubleMap<String> dynamicValues;
public MazeBuff(MazeBuffExcel excel, int ownerEntityId, int waveFlag) {
public MazeBuff(MazeBuffExcel excel, int ownerIndex, int waveFlag) {
this.excel = excel;
this.ownerEntityId = ownerEntityId;
this.ownerIndex = ownerIndex;
this.waveFlag = waveFlag;
}
public void addTargetIndex(int index) {
if (this.targetIndex == null) {
this.targetIndex = new IntArrayList();
}
this.targetIndex.add(index);
}
public void addDynamicValue(String key, double value) {
if (this.dynamicValues == null) {
this.dynamicValues = new Object2DoubleOpenHashMap<>();
@@ -35,9 +46,15 @@ public class MazeBuff {
var proto = BattleBuff.newInstance()
.setId(excel.getBuffId())
.setLevel(excel.getLv())
.setOwnerId(this.getOwnerEntityId())
.setOwnerId(this.getOwnerIndex())
.setWaveFlag(this.getWaveFlag());
if (this.targetIndex != null) {
for (int index : this.targetIndex) {
proto.addTargetIndexList(index);
}
}
if (this.dynamicValues != null) {
for (var entry : this.dynamicValues.object2DoubleEntrySet()) {
var dynamicValue = DynamicValuesEntry.newInstance()

View File

@@ -3,6 +3,7 @@ package emu.lunarcore.game.battle.skills;
import java.util.ArrayList;
import java.util.List;
import emu.lunarcore.data.excel.AvatarExcel;
import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.battle.Battle;
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
@@ -10,10 +11,12 @@ import lombok.Getter;
@Getter
public class MazeSkill {
private int id;
private List<MazeSkillAction> castActions;
private List<MazeSkillAction> attackActions;
public MazeSkill() {
public MazeSkill(AvatarExcel excel) {
this.id = excel.getAvatarID();
this.castActions = new ArrayList<>();
this.attackActions = new ArrayList<>();
}

View File

@@ -3,10 +3,9 @@ package emu.lunarcore.game.battle.skills;
import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.battle.Battle;
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
import lombok.AccessLevel;
import lombok.Getter;
@Getter(AccessLevel.PRIVATE)
@Getter
public class MazeSkillAddBuff extends MazeSkillAction {
private int buffId;
private int duration;
@@ -23,7 +22,8 @@ public class MazeSkillAddBuff extends MazeSkillAction {
@Override
public void onAttack(GameAvatar caster, Battle battle) {
battle.addBuff(buffId);
// TODO add buff for each monster wave
battle.addBuff(buffId, caster.getOwner().getLineupManager().getCurrentLeader(), 1);
}
}

View File

@@ -36,7 +36,7 @@ public class PlayerLineup {
// Set team name if not an extra lineup
if (!this.isExtraLineup()) {
this.name = "Squad " + (index + 1);
this.name = "Team " + (index + 1);
} else {
this.name = "";
}

View File

@@ -17,7 +17,7 @@ public class HandlerSceneCastSkillCsReq extends PacketHandler {
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
var req = SceneCastSkillCsReq.parseFrom(data);
MazeSkill castedSkill = null;
boolean castedSkill = false;
// Check if player casted a maze skill
if (req.getSkillIndex() > 0 && session.getPlayer().getScene().getAvatarEntityIds().contains(req.getAttackerId())) {
@@ -27,15 +27,17 @@ public class HandlerSceneCastSkillCsReq extends PacketHandler {
// Cast skill effects
GameAvatar caster = session.getPlayer().getLineupManager().getCurrentLeaderAvatar();
if (caster != null && caster.getExcel().getMazeSkill() != null) {
castedSkill = caster.getExcel().getMazeSkill();
castedSkill.onCast(caster, req.getTargetMotion());
MazeSkill skill = caster.getExcel().getMazeSkill();
skill.onCast(caster, req.getTargetMotion());
// Set flag
castedSkill = true;
}
}
if (req.hasAttackedEntityIdList()) {
session.getServer().getBattleService().startBattle(session.getPlayer(), req.getAttackerId(), castedSkill, req.getAttackedEntityIdList());
session.getServer().getBattleService().startBattle(session.getPlayer(), req.getAttackerId(), req.getAttackedGroupId(), castedSkill, req.getAttackedEntityIdList());
} else {
session.send(new PacketSceneCastSkillScRsp());
session.send(new PacketSceneCastSkillScRsp(req.getAttackedGroupId()));
}
}

View File

@@ -7,24 +7,37 @@ import emu.lunarcore.server.packet.CmdId;
public class PacketSceneCastSkillScRsp extends BasePacket {
/**
* Returns an error to the client
*/
public PacketSceneCastSkillScRsp() {
this(0);
}
public PacketSceneCastSkillScRsp(int retcode) {
super(CmdId.SceneCastSkillScRsp);
var data = SceneCastSkillScRsp.newInstance()
.setRetcode(retcode);
.setRetcode(1);
this.setData(data);
}
/**
* No battle was started, but we still want to send the attacked group id to the client
* @param attackedGroupId
*/
public PacketSceneCastSkillScRsp(int attackedGroupId) {
super(CmdId.SceneCastSkillScRsp);
var data = SceneCastSkillScRsp.newInstance()
.setAttackedGroupId(attackedGroupId);
this.setData(data);
}
public PacketSceneCastSkillScRsp(Battle battle) {
public PacketSceneCastSkillScRsp(Battle battle, int attackedGroupId) {
super(CmdId.SceneCastSkillScRsp);
// Build data
var data = SceneCastSkillScRsp.newInstance()
.setAttackedGroupId(attackedGroupId)
.setBattleInfo(battle.toProto());
this.setData(data);