This can be accomplished fairly easily with delegates.
Example:
public delegate boolean CheckStatusDelegate(AttackStatusObserver observer);
public class AttackStatusObserver {
protected int value;
protected AttackStatus status;
protected CheckStatusDelegate statusDelegate;
public int Value {
get { return this.value; }
set { this.value = value; }
}
public AttackStatus Status {
get { return this.status; }
}
public AttackStatusObserver(int value, AttackStatus status, CheckStatusDelegate statusDelegate) {
this.value = value;
this.status = status;
this.statusDelegate = statusDelegate;
}
public override bool checkStatus(int value, AttackStatus status) {
if (null != statusDelegate) {
return statusDelegate(this);
}
}
}
public class AlwaysDodgeEffect {
public override void startEffect(Effect effect) {
AttackCalcObserver acObserver = new AttackStatusObserver(value, AttackStatus.DODGE, CheckStatusCallback);
acObserver.checkStatus(AttackStatus.DODGE);
}
private bool CheckStatusCallback(AttackStatusObserver observer) {
if (observer.AttackStatus == AttackStatus.DODGE) {
if (observer.Value <= 1)
effect.endEffect();
else
observer.Value--;
return true;
}
else
return false;
}
}
Another approach would be to use the Visitor pattern.
Implementing the Visitor pattern requires that you add a few methods to the base class and creating a Visitor object. Its a bit more complex but can be VERY powerful.