store entity effects (untested)

This commit is contained in:
bixilon 2020-06-15 20:16:18 +02:00
parent 699b12e036
commit 96fc0aa0d3
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
7 changed files with 253 additions and 72 deletions

View File

@ -17,11 +17,14 @@ import de.bixilon.minosoft.game.datatypes.Slot;
import de.bixilon.minosoft.game.datatypes.Slots;
import de.bixilon.minosoft.game.datatypes.entities.meta.EntityMetaData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public abstract class Entity implements EntityInterface {
final int id;
final HashMap<Slots.Entity, Slot> equipment;
final List<StatusEffect> effectList;
Location location;
Velocity velocity;
int yaw;
@ -35,6 +38,7 @@ public abstract class Entity implements EntityInterface {
this.pitch = pitch;
this.velocity = velocity;
this.equipment = new HashMap<>();
this.effectList = new ArrayList<>();
}
@ -103,4 +107,17 @@ public abstract class Entity implements EntityInterface {
return EntityMetaData.class;
}
public List<StatusEffect> getEffectList() {
return effectList;
}
public void addEffect(StatusEffect effect) {
// effect already applied, maybe the duration or the amplifier changed?
effectList.removeIf(listEffect -> listEffect.getEffect() == effect.getEffect());
effectList.add(effect);
}
public void removeEffect(StatusEffects effect) {
effectList.removeIf(listEffect -> listEffect.getEffect() == effect);
}
}

View File

