Skip to content

Commit

Permalink
Improved handling of nonstackable ActorConditions
Browse files Browse the repository at this point in the history
This is a minimalistic fix for bug Zukero#119 and some other issues that could be used until the bigger change of the actorconditions gets finished.

-Fixes Removable constant effect bug. Zukero#119
-Fixes other cases where longer running conditions are overwritten by shorter running ones with a higher magnitude. The solution is to add the second condition but lowered by the magnitude of the longer lasting one.
-Fixed that unequipping a higher magnitude item will not reduce the magnitude when only a lower magnitude item stays equipped
  • Loading branch information
Chriz76 committed Jun 7, 2019
1 parent 97a81e3 commit 77bd6b5
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ private void removeStackableActorCondition(Actor actor, ActorConditionType type,
}

private void removeNonStackableActorCondition(Player player, ActorConditionType type, int magnitude, int duration) {
int highestMagnitude = 0;
for (Inventory.WearSlot slot : Inventory.WearSlot.values()) {
ItemType t = player.inventory.getItemTypeInWearSlot(slot);
if (t == null) continue;
Expand All @@ -94,11 +95,14 @@ private void removeNonStackableActorCondition(Player player, ActorConditionType
for (ActorConditionEffect e : equipEffects.addedConditions) {
if (!e.conditionType.conditionTypeID.equals(type.conditionTypeID)) continue;
if (e.duration != duration) continue;
// The player is wearing some other item that gives this condition. It will not be removed now.
return;
if (e.magnitude > highestMagnitude)
highestMagnitude = e.magnitude;
}
}
removeStackableActorCondition(player, type, magnitude, duration);

if (highestMagnitude < magnitude) {
removeStackableActorCondition(player, type, magnitude-highestMagnitude, duration);
}
}


Expand Down Expand Up @@ -192,24 +196,53 @@ private void addStackableActorCondition(Actor actor, ActorConditionEffect e, int
actor.conditions.add(c);
actorConditionListeners.onActorConditionAdded(actor, c);
}
private void addNonStackableActorCondition(Actor actor, ActorConditionEffect e, int duration) {
final ActorConditionType type = e.conditionType;

for(int i = actor.conditions.size() - 1; i >= 0; --i) {
ActorCondition c = actor.conditions.get(i);
if (!type.conditionTypeID.equals(c.conditionType.conditionTypeID)) continue;
if (c.magnitude > e.magnitude) return;
if (c.magnitude == e.magnitude) {
if (c.duration >= duration) return;
}
// If the actor already has this condition, but of a lower magnitude, we remove the old one and add this higher magnitude.
actor.conditions.remove(i);
actorConditionListeners.onActorConditionRemoved(actor, c);
}

ActorCondition c = e.createCondition(duration);
actor.conditions.add(c);
actorConditionListeners.onActorConditionAdded(actor, c);
private void addNonStackableActorCondition(Actor actor, ActorConditionEffect e, int duration) {
ActorCondition conditionWithSameDuration = null;
int effectiveMagnitude = e.magnitude;
final ActorConditionType type = e.conditionType;

// Search for conditions with the same or higher duration
for(int i = actor.conditions.size() - 1; i >= 0; --i) {
ActorCondition c = actor.conditions.get(i);
if (!type.conditionTypeID.equals(c.conditionType.conditionTypeID)) continue;
if(c.duration >= duration) {
if (c.duration == duration)
conditionWithSameDuration = c;

effectiveMagnitude -= c.magnitude;
if(effectiveMagnitude <1)
return;
}
}

// reduce the magnitude of shorter running conditions
for(int i=actor.conditions.size() -1; i >= 0; --i) {
ActorCondition c = actor.conditions.get(i);
if (!type.conditionTypeID.equals(c.conditionType.conditionTypeID)) continue;
if (c.duration < duration) {
c.magnitude -= effectiveMagnitude;
if(c.magnitude <1)
{
actor.conditions.remove(i);
actorConditionListeners.onActorConditionRemoved(actor, c);
}
else
actorConditionListeners.onActorConditionMagnitudeChanged(actor, c);
}
}

// if there is an existing condition with the same duration, we use it
if (conditionWithSameDuration != null) {
conditionWithSameDuration.magnitude += effectiveMagnitude;
actorConditionListeners.onActorConditionMagnitudeChanged(actor, conditionWithSameDuration);
}
else {
ActorCondition c = e.createCondition(duration);
c.magnitude = effectiveMagnitude;
actor.conditions.add(c);
actorConditionListeners.onActorConditionAdded(actor, c);
}
}

private void addActorConditionImmunity(Actor actor, ActorConditionEffect e, int duration) {
Expand Down
94 changes: 94 additions & 0 deletions AndorsTrail/test/controller/ActorStatsControllerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.gpl.rpg.AndorsTrail.controller;

import com.gpl.rpg.AndorsTrail.model.actor.Actor;
import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect;
import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionType;

import java.lang.reflect.Method;
import java.util.concurrent.locks.Condition;

import static org.junit.Assert.*;

public class ActorStatsControllerTest {
@org.junit.Test
public void addNonStackableActorCondition() throws Exception {
Method m = Class.forName("com.gpl.rpg.AndorsTrail.controller.ActorStatsController").getDeclaredMethod("addNonStackableActorCondition", Actor.class, ActorConditionEffect.class, int.class);
m.setAccessible(true);

ActorStatsController ctrl = new ActorStatsController(null,null);
ActorConditionType t = new ActorConditionType("typeDummy", "Dummy", 1, null, false, false, null, null, null);
Actor a = new Actor(null, true, false);

// add a permanent conditon
m.invoke(ctrl, a, new ActorConditionEffect(t, 1, 999, null), 999);
assertTrue(a.conditions.size() == 1 && a.conditions.get(0).magnitude == 1);

// adding the same permanent conditon with the same magnitude has no effect
m.invoke(ctrl, a, new ActorConditionEffect(t, 1, 999, null), 999);
assertTrue(a.conditions.size() == 1 && a.conditions.get(0).magnitude == 1);

// add a permanent conditon of another type
ActorConditionType t2 = new ActorConditionType("typeDummy2", "Dummy2", 1, null, false, false, null, null, null);
m.invoke(ctrl, a, new ActorConditionEffect(t2, 1, 999, null), 999);
assertTrue(a.conditions.size() == 2 && a.conditions.get(0).magnitude == 1 && a.conditions.get(1).magnitude == 1);
a.conditions.remove(1);

// adding a permanent condition with a higher magnitude than an existing one of the same type, replaces it
m.invoke(ctrl, a, new ActorConditionEffect(t, 2, 999, null), 999);
assertTrue(a.conditions.size() == 1 && a.conditions.get(0).magnitude == 2);

// adding a short running condition with lower magnitude has no effect
m.invoke(ctrl, a, new ActorConditionEffect(t, 1, 10, null), 10);
assertTrue(a.conditions.size() == 1 && a.conditions.get(0).magnitude == 2);

// adding a short running condition with the same magnitude has no effect
m.invoke(ctrl, a, new ActorConditionEffect(t, 2, 10, null), 10);
assertTrue(a.conditions.size() == 1 && a.conditions.get(0).magnitude == 2);

// adding a short running condition with a higher magnitude gets added but reduced
// by the magnitude of the long running one
m.invoke(ctrl, a, new ActorConditionEffect(t, 3, 10, null), 10);
assertTrue(a.conditions.size() == 2 && a.conditions.get(0).magnitude == 2 && a.conditions.get(1).magnitude == 1);
m.invoke(ctrl, a, new ActorConditionEffect(t, 4, 10, null), 10);
assertTrue(a.conditions.size() == 2 && a.conditions.get(0).magnitude == 2 && a.conditions.get(1).magnitude == 2);

// adding a short running condition with a lower magnitude than an existing one with the same or shorter duration has no effect
m.invoke(ctrl, a, new ActorConditionEffect(t, 3, 10, null), 10);
assertTrue(a.conditions.size() == 2 && a.conditions.get(0).magnitude == 2 && a.conditions.get(1).magnitude == 2);
m.invoke(ctrl, a, new ActorConditionEffect(t, 3, 7, null), 7);
assertTrue(a.conditions.size() == 2 && a.conditions.get(0).magnitude == 2 && a.conditions.get(1).magnitude == 2);

// adding a longer runnig condition with a higher magnitude than a existing long running condition reduces the magnitude of shorter running conditions
m.invoke(ctrl, a, new ActorConditionEffect(t, 3, 999, null), 999);
assertTrue(a.conditions.size() == 2 && a.conditions.get(0).magnitude == 3 && a.conditions.get(1).magnitude == 1);

m.invoke(ctrl, a, new ActorConditionEffect(t, 3, 999, null), 999);
assertTrue(a.conditions.size() == 2 && a.conditions.get(0).magnitude == 3 && a.conditions.get(1).magnitude == 1);

m.invoke(ctrl, a, new ActorConditionEffect(t, 4, 999, null), 999);
assertTrue(a.conditions.size() == 1 && a.conditions.get(0).magnitude == 4);

m.invoke(ctrl, a, new ActorConditionEffect(t, 4, 1000, null), 1000);
assertTrue(a.conditions.size() == 1 && a.conditions.get(0).magnitude == 4 && a.conditions.get(0).duration == 1000);

m.invoke(ctrl, a, new ActorConditionEffect(t, 5, 1001, null), 1001);
assertTrue(a.conditions.size() == 1 && a.conditions.get(0).magnitude == 5 && a.conditions.get(0).duration == 1001);

m.invoke(ctrl, a, new ActorConditionEffect(t, 6, 10, null), 10);
assertTrue(a.conditions.size() == 2 && a.conditions.get(0).magnitude == 5 && a.conditions.get(1).magnitude == 1);

m.invoke(ctrl, a, new ActorConditionEffect(t, 6, 100, null), 100);
assertTrue(a.conditions.size() == 2 && a.conditions.get(0).magnitude == 5 && a.conditions.get(1).magnitude == 1 && a.conditions.get(1).duration == 100);

m.invoke(ctrl, a, new ActorConditionEffect(t, 7, 100, null), 100);
assertTrue(a.conditions.size() == 2 && a.conditions.get(0).magnitude == 5 && a.conditions.get(1).magnitude == 2 && a.conditions.get(1).duration == 100);

m.invoke(ctrl, a, new ActorConditionEffect(t, 6, 200, null), 200);
assertTrue(a.conditions.size() == 3 && a.conditions.get(0).magnitude == 5 && a.conditions.get(1).magnitude == 1 && a.conditions.get(2).magnitude == 1);

m.invoke(ctrl, a, new ActorConditionEffect(t, 7, 300, null), 300);
assertTrue(a.conditions.size() == 2 && a.conditions.get(0).magnitude == 5 && a.conditions.get(1).magnitude == 2);

}
}

0 comments on commit 77bd6b5

Please sign in to comment.