diff --git a/scripts/commands/flourish.py b/scripts/commands/flourish.py index 0bb6cb93..37c26077 100644 --- a/scripts/commands/flourish.py +++ b/scripts/commands/flourish.py @@ -22,7 +22,8 @@ def run(core, actor, target, commandString): if actor.getPerformanceId() <= 0: actor.sendSystemMessage('@performance:flourish_not_performing', 0) return - + + actor.incFlourishCount() actor.sendSystemMessage('@performance:flourish_perform', 0) animation = 'skill_action_' + str(flourish) if flourish == 9: diff --git a/scripts/commands/startdance.py b/scripts/commands/startdance.py index 768e8e55..bae424d8 100644 --- a/scripts/commands/startdance.py +++ b/scripts/commands/startdance.py @@ -91,12 +91,16 @@ def startDance(core, actor, danceName, visual): #this should send a CREO3 actor.setPosture(0x09); + playerObject = actor.getSlottedObject('ghost') + if playerObject and playerObject.getProfession() == "entertainer_1a": + entSvc.startPerformanceExperience(actor) + dance = entSvc.getDance(visual) # performanceId > 0 seems to trigger the note bubble stuff, so use 0 here # instead of dance.getLineNumber() # send CREO6 here # second param is some sort of counter or start tick - entSvc.startPerformance(actor, 0, -842249156 , danceVisual, 1) + entSvc.startPerformance(actor, dance.getLineNumber(), -842249156 , danceVisual, 1) return diff --git a/src/resources/objects/creature/CreatureMessageBuilder.java b/src/resources/objects/creature/CreatureMessageBuilder.java index 443deff3..7e10d950 100644 --- a/src/resources/objects/creature/CreatureMessageBuilder.java +++ b/src/resources/objects/creature/CreatureMessageBuilder.java @@ -256,7 +256,11 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putLong(creature.getTargetId()); buffer.put(creature.getMoodId()); buffer.putInt(creature.getPerformanceCounter()); - buffer.putInt(creature.getPerformanceId()); + /* + * minor dilemma: performance ID is needed for XP calculation, but it can't be sent + * in the CREO, otherwise the evul note bubbles appear + */ + buffer.putInt((creature.getPerformanceType()) ? 0 : creature.getPerformanceId()); buffer.putInt(0); // unks buffer.putInt(0); diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index e9ed6d54..924fe231 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -155,8 +155,14 @@ public class CreatureObject extends TangibleObject implements IPersistent { private SWGList dotList = new SWGList(); @NotPersistent private ScheduledFuture incapTask; + @NotPersistent + private ScheduledFuture entertainerExperience; + @NotPersistent + private ScheduledFuture inspirationTick; private boolean staticNPC = false; // temp + @NotPersistent + private int flourishCount = 0; public CreatureObject(long objectID, Planet planet, Point3D position, Quaternion orientation, String Template) { super(objectID, planet, Template, position, orientation); @@ -353,10 +359,14 @@ public class CreatureObject extends TangibleObject implements IPersistent { public void stopPerformance() { String type = ""; synchronized(objectMutex) { - setPerformanceId(0); + setPerformanceId(0,true); setPerformanceCounter(0); setCurrentAnimation(""); type = (performanceType) ? "dance" : "music"; + if (entertainerExperience != null) { + entertainerExperience.cancel(true); + entertainerExperience = null; + } } sendSystemMessage("@performance:" + type + "_stop_self",(byte)0); @@ -391,6 +401,22 @@ public class CreatureObject extends TangibleObject implements IPersistent { performanceAudience = new SWGList(); } } + public ScheduledFuture getEntertainerExperience() { + return entertainerExperience; + } + + public void setEntertainerExperience(ScheduledFuture entertainerExperience) { + this.entertainerExperience = entertainerExperience; + } + + public ScheduledFuture getInspirationTick() { + return inspirationTick; + } + + public void setInspirationTick(ScheduledFuture inspirationTick) { + this.inspirationTick = inspirationTick; + } + @Override public void setFaction(String faction) { synchronized(objectMutex) { @@ -974,11 +1000,11 @@ public class CreatureObject extends TangibleObject implements IPersistent { } } - public void setPerformanceId(int performanceId) { + public void setPerformanceId(int performanceId, boolean isDance) { synchronized(objectMutex) { this.performanceId = performanceId; } - getClient().getSession().write(messageBuilder.buildPerformanceId(performanceId)); + getClient().getSession().write(messageBuilder.buildPerformanceId((isDance) ? 0 : performanceId)); } public boolean getAcceptBandflourishes() { @@ -1516,5 +1542,23 @@ public class CreatureObject extends TangibleObject implements IPersistent { return this.performanceType; } } + + public void setFlourishCount(int flourishCount) { + synchronized(objectMutex) { + this.flourishCount = flourishCount; + } + } + + public int getFlourishCount() { + synchronized(objectMutex) { + return this.flourishCount; + } + } + + public void incFlourishCount() { + synchronized(objectMutex) { + this.flourishCount++; + } + } } diff --git a/src/services/EntertainmentService.java b/src/services/EntertainmentService.java index 5236846b..acaf3c71 100644 --- a/src/services/EntertainmentService.java +++ b/src/services/EntertainmentService.java @@ -6,6 +6,10 @@ import java.util.Iterator; import java.util.Map; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; import main.NGECore; @@ -34,10 +38,12 @@ import engine.resources.service.INetworkRemoteEvent; public class EntertainmentService implements INetworkDispatch { private NGECore core; + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private Vector buffBuilderSkills = new Vector(); //FIXME: create a wrapper class for double key lookup maps private HashMap performances = new HashMap(); + private HashMap performancesByIndex = new HashMap(); private HashMap danceMap = new HashMap(); public EntertainmentService(NGECore core) { @@ -182,6 +188,7 @@ public class EntertainmentService implements INetworkDispatch { danceMap.put(new Integer(p.getDanceVisualId()), p); } performances.put(p.getPerformanceName(), p); + performancesByIndex.put(r, p); } } catch (InstantiationException | IllegalAccessException e) { @@ -293,7 +300,7 @@ public class EntertainmentService implements INetworkDispatch { } public void startPerformance(CreatureObject actor, int performanceId, int performanceCounter, String skillName, boolean isDance) { - actor.setPerformanceId(performanceId); + actor.setPerformanceId(performanceId, isDance); actor.setPerformanceCounter(performanceCounter); actor.setCurrentAnimation(skillName); actor.setPerformanceType(isDance); @@ -301,8 +308,34 @@ public class EntertainmentService implements INetworkDispatch { actor.startPerformance(); } - - + public void startPerformanceExperience(final CreatureObject entertainer) { + final ScheduledFuture experienceTask = scheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + + Performance p = performancesByIndex.get(entertainer.getPerformanceId()); + if (p == null) { + entertainer.setFlourishCount(0); + return; + } + + int floXP = (int)( (float) p.getFlourishXpMod() / 6.0f); + int floCount = entertainer.getFlourishCount(); + + int XP = ((floCount > 2) ? 2 : floCount) * floXP; + + entertainer.setFlourishCount(0); + core.playerService.giveExperience(entertainer, XP); + + + } + + },10, 10000, TimeUnit.MILLISECONDS); + + entertainer.setEntertainerExperience(experienceTask); + + } @Override public void shutdown() {