mirror of
https://github.com/Melledy/LunarCore.git
synced 2025-12-15 14:54:43 +01:00
Implement techniques that debuff enemies
This commit is contained in:
@@ -121,6 +121,10 @@ public class Battle {
|
|||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasBuff(int buffId) {
|
||||||
|
return this.buffs.stream().filter(buff -> buff.getId() == buffId).findFirst().isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
public void clearBuffs() {
|
public void clearBuffs() {
|
||||||
this.buffs.clear();
|
this.buffs.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,13 +64,13 @@ public class BattleService extends BaseGameService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give the client an error if no attacked entities detected
|
// Skip if no attacked entities detected
|
||||||
if (targetEntities.size() == 0) {
|
if (targetEntities.size() == 0) {
|
||||||
player.sendPacket(new PacketSceneCastSkillScRsp());
|
player.sendPacket(new PacketSceneCastSkillScRsp(attackedGroupId));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Monster list
|
// Separate entities into monster list
|
||||||
List<EntityMonster> monsters = new ArrayList<>();
|
List<EntityMonster> monsters = new ArrayList<>();
|
||||||
|
|
||||||
// Destroy props
|
// Destroy props
|
||||||
@@ -85,6 +85,15 @@ public class BattleService extends BaseGameService {
|
|||||||
player.getScene().removeEntity(entity);
|
player.getScene().removeEntity(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if we are using a skill that doesnt trigger a battle
|
||||||
|
if (castedSkill != null && !castedSkill.isTriggerBattle()) {
|
||||||
|
// Apply buffs to monsters
|
||||||
|
castedSkill.onAttack(player.getCurrentLeaderAvatar(), monsters);
|
||||||
|
// Skip battle if our technique does not trigger a battle
|
||||||
|
player.sendPacket(new PacketSceneCastSkillScRsp(attackedGroupId));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Start battle
|
// Start battle
|
||||||
if (monsters.size() > 0) {
|
if (monsters.size() > 0) {
|
||||||
@@ -109,11 +118,16 @@ public class BattleService extends BaseGameService {
|
|||||||
Battle battle = new Battle(player, player.getLineupManager().getCurrentLineup(), stages);
|
Battle battle = new Battle(player, player.getLineupManager().getCurrentLineup(), stages);
|
||||||
|
|
||||||
// Add npc monsters
|
// Add npc monsters
|
||||||
for (var npcMonster : monsters) {
|
for (var monster : monsters) {
|
||||||
battle.getNpcMonsters().add(npcMonster);
|
battle.getNpcMonsters().add(monster);
|
||||||
|
|
||||||
if (npcMonster.getOverrideLevel() > 0) {
|
// Handle monster buffs
|
||||||
battle.setLevelOverride(npcMonster.getOverrideLevel());
|
// TODO handle multiple waves properly
|
||||||
|
monster.applyBuffs(battle);
|
||||||
|
|
||||||
|
// Override level
|
||||||
|
if (monster.getOverrideLevel() > 0) {
|
||||||
|
battle.setLevelOverride(monster.getOverrideLevel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package emu.lunarcore.game.battle;
|
package emu.lunarcore.game.battle;
|
||||||
|
|
||||||
import emu.lunarcore.data.excel.MazeBuffExcel;
|
import emu.lunarcore.data.excel.MazeBuffExcel;
|
||||||
|
import emu.lunarcore.game.scene.entity.GameEntity;
|
||||||
import emu.lunarcore.proto.BattleBuffOuterClass.BattleBuff;
|
import emu.lunarcore.proto.BattleBuffOuterClass.BattleBuff;
|
||||||
import emu.lunarcore.proto.BattleBuffOuterClass.BattleBuff.DynamicValuesEntry;
|
import emu.lunarcore.proto.BattleBuffOuterClass.BattleBuff.DynamicValuesEntry;
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
@@ -9,6 +10,7 @@ import it.unimi.dsi.fastutil.objects.Object2DoubleMap;
|
|||||||
import it.unimi.dsi.fastutil.objects.Object2DoubleOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2DoubleOpenHashMap;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class MazeBuff {
|
public class MazeBuff {
|
||||||
@@ -19,7 +21,10 @@ public class MazeBuff {
|
|||||||
private IntList targetIndex;
|
private IntList targetIndex;
|
||||||
|
|
||||||
@Getter(AccessLevel.NONE)
|
@Getter(AccessLevel.NONE)
|
||||||
private Object2DoubleMap<String> dynamicValues;
|
private Object2DoubleMap<String> dynamicValues;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private transient GameEntity owner;
|
||||||
|
|
||||||
public MazeBuff(MazeBuffExcel excel, int ownerIndex, int waveFlag) {
|
public MazeBuff(MazeBuffExcel excel, int ownerIndex, int waveFlag) {
|
||||||
this(excel.getBuffId(), excel.getLv(), ownerIndex, waveFlag);
|
this(excel.getBuffId(), excel.getLv(), ownerIndex, waveFlag);
|
||||||
@@ -52,9 +57,12 @@ public class MazeBuff {
|
|||||||
var proto = BattleBuff.newInstance()
|
var proto = BattleBuff.newInstance()
|
||||||
.setId(this.getId())
|
.setId(this.getId())
|
||||||
.setLevel(this.getLevel())
|
.setLevel(this.getLevel())
|
||||||
.setOwnerId(this.getOwnerIndex())
|
|
||||||
.setWaveFlag(this.getWaveFlag());
|
.setWaveFlag(this.getWaveFlag());
|
||||||
|
|
||||||
|
if (this.ownerIndex != 0) {
|
||||||
|
proto.setOwnerId(this.getOwnerIndex());
|
||||||
|
}
|
||||||
|
|
||||||
if (this.targetIndex != null) {
|
if (this.targetIndex != null) {
|
||||||
for (int index : this.targetIndex) {
|
for (int index : this.targetIndex) {
|
||||||
proto.addTargetIndexList(index);
|
proto.addTargetIndexList(index);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import java.util.List;
|
|||||||
import emu.lunarcore.data.excel.AvatarExcel;
|
import emu.lunarcore.data.excel.AvatarExcel;
|
||||||
import emu.lunarcore.game.avatar.GameAvatar;
|
import emu.lunarcore.game.avatar.GameAvatar;
|
||||||
import emu.lunarcore.game.battle.Battle;
|
import emu.lunarcore.game.battle.Battle;
|
||||||
|
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@@ -44,4 +45,13 @@ public class MazeSkill {
|
|||||||
action.onAttack(caster, battle);
|
action.onAttack(caster, battle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Triggered when player attacks an enemy
|
||||||
|
public void onAttack(GameAvatar caster, List<EntityMonster> monsters) {
|
||||||
|
if (this.getAttackActions().size() == 0) return;
|
||||||
|
|
||||||
|
for (var action : this.getAttackActions()) {
|
||||||
|
action.onAttack(caster, monsters);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package emu.lunarcore.game.battle.skills;
|
package emu.lunarcore.game.battle.skills;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import emu.lunarcore.game.avatar.GameAvatar;
|
import emu.lunarcore.game.avatar.GameAvatar;
|
||||||
import emu.lunarcore.game.battle.Battle;
|
import emu.lunarcore.game.battle.Battle;
|
||||||
|
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||||
|
|
||||||
public abstract class MazeSkillAction {
|
public abstract class MazeSkillAction {
|
||||||
@@ -10,4 +13,6 @@ public abstract class MazeSkillAction {
|
|||||||
|
|
||||||
public abstract void onAttack(GameAvatar caster, Battle battle);
|
public abstract void onAttack(GameAvatar caster, Battle battle);
|
||||||
|
|
||||||
|
public abstract void onAttack(GameAvatar caster, List<EntityMonster> monsters);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package emu.lunarcore.game.battle.skills;
|
package emu.lunarcore.game.battle.skills;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import emu.lunarcore.game.avatar.GameAvatar;
|
import emu.lunarcore.game.avatar.GameAvatar;
|
||||||
import emu.lunarcore.game.battle.Battle;
|
import emu.lunarcore.game.battle.Battle;
|
||||||
|
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@@ -29,5 +32,12 @@ public class MazeSkillAddBuff extends MazeSkillAction {
|
|||||||
battle.addBuff(buffId, battle.getLineup().getLeader(), 1 << i);
|
battle.addBuff(buffId, battle.getLineup().getLeader(), 1 << i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttack(GameAvatar caster, List<EntityMonster> monsters) {
|
||||||
|
for (EntityMonster monster : monsters) {
|
||||||
|
monster.addBuff(caster.getAvatarId(), buffId, duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package emu.lunarcore.game.battle.skills;
|
package emu.lunarcore.game.battle.skills;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import emu.lunarcore.game.avatar.GameAvatar;
|
import emu.lunarcore.game.avatar.GameAvatar;
|
||||||
import emu.lunarcore.game.battle.Battle;
|
import emu.lunarcore.game.battle.Battle;
|
||||||
|
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||||
|
|
||||||
public class MazeSkillModifyHP extends MazeSkillAction {
|
public class MazeSkillModifyHP extends MazeSkillAction {
|
||||||
@@ -21,4 +24,9 @@ public class MazeSkillModifyHP extends MazeSkillAction {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttack(GameAvatar caster, List<EntityMonster> monsters) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package emu.lunarcore.game.battle.skills;
|
package emu.lunarcore.game.battle.skills;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import emu.lunarcore.game.avatar.GameAvatar;
|
import emu.lunarcore.game.avatar.GameAvatar;
|
||||||
import emu.lunarcore.game.battle.Battle;
|
import emu.lunarcore.game.battle.Battle;
|
||||||
|
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||||
|
|
||||||
public class MazeSkillModifySP extends MazeSkillAction {
|
public class MazeSkillModifySP extends MazeSkillAction {
|
||||||
@@ -24,4 +27,9 @@ public class MazeSkillModifySP extends MazeSkillAction {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttack(GameAvatar caster, List<EntityMonster> monsters) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package emu.lunarcore.game.battle.skills;
|
package emu.lunarcore.game.battle.skills;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import emu.lunarcore.game.avatar.GameAvatar;
|
import emu.lunarcore.game.avatar.GameAvatar;
|
||||||
import emu.lunarcore.game.battle.Battle;
|
import emu.lunarcore.game.battle.Battle;
|
||||||
|
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||||
|
|
||||||
public class MazeSkillSummonUnit extends MazeSkillAction {
|
public class MazeSkillSummonUnit extends MazeSkillAction {
|
||||||
@@ -16,4 +19,9 @@ public class MazeSkillSummonUnit extends MazeSkillAction {
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttack(GameAvatar caster, List<EntityMonster> monsters) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,10 @@ public class PlayerLineup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int indexOf(int ownerId) {
|
||||||
|
return this.getAvatars().indexOf(ownerId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the slot contains an avatar
|
* Checks if the slot contains an avatar
|
||||||
* @param slot The slot we are checking for
|
* @param slot The slot we are checking for
|
||||||
|
|||||||
16
src/main/java/emu/lunarcore/game/scene/SceneEntityBuff.java
Normal file
16
src/main/java/emu/lunarcore/game/scene/SceneEntityBuff.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package emu.lunarcore.game.scene;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class SceneEntityBuff {
|
||||||
|
private int owner; // Owner avatar id
|
||||||
|
private int id;
|
||||||
|
private long expiry;
|
||||||
|
|
||||||
|
public SceneEntityBuff(int owner, int id, long duration) {
|
||||||
|
this.owner = owner;
|
||||||
|
this.id = id;
|
||||||
|
this.expiry = System.currentTimeMillis() + (duration * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,12 +3,16 @@ package emu.lunarcore.game.scene.entity;
|
|||||||
import emu.lunarcore.data.config.GroupInfo;
|
import emu.lunarcore.data.config.GroupInfo;
|
||||||
import emu.lunarcore.data.config.MonsterInfo;
|
import emu.lunarcore.data.config.MonsterInfo;
|
||||||
import emu.lunarcore.data.excel.NpcMonsterExcel;
|
import emu.lunarcore.data.excel.NpcMonsterExcel;
|
||||||
|
import emu.lunarcore.game.battle.Battle;
|
||||||
import emu.lunarcore.game.scene.Scene;
|
import emu.lunarcore.game.scene.Scene;
|
||||||
|
import emu.lunarcore.game.scene.SceneEntityBuff;
|
||||||
import emu.lunarcore.game.scene.triggers.PropTriggerType;
|
import emu.lunarcore.game.scene.triggers.PropTriggerType;
|
||||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||||
import emu.lunarcore.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
import emu.lunarcore.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
||||||
import emu.lunarcore.proto.SceneNpcMonsterInfoOuterClass.SceneNpcMonsterInfo;
|
import emu.lunarcore.proto.SceneNpcMonsterInfoOuterClass.SceneNpcMonsterInfo;
|
||||||
import emu.lunarcore.util.Position;
|
import emu.lunarcore.util.Position;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
@@ -25,6 +29,7 @@ public class EntityMonster implements GameEntity {
|
|||||||
private final Position pos;
|
private final Position pos;
|
||||||
private final Position rot;
|
private final Position rot;
|
||||||
|
|
||||||
|
private Int2ObjectMap<SceneEntityBuff> buffs;
|
||||||
private int farmElementId;
|
private int farmElementId;
|
||||||
@Setter private int overrideStageId;
|
@Setter private int overrideStageId;
|
||||||
@Setter private int overrideLevel;
|
@Setter private int overrideLevel;
|
||||||
@@ -51,6 +56,39 @@ public class EntityMonster implements GameEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addBuff(int caster, int buffId, int duration) {
|
||||||
|
if (this.buffs == null) {
|
||||||
|
this.buffs = new Int2ObjectOpenHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.buffs.put(buffId, new SceneEntityBuff(caster, buffId, duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyBuffs(Battle battle) {
|
||||||
|
if (this.buffs == null) return;
|
||||||
|
|
||||||
|
for (var entry : this.buffs.int2ObjectEntrySet()) {
|
||||||
|
// Check expiry for buff
|
||||||
|
if (entry.getValue().getExpiry() < battle.getTimestamp()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dont add duplicate buffs
|
||||||
|
if (battle.hasBuff(entry.getIntKey())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get owner index
|
||||||
|
int ownerIndex = battle.getLineup().indexOf(entry.getValue().getOwner());
|
||||||
|
|
||||||
|
// Add buff to battle if owner exists
|
||||||
|
if (ownerIndex != -1) {
|
||||||
|
// TODO handle multiple waves properly
|
||||||
|
battle.addBuff(entry.getIntKey(), ownerIndex, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRemove() {
|
public void onRemove() {
|
||||||
// Try to fire any triggers
|
// Try to fire any triggers
|
||||||
|
|||||||
@@ -57,14 +57,8 @@ public class HandlerSceneCastSkillCsReq extends PacketHandler {
|
|||||||
req.getHitTargetIdList().forEach(targets::add);
|
req.getHitTargetIdList().forEach(targets::add);
|
||||||
req.getAssistMonsterIdList().forEach(targets::add);
|
req.getAssistMonsterIdList().forEach(targets::add);
|
||||||
|
|
||||||
// Check if we can start a battle
|
// Start battle
|
||||||
if (skill != null && !skill.isTriggerBattle()) {
|
session.getServer().getBattleService().startBattle(player, req.getCasterId(), req.getAttackedGroupId(), skill, targets);
|
||||||
// Skip battle if our technique does not trigger a battle
|
|
||||||
session.send(new PacketSceneCastSkillScRsp(req.getAttackedGroupId()));
|
|
||||||
} else {
|
|
||||||
// Start battle normally
|
|
||||||
session.getServer().getBattleService().startBattle(player, req.getCasterId(), req.getAttackedGroupId(), skill, targets);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// We had no targets for some reason
|
// We had no targets for some reason
|
||||||
session.send(new PacketSceneCastSkillScRsp(req.getAttackedGroupId()));
|
session.send(new PacketSceneCastSkillScRsp(req.getAttackedGroupId()));
|
||||||
|
|||||||
Reference in New Issue
Block a user