Page 2 of 2

Re: Converting cards for multiplayer

PostPosted: 29 Dec 2012, 01:46
by swordshine
One question: If a continuous static ability affects each opponent, would you tell me which is correct for the corresponding param, "Affected$ Player.Opponent" or "Affected$ Opponent"?

Re: Converting cards for multiplayer

PostPosted: 29 Dec 2012, 05:17
by friarsol
swordshine wrote:One question: If a continuous static ability affects each opponent, would you tell me which is correct for the corresponding param, "Affected$ Player.Opponent" or "Affected$ Opponent"?
I think both are valid Properties.

Re: Converting cards for multiplayer

PostPosted: 29 Dec 2012, 11:27
by moomarc
friarsol wrote:I think the problem with triggers in Multiplayer matches may be because of:

MagicStack.java | Open
public final void chooseOrderOfSimultaneousStackEntryAll() {
final Player playerTurn = game.getPhaseHandler().getPlayerTurn();

this.chooseOrderOfSimultaneousStackEntry(playerTurn);

if (playerTurn != null) {
this.chooseOrderOfSimultaneousStackEntry(playerTurn.getOpponent());
}
}
I've committed a fix that doesn't seem to have broken anything else yet. I'm starting to think that hunting down methods with get opponent might be a better step forward then doing all the cards first. I'll probably just keep doing as I have been by doing a little of each as I go.

Re: Converting cards for multiplayer

PostPosted: 29 Dec 2012, 18:01
by moomarc
friarsol wrote:
swordshine wrote:One question: If a continuous static ability affects each opponent, would you tell me which is correct for the corresponding param, "Affected$ Player.Opponent" or "Affected$ Opponent"?
I think both are valid Properties.
Just to expand on this, either of those work because Affected checks Player.isValid instead of AbilityFactory.getDefinedPlayers (which is the bothersome version of Opponent). The base valid player types include Self, Opponent, Other and Player which can then be refined further in hasProperty which again has Self and Opponent as well as a bunch more.

Re: Converting cards for multiplayer

PostPosted: 08 Jan 2013, 10:37
by moomarc
I just converted Rainbow Vale to script as part of my ongoing quest to get get rid of getOpponent. The AI never seems to activate it now though (not entirely sure if it did before). Is it something to do with there being no ChoosePlayerAi to override the various things like canPlayAI and doTriggerAINoCost, or is it something else?

Re: Converting cards for multiplayer

PostPosted: 08 Jan 2013, 15:05
by ArsenalNut
moomarc wrote:I just converted Rainbow Vale to script as part of my ongoing quest to get get rid of getOpponent. The AI never seems to activate it now though (not entirely sure if it did before). Is it something to do with there being no ChoosePlayerAi to override the various things like canPlayAI and doTriggerAINoCost, or is it something else?
Stepping through with the debugger, the AI is not using Rainbow Vale because it fails the "dangerous drawbacks" test in the mapManaSources method. You are right that it fails this test because there is no ChoosePlayerAI to override the default value of false for all the AI tests.

Before converting to the delayed trigger script, Rainbow Vale would have passed the "dangerous drawbacks" test because the trigger was hard coded and there was no subAbility to check. The AI would have been blissfully unaware of the consequences of using Rainbow Vale.

Re: Converting cards for multiplayer

PostPosted: 08 Jan 2013, 16:02
by moomarc
In that case I'll have to disabuse the ai and train it what to look out for. :D I should be able to come up with something basic looking at the other AFs. Otherwise I'll let it return to it's oblivious innocence and return true by default.

Thanks for looking into it. That kind of tracking is still out of my league. :P

Re: Converting cards for multiplayer

PostPosted: 09 Jan 2013, 11:23
by moomarc
I just can't seem to get the ai to us Rainbow Vale. I added a barebones logic to override the default false, but still not helping. I added the following to a new file ChoosePlayerAi.java:
Code: Select all
public class ChoosePlayerAi extends SpellAiLogic {

    /* (non-Javadoc)
     * @see forge.card.abilityfactory.SpellAiLogic#canPlayAI(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility)
     */
    @Override
    protected boolean canPlayAI(Player ai, SpellAbility sa) {
        return true;
    }

    @Override
    public boolean chkAIDrawback(SpellAbility sa, Player ai) {
        return canPlayAI(ai, sa);
    }

    @Override
    protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
        return canPlayAI(ai, sa);
    }

}
Am I missing some override or is there something else I need to change somewhere? Appreciate the help.

Re: Converting cards for multiplayer

PostPosted: 10 Jan 2013, 03:18
by ArsenalNut
moomarc wrote:I just can't seem to get the ai to us Rainbow Vale. I added a barebones logic to override the default false, but still not helping.

Am I missing some override or is there something else I need to change somewhere? Appreciate the help.
To connect the AI logic, you have to modify ApiType.java to have the API point to the correct AI class in the forge.card.abilityfactory.ai package.

I checked in your ChoosePlayerAI.java and the changes to ApiType.java that enable it. Now there is still an issue with the AI playing Rainbow Vale because the delayed trigger never gets created. I suspect it is because the subAbilities are skipped.

Edit: I fixed the issue with subAbilities [-o< The AI uses Rainbow Vale and it did change control at the end of the turn.

Re: Converting cards for multiplayer

PostPosted: 10 Jan 2013, 04:16
by moomarc
Thanks ArsenalNut! With a little luck this might have made some other cards work better as well where we didn't even notice there was an issue :D

Re: Converting cards for multiplayer

PostPosted: 14 Jan 2013, 00:46
by swordshine
@moomarc
I've tested Rivalry, it doesn't work if the one who controls the highest lands is not human or the first opponent.

Re: Converting cards for multiplayer

PostPosted: 16 Jan 2013, 06:12
by moomarc
swordshine wrote:@moomarc
I've tested Rivalry, it doesn't work if the one who controls the highest lands is not human or the first opponent.
Sorry it's taken so long to look into this. Landed a huge design project so have been too busy to look at Forge (and will most likely continue until 5 February). Anyway, I had a few moments now and Rivalry seems to work for me. I tried me controlling Rivalry then testing for each player in turn having the most lands, and it worked in each case. Then I tested with each other player controlling the Rivalry and it still worked each time. Are you certain that the second opponent wasn't tied for most lands?