some work on experience rewrites

This commit is contained in:
nossr50 2020-12-04 15:35:59 -08:00
parent 704e24d58b
commit 4e81d4ddb6
22 changed files with 338 additions and 33 deletions

12
pom.xml
View File

@ -116,6 +116,8 @@
<include>net.kyori:adventure-text-serializer-bungeecord</include>
<include>net.kyori:adventure-text-serializer-craftbukkit</include>
<include>co.aikar:acf-bukkit</include>
<include>com.neetgames:mcMMO-API</include>
<include>com.neetgames:jmal</include>
</includes>
</artifactSet>
<!-- <dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml</dependencyReducedPomLocation>-->
@ -193,6 +195,16 @@
<!-- ... -->
</repositories>
<dependencies>
<dependency>
<groupId>com.neetgames</groupId>
<artifactId>mcMMO-API</artifactId>
<version>0.01.00-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.neetgames</groupId>
<artifactId>jmal</artifactId>
<version>0.01.00-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>co.aikar</groupId>
<artifactId>acf-bukkit</artifactId> <!-- Don't forget to replace this -->

View File

@ -0,0 +1,18 @@
package com.gmail.nossr50.datatypes.experience;
import com.gmail.nossr50.datatypes.experience.context.NullExperienceContext;
import org.jetbrains.annotations.NotNull;
public class ExperienceContextBuilder {
private static final @NotNull NullExperienceContext nullExperienceContext = new NullExperienceContext();
/**
* Return a null experience context
* @return a null experience context
*/
public static NullExperienceContext nullContext() {
return nullExperienceContext;
}
}

View File

@ -0,0 +1,22 @@
package com.gmail.nossr50.datatypes.experience;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public interface ExperienceGain {
/**
* Get the target skill for this XP gain
* We define this by a String to allow for custom skills
* @return The target skill
*/
@NotNull UUID getTargetSkill();
/**
* Value of the experience gain, this is the raw value before any mutations are done via modifiers or otherwise
* @return the value of this {@link ExperienceGain}
*/
int getValue();
}

View File

@ -0,0 +1,5 @@
package com.gmail.nossr50.datatypes.experience;
public class ExperienceGainBuilder {
}

View File

