Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ public sealed interface ProfileDataSource permits FlatFileProfileDataSource {
* Update the file for a player's global profile.
*
* @param globalProfile The GlobalProfile object to update the file for.
* @return True if data successfully saved to file.
*/
void updateGlobalProfile(GlobalProfile globalProfile);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,31 @@ public boolean updatePlayer(Player player, PlayerProfile profile) {
}).serializer(new ProfileEntry(false, DataStrings.PLAYER_OFF_HAND_ITEM),
new DefaultSerializer<>(ItemStack.class)).altName("shield").build();

/**
* Sharing Max Health.
*/
public static final Sharable<Double> MAX_HEALTH = new Sharable.Builder<>("max_hit_points", Double.class,
new SharableHandler<Double>() {
@Override
public void updateProfile(PlayerProfile profile, Player player) {
profile.set(MAX_HEALTH, getMaxHealth(player));
}

@Override
public boolean updatePlayer(Player player, PlayerProfile profile) {
Double value = profile.get(MAX_HEALTH);
if (value == null) {
Option.of(maxHealthAttr).map(player::getAttribute)
.peek(attr -> attr.setBaseValue(attr.getDefaultValue()));
return false;
}
Option.of(maxHealthAttr).map(player::getAttribute)
.peek(attr -> attr.setBaseValue(value));
return true;
}
}).stringSerializer(new ProfileEntry(true, DataStrings.PLAYER_MAX_HEALTH))
.altName("maxhealth").altName("maxhp").altName("maxhitpoints").build();

/**
* Sharing Health.
*/
Expand All @@ -184,9 +209,7 @@ public void updateProfile(PlayerProfile profile, Player player) {
double health = player.getHealth();
// Player is dead, so health should be regained to full.
if (health <= 0) {
health = Option.of(maxHealthAttr).map(player::getAttribute)
.map(AttributeInstance::getValue)
.getOrElse(PlayerStats.HEALTH);
health = getMaxHealth(player);
}
profile.set(HEALTH, health);
}
Expand All @@ -199,20 +222,31 @@ public boolean updatePlayer(Player player, PlayerProfile profile) {
return false;
}
try {
double maxHealth = getMaxHealth(player);
// This share may handled before MAX_HEALTH.
// Thus this is needed to ensure there is no loss in health stored
if (value > maxHealth) {
Option.of(maxHealthAttr).map(player::getAttribute)
.peek(attr -> attr.setBaseValue(maxHealth));
}
player.setHealth(value);
} catch (IllegalArgumentException e) {
Logging.fine("Invalid value '" + value + "': " + e.getMessage());
Option.of(maxHealthAttr).map(player::getAttribute)
.map(AttributeInstance::getValue)
.peek(player::setHealth)
.onEmpty(() -> player.setHealth(PlayerStats.HEALTH));
player.setHealth(PlayerStats.HEALTH);
return false;
}
return true;
}

}).stringSerializer(new ProfileEntry(true, DataStrings.PLAYER_HEALTH))
.altName("health").altName("hp").altName("hitpoints").build();

private static double getMaxHealth(Player player) {
return Option.of(maxHealthAttr).map(player::getAttribute)
.map(AttributeInstance::getValue)
.getOrElse(PlayerStats.MAX_HEALTH);
}

/**
* Sharing Remaining Air.
*/
Expand Down Expand Up @@ -661,21 +695,21 @@ public boolean updatePlayer(Player player, PlayerProfile profile) {
* Grouping for player health related sharables.
*/
public static final SharableGroup ALL_HEALTH = new SharableGroup("health",
fromSharables(HEALTH, REMAINING_AIR, MAXIMUM_AIR, FALL_DISTANCE, FIRE_TICKS));
fromSharables(HEALTH, MAX_HEALTH, REMAINING_AIR, MAXIMUM_AIR, FALL_DISTANCE, FIRE_TICKS));

