📄 collectable.cpp
字号:
/*Copyright (C) 2003 Parallel RealitiesThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/#include "collectable.h"/*Create a new collectable item based on supplied arguments.*/void addCollectable(float x, float y, int type, int value, int life){ if (type == P_ANYTHING) { type = P_CASH; int r = rand() % 9; switch (r) { case 0: type = P_PLASMA_AMMO; break; case 1: type = P_SHIELD; break; case 2: type = P_ROCKET; value /= 10; break; } } else if (type == P_WEAPONS) { type = P_PLASMA_RATE; int r = rand() % 61; if (r <= 19) type = P_PLASMA_DAMAGE; else if (r <= 39) type = P_PLASMA_SHOT; else if (r <= 59) type = P_PLASMA_RATE; else type = P_SUPER; } if (type == P_SUPER) value = 1; /* Cash is rare on interceptions. Stops people from point leeching(!) */ if ((currentGame.area == MAX_MISSIONS - 1) && (type == P_CASH)) { if (rand() % 10 > 0) return; } if (value == 0) return; // don't bother! // If the player has a charge cannon or a laser cannon, don't give them // rockets. Causes problems otherwise :) if (type == P_ROCKET) { if ((player.weaponType[1] == W_CHARGER) || (player.weaponType[1] == W_LASER)) { type = P_CASH; } } collectables *collectable = new collectables; collectable->next = NULL; collectable->active = 1; collectable->x = x; collectable->y = y; collectable->dx = Math::rrand(-100, 100); if (collectable->dx != 0) collectable->dx /= 100; collectable->dy = Math::rrand(-100, 100); if (collectable->dy != 0) collectable->dy /= 100; collectable->type = type; collectable->value = value; collectable->life = life; switch(type) { case P_CASH: collectable->image = graphics.shape[24]; break; case P_ROCKET: collectable->image = graphics.shape[49]; break; case P_PLASMA_AMMO: collectable->image = graphics.shape[25]; break; case P_SHIELD: collectable->image = graphics.shape[26]; break; case P_PLASMA_SHOT: collectable->image = graphics.shape[27]; break; case P_PLASMA_RATE: collectable->image = graphics.shape[28]; break; case P_PLASMA_DAMAGE: collectable->image = graphics.shape[29]; break; case P_CARGO: collectable->image = graphics.shape[32]; break; case P_SUPER: collectable->image = graphics.shape[50]; break; case P_MINE: collectable->image = graphics.shape[31]; break; case P_SLAVES: case P_ESCAPEPOD: collectable->image = graphics.shape[45]; break; case P_ORE: collectable->image = graphics.shape[46 + rand() % 3]; break; } engine.collectableTail->next = collectable; engine.collectableTail = collectable;}void explodeMine(collectables *collectable){ if ((collectable->x >= 0) && (collectable->x <= 800) && (collectable->y >= 0) && (collectable->y <= 600)) playSound(SFX_EXPLOSION); for (int i = 0 ; i < 10 ; i++) addExplosion(collectable->x + rand() % 25 - rand() % 25, collectable->y + rand() % 25 - rand() % 25, E_BIG_EXPLOSION); if (checkPlayerShockDamage(collectable->x, collectable->y, 50)) setInfoLine("Warning: Mine damage to shield!!", FONT_RED);}void checkMineBulletCollisions(object *bullet){ collectables *collectable = engine.collectableHead; collectables *prevCollectable = engine.collectableHead; engine.collectableTail = engine.collectableHead; while (collectable->next != NULL) { collectable = collectable->next; if (collectable->type == P_MINE) { if (Collision::collision(collectable, bullet)) { collectable->active = 0; if (bullet->id != WT_CHARGER) { bullet->active = 0; } else { bullet->shield--; if (bullet->shield < 0) bullet->active = 0; } if (bullet->owner == &player) { currentGame.minesKilled++; currentGame.hits++; } } } if (collectable->active == 1) { prevCollectable = collectable; engine.collectableTail = collectable; } else { explodeMine(collectable); prevCollectable->next = collectable->next; delete collectable; collectable = prevCollectable; } }}/*Loops through the currently active collectables (in a linked list). The collectablewill travel in the direction that was defined when it was made. Its life will decreasedwhilst it remains active. It will be removed if the player touches it or if its lifereaches 0. When it is picked up, depending on the type of collectable it is, mission requirementswill be updated. Information will be displayed and appropriate player variables altered.*/void doCollectables(){ collectables *collectable = engine.collectableHead; collectables *prevCollectable = engine.collectableHead; engine.collectableTail = engine.collectableHead; while (collectable->next != NULL) { collectable = collectable->next; if (collectable->active == 1) { if ((collectable->x + collectable->image->w > 0) && (collectable->x < 800) && (collectable->y + collectable->image->h > 0) && (collectable->y < 600)) graphics.blit(collectable->image, (int)collectable->x, (int)collectable->y); collectable->x += engine.ssx; collectable->y += engine.ssy; collectable->x += collectable->dx; collectable->y += collectable->dy; collectable->life--; if ((player.shield > 0) && (Collision::collision(collectable, &player))) { char temp[40]; switch(collectable->type) { case P_CASH: currentGame.cash += collectable->value; currentGame.cashEarned += collectable->value; sprintf(temp, "Got $%d ", collectable->value); break; case P_ROCKET: Math::limitChar(&(player.ammo[1] += collectable->value), 0, currentGame.maxRocketAmmo); if (player.ammo[1] == currentGame.maxRocketAmmo) sprintf(temp, "Rocket Ammo at Maximum"); else { if (collectable->value > 1) sprintf(temp, "Got %d rockets", collectable->value); else sprintf(temp, "Got a rocket"); } currentGame.rocketPickups += collectable->value; break; case P_SHIELD: Math::limitInt(&(player.shield += 10), 0, player.maxShield); currentGame.shieldPickups ++; sprintf(temp, "Restored 10 shield points"); break; case P_PLASMA_RATE: Math::limitChar(&(weapon[1].reload[0] -= 2), currentGame.maxPlasmaRate, 15); player.weaponType[0] = 1; if (player.ammo[0] < 50) player.ammo[0] = 50; Math::limitChar(&(player.ammo[0]), 0, currentGame.maxPlasmaAmmo); if (weapon[1].reload[0] == currentGame.maxPlasmaRate) sprintf(temp, "Firing Rate at Maximum"); else sprintf(temp, "Firing rate increased"); currentGame.powerups++; break; case P_PLASMA_SHOT: Math::limitChar(&(weapon[1].ammo[0] += 1), 1, currentGame.maxPlasmaOutput); if (player.ammo[0] < 50) player.ammo[0] = 50; Math::limitChar(&(player.ammo[0]), 0, currentGame.maxPlasmaAmmo); if (weapon[1].ammo[0] == currentGame.maxPlasmaOutput) sprintf(temp, "Plasma output at Maximum"); else sprintf(temp, "Plasma output increased"); player.weaponType[0] = 1; currentGame.powerups++; break; case P_PLASMA_DAMAGE: Math::limitChar(&(weapon[1].damage += 1), 1, currentGame.maxPlasmaDamage); if (player.ammo[0] < 50) player.ammo[0] = 50; Math::limitChar(&(player.ammo[0]), 0, currentGame.maxPlasmaAmmo); if (weapon[1].damage == currentGame.maxPlasmaDamage) sprintf(temp, "Plasma damage at Maximum"); else sprintf(temp, "Plasma damage increased"); player.weaponType[0] = 1; currentGame.powerups++; break; case P_SUPER: weapon[1].ammo[0] = 5; weapon[1].damage = 5; weapon[1].reload[0] = 7; if (weapon[1].flags & WF_STRAIGHT) weapon[1].flags -= WF_STRAIGHT; if (weapon[1].flags & WF_THIN_SPREAD) weapon[1].flags -= WF_THIN_SPREAD; if (!(weapon[1].flags & WF_WIDE_SPREAD)) weapon[1].flags += WF_WIDE_SPREAD; sprintf(temp, "Picked up a Super Charge!!"); if (player.ammo[0] < 50) player.ammo[0] = 50; player.weaponType[0] = 1; currentGame.powerups++; break; case P_PLASMA_AMMO: Math::limitChar(&(player.ammo[0] += collectable->value), 0, currentGame.maxPlasmaAmmo); if (player.ammo[0] == currentGame.maxPlasmaAmmo) sprintf(temp, "Plasma cells at Maximum"); else { if (collectable->value > 1) { sprintf(temp, "Got %d plasma cells", collectable->value); } else { sprintf(temp, "Got a plasma cell"); if ((rand() % 25) == 0) sprintf(temp, "Got one whole plasma cell (wahoo!)"); } } player.weaponType[0] = 1; currentGame.cellPickups += collectable->value; break; case P_CARGO: strcpy(temp, "Picked up some Cargo"); currentGame.cargoPickups++; break; case P_SLAVES: sprintf(temp, "Rescued %d slaves", collectable->value); currentGame.slavesRescued += collectable->value; break; case P_ESCAPEPOD: sprintf(temp, "Picked up an Escape Pod"); break; case P_ORE: sprintf(temp, "Picked up some Ore"); break; } updateMissionRequirements(M_COLLECT, collectable->type, collectable->value); collectable->active = 0; if (collectable->type != P_MINE) { setInfoLine(temp, FONT_WHITE); if (collectable->type == P_SHIELD) playSound(SFX_SHIELDUP); else playSound(SFX_PICKUP); } } // stop people from exploiting a weapon check condition if (player.ammo[0] == 0) { player.weaponType[0] = 0; weapon[1] = weapon[0]; // reset to weapon 1 defaults } } if (collectable->life < 1) { collectable->active = 0; if ((collectable->type == P_CARGO) || (collectable->type == P_ESCAPEPOD) || (collectable->type == P_SLAVES)) updateMissionRequirements(M_PROTECT_PICKUP, collectable->type, 1); } if (collectable->active == 1) { prevCollectable = collectable; engine.collectableTail = collectable; } else { if (collectable->type == P_MINE) explodeMine(collectable); prevCollectable->next = collectable->next; delete collectable; collectable = prevCollectable; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -