1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.replica.replicaisland;
18
19import com.replica.replicaisland.GameObject.ActionType;
20
21public class TheSourceComponent extends GameComponent {
22	public final static float SHAKE_TIME = 0.6f;
23	private final static float DIE_TIME = 30.0f;
24	private final static float EXPLOSION_TIME = 0.1f;
25	private final static float SHAKE_MAGNITUDE = 5.0f;
26	private final static float SHAKE_SCALE = 300.0f;
27	private final static float CAMERA_HIT_SHAKE_MAGNITUDE = 3.0f;
28
29	private final static float SINK_SPEED = -20.0f;
30	private float mTimer;
31	private float mExplosionTimer;
32	private float mShakeStartPosition;
33	private ChannelSystem.Channel mChannel;
34	private int mGameEvent;
35	private int mGameEventIndex;
36	private boolean mDead;
37
38	private static ChannelSystem.ChannelBooleanValue sChannelValue = new ChannelSystem.ChannelBooleanValue();
39
40	public TheSourceComponent() {
41		super();
42        reset();
43        setPhase(ComponentPhases.THINK.ordinal());
44	}
45
46	@Override
47	public void reset() {
48		mTimer = 0.0f;
49		mExplosionTimer = 0.0f;
50		mShakeStartPosition = 0.0f;
51		mChannel = null;
52		sChannelValue.value = false;
53		mGameEvent = -1;
54		mGameEventIndex = -1;
55		mDead = false;
56	}
57
58	@Override
59	public void update(float timeDelta, BaseObject parent) {
60		GameObject parentObject = (GameObject)parent;
61		GameObject.ActionType currentAction = parentObject.getCurrentAction();
62
63		CameraSystem camera = sSystemRegistry.cameraSystem;
64
65		if (currentAction == ActionType.HIT_REACT) {
66			if (parentObject.life > 0) {
67				mTimer = SHAKE_TIME;
68				camera.shake(SHAKE_TIME, CAMERA_HIT_SHAKE_MAGNITUDE);
69				mShakeStartPosition = parentObject.getPosition().x;
70				parentObject.setCurrentAction(ActionType.IDLE);
71				currentAction = ActionType.IDLE;
72			} else {
73				parentObject.setCurrentAction(ActionType.DEATH);
74				currentAction = ActionType.DEATH;
75				mTimer = DIE_TIME;
76				mExplosionTimer = EXPLOSION_TIME;
77				if (mChannel != null) {
78					mChannel.value = sChannelValue;
79					sChannelValue.value = true;
80				}
81				mDead = true;
82			}
83
84		}
85
86		mTimer -= timeDelta;
87
88		if (mDead) {
89			// Wait for the player to take the camera back, then steal it!
90			GameObjectManager manager = sSystemRegistry.gameObjectManager;
91
92			if (camera != null && manager != null && camera.getTarget() == manager.getPlayer()) {
93				camera.setTarget(parentObject);
94			}
95
96			final float offset = SINK_SPEED * timeDelta;
97			parentObject.getPosition().y += offset;
98
99			mExplosionTimer -= timeDelta;
100			if (mExplosionTimer < 0.0f) {
101				GameObjectFactory factory = sSystemRegistry.gameObjectFactory;
102				if (factory != null) {
103					float x = ((float)Math.random() - 0.5f) * (parentObject.width * 0.75f);
104					float y = ((float)Math.random() - 0.5f) * (parentObject.height * 0.75f);
105					GameObject object =
106						factory.spawn(GameObjectFactory.GameObjectType.EXPLOSION_GIANT,
107							parentObject.getCenteredPositionX() + x,
108							parentObject.getCenteredPositionY() + y,
109							false);
110					if (object != null) {
111						manager.add(object);
112					}
113					mExplosionTimer = EXPLOSION_TIME;
114				}
115			}
116
117			if (mTimer - timeDelta <= 0.0f) {
118				mTimer = 0.0f;
119				if (mGameEvent != -1) {
120					HudSystem hud = sSystemRegistry.hudSystem;
121    	        	if (hud != null) {
122    	        		hud.startFade(false, 1.5f);
123    	        		hud.sendGameEventOnFadeComplete(mGameEvent, mGameEventIndex);
124    	        		mGameEvent = -1;
125    	        	}
126	    		}
127			}
128		} else if (mTimer > 0) {
129			// shake
130			float delta = (float)Math.sin(mTimer * SHAKE_SCALE);
131			delta *= SHAKE_MAGNITUDE;
132			parentObject.getPosition().x = mShakeStartPosition + delta;
133			if (mTimer - timeDelta <= 0.0f) {
134				// end one step early and fix the position.
135				mTimer = 0;
136				parentObject.getPosition().x = mShakeStartPosition;
137			}
138		}
139	}
140
141	public void setChannel(ChannelSystem.Channel channel) {
142		mChannel = channel;
143	}
144
145	public void setGameEvent(int event, int index) {
146		mGameEvent = event;
147		mGameEventIndex = index;
148	}
149}
150