@ -13,78 +13,31 @@
package de.bixilon.minosoft.game.datatypes.entities;
public enum StatusEffect {
SPEED("speed", 1, Impact.POSITIVE),
SLOWNESS("slowness", 2, Impact.NEGATIVE),
HASTE("haste", 3, Impact.POSITIVE),
MINING_FATIGUE("mining_fatigue", 4, Impact.NEGATIVE),
STRENGTH("strength", 5, Impact.POSITIVE),
INSTANT_HEALTH("instant_health", 6, Impact.POSITIVE),
INSTANT_DAMAGE("instant_damage", 7, Impact.POSITIVE),
JUMP_BOOST("jump_boost", 8, Impact.POSITIVE),
NAUSEA("nausea", 9, Impact.NEGATIVE),
REGENERATION("regeneration", 10, Impact.POSITIVE),
RESISTANCE("resistance", 11, Impact.POSITIVE),
FIRE_RESISTANCE("fire_resistance", 12, Impact.POSITIVE),
WATER_BREATHING("water_breathing", 13, Impact.POSITIVE),
INVISIBILITY("invisibility", 14, Impact.POSITIVE),
BLINDNESS("blindness", 15, Impact.NEGATIVE),
NIGHT_VISION("night_vision", 16, Impact.POSITIVE),
HUNGER("hunger", 17, Impact.NEGATIVE),
WEAKNESS("weakness", 18, Impact.NEGATIVE),
POISON("poison", 19, Impact.NEGATIVE),
WITHER("wither", 20, Impact.NEGATIVE),
HEALTH_BOOST("health_boost", 21, Impact.POSITIVE),
ABSORPTION("absorption", 22, Impact.POSITIVE),
SATURATION("saturation", 23, Impact.POSITIVE),
GLOWING("glowing", 24, Impact.NEGATIVE),
LEVITATION("levitation", 25, Impact.NEGATIVE),
LUCK("luck", 26, Impact.POSITIVE),
UNLUCK("unluck", 27, Impact.NEGATIVE),
SLOW_FALLING("slow_falling", 28, Impact.POSITIVE),
CONDUIT_POWER("conduit_power", 29, Impact.POSITIVE),
DOLPHINS_GRACE("dolphins_grace", 30, Impact.POSITIVE),
BAD_OMEN("bad_omen", 31, Impact.NEGATIVE),
HERO_OF_THE_VILLAGE("hero_of_the_village", 32, Impact.POSITIVE);
public class StatusEffect {
StatusEffects effect;
byte amplifier;
short duration;
final String name;
final int id;
final Impact impact;
StatusEffect(String name, int id, Impact impact) {
this.name = name;
this.id = id;
this.impact = impact;
public StatusEffect(StatusEffects effect, byte amplifier, short duration) {
this.effect = effect;
this.amplifier = amplifier;
this.duration = duration;
}
public static StatusEffect byId(int id) {
for (StatusEffect s : values()) {
if (s.getId() == id) {
return s;
}
}
return null;
public byte getAmplifier() {
return amplifier;
}
public static StatusEffect byName(String name) {
for (StatusEffect s : values()) {
if (s.getName().equals(name)) {
return s;
}
}
return null;
public short getDuration() {
return duration;
}
public String getName() {
return name;
public StatusEffects getEffect() {
return effect;
}
public int getId() {
return id;
}
public enum Impact {
POSITIVE,
NEGATIVE
@Override
public String toString() {
return String.format("%s (amplifier: %d, duration: %d)", effect.name(), amplifier, duration);
}
}

View File

@ -0,0 +1,90 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.game.datatypes.entities;
public enum StatusEffects {
SPEED("speed", 1, Impact.POSITIVE),
SLOWNESS("slowness", 2, Impact.NEGATIVE),
HASTE("haste", 3, Impact.POSITIVE),
MINING_FATIGUE("mining_fatigue", 4, Impact.NEGATIVE),
STRENGTH("strength", 5, Impact.POSITIVE),
INSTANT_HEALTH("instant_health", 6, Impact.POSITIVE),
INSTANT_DAMAGE("instant_damage", 7, Impact.POSITIVE),
JUMP_BOOST("jump_boost", 8, Impact.POSITIVE),
NAUSEA("nausea", 9, Impact.NEGATIVE),
REGENERATION("regeneration", 10, Impact.POSITIVE),
RESISTANCE("resistance", 11, Impact.POSITIVE),
FIRE_RESISTANCE("fire_resistance", 12, Impact.POSITIVE),
WATER_BREATHING("water_breathing", 13, Impact.POSITIVE),
INVISIBILITY("invisibility", 14, Impact.POSITIVE),
BLINDNESS("blindness", 15, Impact.NEGATIVE),
NIGHT_VISION("night_vision", 16, Impact.POSITIVE),
HUNGER("hunger", 17, Impact.NEGATIVE),
WEAKNESS("weakness", 18, Impact.NEGATIVE),
POISON("poison", 19, Impact.NEGATIVE),
WITHER("wither", 20, Impact.NEGATIVE),
HEALTH_BOOST("health_boost", 21, Impact.POSITIVE),
ABSORPTION("absorption", 22, Impact.POSITIVE),
SATURATION("saturation", 23, Impact.POSITIVE),
GLOWING("glowing", 24, Impact.NEGATIVE),
LEVITATION("levitation", 25, Impact.NEGATIVE),
LUCK("luck", 26, Impact.POSITIVE),
UNLUCK("unluck", 27, Impact.NEGATIVE),
SLOW_FALLING("slow_falling", 28, Impact.POSITIVE),
CONDUIT_POWER("conduit_power", 29, Impact.POSITIVE),
DOLPHINS_GRACE("dolphins_grace", 30, Impact.POSITIVE),
BAD_OMEN("bad_omen", 31, Impact.NEGATIVE),
HERO_OF_THE_VILLAGE("hero_of_the_village", 32, Impact.POSITIVE);
final String name;
final int id;
final Impact impact;
StatusEffects(String name, int id, Impact impact) {
this.name = name;
this.id = id;
this.impact = impact;
}
public static StatusEffects byId(int id) {
for (StatusEffects s : values()) {
if (s.getId() == id) {
return s;
}
}
return null;
}
public static StatusEffects byName(String name) {
for (StatusEffects s : values()) {
if (s.getName().equals(name)) {
return s;
}
}
return null;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public enum Impact {
POSITIVE,
NEGATIVE
}
}

View File

@ -0,0 +1,56 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.entities.StatusEffect;
import de.bixilon.minosoft.game.datatypes.entities.StatusEffects;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InPacketBuffer;
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
public class PacketEntityEffect implements ClientboundPacket {
int entityId;
StatusEffect effect;
@Override
public void read(InPacketBuffer buffer, ProtocolVersion v) {
switch (v) {
case VERSION_1_7_10:
entityId = buffer.readInteger();
effect = new StatusEffect(StatusEffects.byId(buffer.readByte()), buffer.readByte(), buffer.readShort());
break;
}
}
@Override
public void log() {
Log.game(String.format("Entity effect added: %d %s", entityId, effect.toString()));
}
@Override
public void handle(PacketHandler h) {
h.handle(this);
}
public int getEntityId() {
return entityId;
}
public StatusEffect getEffect() {
return effect;
}
}

View File

@ -0,0 +1,55 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.entities.StatusEffects;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InPacketBuffer;
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
public class PacketRemoveEntityEffect implements ClientboundPacket {
int entityId;
StatusEffects effect;
@Override
public void read(InPacketBuffer buffer, ProtocolVersion v) {
switch (v) {
case VERSION_1_7_10:
entityId = buffer.readInteger();
effect = StatusEffects.byId(buffer.readByte());
break;
}
}
@Override
public void log() {
Log.game(String.format("Entity effect removed: %d %s", entityId, effect.name()));
}
@Override
public void handle(PacketHandler h) {
h.handle(this);
}
public int getEntityId() {
return entityId;
}
public StatusEffects getEffect() {
return effect;
}
}

View File

@ -243,4 +243,12 @@ public class PacketHandler {
public void handle(PacketChunkData pkg) {
connection.getPlayer().getWorld().setChunk(pkg.getLocation(), pkg.getChunk());
}
public void handle(PacketEntityEffect pkg) {
connection.getPlayer().getWorld().getEntity(pkg.getEntityId()).addEffect(pkg.getEffect());
}
public void handle(PacketRemoveEntityEffect pkg) {
connection.getPlayer().getWorld().getEntity(pkg.getEntityId()).removeEffect(pkg.getEffect());
}
}

View File

@ -26,14 +26,6 @@ import java.util.HashMap;
public interface Protocol {
HashMap<Packets.Clientbound, Class<? extends ClientboundPacket>> packetClassMapping = new HashMap<>();
int getProtocolVersion();
int getPacketCommand(Packets.Serverbound p);
String getName();
Packets.Clientbound getPacketByCommand(ConnectionState s, int command);
static Class<? extends ClientboundPacket> getPacketByPacket(Packets.Clientbound p) {
if (packetClassMapping.size() == 0) {
// init
@ -82,5 +74,15 @@ public interface Protocol {
packetClassMapping.put(Packets.Clientbound.PLAY_SPAWN_EXPERIENCE_ORB, PacketSpawnExperienceOrb.class);
packetClassMapping.put(Packets.Clientbound.PLAY_SPAWN_WEATHER_ENTITY, PacketSpawnWeatherEntity.class);
packetClassMapping.put(Packets.Clientbound.PLAY_CHUNK_DATA, PacketChunkData.class);
packetClassMapping.put(Packets.Clientbound.PLAY_ENTITY_EFFECT, PacketEntityEffect.class);
packetClassMapping.put(Packets.Clientbound.PLAY_REMOVE_ENTITY_EFFECT, PacketRemoveEntityEffect.class);
}
int getProtocolVersion();
int getPacketCommand(Packets.Serverbound p);
String getName();
Packets.Clientbound getPacketByCommand(ConnectionState s, int command);
}