/**
* Grouping for player stat related sharables not including inventory.
*/
public static final SharableGroup STATS = new SharableGroup("stats",
fromSharables(HEALTH, FOOD_LEVEL, SATURATION, EXHAUSTION, EXPERIENCE, TOTAL_EXPERIENCE, LEVEL,
fromSharables(HEALTH, MAX_HEALTH, FOOD_LEVEL, SATURATION, EXHAUSTION, EXPERIENCE, TOTAL_EXPERIENCE, LEVEL,
REMAINING_AIR, MAXIMUM_AIR, FALL_DISTANCE, FIRE_TICKS, POTIONS));

/**
* Grouping for ALL default sharables.
* TODO: make this really mean all, including 3rd party.
*/
public static final SharableGroup ALL_DEFAULT = new SharableGroup("all", fromSharables(HEALTH, ECONOMY,
FOOD_LEVEL, SATURATION, EXHAUSTION, EXPERIENCE, TOTAL_EXPERIENCE, LEVEL, INVENTORY, ARMOR, BED_SPAWN,
public static final SharableGroup ALL_DEFAULT = new SharableGroup("all", fromSharables(HEALTH, MAX_HEALTH,
ECONOMY, FOOD_LEVEL, SATURATION, EXHAUSTION, EXPERIENCE, TOTAL_EXPERIENCE, LEVEL, INVENTORY, ARMOR, BED_SPAWN,
MAXIMUM_AIR, REMAINING_AIR, FALL_DISTANCE, FIRE_TICKS, POTIONS, LAST_LOCATION, ENDER_CHEST, OFF_HAND),
"*", "everything");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ public final class DataStrings {
* Player profile type identifier.
*/
public static final String PLAYER_PROFILE_TYPE = "profileType";
/**
* Player max health identifier.
*/
public static final String PLAYER_MAX_HEALTH = "mhp";
/**
* Player health identifier.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ public class PlayerStats {
* Number of slots in an ender chest.
*/
public static final int ENDER_CHEST_SIZE = 27;
/**
* Default max health value.
*/
public static final double MAX_HEALTH = 20;
/**
* Default health value.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.mvplugins.multiverse.inventories.gameplay
package org.mvplugins.multiverse.inventories.handleshare

import org.mvplugins.multiverse.inventories.TestWithMockBukkit

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.mvplugins.multiverse.inventories.handleshare

import org.mockbukkit.mockbukkit.entity.PlayerMock
import org.mvplugins.multiverse.inventories.TestWithMockBukkit
import org.mvplugins.multiverse.inventories.profile.ProfileDataSource
import org.mvplugins.multiverse.inventories.profile.ProfileTypes
import org.mvplugins.multiverse.inventories.profile.container.ContainerType
import org.mvplugins.multiverse.inventories.share.Sharables
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals

class ShareHandlingUpdaterTest : TestWithMockBukkit() {

private lateinit var profileDataSource: ProfileDataSource
private lateinit var player: PlayerMock

@BeforeTest
fun setUp() {
player = server.addPlayer("benthecat10")
profileDataSource = serviceLocator.getService(ProfileDataSource::class.java).takeIf { it != null } ?: run {
throw IllegalStateException("ProfileDataSource is not available as a service")
}
}

@Test
fun `Test updating profile`() {
player.health = 4.4
player.maxHealth = 15.1

val playerProfile = profileDataSource.getPlayerData(ContainerType.WORLD, "world", ProfileTypes.SURVIVAL, player.uniqueId)
ShareHandlingUpdater.updateProfile(multiverseInventories, player, PersistingProfile(Sharables.allOf(), playerProfile))

assertEquals(4.4, playerProfile.get(Sharables.HEALTH))
assertEquals(15.1, playerProfile.get(Sharables.MAX_HEALTH))
}

@Test
fun `Test updating player`() {
val playerProfile = profileDataSource.getPlayerData(ContainerType.WORLD, "world", ProfileTypes.SURVIVAL, player.uniqueId)
playerProfile.set(Sharables.HEALTH, 4.4)
playerProfile.set(Sharables.MAX_HEALTH, 15.1)

ShareHandlingUpdater.updatePlayer(multiverseInventories, player, PersistingProfile(Sharables.allOf(), playerProfile))

assertEquals(4.4, player.health)
assertEquals(15.1, player.maxHealth)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.mvplugins.multiverse.inventories.gameplay
package org.mvplugins.multiverse.inventories.handleshare

import com.dumptruckman.minecraft.util.Logging
import org.bukkit.Material
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package org.mvplugins.multiverse.inventories.gameplay
package org.mvplugins.multiverse.inventories.profile

import org.bukkit.Material
import org.bukkit.inventory.ItemStack
import org.mockbukkit.mockbukkit.entity.PlayerMock
import org.mvplugins.multiverse.core.world.WorldManager
import org.mvplugins.multiverse.core.world.options.CreateWorldOptions
import org.mvplugins.multiverse.inventories.TestWithMockBukkit
import org.mvplugins.multiverse.inventories.profile.ProfileDataSource
import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager
import java.nio.file.Path
import kotlin.test.BeforeTest
Expand Down