mirror of
https://github.com/Melledy/LunarCore.git
synced 2025-12-13 05:44:36 +01:00
Implement techniques that debuff enemies
This commit is contained in:
@@ -121,6 +121,10 @@ public class Battle {
|
||||
return buff;
|
||||
}
|
||||
|
||||
public boolean hasBuff(int buffId) {
|
||||
return this.buffs.stream().filter(buff -> buff.getId() == buffId).findFirst().isPresent();
|
||||
}
|
||||
|
||||
public void clearBuffs() {
|
||||
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) {
|
||||
player.sendPacket(new PacketSceneCastSkillScRsp());
|
||||
player.sendPacket(new PacketSceneCastSkillScRsp(attackedGroupId));
|
||||
return;
|
||||
}
|
||||
|
||||
// Monster list
|
||||
// Separate entities into monster list
|
||||
List<EntityMonster> monsters = new ArrayList<>();
|
||||
|
||||
// Destroy props
|
||||
@@ -85,6 +85,15 @@ public class BattleService extends BaseGameService {
|
||||
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
|
||||
if (monsters.size() > 0) {
|
||||
@@ -109,11 +118,16 @@ public class BattleService extends BaseGameService {
|
||||
Battle battle = new Battle(player, player.getLineupManager().getCurrentLineup(), stages);
|
||||
|
||||
// Add npc monsters
|
||||
for (var npcMonster : monsters) {
|
||||
battle.getNpcMonsters().add(npcMonster);
|
||||
for (var monster : monsters) {
|
||||
battle.getNpcMonsters().add(monster);
|
||||
|
||||
if (npcMonster.getOverrideLevel() > 0) {
|
||||
battle.setLevelOverride(npcMonster.getOverrideLevel());
|
||||
// Handle monster buffs
|
||||
// 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;
|
||||
|
||||
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.DynamicValuesEntry;
|
||||
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 lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
public class MazeBuff {
|
||||
@@ -19,7 +21,10 @@ public class MazeBuff {
|
||||
private IntList targetIndex;
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
private Object2DoubleMap<String> dynamicValues;
|
||||
private Object2DoubleMap<String> dynamicValues;
|
||||
|
||||
@Setter
|
||||
private transient GameEntity owner;
|
||||
|
||||
public MazeBuff(MazeBuffExcel excel, int ownerIndex, int waveFlag) {
|
||||
this(excel.getBuffId(), excel.getLv(), ownerIndex, waveFlag);
|
||||
@@ -52,9 +57,12 @@ public class MazeBuff {
|
||||
var proto = BattleBuff.newInstance()
|
||||
.setId(this.getId())
|
||||
.setLevel(this.getLevel())
|
||||
.setOwnerId(this.getOwnerIndex())
|
||||
.setWaveFlag(this.getWaveFlag());
|
||||
|
||||
if (this.ownerIndex != 0) {
|
||||
proto.setOwnerId(this.getOwnerIndex());
|
||||
}
|
||||
|
||||
if (this.targetIndex != null) {
|
||||
for (int index : this.targetIndex) {
|
||||
proto.addTargetIndexList(index);
|
||||
|
||||
@@ -6,6 +6,7 @@ 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.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -44,4 +45,13 @@ public class MazeSkill {
|
||||
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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
|
||||
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, List<EntityMonster> monsters);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package emu.lunarcore.game.battle.skills;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
import lombok.Getter;
|
||||
|
||||
@@ -29,5 +32,12 @@ public class MazeSkillAddBuff extends MazeSkillAction {
|
||||
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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
|
||||
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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
|
||||
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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
|
||||
public class MazeSkillSummonUnit extends MazeSkillAction {
|
||||
@@ -16,4 +19,9 @@ public class MazeSkillSummonUnit extends MazeSkillAction {
|
||||
// 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
|
||||
* @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.MonsterInfo;
|
||||
import emu.lunarcore.data.excel.NpcMonsterExcel;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.scene.Scene;
|
||||
import emu.lunarcore.game.scene.SceneEntityBuff;
|
||||
import emu.lunarcore.game.scene.triggers.PropTriggerType;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
import emu.lunarcore.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
||||
import emu.lunarcore.proto.SceneNpcMonsterInfoOuterClass.SceneNpcMonsterInfo;
|
||||
import emu.lunarcore.util.Position;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@@ -25,6 +29,7 @@ public class EntityMonster implements GameEntity {
|
||||
private final Position pos;
|
||||
private final Position rot;
|
||||
|
||||
private Int2ObjectMap<SceneEntityBuff> buffs;
|
||||
private int farmElementId;
|
||||
@Setter private int overrideStageId;
|
||||
@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
|
||||
public void onRemove() {
|
||||
// Try to fire any triggers
|
||||
|
||||
@@ -57,14 +57,8 @@ public class HandlerSceneCastSkillCsReq extends PacketHandler {
|
||||
req.getHitTargetIdList().forEach(targets::add);
|
||||
req.getAssistMonsterIdList().forEach(targets::add);
|
||||
|
||||
// Check if we can start a battle
|
||||
if (skill != null && !skill.isTriggerBattle()) {
|
||||
// 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);
|
||||
}
|
||||
// Start battle
|
||||
session.getServer().getBattleService().startBattle(player, req.getCasterId(), req.getAttackedGroupId(), skill, targets);
|
||||
} else {
|
||||
// We had no targets for some reason
|
||||
session.send(new PacketSceneCastSkillScRsp(req.getAttackedGroupId()));
|
||||
|
||||
Reference in New Issue
Block a user