2 Copyright © 2004 Parallel Realities
3 Copyright © 2007-2008 Kõvágó Zoltán <DirtY.iCE.hu@gmail.com>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
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.
14 See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "CCollision.h"
25 #include "CGameData.h"
26 #include "CGraphics.h"
29 #include "CObjective.h"
30 #include "gettext.hpp"
33 void addItem(int itemType
, const char *name
, int x
, int y
, const char *spriteName
, int health
, int value
, int flags
, bool randomMovement
)
35 Entity
*item
= new Entity();
40 item
->setSprites(graphics
.getSprite(spriteName
, true), graphics
.getSprite(spriteName
, true), graphics
.getSprite(spriteName
, true));
41 item
->health
= health
;
43 item
->flags
= ENT_INANIMATE
+ ENT_BOUNCES
+ ENT_COLLECTABLE
;
45 // raise items taller than the enemy
46 int x1
= x
>> BRICKSHIFT
;
47 int x2
= (x
+ item
->width
- 1) >> BRICKSHIFT
;
48 int y2
= (y
+ item
->height
- 1) >> BRICKSHIFT
;
49 if ((map
.isSolid(x1
, y2
)) || (map
.isSolid(x2
, y2
)))
51 item
->y
= (y2
* BRICKSIZE
) - item
->height
;
56 item
->setRandomVelocity();
59 item
->health
+= rand() % 120;
61 Math::addBit(&item
->flags
, flags
);
63 if (item
->id
== ITEM_MISC_INVISIBLE
)
65 if ((gameData
.completedWorld
) || (game
.skill
== 3))
67 item
->id
= ITEM_MISC_NOSHOW
;
74 void dropBossItems(int x
, int y
)
81 int r
= Math::rrand(ITEM_PISTOL
, ITEM_DOUBLECHERRY
);
83 if (player
.environment
== ENV_WATER
)
85 r
= Math::rrand(ITEM_CHERRY
, ITEM_DOUBLECHERRY
);
88 if ((rand() % 10) == 0)
90 r
= ITEM_TRIPLECHERRY
;
93 addItem(defItem
[r
].id
, defItem
[r
].name
, x
, y
, defItem
[r
].sprite
[0]->name
, 240, defItem
[r
].value
, ENT_DYING
, true);
96 void dropRandomItems(int x
, int y
)
98 int mapX
= x
>> BRICKSHIFT
;
99 int mapY
= y
>> BRICKSHIFT
;
101 if (map
.isSolid(mapX
, mapY
))
106 if (map
.isBossMission
)
112 int amount
= Math::rrand(1, 5);
113 int r
= Math::rrand(ITEM_POINTS
, ITEM_POINTS7
);
115 int cherryChance
= 10 + (10 * game
.skill
);
117 for (int i
= 0 ; i
< amount
; i
++)
119 if ((rand() % 8) == 0)
121 r
= Math::rrand(ITEM_PISTOL
, ITEM_SPREAD
);
124 if ((rand() % 13) == 0)
126 switch (rand() % cherryChance
)
129 r
= ITEM_TRIPLECHERRY
;
136 r
= ITEM_DOUBLECHERRY
;
144 addItem(defItem
[r
].id
, defItem
[r
].name
, x
, y
, defItem
[r
].sprite
[0]->name
, 240, defItem
[r
].value
, ENT_DYING
, true);
146 r
= Math::rrand(ITEM_POINTS
, ITEM_POINTS7
);
150 void dropHelperItems(int x
, int y
)
152 int amount
= Math::rrand(1, 5);
155 for (int i
= 0 ; i
< amount
; i
++)
157 r
= Math::rrand(ITEM_PISTOL
, ITEM_TRIPLECHERRY
);
159 addItem(defItem
[r
].id
, defItem
[r
].name
, x
, y
, defItem
[r
].sprite
[0]->name
, 240, defItem
[r
].value
, ENT_DYING
, true);
165 Entity
*item
= (Entity
*)map
.itemList
.getHead();
167 Objective
*objective
= (Objective
*)map
.objectiveList
.getHead();
169 while (objective
->next
!= NULL
)
171 objective
= (Objective
*)objective
->next
;
172 objective
->completed
= true;
173 objective
->currentValue
= objective
->targetValue
;
176 while (item
->next
!= NULL
)
178 item
= (Entity
*)item
->next
;
180 if (strcmp(item
->name
, "Reality Crystal") == 0)
184 Math::addBit(&item
->flags
, ENT_TELEPORTING
);
185 addTeleportParticles(item
->x
+ (item
->width
/ 2), item
->y
+ (item
->height
/ 2), 50, SND_TELEPORT3
);
192 We have to do this to avoid items being permanently lost.
193 To ensure we drop them in a safe place we put them in the player's
194 last check point position...
196 void dropCarriedItems()
198 Entity
*item
= (Entity
*)map
.itemList
.getHead();
200 while (item
->next
!= NULL
)
202 item
= (Entity
*)item
->next
;
204 if (item
->owner
!= &player
)
207 Math::removeBit(&item
->flags
, ENT_DYING
);
213 item
->x
= game
.checkPointX
+ Math::rrand(0, 6);
214 item
->y
= game
.checkPointY
;
215 item
->flags
= ENT_INANIMATE
+ ENT_BOUNCES
+ ENT_NOCOLLISIONS
;
219 void pickUpItem(Entity
*item
)
223 if (item
->flags
& ENT_DYING
)
225 game
.totalBonusesCollected
++;
227 else if (item
->id
>= ITEM_MISC
)
229 game
.currentMissionItemsCollected
++;
234 item
->flags
= ENT_WEIGHTLESS
+ ENT_DYING
+ ENT_NOCOLLISIONS
;
241 case ITEM_MACHINEGUN
:
245 player
.currentWeapon
= &weapon
[item
->id
];
246 game
.currentWeapon
= item
->id
;
247 audio
.playSound(SND_GETWEAPON
, CH_ITEM
);
256 game
.score
+= item
->value
;
257 audio
.playSound(SND_ITEM
, CH_ITEM
);
260 case ITEM_DOUBLECHERRY
:
261 case ITEM_TRIPLECHERRY
:
262 Math::limitInt(&(player
.health
+= item
->value
), 0, MAX_HEALTH
);
263 audio
.playSound(SND_GULP
+ (rand() % 2), CH_ITEM
);
266 item
->owner
= &player
;
267 case ITEM_MISC_NOSHOW
:
268 audio
.playSound(SND_ITEM
, CH_ITEM
);
272 if ((item
->id
< ITEM_POINTS
) || (item
->id
> ITEM_POINTS7
))
274 if (!map
.isBossMission
)
277 oh yeah, right... because "Picked up a Ancient Cog" is really good English, isn't it? It's almost
278 as bad as Medal of Honor: Frontline where it said "Picked up 3 Stick Grenade(s)"... Would it really
279 have taken that much effort to pass the item number to a function that worked out some basic grammer
280 for how many items had been picked up??! Yeah... and EA expect us to pay £45 for that! Probably the
281 worst bit about that game was that it was just fecking crap anyway!
283 std::string item_name
= item
->name
;
284 if (item_name
.find_first_of(_("aeiouAEIOU")) == 0)
285 engine
.setInfoMessage(_("Picked up an") + " " + _(item_name
), 0, INFO_NORMAL
);
287 engine
.setInfoMessage(_("Picked up a") + " " + _(item_name
), 0, INFO_NORMAL
);
290 checkObjectives(item
->name
, true);
294 bool carryingItem(const char *name
)
296 Entity
*item
= (Entity
*)map
.itemList
.getHead();
298 while (item
->next
!= NULL
)
300 item
= (Entity
*)item
->next
;
302 if (item
->owner
!= &player
)
305 if (strcmp(item
->name
, name
) == 0)
316 void showCarriedItems()
322 Entity
*item
= (Entity
*)map
.itemList
.getHead();
324 while (item
->next
!= NULL
)
326 item
= (Entity
*)item
->next
;
328 if (item
->owner
!= &player
)
331 x
+= (item
->width
+ 8);
337 item
= (Entity
*)map
.itemList
.getHead();
339 while (item
->next
!= NULL
)
341 item
= (Entity
*)item
->next
;
343 if (item
->owner
!= &player
)
346 graphics
.blit(item
->getFaceImage(), bx
+x
, by
+y
, graphics
.screen
, false);
348 x
+= (item
->width
+ 8);
352 graphics
.drawString(_("Not carrying anything"), bx
+320, by
+210, TXT_CENTERED
, graphics
.screen
);
357 Entity
*item
= (Entity
*)map
.itemList
.getHead();
358 Entity
*previous
= item
;
362 while (item
->next
!= NULL
)
366 item
= (Entity
*)item
->next
;
368 if (item
->id
== ITEM_MISC_INVISIBLE
)
373 x
= (int)(item
->x
- map
.offsetX
);
374 y
= (int)(item
->y
- map
.offsetY
);
378 if (item
->flags
& ENT_TELEPORTING
)
382 else if ((abs(x
) <= (graphics
.width
+ 160)) && (abs(y
) <= (graphics
.height
+ 120)) && (item
->owner
== item
))
385 if (!(item
->flags
& ENT_WEIGHTLESS
))
386 item
->applyGravity();
393 if ((item
->health
>= 60) || ((engine
.getFrameLoop() % 3) == 0))
395 graphics
.blit(item
->getFaceImage(), x
, y
, graphics
.screen
, false);
400 if ((player
.health
> 0) && (!(player
.flags
& ENT_TELEPORTING
)))
402 if (Collision::collision(&player
, item
))
404 if (item
->flags
& ENT_COLLECTABLE
)
412 if ((item
->health
<= 0) && (item
->owner
!= &player
))
414 map
.itemList
.remove(previous
, item
);
422 if (!engine
.loadData("data/defItems"))
423 graphics
.showErrorAndExit(_("Couldn't load item definitions file (%s)"), "data/defItems");
425 char *token
= strtok((char*)engine
.dataBuffer
, "\n");
434 if (strcmp(token
, "@EOF@") == 0)
437 sscanf(token
, "%d %*c %[^\"] %*c %s %d", &id
, name
, sprite
, &value
);
440 defItem
[id
].setName(name
);
441 defItem
[id
].setSprites(graphics
.getSprite(sprite
, true), graphics
.getSprite(sprite
, true), graphics
.getSprite(sprite
, true));
442 defItem
[id
].value
= value
;
444 token
= strtok(NULL
, "\n");