Thursday, July 1, 2010

Destruction

The last one and half a month were really sparse on working on Laterna Magica. It was the countdown of my school year and I was busy with a lot of stuff. There were loads of very work-intensive homeworks, and my year's project was also due. Anyone with experience on projects knows that half of the work is done in the two weeks before the end date and the other half is done in the two weeks after ;)

I can tell you, I didn't find a single minute to work on my program, but today I finally got back to it. I don't know if I can work on it regularly again, but I will try.

Before my big break, I told you that one of my next steps will be combat, but combat is a big thing and it takes many parts to work. One of these is damage.

Until very recent, damage was a simple concept: Players and creatures can receive damage. When a player receives damage, he looses life; when a creature receives enough damage, it is destroyed. However, two recent changes turned things around a bit: Planeswalkers, but more importantly Wither and the accompanying changes of Lifelink etc. To make things worse, damage has also another special concept found (nearly) nowhere else in the game: sources.

I suspect damage to be very annoying to program, but happily there's another thing to be done before damage really makes sense... Which happens to be what I've done today: Destruction, which was in fact so easy that I can fit it here without worrying that it will overload my post:

public class DestroyPermanentEvent extends ReplaceableEvent {
    private MagicObject o;
   
    public DestroyPermanentEvent(MagicObject o) {
        super(o);
        this.o = o;
    }
   
    @Override
    protected boolean execute0() {
        if(o.getZone().getType() != Zones.BATTLEFIELD) return false;
        o.setZone(o.getOwner().getGraveyard());
        return true;
    }
}

execute0() is very straightforward, which is possible because "destroy" only has one meaning, as opposed to damage, which would make a decision based on the receiver's type and both source's and receiver's abilities. Making DestroyPermanentEvent a ReplaceableEvent easily takes care of Regeneration and indestructibility. The only thing I'm not sure about is "... can't be regenerated".

6 comments:

nantuko84 said...

I believe "can't be regenerated" woule be handled by regeneration itself.
not sure about another aspect: once regeneration fails, may you choose to apply another replacement effect?

e.g.: you have drudge skeletons with 2 totem armors on it. when it is being destroyed by Terminate, you choose what replacement effect to apply. if you choose regeneration, then it would fail. I believe after that you still able to choose one of armor replacement effects so drudge skeletons would stay on battlefield (as well as another totem armor)

Silly Freak said...

It's pretty straightforward. When a replaceable event occurs, the game determines which replacement effects could be applied, the you can choose one. In that case, regeneration can't replace the event, so you don't even have the choice. Totem armor can, though. After that, the game looks again: the event is not destruction any more, so no more effects to apply.

Silly Freak said...

Ps: thanks for your input, putting it in regeneration is probably the easiest approach.

Another classic example is double furnace of rath: once an effect was applied, It's removed from the list to search, so you get exactly the expected result.

Btw, code is at code.google.com/p/laterna-magica/source/browse/trunk/laterna/src/laterna/magica/effect/replacement/ReplacementEngine.java and It's even documented ;)

Incantus said...

This is a good approach - however it won't correctly handle indestructibility, since that isn't a replacement effect. For example, if you regenerate a creature, sacrifice Dauntless Escort (Sacrifice Dauntless Escort: Creatures you control are indestructible this turn.) and then try and destroy the original creature, you won't get the option to use up the regeneration shield (not that you would ever want to).

Silly Freak said...

you have a point here; are you sure that destroying an indestructible permanent doesn't allow replacement effects, though? like in:

"whenever a creature is destroyed, draw a card"

would I draw a card?

Silly Freak said...

man, somehow I had a blackout while writing this example; i wanted to do a replacement effect of course, like

"if a creature would be destroyed, draw a card instead"

I share your opinion though; it feels more natural that you don't draw a card, but the problem is pretty hard. consider this:

if ~ would be sacrificed, destroy it instead

this would be just crazy, it would mean I have to check for indestructible in my replacement engine. execute0 is not enough since the destroy event could be replaced again - which shouldn't happen considering this interpretation of the rules