home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////
- //
- // Snipe2d ludum dare 48h compo entry
- //
- // Jari Komppa aka Sol
- // http://iki.fi/sol
- //
- ///////////////////////////////////////////////
- // License
- ///////////////////////////////////////////////
- //
- // This software is provided 'as-is', without any express or implied
- // warranty. In no event will the authors be held liable for any damages
- // arising from the use of this software.
- //
- // Permission is granted to anyone to use this software for any purpose,
- // including commercial applications, and to alter it and redistribute it
- // freely, subject to the following restrictions:
- //
- // 1. The origin of this software must not be misrepresented; you must not
- // claim that you wrote the original software. If you use this software
- // in a product, an acknowledgment in the product documentation would be
- // appreciated but is not required.
- // 2. Altered source versions must be plainly marked as such, and must not be
- // misrepresented as being the original software.
- // 3. This notice may not be removed or altered from any source distribution.
- //
- // (eg. same as ZLIB license)
- //
- ///////////////////////////////////////////////
- //
- // Houses are taken from a satellite picture of glasgow.
- //
- // The sources are a mess, as I didn't even try to do anything
- // really organized here.. and hey, it's a 48h compo =)
- //
- #include "snipe2d.h"
-
- //#define DRAW_DEBUGLINES
-
- int route(int x1,int y1,int x2, int y2)
- {
- if ( SDL_LockSurface(gAIMap) < 0 )
- return 0;
-
- char *t = (char*)gAIMap->pixels;
-
- int x, y;
- int xinc;
- int yinc;
- int len,i;
-
- len = abs(x2 - x1);
- i = abs(y2 - y1);
- if (i > len) len = i;
- if (len == 0) return 0;
-
- xinc = ((x2 - x1) << SHIFT_AMOUNT) / len;
- yinc = ((y2 - y1) << SHIFT_AMOUNT) / len;
-
- x = (x1 << SHIFT_AMOUNT) + ((1 << SHIFT_AMOUNT) / 2);
- y = (y1 << SHIFT_AMOUNT) + ((1 << SHIFT_AMOUNT) / 2);
-
- for (i = 1; i <= len; i++)
- {
- if ((t[(x >> SHIFT_AMOUNT) +
- (y >> SHIFT_AMOUNT) *
- (gAIMap->pitch)] & 0xff) == 1)
- return 0;
- x = x + xinc;
- y = y + yinc;
- }
-
- SDL_UnlockSurface(gAIMap);
- return len;
- }
-
- void drawLine(SDL_Surface * aTarget, int x1,int y1,int x2, int y2, int clr)
- {
- if ( SDL_LockSurface(aTarget) < 0 )
- return;
-
- short *t = (short*)aTarget->pixels;
-
- int x, y;
- int xinc;
- int yinc;
- int len,i;
-
- len = abs(x2 - x1);
- i = abs(y2 - y1);
- if (i > len) len = i;
- if (len == 0) return;
-
- xinc = ((x2 - x1) << SHIFT_AMOUNT) / len;
- yinc = ((y2 - y1) << SHIFT_AMOUNT) / len;
-
- x = (x1 << SHIFT_AMOUNT) + ((1 << SHIFT_AMOUNT) / 2);
- y = (y1 << SHIFT_AMOUNT) + ((1 << SHIFT_AMOUNT) / 2);
-
- for (i = 1; i <= len; i++)
- {
- t[(x >> SHIFT_AMOUNT) +
- (y >> SHIFT_AMOUNT) *
- (aTarget->pitch / 2)] = clr;
-
- x = x + xinc;
- y = y + yinc;
- }
-
- SDL_UnlockSurface(aTarget);
- }
-
-
-
- void precalc_ai()
- {
- if ( SDL_LockSurface(gAIMap) < 0 )
- return;
- // Count waypoints
-
- gWaypointCount = 0;
- gSpawnpointCount = 0;
- int i,j;
- for (j = 0; j < 600; j++)
- {
- int ofs = j * gAIMap->pitch;
- for (i = 0; i < 800; i++)
- {
- switch (*((char*)gAIMap->pixels + ofs) & 0xff)
- {
- case 0: // street
- break;
- case 1: // house
- break;
- case 2: // bad guys spawn points
- gSpawnpointCount++;
- gBadGuySpawnCount++;
- break;
- case 3: // VIP spawn points
- gSpawnpointCount++;
- gVIPSpawnCount++;
- break;
- case 4: // waypoints
- gWaypointCount++;
- break;
- case 5: // neutral spawn points
- gSpawnpointCount++;
- gPedestrianSpawnCount++;
- break;
- }
- ofs++;
- }
- }
- gSpawnpoint = new SPAWNPOINT[gSpawnpointCount];
- gWaypoint = new WAYPOINT[gWaypointCount];
- int waypoint = 0;
- int spawnpoint = 0;
- for (j = 0; j < 600; j++)
- {
- int ofs = j * gAIMap->pitch;
- for (i = 0; i < 800; i++)
- {
- switch (*((char*)gAIMap->pixels + ofs) & 0xff)
- {
- case 0: // street
- break;
- case 1: // house
- break;
- case 2: // bad guys spawn points
- gSpawnpoint[spawnpoint].mX = i;
- gSpawnpoint[spawnpoint].mY = j;
- gSpawnpoint[spawnpoint].mType = CHAR_BADGUY;
- spawnpoint++;
- break;
- case 3: // VIP spawn points
- gSpawnpoint[spawnpoint].mX = i;
- gSpawnpoint[spawnpoint].mY = j;
- gSpawnpoint[spawnpoint].mType = CHAR_VIP;
- spawnpoint++;
- break;
- case 4: // waypoints
- gWaypoint[waypoint].mX = i;
- gWaypoint[waypoint].mY = j;
- waypoint++;
- break;
- case 5: // neutral spawn points
- gSpawnpoint[spawnpoint].mX = i;
- gSpawnpoint[spawnpoint].mY = j;
- gSpawnpoint[spawnpoint].mType = 2;
- spawnpoint++;
- break;
- }
- ofs++;
- }
- }
-
- // Find and store connections
-
- for (i = 0; i < gWaypointCount; i++)
- {
- waypoint = 0;
- for (j = 0; j < gWaypointCount; j++)
- if (route(gWaypoint[i].mX, gWaypoint[i].mY, gWaypoint[j].mX, gWaypoint[j].mY))
- waypoint++;
-
- gWaypoint[i].mConnections = waypoint;
- gWaypoint[i].mConnection = new int[waypoint];
-
- waypoint = 0;
- for (j = 0; j < gWaypointCount; j++)
- if (route(gWaypoint[i].mX, gWaypoint[i].mY, gWaypoint[j].mX, gWaypoint[j].mY))
- {
- #ifdef DRAW_DEBUGLINES
- drawLine(gMap, gWaypoint[i].mX, gWaypoint[i].mY, gWaypoint[j].mX, gWaypoint[j].mY, 0xffff);
- #endif
- gWaypoint[i].mConnection[waypoint] = j;
- waypoint++;
- }
- }
-
- for (i = 0; i < gSpawnpointCount; i++)
- {
- int spawndist = 10000;
- for (j = 0; j < gWaypointCount; j++)
- {
- int newdist = route(gSpawnpoint[i].mX, gSpawnpoint[i].mY, gWaypoint[j].mX, gWaypoint[j].mY);
- if (newdist && newdist < spawndist)
- {
- spawndist = newdist;
- gSpawnpoint[i].mClosestWaypoint = j;
- }
- }
- }
- #ifdef DRAW_DEBUGLINES
- for (i = 0; i < gSpawnpointCount; i++)
- drawLine(gMap, gSpawnpoint[i].mX, gSpawnpoint[i].mY, gWaypoint[gSpawnpoint[i].mClosestWaypoint].mX, gWaypoint[gSpawnpoint[i].mClosestWaypoint].mY, 0xf << (gSpawnpoint[i].mType * 6));
- #endif
-
- SDL_UnlockSurface(gAIMap);
- }
-
- float distance(float aX1, float aY1, float aX2, float aY2)
- {
- return (float)sqrt((aX2 - aX1) * (aX2 - aX1) + (aY2 - aY1) * (aY2 - aY1));
- }
-
- float distance(int aWaypoint, float aX, float aY)
- {
- return distance((float)gWaypoint[aWaypoint].mX, (float)gWaypoint[aWaypoint].mY, aX, aY);
- }
-
- float distance(int aWaypoint1, int aWaypoint2)
- {
- return distance((float)gWaypoint[aWaypoint1].mX, (float)gWaypoint[aWaypoint1].mY, (float)gWaypoint[aWaypoint2].mX, (float)gWaypoint[aWaypoint2].mY);
- }
-
- void validateWaypoint(CHARACTER &c, int &next)
- {
- int valid = 0;
- int candidate = next;
- while (!valid)
- {
- valid = 1;
- int i;
- for (i = 0; i < 7; i++)
- if (c.mLastWaypoints[i] == gWaypoint[c.mNextWaypoint].mConnection[candidate])
- valid = 0;
- if (!valid)
- {
- candidate++;
- if (candidate >= gWaypoint[c.mNextWaypoint].mConnections)
- candidate = 0;
- if (candidate == next) // no valid waypoints
- return;
- }
- }
- next = candidate;
- }
-
- void handle_ai(CHARACTER &c)
- {
- // is this AI inactive?
- if (c.mType == -1)
- return;
-
- // Kludge: hit position sign
- if (c.mType == 3 || c.mType == 4)
- {
-
- c.mTTL--;
- if (c.mTTL < 0)
- c.mType = -1;
- return;
- }
-
- // Pedestrian AI
- // Pedestrians just walk around, and try not to walk
- // in circles.
- if (c.mType == 2)
- {
- float dist = distance(c.mNextWaypoint, c.mX, c.mY);
- // Have we arrived at waypoint?
- if (dist < 4)
- {
-
- #ifdef RECYCLE_PEDESTRIANS
- // Reduce time to live..
- c.mTTL--;
- if (c.mTTL <= 0)
- {
- // Wipe and recycle..
- spa(2);
- c.mType = -1;
- return;
- }
- #endif
- // Store current waypoint in old waypoints list..
- c.mLastWaypoints[c.mLastWaypoint] = c.mNextWaypoint;
- c.mLastWaypoint++;
- if (c.mLastWaypoint >= 7)
- c.mLastWaypoint = 0;
- // Find a new waypoint
-
- int next = rand() % gWaypoint[c.mNextWaypoint].mConnections;
- validateWaypoint(c, next);
- c.mNextWaypoint = gWaypoint[c.mNextWaypoint].mConnection[next];
- // Calculate vector..
- dist = distance(c.mNextWaypoint, c.mX, c.mY);
- c.mXi = ((gWaypoint[c.mNextWaypoint].mX - c.mX) / dist) * c.mSpeed;
- c.mYi = ((gWaypoint[c.mNextWaypoint].mY - c.mY) / dist) * c.mSpeed;
-
- }
- }
-
- // VIP AI
- // VIPs try to find their way to their exit point.
- if (c.mType == CHAR_VIP)
- {
- if (c.mNextWaypoint == -1)
- {
- // Have we arrived home?
- float dist = distance((float)gSpawnpoint[c.mTarget].mX, (float)gSpawnpoint[c.mTarget].mY, c.mX, c.mY);
- if (dist < 4)
- {
- // arrived safely.
- c.mType = -1;
- gScore += 5000;
- gVIPCount--;
- gVIPsGottenToSafety++;
- }
- }
- else
- {
- float dist = distance(c.mNextWaypoint, c.mX, c.mY);
- // Have we arrived at waypoint?
- if (dist < 4)
- {
- // Store current waypoint in old waypoints list..
- c.mLastWaypoints[c.mLastWaypoint] = c.mNextWaypoint;
- c.mLastWaypoint++;
- if (c.mLastWaypoint >= 7)
- c.mLastWaypoint = 0;
- // Find a new waypoint
-
- // Can we get to the final destination from here?
- if (route((int)c.mX, (int)c.mY, gSpawnpoint[c.mTarget].mX, gSpawnpoint[c.mTarget].mY))
- {
- // Yep, calculate vector to home
- c.mNextWaypoint = -1;
- dist = distance((float)gSpawnpoint[c.mTarget].mX, (float)gSpawnpoint[c.mTarget].mY, c.mX, c.mY);
- c.mXi = ((gSpawnpoint[c.mTarget].mX - c.mX) / dist) * c.mSpeed;
- c.mYi = ((gSpawnpoint[c.mTarget].mY - c.mY) / dist) * c.mSpeed;
- }
- else
- {
- // Nope, try to figure out the closest waypoint to target that's connected from here
- int next = 0;
- dist = distance(gWaypoint[c.mNextWaypoint].mConnection[0], (float)gSpawnpoint[c.mTarget].mX, (float)gSpawnpoint[c.mTarget].mY);
- int i;
- for (i = 1; i < gWaypoint[c.mNextWaypoint].mConnections; i++)
- {
- float newdist = distance(gWaypoint[c.mNextWaypoint].mConnection[i], (float)gSpawnpoint[c.mTarget].mX, (float)gSpawnpoint[c.mTarget].mY);
- if (newdist < dist)
- {
- dist = newdist;
- next = i;
- }
- }
- // Make sure we're not walking in circles:
- validateWaypoint(c, next);
- c.mNextWaypoint = gWaypoint[c.mNextWaypoint].mConnection[next];
- // Calculate vector..
- dist = distance(c.mNextWaypoint, c.mX, c.mY);
- c.mXi = ((gWaypoint[c.mNextWaypoint].mX - c.mX) / dist) * c.mSpeed;
- c.mYi = ((gWaypoint[c.mNextWaypoint].mY - c.mY) / dist) * c.mSpeed;
- }
-
- }
- }
- }
-
- // Bad guy AI
- // Bad guys try to find their way to a VIP.
- if (c.mType == CHAR_BADGUY)
- {
- if (c.mTarget != -1 && gCharacter[c.mTarget].mType != 1)
- {
- // Lost target
- c.mTarget = -1;
- }
-
- if (c.mTarget == -1) // Bad guy without a target
- {
- if (gVIPCount == 0)
- {
- // No VIPs to pester, walk around randomly
-
- if (c.mNextWaypoint == -1)
- {
- // We were walking towards a VIP last time, so
- // we'll need to find the closest waypoint and walk to that.
- c.mNextWaypoint = 0;
- int i;
- float dist = distance(0, c.mX, c.mY);
- for (i = 1; i < gWaypointCount; i++)
- {
- float newdist = distance(i, c.mX, c.mY);
- if (newdist < dist && route(gWaypoint[i].mX, gWaypoint[i].mY, (int)c.mX, (int)c.mY))
- {
- dist = newdist;
- c.mNextWaypoint = i;
- }
- }
- // Calculate vector towards the closest waypoint
- c.mXi = ((gWaypoint[c.mNextWaypoint].mX - c.mX) / dist) * c.mSpeed;
- c.mYi = ((gWaypoint[c.mNextWaypoint].mY - c.mY) / dist) * c.mSpeed;
- }
- else // just walk towards the next waypoint normally
- {
- float dist = distance(c.mNextWaypoint, c.mX, c.mY);
- // Have we arrived at waypoint?
- if (dist < 4)
- {
- int next = rand() % gWaypoint[c.mNextWaypoint].mConnections;
- // Bad guys have nowhere to go, so they might
- // as well walk in circles.. (hence, no validatewaypoint)
- c.mNextWaypoint = gWaypoint[c.mNextWaypoint].mConnection[next];
- // Calculate vector..
- dist = distance(c.mNextWaypoint, c.mX, c.mY);
- c.mXi = ((gWaypoint[c.mNextWaypoint].mX - c.mX) / dist) * c.mSpeed;
- c.mYi = ((gWaypoint[c.mNextWaypoint].mY - c.mY) / dist) * c.mSpeed;
- }
- }
- }
- else // target a VIP
- {
- int t = rand() % gVIPCount;
- int i = 0;
- while (t > 0 || gCharacter[i].mType != CHAR_VIP)
- {
- if (gCharacter[i].mType == CHAR_VIP)
- t--;
- i++;
- }
- c.mTarget = i;
- // Avoid sudden death:
- if (distance(c.mX, c.mY, gCharacter[c.mTarget].mX, gCharacter[c.mTarget].mY) < 20)
- {
- c.mTarget = -1;
- if (c.mNextWaypoint == -1)
- {
- c.mXi = 0;
- c.mYi = 0;
- }
- }
- }
- }
-
- int nolineofsight = 1;
-
- // Do we have line of sight to the VIP?
- if (route((int)c.mX, (int)c.mY, (int)gCharacter[c.mTarget].mX, (int)gCharacter[c.mTarget].mY))
- {
- nolineofsight = 0;
- // Calculate new vector to it
- float dist = distance(gCharacter[c.mTarget].mX, gCharacter[c.mTarget].mY, c.mX, c.mY);
- c.mXi = ((gCharacter[c.mTarget].mX - c.mX) / dist) * c.mSpeed;
- c.mYi = ((gCharacter[c.mTarget].mY - c.mY) / dist) * c.mSpeed;
- c.mNextWaypoint = -1;
- }
-
-
- if (c.mNextWaypoint == -1)
- {
- // Caught up with the VIP?
- float dist = distance((float)gCharacter[c.mTarget].mX, (float)gCharacter[c.mTarget].mY, c.mX, c.mY);
- if (dist < 3)
- {
- // arrived safely.
- c.mType = -1;
- gScore -= 10000; // +game over
- gVIPCount--;
- gBadGuyCount--;
- gCharacter[c.mTarget].mType = -1;
- #ifdef DISPLAY_GAMEOVER_SCREEN
- gameoverscreen(2);
- return;
- #endif
- }
- else
- {
- if (nolineofsight)
- {
- // Lost the VIP. Find closest accessible waypoint.
- c.mNextWaypoint = 0;
- int i;
- float dist = distance(0, gCharacter[c.mTarget].mX, gCharacter[c.mTarget].mY);
- for (i = 1; i < gWaypointCount; i++)
- {
- float newdist = distance(i, gCharacter[c.mTarget].mX, gCharacter[c.mTarget].mY);
- if (newdist < dist && route(gWaypoint[i].mX, gWaypoint[i].mY, (int)c.mX, (int)c.mY))
- {
- dist = newdist;
- c.mNextWaypoint = i;
- }
- }
- // Calculate vector towards the closest waypoint
- dist = distance(c.mNextWaypoint, c.mX, c.mY);
- c.mXi = ((gWaypoint[c.mNextWaypoint].mX - c.mX) / dist) * c.mSpeed;
- c.mYi = ((gWaypoint[c.mNextWaypoint].mY - c.mY) / dist) * c.mSpeed;
- }
- }
- }
- else
- {
- float dist = distance(c.mNextWaypoint, c.mX, c.mY);
- // Have we arrived at waypoint?
- if (dist < 4)
- {
- // Find a new waypoint
-
- if (nolineofsight)
- {
- // Can't see the VIP, try to figure out the closest waypoint to target that's connected from here
- int next = 0;
- dist = distance(gWaypoint[c.mNextWaypoint].mConnection[0], gCharacter[c.mTarget].mX, gCharacter[c.mTarget].mY);
- int i;
- for (i = 1; i < gWaypoint[c.mNextWaypoint].mConnections; i++)
- {
- float newdist = distance(gWaypoint[c.mNextWaypoint].mConnection[i], gCharacter[c.mTarget].mX, gCharacter[c.mTarget].mY);
- if (newdist < dist)
- {
- dist = newdist;
- next = i;
- }
- }
- // Note: bad guys MAY run in circles.
- c.mNextWaypoint = gWaypoint[c.mNextWaypoint].mConnection[next];
- // Calculate vector..
- dist = distance(c.mNextWaypoint, c.mX, c.mY);
- c.mXi = ((gWaypoint[c.mNextWaypoint].mX - c.mX) / dist) * c.mSpeed;
- c.mYi = ((gWaypoint[c.mNextWaypoint].mY - c.mY) / dist) * c.mSpeed;
- }
-
- }
- }
- }
-
-
- // Make 'em walk
- c.mX += c.mXi;
- c.mY += c.mYi;
- }
-
- int findspawnpoint(int aIndex, int aType)
- {
- int i, j;
- j = 0;
- i = 0;
- while (i < gSpawnpointCount)
- {
- if (gSpawnpoint[i].mType == aType)
- j++;
- if (j > aIndex)
- return i;
- i++;
- }
- return i;
- }
-
- int spawn_ai(int aType)
- {
-
- // find empty slot
- int slot = 0;
- while (slot < gCharacterCount && gCharacter[slot].mType != -1) slot++;
- gCharacter[slot].mType = -1; // Overwrite the last slot if all slots were in use
- gCharacter[slot].mLastWaypoint = 0;
- int i;
- for (i = 0; i < 7; i++)
- gCharacter[slot].mLastWaypoints[i] = -1;
-
- if (aType == CHAR_BADGUY)
- {
- gBadGuyCount++;
- // spawn a bad guy
- int spawnpoint = 0;
- int i = rand() % gBadGuySpawnCount;
- spawnpoint = findspawnpoint(i, CHAR_BADGUY);
-
- gCharacter[slot].mType = CHAR_BADGUY;
- gCharacter[slot].mX = (float)gSpawnpoint[spawnpoint].mX;
- gCharacter[slot].mY = (float)gSpawnpoint[spawnpoint].mY;
- gCharacter[slot].mTarget = -1; // find target at next handle_ai pass
- gCharacter[slot].mNextWaypoint = gSpawnpoint[spawnpoint].mClosestWaypoint;
- }
-
- if (aType == CHAR_VIP)
- {
- if (gVIPCount >= 3)
- return 0; // 3 vips at a time, thanks
- gVIPCount++;
- // spawn a VIP
- int spawnpoint = 0;
- int i = rand() % gVIPSpawnCount;
- spawnpoint = findspawnpoint(i, CHAR_VIP);
-
- gCharacter[slot].mType = CHAR_VIP;
- gCharacter[slot].mX = (float)gSpawnpoint[spawnpoint].mX;
- gCharacter[slot].mY = (float)gSpawnpoint[spawnpoint].mY;
- gCharacter[slot].mNextWaypoint = gSpawnpoint[spawnpoint].mClosestWaypoint;
-
- int targetspawnpoint = 0;
- float dist = 0;
- // find target waypont, avoiding free score
- while (dist < 20)
- {
- i = rand() % gVIPSpawnCount;
- targetspawnpoint = findspawnpoint(i, 1);
- dist = distance(gCharacter[slot].mX, gCharacter[slot].mY, (float)gSpawnpoint[targetspawnpoint].mX, (float)gSpawnpoint[targetspawnpoint].mY);
- }
- gCharacter[slot].mTarget = targetspawnpoint;
- }
-
- if (aType == CHAR_PEDESTRIAN)
- {
- // spawn a pedestrian
- int spawnpoint = 0;
- int i = rand() % gPedestrianSpawnCount;
- spawnpoint = findspawnpoint(i, CHAR_PEDESTRIAN);
- gCharacter[slot].mType = CHAR_PEDESTRIAN;
- gCharacter[slot].mX = (float)gSpawnpoint[spawnpoint].mX;
- gCharacter[slot].mY = (float)gSpawnpoint[spawnpoint].mY;
- gCharacter[slot].mTTL = rand() % 10 + 5;
- gCharacter[slot].mNextWaypoint = gSpawnpoint[spawnpoint].mClosestWaypoint;
- }
- float dist = distance(gCharacter[slot].mNextWaypoint, gCharacter[slot].mX, gCharacter[slot].mY);
- gCharacter[slot].mSpeed = (((rand()/32768.0f) + 0.5f) * 0.5f) / 5.0f; // HatConstant(tm)
- // slow down pedestrians, they're not in a hurry..
- if (aType == CHAR_PEDESTRIAN) gCharacter[slot].mSpeed *= 0.5f;
- gCharacter[slot].mXi = ((gWaypoint[gCharacter[slot].mNextWaypoint].mX - gCharacter[slot].mX) / dist) * gCharacter[slot].mSpeed;
- gCharacter[slot].mYi = ((gWaypoint[gCharacter[slot].mNextWaypoint].mY - gCharacter[slot].mY) / dist) * gCharacter[slot].mSpeed;
- return slot;
- }
-
-
-
- void shoot()
- {
- gWobbleIndex += 2048;
- gReloading = RELOAD_TIME;
- #ifdef CAMERA_RECOIL
- if (gMouseZ < 0.25f) gMouseZ = 0.25f;
- #ifndef CAMERA_STEPS
- gCoordScale = gMouseZ;
- #else
- gCoordScale = ((int)(gMouseZ * 4)) / 4.0f;
- if (gCoordScale < 0.05f) gCoordScale = 0.05f;
- #endif
- #endif
- int slot = 0;
- while (gCharacter[slot].mType != -1) slot++;
- gCharacter[slot].mLastWaypoint = 0;
-
- float worldx = gMouseX + gWobbleX + gCenterX + 320 * gCoordScale;
- float worldy = gMouseY + gWobbleY + gCenterY + 240 * gCoordScale;
-
- int hit = 0;
- int gameover = 0;
- int i;
- for (i = 0; i < gCharacterCount; i++)
- {
- if (gCharacter[i].mType != -1)
- {
- if (gCharacter[i].mX > worldx - 1 &&
- gCharacter[i].mX < worldx + 1 &&
- gCharacter[i].mY > worldy - 1 &&
- gCharacter[i].mY < worldy + 1)
- {
- if (gCharacter[i].mType == CHAR_BADGUY)
- {
- gScore += 1000;
- gBadGuyCount--;
- gBadGuisKilled++;
- }
- if (gCharacter[i].mType == CHAR_VIP)
- {
- gScore -= 100000; // +game over
- gameover = 1;
- gVIPCount--;
- }
- if (gCharacter[i].mType == CHAR_PEDESTRIAN)
- {
- gPedestriansKilled++;
- gScore -= 100;
- #ifdef RECYCLE_PEDESTRIANS
- spawn_ai(2); // spawn a new pedestrian
- #endif
- }
- gCharacter[i].mType = -1;
- hit = 1;
- }
- }
- }
- #ifdef DISPLAY_GAMEOVER_SCREEN
- if (gameover)
- {
- gameoverscreen(1);
- }
- #endif
-
- gCharacter[slot].mType = hit?3:4; // hit marker
- gCharacter[slot].mX = worldx;
- gCharacter[slot].mY = worldy;
- gCharacter[slot].mTTL = 100;
- }