View Javadoc

1   /*
2    *   Magic-Project is a turn based strategy simulator
3    *   Copyright (C) 2003-2007 Fabrice Daugan
4    *
5    *   This program is free software; you can redistribute it and/or modify it 
6    * under the terms of the GNU General Public License as published by the Free 
7    * Software Foundation; either version 2 of the License, or (at your option) any
8    * later version.
9    *
10   *   This program is distributed in the hope that it will be useful, but WITHOUT 
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
13   * details.
14   *
15   *   You should have received a copy of the GNU General Public License along  
16   * with this program; if not, write to the Free Software Foundation, Inc., 
17   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  package net.sf.magicproject.action;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  
24  import net.sf.magicproject.action.context.ActionContextWrapper;
25  import net.sf.magicproject.action.context.BooleanArray;
26  import net.sf.magicproject.action.handler.FollowAction;
27  import net.sf.magicproject.action.handler.StandardAction;
28  import net.sf.magicproject.clickable.ability.Ability;
29  import net.sf.magicproject.clickable.targetable.Targetable;
30  import net.sf.magicproject.clickable.targetable.card.MCard;
31  import net.sf.magicproject.event.FacedDown;
32  import net.sf.magicproject.event.FacedUp;
33  import net.sf.magicproject.event.context.ContextEventListener;
34  import net.sf.magicproject.stack.StackManager;
35  import net.sf.magicproject.token.Visibility;
36  import net.sf.magicproject.token.VisibilityChange;
37  import net.sf.magicproject.tools.Log;
38  
39  /***
40   * Action used to face up or down cards referenced by the target-list.
41   * 
42   * @author <a href="mailto:hoani.cross@gmail.com">Hoani CROSS</a>
43   * @since 0.90
44   * @since 0.91 'for' constraint attribute, default [everyone] is added.
45   */
46  class Face extends UserAction implements StandardAction, FollowAction {
47  
48  	/***
49  	 * Create an instance of Face action.
50  	 * <ul>
51  	 * Structure of stream :
52  	 * <li>idAction [1]</li>
53  	 * <li>int8 : 0 means face-down, >0 means face-up [1]</li>
54  	 * <li>visibility [1]</li>
55  	 * </ul>
56  	 * 
57  	 * @param inputFile
58  	 *          the file to read the action from
59  	 * @throws IOException
60  	 *           if an IO error occurred
61  	 * @see Actiontype
62  	 */
63  	Face(InputStream inputFile) throws IOException {
64  		super(inputFile);
65  		faceUpFlag = inputFile.read() > 0;
66  		visibilityChange = VisibilityChange.deserialize(inputFile);
67  	}
68  
69  	@Override
70  	public Actiontype getIdAction() {
71  		return Actiontype.FACE;
72  	}
73  
74  	public boolean play(ContextEventListener context, Ability ability) {
75  		for (Targetable targetable : StackManager.getInstance().getTargetedList().list) {
76  			if (targetable.isCard()) {
77  				final MCard card = (MCard) targetable;
78  				if (checkTimeStamp(context, card)) {
79  					if (faceUpFlag) {
80  						FacedUp.dispatchEvent(card);
81  						card.returnCard(card.visibility.increaseFor(card.getController(),
82  								visibilityChange));
83  					} else {
84  						FacedDown.dispatchEvent(card);
85  						card.returnCard(card.visibility.decreaseFor(card.getController(),
86  								visibilityChange));
87  					}
88  				} else {
89  					Log.error("In FACE action, erreur timestamp for card " + card);
90  				}
91  			} else {
92  				Log
93  						.warn("In FACE action, target list contains non 'Card' object. Ignored");
94  			}
95  		}
96  		return true;
97  	}
98  
99  	public void rollback(ActionContextWrapper actionContext,
100 			ContextEventListener context, Ability ability) {
101 		final BooleanArray bContext = (BooleanArray) actionContext.actionContext;
102 		for (int i = StackManager.getInstance().getTargetedList().size(); i-- > 0;) {
103 			if (StackManager.getInstance().getTargetedList().get(i).isCard()) {
104 				final MCard card = (MCard) StackManager.getInstance().getTargetedList()
105 						.get(i);
106 				if (bContext.getBoolean(i)) {
107 					card.tap(!faceUpFlag);
108 					if (faceUpFlag) {
109 						card.returnCard(Visibility.HIDDEN);
110 					} else {
111 						card.returnCard(Visibility.PUBLIC);
112 					}
113 				}
114 			} else {
115 				Log
116 						.warn("In FACE action, target list contains non 'Card' object. Ignored");
117 			}
118 		}
119 	}
120 
121 	public void simulate(ActionContextWrapper actionContext,
122 			ContextEventListener context, Ability ability) {
123 		final BooleanArray bContext = new BooleanArray(StackManager.getInstance()
124 				.getTargetedList().size());
125 		actionContext.actionContext = bContext;
126 		for (int i = StackManager.getInstance().getTargetedList().size(); i-- > 0;) {
127 			if (StackManager.getInstance().getTargetedList().get(i).isCard()) {
128 				final MCard card = (MCard) StackManager.getInstance().getTargetedList()
129 						.get(i);
130 				if (card.visibility == Visibility.PUBLIC && !faceUpFlag
131 						|| card.visibility != Visibility.PUBLIC && faceUpFlag) {
132 					bContext.setBoolean(i, true);
133 					if (faceUpFlag) {
134 						card.returnCard(Visibility.PUBLIC);
135 					} else {
136 						card.returnCard(Visibility.HIDDEN);
137 					}
138 				}
139 			} else {
140 				Log
141 						.warn("In FACE action, target list contains non 'Card' object. Ignored");
142 			}
143 		}
144 	}
145 
146 	@Override
147 	public String toString(Ability ability) {
148 		return "face-" + (faceUpFlag ? "up" : "down");
149 	}
150 
151 	/***
152 	 * <code>true</code> if the action if to face cards up, <code>false</code>
153 	 * if the action if to face them down.
154 	 */
155 	private final boolean faceUpFlag;
156 
157 	/***
158 	 * The visibility to set.
159 	 */
160 	private final VisibilityChange visibilityChange;
161 }