/** * eAdventure (formerly <e-Adventure> and <e-Game>) is a research project of the * <e-UCM> research group. * * Copyright 2005-2010 <e-UCM> research group. * * You can access a list of all the contributors to eAdventure at: * http://e-adventure.e-ucm.es/contributors * * <e-UCM> is a research group of the Department of Software Engineering * and Artificial Intelligence at the Complutense University of Madrid * (School of Computer Science). * * C Profesor Jose Garcia Santesmases sn, * 28040 Madrid (Madrid), Spain. * * For more info please visit: <http://e-adventure.e-ucm.es> or * <http://www.e-ucm.es> * * **************************************************************************** * * This file is part of eAdventure, version 2.0 * * eAdventure is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * eAdventure is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with eAdventure. If not, see <http://www.gnu.org/licenses/>. */ package ead.importer.subimporters.chapter.cutscene; import java.awt.Dimension; import java.util.ArrayList; import java.util.List; import com.google.inject.Inject; import es.eucm.ead.model.assets.drawable.basics.Image; import es.eucm.ead.model.assets.drawable.basics.animation.FramesAnimation; import es.eucm.ead.model.elements.BasicElement; import es.eucm.ead.model.elements.conditions.EmptyCond; import es.eucm.ead.model.elements.effects.ChangeSceneEf; import es.eucm.ead.model.elements.effects.TriggerMacroEf; import es.eucm.ead.model.elements.effects.variables.ChangeFieldEf; import es.eucm.ead.model.elements.events.SceneElementEv; import es.eucm.ead.model.elements.events.TimedEv; import es.eucm.ead.model.elements.events.enums.SceneElementEvType; import es.eucm.ead.model.elements.events.enums.TimedEvType; import es.eucm.ead.model.elements.extra.EAdList; import es.eucm.ead.model.elements.huds.InventoryHud; import es.eucm.ead.model.elements.operations.ElementField; import es.eucm.ead.model.elements.scenes.Scene; import es.eucm.ead.model.elements.scenes.SceneElement; import es.eucm.ead.model.elements.transitions.Transition; import es.eucm.ead.model.elements.transitions.EmptyTransition; import es.eucm.ead.model.params.guievents.MouseGEv; import ead.importer.EAdElementImporter; import ead.importer.annotation.ImportAnnotator; import ead.importer.interfaces.EAdElementFactory; import ead.importer.interfaces.EffectsImporterFactory; import ead.importer.interfaces.ResourceImporter; import ead.importer.subimporters.chapter.scene.SceneImporter; import es.eucm.ead.tools.StringHandler; import es.eucm.eadventure.common.data.animation.Animation; import es.eucm.eadventure.common.data.animation.Frame; import es.eucm.eadventure.common.data.animation.ImageLoaderFactory; import es.eucm.eadventure.common.data.chapter.conditions.Conditions; import es.eucm.eadventure.common.data.chapter.resources.Resources; import es.eucm.eadventure.common.data.chapter.scenes.Slidescene; import es.eucm.eadventure.common.loader.InputStreamCreator; import es.eucm.eadventure.common.loader.Loader; /** * Scenes importer * */ public class SlidesceneImporter extends CutsceneImporter<Slidescene> { private ImageLoaderFactory imageLoader; private InputStreamCreator inputStreamCreator; private Animation animation; private FramesAnimation frames; private EAdElementImporter<Conditions, Condition> conditionsImporter; private static final ElementField SHOW_INVENTORY = new ElementField( new BasicElement(InventoryHud.ID), SceneElement.VAR_VISIBLE); @Inject public SlidesceneImporter(EffectsImporterFactory effectsImporter, EAdElementImporter<Conditions, Condition> conditionsImporter, EAdElementFactory factory, ResourceImporter resourceImporter, StringHandler stringHandler, ImageLoaderFactory imageLoader, InputStreamCreator inputStreamCreator, ImportAnnotator annotator) { super(stringHandler, factory, effectsImporter, resourceImporter, annotator); this.imageLoader = imageLoader; this.inputStreamCreator = inputStreamCreator; this.conditionsImporter = conditionsImporter; } @Override public Scene init(Slidescene oldSlideScene) { Scene scene = new Scene(); return scene; } @Override public Scene convert(Slidescene oldSlideScene, Object object) { Scene cutscene = super.convert(oldSlideScene, object); return cutscene; } protected void importResources(Slidescene oldSlides, Scene cutscene) { // Hide inventory event addHideInventoryEvent(cutscene); Effect changeNextScene = getEndEffect(oldSlides); List<String> musicPaths = new ArrayList<String>(); List<Condition> conditions = new ArrayList<Condition>(); if (oldSlides.getResources().size() == 1) { createSceneFromSlides(cutscene, oldSlides, oldSlides.getResources() .get(0), changeNextScene); musicPaths.add(oldSlides.getResources().get(0).getAssetPath( Slidescene.RESOURCE_TYPE_MUSIC)); conditions.add(EmptyCond.TRUE); } else { // When there's more than one appearance, we create a series of // scene for every animation. // Then, the initial cutscene decides which appearance to launch TriggerMacroEf triggerMacro = new TriggerMacroEf(); for (Resources res : oldSlides.getResources()) { Scene scene = new Scene(); createSceneFromSlides(scene, oldSlides, res, changeNextScene); EAdList<Effect> macro = new EAdList<Effect>(); macro.add(new ChangeSceneEf(scene)); Condition c = conditionsImporter.init(res.getConditions()); c = conditionsImporter.convert(res.getConditions(), c); musicPaths .add(res.getAssetPath(Slidescene.RESOURCE_TYPE_MUSIC)); conditions.add(c); triggerMacro.putEffects(c, macro); } SceneElementEv event = new SceneElementEv(); event.addEffect(SceneElementEvType.ADDED, triggerMacro); cutscene.addEvent(event); } SceneImporter.importSceneMusic(musicPaths, resourceImporter, cutscene, conditions); } private void createSceneFromSlides(Scene cutscene, Slidescene oldSlides, Resources res, Effect changeNextScene) { String assetPath = res.getAssetPath(Slidescene.RESOURCE_TYPE_SLIDES); // Change scene after slide show // FIXME music is not imported for animations initAnimation(assetPath); // generate slides properties List<Image> backgroundImages = generateBgImages(); List<Transition> transitions = generateTransitions(); List<Integer> times = generateTimes(); Scene[] scenes = new Scene[backgroundImages.size()]; for (int i = 0; i < scenes.length; i++) { if (i == 0 && oldSlides.getResources().size() == 1) scenes[i] = cutscene; else scenes[i] = new Scene(); Image drawable = backgroundImages.get(i); SceneElement background = new SceneElement(drawable); // Adjust scene background to 800x600 (restriction from old // model) Dimension d = resourceImporter.getDimensionsForNewImage(drawable .getUri()); float scaleX = 800.0f / d.width; float scaleY = 600.0f / d.height; background.setScale(scaleX, scaleY); scenes[i].setBackground(background); scenes[i].setReturnable(false); } for (int i = 0; i < scenes.length; i++) { Effect effect = null; if (i == scenes.length - 1) { effect = changeNextScene; ChangeFieldEf showInventory = new ChangeFieldEf(SHOW_INVENTORY, EmptyCond.TRUE); effect.getNextEffects().add(showInventory); } else { effect = new ChangeSceneEf(); ((ChangeSceneEf) effect).setNextScene(scenes[i + 1]); } if (effect instanceof ChangeSceneEf) ((ChangeSceneEf) effect).setTransition(transitions.get(i)); scenes[i].getBackground().addBehavior(MouseGEv.MOUSE_LEFT_PRESSED, effect); if (i != scenes.length - 1 && times.get(i) != -1) { Event changeEvent = getChangeSceneEvent(scenes[i + 1], times .get(i), effect); scenes[i].getBackground().addEvent(changeEvent); } } } private void initAnimation(String assetPath) { if (assetPath.endsWith(".eaa")) { animation = Loader.loadAnimation(inputStreamCreator, assetPath, imageLoader); } else { frames = (FramesAnimation) resourceImporter.getAssetDescritptor( assetPath, FramesAnimation.class); } } private List<Integer> generateTimes() { ArrayList<Integer> times = new ArrayList<Integer>(); if (animation != null) { for (int i = 0; i < animation.getFrames().size(); i++) { if (animation.getFrame(i).isWaitforclick()) { // Minus one means that no timed event for changing the // scene must be added times.add(-1); } else { times.add(new Long(animation.getFrame(i).getTime()) .intValue()); } } } else { for (es.eucm.ead.model.assets.drawable.basics.animation.Frame f : frames .getFrames()) { times.add(f.getTime()); } } return times; } private List<Transition> generateTransitions() { ArrayList<Transition> transitions = new ArrayList<Transition>(); if (animation != null) { for (int i = 0; i < animation.getFrames().size(); i++) { es.eucm.eadventure.common.data.animation.Transition t = animation.getTranstionForFrame(i); if (t != null) { transitions.add(getTransition(t.getType(), new Long(t .getTime()).intValue())); } else { transitions.add(EmptyTransition.instance()); } } } else { for (int i = 0; i < frames.getFrameCount(); i++) { transitions.add(EmptyTransition.instance()); } } return transitions; } private List<Image> generateBgImages() { ArrayList<Image> images = new ArrayList<Image>(); if (animation != null) { for (Frame f : animation.getFrames()) { String uri = resourceImporter.getString(f.getUri()); images.add(new Image(uri)); } } else { for (int i = 0; i < frames.getFrameCount(); i++) { images.add((Image) frames.getFrame(i).getDrawable()); } } return images; } private void addHideInventoryEvent(Scene cutscene) { ChangeFieldEf hideInventory = new ChangeFieldEf(SHOW_INVENTORY, EmptyCond.FALSE); SceneElementEv bgEvent = new SceneElementEv(); bgEvent.addEffect(SceneElementEvType.ADDED, hideInventory); cutscene.addEvent(bgEvent); } private Event getChangeSceneEvent(Scene Scene, int time, Effect changeScene) { TimedEv event = new TimedEv(); event.setRepeats(1); event.setTime(time); event.addEffect(TimedEvType.END_TIME, changeScene); return event; } @Override protected void importConfiguration(Scene scene, Effect endEffect) { } }