2 Copyright (C) 2004 Parallel Realities
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
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.
23 void addItem(int itemType, const char *name, int x, int y, const char *spriteName, int health, int value, int flags, bool randomMovement)
25 Entity *item = new Entity();
30 item->setSprites(graphics.getSprite(spriteName, true), graphics.getSprite(spriteName, true), graphics.getSprite(spriteName, true));
31 item->health = health;
33 item->flags = ENT_INANIMATE + ENT_BOUNCES + ENT_COLLECTABLE;
35 // raise items taller than the enemy
36 int x1 = x >> BRICKSHIFT;
37 int x2 = (x + item->width - 1) >> BRICKSHIFT;
38 int y2 = (y + item->height - 1) >> BRICKSHIFT;
39 if ((map.isSolid(x1, y2)) || (map.isSolid(x2, y2)))
41 item->y = (y2 * BRICKSIZE) - item->height;
46 item->setRandomVelocity();
49 item->health += Math::prand() % 120;
51 Math::addBit(&item->flags, flags);
53 if (item->id == ITEM_MISC_INVISIBLE)
55 if ((gameData.completedWorld) || (game.skill == 3))
57 item->id = ITEM_MISC_NOSHOW;
64 void dropBossItems(int x, int y)
66 if ((Math::prand() % 5) > 0)
71 int r = Math::rrand(ITEM_PISTOL, ITEM_DOUBLECHERRY);
73 if (player.environment == ENV_WATER)
75 r = Math::rrand(ITEM_CHERRY, ITEM_DOUBLECHERRY);
78 if ((Math::prand() % 10) == 0)
80 r = ITEM_TRIPLECHERRY;
83 addItem(defItem[r].id, defItem[r].name, x, y, defItem[r].sprite[0]->name, 240, defItem[r].value, ENT_DYING, true);
86 void dropRandomItems(int x, int y)
88 int mapX = x >> BRICKSHIFT;
89 int mapY = y >> BRICKSHIFT;
91 if (map.isSolid(mapX, mapY))
96 if (map.isBossMission)
102 int amount = Math::rrand(1, 5);
103 int r = Math::rrand(ITEM_POINTS, ITEM_POINTS7);
105 int cherryChance = 10 + (10 * game.skill);
107 for (int i = 0 ; i < amount ; i++)
109 if ((Math::prand() % 8) == 0)
111 r = Math::rrand(ITEM_PISTOL, ITEM_SPREAD);
114 if ((Math::prand() % 13) == 0)
116 switch (Math::prand() % cherryChance)
119 r = ITEM_TRIPLECHERRY;
126 r = ITEM_DOUBLECHERRY;
134 addItem(defItem[r].id, defItem[r].name, x, y, defItem[r].sprite[0]->name, 240, defItem[r].value, ENT_DYING, true);
136 r = Math::rrand(ITEM_POINTS, ITEM_POINTS7);
140 void dropHelperItems(int x, int y)
142 int amount = Math::rrand(1, 5);
145 for (int i = 0 ; i < amount ; i++)
147 r = Math::rrand(ITEM_PISTOL, ITEM_TRIPLECHERRY);
149 addItem(defItem[r].id, defItem[r].name, x, y, defItem[r].sprite[0]->name, 240, defItem[r].value, ENT_DYING, true);
155 Entity *item = (Entity*)map.itemList.getHead();
157 Objective *objective = (Objective*)map.objectiveList.getHead();
159 while (objective->next != NULL)
161 objective = (Objective*)objective->next;
162 objective->completed = true;
163 objective->currentValue = objective->targetValue;
166 while (item->next != NULL)
168 item = (Entity*)item->next;
170 if (strcmp(item->name, "Reality Crystal") == 0)
174 Math::addBit(&item->flags, ENT_TELEPORTING);
175 addTeleportParticles(item->x + (item->width / 2), item->y + (item->height / 2), 50, SND_TELEPORT3);
182 We have to do this to avoid items being permanently lost.
183 To ensure we drop them in a safe place we put them in the player's
184 last check point position...
186 void dropCarriedItems()
188 Entity *item = (Entity*)map.itemList.getHead();
190 while (item->next != NULL)
192 item = (Entity*)item->next;
194 if (item->owner != &player)
197 Math::removeBit(&item->flags, ENT_DYING);
203 item->x = game.checkPointX + Math::rrand(0, 6);
204 item->y = game.checkPointY;
205 item->flags = ENT_INANIMATE + ENT_BOUNCES + ENT_NOCOLLISIONS;
209 void pickUpItem(Entity *item)
213 if (item->flags & ENT_DYING)
215 game.totalBonusesCollected++;
217 else if (item->id >= ITEM_MISC)
219 game.currentMissionItemsCollected++;
224 item->flags = ENT_WEIGHTLESS + ENT_DYING + ENT_NOCOLLISIONS;
231 case ITEM_MACHINEGUN:
235 player.currentWeapon = &weapon[item->id];
236 game.currentWeapon = item->id;
237 audio.playSound(SND_GETWEAPON, CH_ITEM);
246 addPlayerScore(item->value);
247 audio.playSound(SND_ITEM, CH_ITEM);
250 case ITEM_DOUBLECHERRY:
251 case ITEM_TRIPLECHERRY:
252 Math::limitInt(&(player.health += item->value), 0, MAX_HEALTH);
253 audio.playSound(SND_GULP + (Math::prand() % 2), CH_ITEM);
256 item->owner = &player;
257 case ITEM_MISC_NOSHOW:
258 audio.playSound(SND_ITEM, CH_ITEM);
262 if ((item->id < ITEM_POINTS) || (item->id > ITEM_POINTS7))
265 oh yeah, right... because "Picked up a Ancient Cog" is really good English, isn't it? It's almost
266 as bad as Medal of Honor: Frontline where it said "Picked up 3 Stick Grenade(s)"... Would it really
267 have taken that much effort to pass the item number to a function that worked out some basic grammar
268 for how many items had been picked up??! Yeah... and EA expect us to pay �45 for that! Probably the
269 worst bit about that game was that it was just fecking crap anyway!
271 switch (item->name[0])
281 snprintf(string, sizeof string, _("Picked up an %s"), item->name);
284 snprintf(string, sizeof string, _("Picked up a %s"), item->name);
288 if (!map.isBossMission)
289 engine.setInfoMessage(string, 0, INFO_NORMAL);
291 checkObjectives(item->name, true);
293 if (strcmp(item->name, "LRTS") == 0)
295 presentPlayerMedal("LRTS_PART");
300 bool carryingItem(const char *name)
302 Entity *item = (Entity*)map.itemList.getHead();
304 while (item->next != NULL)
306 item = (Entity*)item->next;
308 if (item->owner != &player)
311 if (strcmp(item->name, name) == 0)
322 void showCarriedItems()
328 Entity *item = (Entity*)map.itemList.getHead();
330 while (item->next != NULL)
332 item = (Entity*)item->next;
334 if (item->owner != &player)
337 x += (item->width + 8);
343 item = (Entity*)map.itemList.getHead();
345 while (item->next != NULL)
347 item = (Entity*)item->next;
349 if (item->owner != &player)
352 graphics.blit(item->getFaceImage(), x, y, graphics.screen, false);
354 x += (item->width + 8);
358 graphics.drawString(_("Not carrying anything"), 320, 210, TXT_CENTERED, graphics.screen);
363 Entity *item = (Entity*)map.itemList.getHead();
364 Entity *previous = item;
368 while (item->next != NULL)
372 item = (Entity*)item->next;
374 if (item->id == ITEM_MISC_INVISIBLE)
379 x = (int)(item->x - engine.playerPosX);
380 y = (int)(item->y - engine.playerPosY);
384 if (item->flags & ENT_TELEPORTING)
388 else if ((abs(x) <= 800) && (abs(y) <= 600) && (item->owner == item))
391 if (!(item->flags & ENT_WEIGHTLESS))
392 item->applyGravity();
399 if ((item->health >= 60) || ((engine.getFrameLoop() % 3) == 0))
401 graphics.blit(item->getFaceImage(), x, y, graphics.screen, false);
406 if ((player.health > 0) && (!(player.flags & ENT_TELEPORTING)))
408 if (Collision::collision(&player, item))
410 if (item->flags & ENT_COLLECTABLE)
418 if ((item->health <= 0) && (item->owner != &player))
420 map.itemList.remove(previous, item);
428 if (!engine.loadData("data/defItems"))
429 graphics.showErrorAndExit("Couldn't load item definitions file (%s)", "data/defItems");
431 char *token = strtok((char*)engine.dataBuffer, "\n");
440 if (strcmp(token, "@EOF@") == 0)
443 sscanf(token, "%d %*c %[^\"] %*c %s %d", &id, name, sprite, &value);
446 defItem[id].setName(name);
447 defItem[id].setSprites(graphics.getSprite(sprite, true), graphics.getSprite(sprite, true), graphics.getSprite(sprite, true));
448 defItem[id].value = value;
450 token = strtok(NULL, "\n");