1 /**
2  * nInvaders - a space invaders clone for ncurses
3  * Copyright (C) 2002-2003 Dettus
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18  *
19  * homepage: http://ninvaders.sourceforge.net
20  * mailto: ninvaders-devel@lists.sourceforge.net
21  *
22  */
23 
24 
25 #include "player.h"
26 #include "aliens.h"
27 #include "ufo.h"
28 #include "nInvaders.h"
29 
30 typedef struct Player Player;
31 
32 struct Player {
33 	int posX;	  // horizontal position of player
34 	int posY;	  // vertical position of player
35 	int speed;	  // 0: no movement; 1: one per turn; etc.
36 	int missileFired; // 0: missile not running; 1: missile running
37 	int missileX;	  // horizontal position of missile
38 	int missileY;	  // vertical position of missile
39 };
40 
41 Player player;
42 
43 /**
44  * initialize player attributes
45  */
playerReset()46 void playerReset()
47 {
48 	// if missile was fired clear that position
49 	if (player.missileFired == 1) {
50 		playerMissileClear(player.missileX, player.missileY);
51 	}
52 
53 	playerClear(player.posX, player.posY);	// clear old position of player
54 
55 	player.posY = PLAYERPOSY;	// set vertical Position
56 	player.posX = 0;		// set horizontal Position
57 	player.speed = 1;
58 	player.missileFired = 0;
59 	player.missileX=0;
60 	player.missileY=0;
61 
62 	playerDisplay(player.posX, player.posY);	// display new position of player
63 }
64 
65 
66 /**
67  * move player horizontally to position newPosX
68  */
playerMove(int newPosX)69 static void playerMove(int newPosX)
70 {
71 	playerClear(player.posX, player.posY);	 // clear sprite
72 	player.posX = newPosX;	 // make movement
73   	playerDisplay(player.posX, player.posY); // display sprite
74 }
75 
76 
77 /**
78  * move player left
79  */
playerMoveLeft()80 void playerMoveLeft()
81 {
82 	// check if space between player and border of screen is big enough
83 	if (player.posX > 0 + player.speed) {
84 		// desired movement is possible
85 		playerMove(player.posX - player.speed);
86 	} else {
87 		// space too small, move to left-most position
88 		playerMove(0);
89 	}
90 }
91 
92 
93 /**
94  * move player right
95  */
playerMoveRight()96 void playerMoveRight()
97 {
98 	// check if space between player and border of screen is big enough
99 	if (player.posX < SCREENWIDTH - PLAYERWIDTH - player.speed) {
100 		// desired movement is possible
101 		playerMove(player.posX + player.speed);
102 	} else {
103 		// space too small, move to right-most position
104 		playerMove(SCREENWIDTH - PLAYERWIDTH);
105 	}
106 }
107 
108 
109 /**
110  * toggle turbo mode on (if key is kept pressed)
111  */
playerTurboOn()112 void playerTurboOn()
113 {
114 	player.speed = 2;
115 }
116 
117 
118 /**
119  * toggle turbo mode off (if key is kept pressed)
120  */
playerTurboOff()121 void playerTurboOff()
122 {
123 	player.speed = 1;
124 }
125 
126 
127 /**
128  * player was hit by an alien shot
129  */
playerHitCheck(int hostileShotX,int hostileShotY)130 int playerHitCheck(int hostileShotX, int hostileShotY)
131 {
132 	int fPlayerWasHit = 0;
133 
134 	// if shot reached vertikal position of player
135 	if (hostileShotY == PLAYERPOSY) {
136 		// if shot hits player
137 		if (hostileShotX >= player.posX && hostileShotX <= player.posX + PLAYERWIDTH -1) {
138 			fPlayerWasHit = 1;		// set return value
139 		}
140 	}
141 
142 	return fPlayerWasHit;				// return if player was hit
143 }
144 
145 
146 /**
147  * Launch Missile
148  */
playerLaunchMissile()149 void playerLaunchMissile()
150 {
151 	// only launch missile if no other is on its way
152 	if (player.missileFired == 0) {
153 		player.missileFired = 1;	// missile is on its way
154 		player.missileX = player.posX + PLAYERWIDTH / 2;	// launched from the middle of player...
155 		player.missileY = PLAYERPOSY;	// ...at same horizontal position
156 	}
157 }
158 
159 
160 /**
161  * Reload Missile
162  */
playerReloadMissile()163 static void playerReloadMissile()
164 {
165 	player.missileFired = 0;	// no player missile flying
166 }
167 
168 
169 /**
170  * move player missile and do alien/bunker hit testing
171  * return value - 0: still some aliens left, 1: no aliens left
172  */
playerMoveMissile()173 int playerMoveMissile()
174 {
175 	int fNoAliensLeft = 0;	// return value
176 	int alienTypeHit = 0;
177 
178 	// only do movements if there is a missile to move
179 	if (player.missileFired == 1) {
180 
181 		playerMissileClear(player.missileX, player.missileY);		// clear old missile position
182 		playerDisplay(player.posX, player.posY); // todo: check if this can be removed later if missiled is fired,
183 						//the middle of player is cleared
184 		player.missileY--;						// move missile
185 
186 		// if missile out of battlefield
187 		if (player.missileY < 0) {
188 			playerReloadMissile();				// reload missile
189 		} else {
190 			playerMissileDisplay(player.missileX, player.missileY);	// display missile at new position
191 		}
192 
193 		// if missile hits an alien (TODO)
194 		alienTypeHit = aliensHitCheck(player.missileX, player.missileY);
195 		if (alienTypeHit != 0) {
196 
197 			doScoring(alienTypeHit);			// increase score
198 			playerReloadMissile();				// reload missile
199 
200 			aliensClear(aliens.posX, aliens.posY, aliens.right, aliens.bottom); // clear old posiiton of aliens
201 
202 			render();
203 			if (shipnum == 0) {
204 				fNoAliensLeft = 1;
205 			}
206 
207 			// speed of aliens
208 			weite = (shipnum + (skill_level * 10) - (level * 5) + 5) / 10;
209 			if (weite < 0) {
210 				weite = 0;
211 			}
212 
213 			playerMissileClear(player.missileX, player.missileY);	// clear old missile position
214 			aliensDisplay(aliens.posX, aliens.posY, aliens.right, aliens.bottom);  // display aliens
215 		}
216 
217 		// if missile hits a bunker
218 		if (bunkersHitCheck(player.missileX, player.missileY) == 1) {
219 			bunkersClearElement(player.missileX, player.missileY);	// clear element of bunker
220 			playerReloadMissile();				// reload player missile
221 		}
222 
223 		// if missile hits ufo
224 		if (ufoHitCheck(player.missileX, player.missileY) == 1) {
225 			doScoring(UFO_ALIEN_TYPE);
226 			playerReloadMissile();
227 		}
228 	}
229 
230 	return fNoAliensLeft;
231 
232 }
233 
234 /**
235  * let player explode
236  */
playerExplode()237 void playerExplode(){
238 	playerExplosionDisplay(player.posX, player.posY);
239 	playerDisplay(player.posX, player.posY);
240 }
241