1cfd74d65d832137e20e193c960802afba73b5d38sm/*
23c1e67e433728684b5f228c5d4f3e5b1457bb271sm * Copyright (C) 2010 The Android Open Source Project
3cfd74d65d832137e20e193c960802afba73b5d38sm *
4cfd74d65d832137e20e193c960802afba73b5d38sm * Licensed under the Apache License, Version 2.0 (the "License");
5cfd74d65d832137e20e193c960802afba73b5d38sm * you may not use this file except in compliance with the License.
6cfd74d65d832137e20e193c960802afba73b5d38sm * You may obtain a copy of the License at
7cfd74d65d832137e20e193c960802afba73b5d38sm *
8cfd74d65d832137e20e193c960802afba73b5d38sm *      http://www.apache.org/licenses/LICENSE-2.0
9cfd74d65d832137e20e193c960802afba73b5d38sm *
10cfd74d65d832137e20e193c960802afba73b5d38sm * Unless required by applicable law or agreed to in writing, software
11cfd74d65d832137e20e193c960802afba73b5d38sm * distributed under the License is distributed on an "AS IS" BASIS,
12cfd74d65d832137e20e193c960802afba73b5d38sm * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cfd74d65d832137e20e193c960802afba73b5d38sm * See the License for the specific language governing permissions and
14cfd74d65d832137e20e193c960802afba73b5d38sm * limitations under the License.
15cfd74d65d832137e20e193c960802afba73b5d38sm */
16cfd74d65d832137e20e193c960802afba73b5d38sm
17cfd74d65d832137e20e193c960802afba73b5d38smpackage com.replica.replicaisland;
18cfd74d65d832137e20e193c960802afba73b5d38sm
19cfd74d65d832137e20e193c960802afba73b5d38smimport com.replica.replicaisland.GameObject.ActionType;
20cfd74d65d832137e20e193c960802afba73b5d38sm
21cfd74d65d832137e20e193c960802afba73b5d38sm/**
22cfd74d65d832137e20e193c960802afba73b5d38sm * A component that allows an object to spawn other objects and apply velocity to them at
23cfd74d65d832137e20e193c960802afba73b5d38sm * specific intervals.  Can be used to launch projectiles, particle effects, or any other type
24cfd74d65d832137e20e193c960802afba73b5d38sm * of game object.
25cfd74d65d832137e20e193c960802afba73b5d38sm */
26cfd74d65d832137e20e193c960802afba73b5d38smpublic class LaunchProjectileComponent extends GameComponent {
27cfd74d65d832137e20e193c960802afba73b5d38sm    private GameObjectFactory.GameObjectType mObjectTypeToSpawn;
28cfd74d65d832137e20e193c960802afba73b5d38sm    private float mOffsetX;
29cfd74d65d832137e20e193c960802afba73b5d38sm    private float mOffsetY;
30cfd74d65d832137e20e193c960802afba73b5d38sm    private float mVelocityX;
31cfd74d65d832137e20e193c960802afba73b5d38sm    private float mVelocityY;
32cfd74d65d832137e20e193c960802afba73b5d38sm    private float mThetaError;
33cfd74d65d832137e20e193c960802afba73b5d38sm    private GameObject.ActionType mRequiredAction;
34cfd74d65d832137e20e193c960802afba73b5d38sm    private float mDelayBetweenShots;
35cfd74d65d832137e20e193c960802afba73b5d38sm    private int mProjectilesInSet;
36cfd74d65d832137e20e193c960802afba73b5d38sm    private float mDelayBetweenSets;
37cfd74d65d832137e20e193c960802afba73b5d38sm    private int mSetsPerActivation;
38cfd74d65d832137e20e193c960802afba73b5d38sm    private float mDelayBeforeFirstSet;
39cfd74d65d832137e20e193c960802afba73b5d38sm
40cfd74d65d832137e20e193c960802afba73b5d38sm    private float mLastProjectileTime;
41cfd74d65d832137e20e193c960802afba73b5d38sm    private float mSetStartedTime;
42cfd74d65d832137e20e193c960802afba73b5d38sm    private int mLaunchedCount;
43cfd74d65d832137e20e193c960802afba73b5d38sm    private int mSetCount;
44cfd74d65d832137e20e193c960802afba73b5d38sm
45cfd74d65d832137e20e193c960802afba73b5d38sm    private boolean mTrackProjectiles;
46cfd74d65d832137e20e193c960802afba73b5d38sm    private int mMaxTrackedProjectiles;
47cfd74d65d832137e20e193c960802afba73b5d38sm    private int mTrackedProjectileCount;
48cfd74d65d832137e20e193c960802afba73b5d38sm
49cfd74d65d832137e20e193c960802afba73b5d38sm    private Vector2 mWorkingVector;
50cfd74d65d832137e20e193c960802afba73b5d38sm
51cfd74d65d832137e20e193c960802afba73b5d38sm    private SoundSystem.Sound mShootSound;
52cfd74d65d832137e20e193c960802afba73b5d38sm
53cfd74d65d832137e20e193c960802afba73b5d38sm
54cfd74d65d832137e20e193c960802afba73b5d38sm    public LaunchProjectileComponent() {
55cfd74d65d832137e20e193c960802afba73b5d38sm        super();
56cfd74d65d832137e20e193c960802afba73b5d38sm        setPhase(ComponentPhases.POST_COLLISION.ordinal());
57cfd74d65d832137e20e193c960802afba73b5d38sm        mWorkingVector = new Vector2();
58cfd74d65d832137e20e193c960802afba73b5d38sm        reset();
59cfd74d65d832137e20e193c960802afba73b5d38sm    }
60cfd74d65d832137e20e193c960802afba73b5d38sm
61cfd74d65d832137e20e193c960802afba73b5d38sm    @Override
62cfd74d65d832137e20e193c960802afba73b5d38sm    public void reset() {
63cfd74d65d832137e20e193c960802afba73b5d38sm        mRequiredAction = ActionType.INVALID;
64cfd74d65d832137e20e193c960802afba73b5d38sm        mObjectTypeToSpawn = GameObjectFactory.GameObjectType.INVALID;
65cfd74d65d832137e20e193c960802afba73b5d38sm        mOffsetX = 0.0f;
66cfd74d65d832137e20e193c960802afba73b5d38sm        mOffsetY = 0.0f;
67cfd74d65d832137e20e193c960802afba73b5d38sm        mVelocityX = 0.0f;
68cfd74d65d832137e20e193c960802afba73b5d38sm        mVelocityY = 0.0f;
69cfd74d65d832137e20e193c960802afba73b5d38sm        mDelayBetweenShots = 0.0f;
70cfd74d65d832137e20e193c960802afba73b5d38sm        mProjectilesInSet = 0;
71cfd74d65d832137e20e193c960802afba73b5d38sm        mDelayBetweenSets = 0.0f;
72cfd74d65d832137e20e193c960802afba73b5d38sm        mLastProjectileTime = 0.0f;
73cfd74d65d832137e20e193c960802afba73b5d38sm        mSetStartedTime = -1.0f;
74cfd74d65d832137e20e193c960802afba73b5d38sm        mLaunchedCount = 0;
75cfd74d65d832137e20e193c960802afba73b5d38sm        mSetCount = 0;
76cfd74d65d832137e20e193c960802afba73b5d38sm        mSetsPerActivation = -1;
77cfd74d65d832137e20e193c960802afba73b5d38sm        mProjectilesInSet = 0;
78cfd74d65d832137e20e193c960802afba73b5d38sm        mDelayBeforeFirstSet = 0.0f;
79cfd74d65d832137e20e193c960802afba73b5d38sm        mTrackProjectiles = false;
80cfd74d65d832137e20e193c960802afba73b5d38sm        mMaxTrackedProjectiles = 0;
81cfd74d65d832137e20e193c960802afba73b5d38sm        mTrackedProjectileCount = 0;
82cfd74d65d832137e20e193c960802afba73b5d38sm        mThetaError = 0.0f;
83cfd74d65d832137e20e193c960802afba73b5d38sm        mShootSound = null;
84cfd74d65d832137e20e193c960802afba73b5d38sm    }
85cfd74d65d832137e20e193c960802afba73b5d38sm
86cfd74d65d832137e20e193c960802afba73b5d38sm    @Override
87cfd74d65d832137e20e193c960802afba73b5d38sm    public void update(float timeDelta, BaseObject parent) {
88cfd74d65d832137e20e193c960802afba73b5d38sm        GameObject parentObject = (GameObject) parent;
89cfd74d65d832137e20e193c960802afba73b5d38sm
90cfd74d65d832137e20e193c960802afba73b5d38sm        final TimeSystem time = sSystemRegistry.timeSystem;
91cfd74d65d832137e20e193c960802afba73b5d38sm        final float gameTime = time.getGameTime();
92cfd74d65d832137e20e193c960802afba73b5d38sm
93cfd74d65d832137e20e193c960802afba73b5d38sm        if (mTrackedProjectileCount < mMaxTrackedProjectiles || !mTrackProjectiles) {
94cfd74d65d832137e20e193c960802afba73b5d38sm            if (parentObject.getCurrentAction() == mRequiredAction
95cfd74d65d832137e20e193c960802afba73b5d38sm                    || mRequiredAction == ActionType.INVALID) {
96cfd74d65d832137e20e193c960802afba73b5d38sm
97cfd74d65d832137e20e193c960802afba73b5d38sm                if (mSetStartedTime == -1.0f) {
98cfd74d65d832137e20e193c960802afba73b5d38sm                    mLaunchedCount = 0;
99cfd74d65d832137e20e193c960802afba73b5d38sm                    mLastProjectileTime = 0.0f;
100cfd74d65d832137e20e193c960802afba73b5d38sm                    mSetStartedTime = gameTime;
101cfd74d65d832137e20e193c960802afba73b5d38sm                }
102cfd74d65d832137e20e193c960802afba73b5d38sm
103cfd74d65d832137e20e193c960802afba73b5d38sm                final float setDelay = mSetCount > 0 ? mDelayBetweenSets : mDelayBeforeFirstSet;
104cfd74d65d832137e20e193c960802afba73b5d38sm
105cfd74d65d832137e20e193c960802afba73b5d38sm                if (gameTime - mSetStartedTime >= setDelay &&
106cfd74d65d832137e20e193c960802afba73b5d38sm                        (mSetCount < mSetsPerActivation || mSetsPerActivation == -1)) {
107cfd74d65d832137e20e193c960802afba73b5d38sm                    // We can start shooting.
108cfd74d65d832137e20e193c960802afba73b5d38sm                    final float timeSinceLastShot = gameTime - mLastProjectileTime;
109cfd74d65d832137e20e193c960802afba73b5d38sm
110cfd74d65d832137e20e193c960802afba73b5d38sm                    if (timeSinceLastShot >= mDelayBetweenShots) {
111cfd74d65d832137e20e193c960802afba73b5d38sm
112cfd74d65d832137e20e193c960802afba73b5d38sm                        launch(parentObject);
113cfd74d65d832137e20e193c960802afba73b5d38sm                        mLastProjectileTime = gameTime;
114cfd74d65d832137e20e193c960802afba73b5d38sm
115cfd74d65d832137e20e193c960802afba73b5d38sm                        if (mLaunchedCount >= mProjectilesInSet && mProjectilesInSet > 0) {
116cfd74d65d832137e20e193c960802afba73b5d38sm                            mSetStartedTime = -1.0f;
117cfd74d65d832137e20e193c960802afba73b5d38sm                            mSetCount++;
118cfd74d65d832137e20e193c960802afba73b5d38sm                        }
119cfd74d65d832137e20e193c960802afba73b5d38sm                    }
120cfd74d65d832137e20e193c960802afba73b5d38sm                }
121cfd74d65d832137e20e193c960802afba73b5d38sm            } else {
122cfd74d65d832137e20e193c960802afba73b5d38sm                // Force the timer to start counting when the right action is activated.
123cfd74d65d832137e20e193c960802afba73b5d38sm                mSetStartedTime = -1.0f;
124cfd74d65d832137e20e193c960802afba73b5d38sm                mSetCount = 0;
125cfd74d65d832137e20e193c960802afba73b5d38sm            }
126cfd74d65d832137e20e193c960802afba73b5d38sm        }
127cfd74d65d832137e20e193c960802afba73b5d38sm    }
128cfd74d65d832137e20e193c960802afba73b5d38sm
129cfd74d65d832137e20e193c960802afba73b5d38sm    private void launch(GameObject parentObject) {
130cfd74d65d832137e20e193c960802afba73b5d38sm        mLaunchedCount++;
131cfd74d65d832137e20e193c960802afba73b5d38sm        GameObjectFactory factory = sSystemRegistry.gameObjectFactory;
132cfd74d65d832137e20e193c960802afba73b5d38sm        GameObjectManager manager = sSystemRegistry.gameObjectManager;
133cfd74d65d832137e20e193c960802afba73b5d38sm        if (factory != null && manager != null) {
134cfd74d65d832137e20e193c960802afba73b5d38sm            float offsetX = mOffsetX;
135cfd74d65d832137e20e193c960802afba73b5d38sm            float offsetY = mOffsetY;
136cfd74d65d832137e20e193c960802afba73b5d38sm            boolean flip = false;
137cfd74d65d832137e20e193c960802afba73b5d38sm            if (parentObject.facingDirection.x < 0.0f) {
138cfd74d65d832137e20e193c960802afba73b5d38sm                offsetX = parentObject.width - mOffsetX;
139cfd74d65d832137e20e193c960802afba73b5d38sm                flip = true;
140cfd74d65d832137e20e193c960802afba73b5d38sm            }
141cfd74d65d832137e20e193c960802afba73b5d38sm
142cfd74d65d832137e20e193c960802afba73b5d38sm            if (parentObject.facingDirection.y < 0.0f) {
143cfd74d65d832137e20e193c960802afba73b5d38sm                offsetY = parentObject.height - mOffsetY;
144cfd74d65d832137e20e193c960802afba73b5d38sm            }
145cfd74d65d832137e20e193c960802afba73b5d38sm
146cfd74d65d832137e20e193c960802afba73b5d38sm            final float x = parentObject.getPosition().x + offsetX;
147cfd74d65d832137e20e193c960802afba73b5d38sm            final float y = parentObject.getPosition().y + offsetY;
148cfd74d65d832137e20e193c960802afba73b5d38sm            GameObject object = factory.spawn(mObjectTypeToSpawn, x, y, flip);
1499d4cc2572d37983607df38b0f4216ed76ac51814sm            if (object != null) {
1509d4cc2572d37983607df38b0f4216ed76ac51814sm	            mWorkingVector.set(1.0f, 1.0f);
1519d4cc2572d37983607df38b0f4216ed76ac51814sm	            if (mThetaError > 0.0f) {
1529d4cc2572d37983607df38b0f4216ed76ac51814sm	                final float angle = (float)(Math.random() * mThetaError * Math.PI * 2.0f);
1539d4cc2572d37983607df38b0f4216ed76ac51814sm	                mWorkingVector.x = (float)Math.sin(angle);
1549d4cc2572d37983607df38b0f4216ed76ac51814sm	                mWorkingVector.y = (float)Math.cos(angle);
1559d4cc2572d37983607df38b0f4216ed76ac51814sm	                if (Utils.close(mWorkingVector.length2(), 0.0f)) {
1569d4cc2572d37983607df38b0f4216ed76ac51814sm	                    mWorkingVector.set(1.0f, 1.0f);
1579d4cc2572d37983607df38b0f4216ed76ac51814sm	                }
1589d4cc2572d37983607df38b0f4216ed76ac51814sm	            }
1599d4cc2572d37983607df38b0f4216ed76ac51814sm	            mWorkingVector.x *= flip ? -mVelocityX : mVelocityX;
1609d4cc2572d37983607df38b0f4216ed76ac51814sm	            mWorkingVector.y *= mVelocityY;
1619d4cc2572d37983607df38b0f4216ed76ac51814sm
1629d4cc2572d37983607df38b0f4216ed76ac51814sm	            object.getVelocity().set(mWorkingVector);
1639d4cc2572d37983607df38b0f4216ed76ac51814sm	            object.getTargetVelocity().set(mWorkingVector);
1649d4cc2572d37983607df38b0f4216ed76ac51814sm	            // Center the projectile on the spawn point.
1659d4cc2572d37983607df38b0f4216ed76ac51814sm	            object.getPosition().x -= object.width / 2.0f;
1669d4cc2572d37983607df38b0f4216ed76ac51814sm	            object.getPosition().y -= object.height / 2.0f;
1679d4cc2572d37983607df38b0f4216ed76ac51814sm
1689d4cc2572d37983607df38b0f4216ed76ac51814sm
1699d4cc2572d37983607df38b0f4216ed76ac51814sm	            if (mTrackProjectiles) {
1709d4cc2572d37983607df38b0f4216ed76ac51814sm	                object.commitUpdates();
1719d4cc2572d37983607df38b0f4216ed76ac51814sm	                LifetimeComponent projectileLife = object.findByClass(LifetimeComponent.class);
1729d4cc2572d37983607df38b0f4216ed76ac51814sm	                if (projectileLife != null) {
1739d4cc2572d37983607df38b0f4216ed76ac51814sm	                    projectileLife.setTrackingSpawner(this);
1749d4cc2572d37983607df38b0f4216ed76ac51814sm	                    mTrackedProjectileCount++;
1759d4cc2572d37983607df38b0f4216ed76ac51814sm	                }
1769d4cc2572d37983607df38b0f4216ed76ac51814sm	            }
1779d4cc2572d37983607df38b0f4216ed76ac51814sm	            manager.add(object);
1789d4cc2572d37983607df38b0f4216ed76ac51814sm
1799d4cc2572d37983607df38b0f4216ed76ac51814sm	            if (mShootSound != null) {
1809d4cc2572d37983607df38b0f4216ed76ac51814sm	            	SoundSystem sound = sSystemRegistry.soundSystem;
1819d4cc2572d37983607df38b0f4216ed76ac51814sm	            	if (sound != null) {
1829d4cc2572d37983607df38b0f4216ed76ac51814sm	            		sound.play(mShootSound, false, SoundSystem.PRIORITY_NORMAL);
1839d4cc2572d37983607df38b0f4216ed76ac51814sm	            	}
1849d4cc2572d37983607df38b0f4216ed76ac51814sm	            }
185cfd74d65d832137e20e193c960802afba73b5d38sm            }
186cfd74d65d832137e20e193c960802afba73b5d38sm        }
187cfd74d65d832137e20e193c960802afba73b5d38sm
188cfd74d65d832137e20e193c960802afba73b5d38sm
189cfd74d65d832137e20e193c960802afba73b5d38sm    }
190cfd74d65d832137e20e193c960802afba73b5d38sm
191cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setObjectTypeToSpawn(GameObjectFactory.GameObjectType objectTypeToSpawn) {
192cfd74d65d832137e20e193c960802afba73b5d38sm        mObjectTypeToSpawn = objectTypeToSpawn;
193cfd74d65d832137e20e193c960802afba73b5d38sm    }
194cfd74d65d832137e20e193c960802afba73b5d38sm
195cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setOffsetX(float offsetX) {
196cfd74d65d832137e20e193c960802afba73b5d38sm        mOffsetX = offsetX;
197cfd74d65d832137e20e193c960802afba73b5d38sm    }
198cfd74d65d832137e20e193c960802afba73b5d38sm
199cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setOffsetY(float offsetY) {
200cfd74d65d832137e20e193c960802afba73b5d38sm        mOffsetY = offsetY;
201cfd74d65d832137e20e193c960802afba73b5d38sm    }
202cfd74d65d832137e20e193c960802afba73b5d38sm
203cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setVelocityX(float velocityX) {
204cfd74d65d832137e20e193c960802afba73b5d38sm        mVelocityX = velocityX;
205cfd74d65d832137e20e193c960802afba73b5d38sm    }
206cfd74d65d832137e20e193c960802afba73b5d38sm
207cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setVelocityY(float velocityY) {
208cfd74d65d832137e20e193c960802afba73b5d38sm        mVelocityY = velocityY;
209cfd74d65d832137e20e193c960802afba73b5d38sm    }
210cfd74d65d832137e20e193c960802afba73b5d38sm
211cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setRequiredAction(GameObject.ActionType requiredAction) {
212cfd74d65d832137e20e193c960802afba73b5d38sm        mRequiredAction = requiredAction;
213cfd74d65d832137e20e193c960802afba73b5d38sm    }
214cfd74d65d832137e20e193c960802afba73b5d38sm
215cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setDelayBetweenShots(float launchDelay) {
216cfd74d65d832137e20e193c960802afba73b5d38sm        mDelayBetweenShots = launchDelay;
217cfd74d65d832137e20e193c960802afba73b5d38sm    }
218cfd74d65d832137e20e193c960802afba73b5d38sm
219cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setDelayBetweenSets(float delayBetweenSets) {
220cfd74d65d832137e20e193c960802afba73b5d38sm        mDelayBetweenSets = delayBetweenSets;
221cfd74d65d832137e20e193c960802afba73b5d38sm    }
222cfd74d65d832137e20e193c960802afba73b5d38sm
223cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setDelayBeforeFirstSet(float delayBeforeFirstSet) {
224cfd74d65d832137e20e193c960802afba73b5d38sm        mDelayBeforeFirstSet = delayBeforeFirstSet;
225cfd74d65d832137e20e193c960802afba73b5d38sm    }
226cfd74d65d832137e20e193c960802afba73b5d38sm
227cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setShotsPerSet(int shotCount) {
228cfd74d65d832137e20e193c960802afba73b5d38sm        mProjectilesInSet = shotCount;
229cfd74d65d832137e20e193c960802afba73b5d38sm    }
230cfd74d65d832137e20e193c960802afba73b5d38sm
231cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setSetsPerActivation(int setCount) {
232cfd74d65d832137e20e193c960802afba73b5d38sm        mSetsPerActivation = setCount;
233cfd74d65d832137e20e193c960802afba73b5d38sm    }
234cfd74d65d832137e20e193c960802afba73b5d38sm
235cfd74d65d832137e20e193c960802afba73b5d38sm    public final void enableProjectileTracking(int max) {
236cfd74d65d832137e20e193c960802afba73b5d38sm        mMaxTrackedProjectiles = max;
237cfd74d65d832137e20e193c960802afba73b5d38sm        mTrackProjectiles = true;
238cfd74d65d832137e20e193c960802afba73b5d38sm    }
239cfd74d65d832137e20e193c960802afba73b5d38sm
2402b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm    public final void disableProjectileTracking() {
2412b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm        mMaxTrackedProjectiles = 0;
2422b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm        mTrackProjectiles = false;
2432b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm    }
2442b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm
245cfd74d65d832137e20e193c960802afba73b5d38sm    public final void trackedProjectileDestroyed() {
246cfd74d65d832137e20e193c960802afba73b5d38sm        assert mTrackProjectiles;
247cfd74d65d832137e20e193c960802afba73b5d38sm        if (mTrackedProjectileCount == mMaxTrackedProjectiles) {
248cfd74d65d832137e20e193c960802afba73b5d38sm            // Let's restart the set.
249cfd74d65d832137e20e193c960802afba73b5d38sm            mSetStartedTime = -1.0f;
250cfd74d65d832137e20e193c960802afba73b5d38sm            mSetCount = 0;
251cfd74d65d832137e20e193c960802afba73b5d38sm        }
252cfd74d65d832137e20e193c960802afba73b5d38sm        mTrackedProjectileCount--;
253cfd74d65d832137e20e193c960802afba73b5d38sm    }
254cfd74d65d832137e20e193c960802afba73b5d38sm
255cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setThetaError(float error) {
256cfd74d65d832137e20e193c960802afba73b5d38sm        mThetaError = error;
257cfd74d65d832137e20e193c960802afba73b5d38sm    }
258cfd74d65d832137e20e193c960802afba73b5d38sm
259cfd74d65d832137e20e193c960802afba73b5d38sm    public final void setShootSound(SoundSystem.Sound shoot) {
260cfd74d65d832137e20e193c960802afba73b5d38sm    	mShootSound = shoot;
261cfd74d65d832137e20e193c960802afba73b5d38sm    }
262cfd74d65d832137e20e193c960802afba73b5d38sm
263cfd74d65d832137e20e193c960802afba73b5d38sm}
264