@ -1,4 +1,4 @@
package com.gmail.nossr50.datatypes.player;
package com.gmail.nossr50.datatypes.experience;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
@ -7,6 +7,8 @@ import com.gmail.nossr50.datatypes.experience.SkillXpGain;
import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.experience.XPGainSource;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PersistentPlayerData;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.party.ShareHandler;
@ -26,19 +28,24 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
import java.util.UUID;
public class ExperienceManager {
private boolean isUsingUnarmed = false;
private final @NotNull PersistentPlayerData persistentPlayerDataRef;
private final @NotNull McMMOPlayer mmoPlayer;
private @Nullable McMMOPlayer mmoPlayer;
public ExperienceManager(@NotNull McMMOPlayer mmoPlayer) {
this.mmoPlayer = mmoPlayer;
this.persistentPlayerDataRef = mmoPlayer.getPersistentPlayerData();
}
public ExperienceManager(@NotNull PersistentPlayerData persistentPlayerData) {
this.persistentPlayerDataRef = persistentPlayerData;
}
/**
* Gets the power level of this player.
* A power level is the sum of all skill levels for this player
@ -60,7 +67,7 @@ public class ExperienceManager {
* @param primarySkillType target skill
* @return the value of raw XP for target skill
*/
public float getSkillXpLevelRaw(PrimarySkillType primarySkillType) {
public float getSkillXpLevelRaw(@NotNull PrimarySkillType primarySkillType) {
return persistentPlayerDataRef.getSkillsExperienceMap().get(primarySkillType);
}
@ -289,7 +296,7 @@ public class ExperienceManager {
public float getRegisteredXpGain(@NotNull PrimarySkillType primarySkillType) {
float xp = 0F;
if (rollingSkillsXp.get(primarySkillType) != null) {
if (get(primarySkillType) != null) { //??
xp = rollingSkillsXp.get(primarySkillType);
}
@ -359,15 +366,18 @@ public class ExperienceManager {
* @param xp Experience amount to add
*/
public void applyXpGain(@NotNull PrimarySkillType primarySkillType, float xp, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) {
//Only check for permissions if the player is online, otherwise just assume a command is being executed by an admin or some other means and add the XP
if(mmoPlayer != null) {
if (!primarySkillType.getPermissions(mmoPlayer.getPlayer())) {
return;
}
}
if (primarySkillType.isChildSkill()) {
Set<PrimarySkillType> parentSkills = FamilyTree.getParents(primarySkillType);
for (PrimarySkillType parentSkill : parentSkills) {
applyXpGain(mmoPlayer, parentSkill, xp / parentSkills.size(), xpGainReason, xpGainSource);
applyXpGain(parentSkill, xp / parentSkills.size(), xpGainReason, xpGainSource);
}
return;
@ -377,16 +387,22 @@ public class ExperienceManager {
return;
}
mmoPlayer.getExperienceManager().setUsingUnarmed(primarySkillType == PrimarySkillType.UNARMED);
updateLevelStats(mmoPlayer, primarySkillType, xpGainReason, xpGainSource);
setUsingUnarmed(primarySkillType == PrimarySkillType.UNARMED);
updateLevelStats(primarySkillType, xpGainReason, xpGainSource);
}
public void processPostXpEvent(@NotNull PrimarySkillType primarySkillType, @NotNull Plugin plugin, @NotNull XPGainSource xpGainSource)
{
/*
* Everything in this method requires an online player, so if they aren't online we don't waste our time
*/
if(mmoPlayer == null)
return;
//Check if they've reached the power level cap just now
if(mmoPlayer.getExperienceManager().hasReachedPowerLevelCap()) {
if(hasReachedPowerLevelCap()) {
NotificationManager.sendPlayerInformationChatOnly(mmoPlayer.getPlayer(), "LevelCap.PowerLevel", String.valueOf(Config.getInstance().getPowerLevelCap()));
} else if(mmoPlayer.getExperienceManager().hasReachedLevelCap(primarySkillType)) {
} else if(hasReachedLevelCap(primarySkillType)) {
NotificationManager.sendPlayerInformationChatOnly(mmoPlayer.getPlayer(), "LevelCap.Skill", String.valueOf(Config.getInstance().getLevelCap(primarySkillType)), primarySkillType.getName());
}
@ -407,25 +423,24 @@ public class ExperienceManager {
* @param primarySkillType The skill to check
*/
public void updateLevelStats(@NotNull PrimarySkillType primarySkillType, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) {
ExperienceManager em = mmoPlayer.getExperienceManager();
if(em.hasReachedLevelCap(primarySkillType))
if(hasReachedLevelCap(primarySkillType))
return;
if (em.getSkillXpLevelRaw(primarySkillType) < em.getXpToLevel(primarySkillType)) {
processPostXpEvent(mmoPlayer, primarySkillType, mcMMO.p, xpGainSource);
if (getSkillXpLevelRaw(primarySkillType) < getXpToLevel(primarySkillType)) {
processPostXpEvent(primarySkillType, mcMMO.p, xpGainSource);
return;
}
int levelsGained = 0;
float xpRemoved = 0;
while (em.getSkillXpLevelRaw(primarySkillType) >= em.getXpToLevel(primarySkillType)) {
if (em.hasReachedLevelCap(primarySkillType)) {
em.setSkillXpValue(primarySkillType, 0);
while (getSkillXpLevelRaw(primarySkillType) >= getXpToLevel(primarySkillType)) {
if (hasReachedLevelCap(primarySkillType)) {
setSkillXpValue(primarySkillType, 0);
break;
}
xpRemoved += em.levelUp(primarySkillType);
xpRemoved += levelUp(primarySkillType);
levelsGained++;
}
@ -441,10 +456,10 @@ public class ExperienceManager {
* Check to see if the player unlocked any new skills
*/
NotificationManager.sendPlayerLevelUpNotification(mmoPlayer, primarySkillType, levelsGained, em.getSkillLevel(primarySkillType));
NotificationManager.sendPlayerLevelUpNotification(mmoPlayer, primarySkillType, levelsGained, getSkillLevel(primarySkillType));
//UPDATE XP BARS
processPostXpEvent(mmoPlayer, primarySkillType, mcMMO.p, xpGainSource);
processPostXpEvent(primarySkillType, mcMMO.p, xpGainSource);
}

View File

@ -0,0 +1,5 @@
package com.gmail.nossr50.datatypes.experience;
public class ExperienceProcessor {
}

View File

@ -0,0 +1,6 @@
package com.gmail.nossr50.datatypes.experience;
public enum ExperienceVector {
ALL,
TARGETED,
}

View File

@ -0,0 +1,11 @@
package com.gmail.nossr50.datatypes.experience;
public interface PartyExperienceGain extends ExperienceGain {
/**
* The original value of this experience gain
* This is not equivalent to the amount of XP the players in party will get, but it was the value of the XP before it was distributed to party members
* @return the original value of the experience gain
*/
int originalValue();
}

View File

@ -0,0 +1,26 @@
package com.gmail.nossr50.datatypes.experience.capture;
import com.gmail.nossr50.datatypes.experience.context.ExperienceContext;
import com.neetgames.mcmmo.skill.SkillIdentity;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
public class ExperienceCapture {
private @NotNull ExperienceContext experienceContext;
private @NotNull HashSet<SkillIdentity> affectedSkills;
public ExperienceCapture(@NotNull ExperienceContext experienceContext, @NotNull HashSet<SkillIdentity> affectedSkills) {
this.experienceContext = experienceContext;
this.affectedSkills = affectedSkills;
}
/**
* Check whether or not a skill is targeted in this experience capture
* @param skillIdentity target skill
* @return true if this skill is targeted in this experience capture
*/
public boolean isSkillAffected(@NotNull SkillIdentity skillIdentity) {
return affectedSkills.contains(skillIdentity);
}
}

View File

@ -0,0 +1,36 @@
package com.gmail.nossr50.datatypes.experience.capture;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SkillIdentity;
import org.jetbrains.annotations.NotNull;
public interface ExperienceSnapshot {
/**
* Check whether or not a skill is targeted in this experience capture
*
* @param skillIdentity target skill
* @return true if this skill is targeted in this experience capture
*/
boolean isSkillAffected(@NotNull SkillIdentity skillIdentity);
/**
* Check whether or not a skill is targeted in this experience capture
*
* @param skillId target skill
* @return true if this skill is targeted in this experience capture
*/
boolean isSkillAffected(@NotNull String skillId);
/**
* Check whether or not a skill is targeted in this experience capture
*
* @param primarySkillType target skill
* @return true if this skill is targeted in this experience capture
* @deprecated the {@link PrimarySkillType} type is going to be phased out in favour of {@link SkillIdentity} at some point in the future
*/
@Deprecated
boolean isSkillAffected(@NotNull PrimarySkillType primarySkillType);
@NotNull PlayerProfile[] getPlayers();
}

View File

@ -0,0 +1,31 @@
package com.gmail.nossr50.datatypes.experience;
import com.gmail.nossr50.datatypes.experience.capture.ExperienceCapture;
import com.gmail.nossr50.datatypes.experience.context.ExperienceContext;
import com.gmail.nossr50.datatypes.skills.SkillIdentity;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
public class MultiExperienceCapture extends ExperienceCapture {
private @NotNull ExperienceContext experienceContext;
private @NotNull HashSet<SkillIdentity> affectedSkills;
public ExperienceCapture(@NotNull ExperienceContext experienceContext, @NotNull HashSet<SkillIdentity> affectedSkills) {
this.experienceContext = experienceContext;
this.affectedSkills = affectedSkills;
}
public MultiExperienceCapture(@NotNull ExperienceContext experienceContext, @NotNull HashSet<SkillIdentity> affectedSkills) {
super(experienceContext, affectedSkills);
}
/**
* Check whether or not a skill is targeted in this experience capture
* @param skillIdentity target skill
* @return true if this skill is targeted in this experience capture
*/
public boolean isSkillAffected(@NotNull SkillIdentity skillIdentity) {
return affectedSkills.contains(skillIdentity);
}
}

View File

@ -0,0 +1,29 @@
package com.gmail.nossr50.datatypes.experience.context;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class BlockExperienceContext implements ExperienceContext {
@NotNull Block blockExperienceContext;
public BlockExperienceContext(@NotNull Block block) {
this.blockExperienceContext = block;
}
@Nullable
@Override
public Object getContext() {
return blockExperienceContext;
}
/**
* Get the Block involved in this experience context
*
* @return the {@link Block} involved in this experience context
*/
public @NotNull Block getBlockExperienceContext() {
return blockExperienceContext;
}
}

View File

@ -0,0 +1,29 @@
package com.gmail.nossr50.datatypes.experience.context;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class CombatContext implements ExperienceContext {
private final @NotNull LivingEntity livingEntity;
public CombatContext(@NotNull LivingEntity livingEntity) {
this.livingEntity = livingEntity;
}
@Nullable
@Override
public Object getContext() {
return livingEntity;
}
/**
* Get the {@link LivingEntity} involved in this experience context
*
* @return the {@link LivingEntity} involved in this experience context
*/
public @NotNull LivingEntity getLivingEntity() {
return livingEntity;
}
}

View File

@ -0,0 +1,12 @@
package com.gmail.nossr50.datatypes.experience.context;
import javax.annotation.Nullable;
public interface ExperienceContext {
/**
* The source for this experience gain, can be anything from a block to an entity, etc
* Context is available as long as it can be
* @return the context (source) of this experience
*/
@Nullable Object getContext();
}

View File

@ -0,0 +1,13 @@
package com.gmail.nossr50.datatypes.experience.context;
import org.jetbrains.annotations.Nullable;
/**
* Represents an experience context with an undefined source
*/
public class NullExperienceContext implements ExperienceContext {
@Override
public @Nullable Object getContext() {
return null;
}
}

View File

@ -0,0 +1,13 @@
package com.gmail.nossr50.datatypes.experience.context;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface SharedExperienceContext {
/**
* The {@link McMMOPlayer} who originally gained the XP that was then shared
* @return the {@link McMMOPlayer} to which this experience context originates
*/
@NotNull McMMOPlayer getSharedContextSource();
}

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.datatypes.player;
import com.gmail.nossr50.datatypes.MobHealthBarType;
import com.gmail.nossr50.datatypes.experience.ExperienceManager;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.mcMMO;
import org.bukkit.entity.Player;

View File

@ -0,0 +1,5 @@
package com.gmail.nossr50.datatypes.skills;
public interface PrimarySkill {
}

View File

@ -18,6 +18,9 @@ import org.jetbrains.annotations.Nullable;
*
* Skills with parents do not gain experience, and instead their intended effects will be based on the strength of the parent skill (its level)
* Skills are registered, no two skills can share the same fully qualified name (in this case, a combination of the namespace and skill name)
*
* A fully qualified name is generated based on the namespace and skill name
* @see #genFullyQualifiedName()
*/
public class SkillIdentity {
@NotNull private final String nameSpace;

View File

@ -0,0 +1,24 @@
package com.gmail.nossr50.events.experience;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull;
public class ExperienceCaptureEvent extends PlayerEvent {
public ExperienceCaptureEvent(@NotNull Player who) {
super(who);
}
private static final HandlerList handlers = new HandlerList();
@Override
public @NotNull HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -258,7 +258,7 @@ public class HerbalismManager extends SkillManager {
public void checkDoubleDropsOnBrokenPlants(Player player, Collection<Block> brokenPlants) {
//Only proceed if skill unlocked and permission enabled
if (!RankUtils.hasUnlockedSubskill(player, SubSkillType.HERBALISM_DOUBLE_DROPS)
if (!RankUtils.hasUnlockedSubskill(mmoPlayer, SubSkillType.HERBALISM_DOUBLE_DROPS)
|| !Permissions.isSubSkillEnabled(player, SubSkillType.HERBALISM_DOUBLE_DROPS)) {
return;
}

View File

@ -1,23 +1,12 @@
package com.gmail.nossr50.util.experience;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.experience.XPGainSource;
import com.gmail.nossr50.datatypes.player.ExperienceManager;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.child.FamilyTree;
import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.player.NotificationManager;
import com.gmail.nossr50.util.sounds.SoundManager;
import com.gmail.nossr50.util.sounds.SoundType;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
public class ExperienceUtils {
private ExperienceUtils() {}