Esempio n. 1
0
void CK6_MapMiscFlagsCheck(CK_object *obj)
{
  if (obj->user3 == 0)
  {
    int tileX = obj->clipRects.tileXmid;
    int tileY = RF_UnitToTile(obj->clipRects.unitY1 +
      (obj->clipRects.unitY2 - obj->clipRects.unitY1)/2);
    uint16_t tile = CA_TileAtPos(tileX, tileY, 1);
    uint8_t miscValue = TI_ForeMisc(tile);

    if (miscValue == MISCFLAG_TELEPORT)
      CK_AnimateMapTeleporter(tileX, tileY);
  }
}
Esempio n. 2
0
void CK6_RocketFly(CK_object *obj)
{
  if (!ck_nextX && !ck_nextY)
  {
    if (!SD_SoundPlaying())
      SD_PlaySound(SOUND_ROCKETFLY);

    int delta = SD_GetSpriteSync() * 32;

    // Will we reach a new tile?
    if (obj->user2 > delta)
    {
      // No... keep moving in the same direction.
      obj->user2 -= delta;

      int dirX = ck_infoplaneArrowsX[obj->user1];
      if (dirX == 1)
      {
        // Moving right.
        ck_nextX += delta;
      }
      else if (dirX == -1)
      {
        // Moving left
        ck_nextX -= delta;
      }

      int dirY = ck_infoplaneArrowsY[obj->user1];
      if (dirY == 1)
      {
        // Moving down
        ck_nextY += delta;
      }
      else if (dirY == -1)
      {
        // Moving up
        ck_nextY -= delta;
      }
    }
    else
    {
      // Move to next tile.
      int dirX = ck_infoplaneArrowsX[obj->user1];
      if (dirX == 1)
      {
        // Moving right.
        ck_nextX += obj->user2;
      }
      else if (dirX == -1)
      {
        // Moving left
        ck_nextX -= obj->user2;
      }

      int dirY = ck_infoplaneArrowsY[obj->user1];
      if (dirY == 1)
      {
        // Moving down
        ck_nextY += obj->user2;
      }
      else if (dirY == -1)
      {
        // Moving up
        ck_nextY -= obj->user2;
      }

      int tileX = (uint16_t)RF_UnitToTile(obj->posX + ck_nextX);
      int tileY = (uint16_t)RF_UnitToTile(obj->posY + ck_nextY);

      obj->user1 = CA_TileAtPos(tileX, tileY, 2) - 0x5B;

      if ((obj->user1 < 0) || (obj->user1 > 8))
      {
        obj->posX += ck_nextX;
        obj->posY += ck_nextY;
        CK_SetAction2(obj, CK_GetActionByName("CK6_ACT_RocketSit0"));

        ck_keenObj->posX = RF_TileToUnit(tileX + 1) + 0x10;
        ck_keenObj->posY = RF_TileToUnit(tileY + 1);
        ck_keenObj->type = CT_Player;
        ck_keenObj->gfxChunk = 0xBD;
        ck_keenObj->clipped = CLIP_normal;
        CK_SetAction(ck_keenObj, CK_GetActionByName("CK_ACT_MapKeenStart"));
        ck_gameState.ep.ck6.inRocket ^= 1;
        return;
      }

      delta -= obj->user2;
      obj->user2 = 256 - delta;

      // Move in the new direction.
      dirX = ck_infoplaneArrowsX[obj->user1];
      if (dirX == 1)
      {
        // Moving right.
        ck_nextX += delta;
      }
      else if (dirX == -1)
      {
        // Moving left
        ck_nextX -= delta;
      }

      dirY = ck_infoplaneArrowsY[obj->user1];
      if (dirY == 1)
      {
        // Moving down
        ck_nextY += delta;
      }
      else if (dirY == -1)
      {
        // Moving up
        ck_nextY -= delta;
      }
    }
  }
}
Esempio n. 3
0
// TODO: Cache stuff here instead of spawner handlers
void CK6_ScanInfoLayer()
{

	//TODO: Work out where to store current map number, etc.
	int mapW = CA_MapHeaders[ca_mapOn]->width;
	int mapH = CA_MapHeaders[ca_mapOn]->height;

	for (int y = 0; y < mapH; ++y)
	{
		for (int x = 0; x < mapW; ++x)
		{
			int infoValue = CA_TileAtPos(x, y, 2);
			switch (infoValue)
			{
			case 1:
				CK_SpawnKeen(x, y, 1);
				CK_DemoSignSpawn();
				ca_graphChunkNeeded[175] |= ca_levelbit;
				ck6_lumpsNeeded[Lump_Keen] = true;
				break;
			case 2:
				CK_SpawnKeen(x, y, -1);
				CK_DemoSignSpawn();
				ca_graphChunkNeeded[175] |= ca_levelbit;
				ck6_lumpsNeeded[Lump_Keen] = true;
				break;

			case 3:
				CK_DemoSignSpawn();
				ca_graphChunkNeeded[175] |= ca_levelbit;
				CK_SpawnMapKeen(x, y);
				ck6_lumpsNeeded[Lump_Mapkeen] = true;
				break;

			// Bloogs
			case 6:
				if (ck_gameState.difficulty < D_Hard)
					break;
			case 5:
				if (ck_gameState.difficulty < D_Normal)
					break;
			case 4:
				ck6_lumpsNeeded[Lump_Bloog] = true;
				CK6_SpawnBloog(x, y);
				break;

			case 7:
			case 8:
			case 9:
			case 10:
			case 11:
			case 12:
			case 13:
			case 14:
			{
				int color = (infoValue - 7) % 4;
				ck6_lumpsNeeded[Lump_BloogletR + color] = true;
				CK6_SpawnBlooglet(x, y, infoValue - 7);
				break;
			}

			case 15:
			case 16:
				CK6_SpawnMapCliff(x, y, infoValue - 15);
				break;

			case 24:
				ck6_lumpsNeeded[Lump_Molly] = true;
				CK6_SpawnMolly(x, y);
				break;

				// Fleex
			case 20:
				if (ck_gameState.difficulty < D_Hard)
					break;
			case 19:
				if (ck_gameState.difficulty < D_Normal)
					break;
			case 18:
				ck6_lumpsNeeded[Lump_Fleex] = true;
				CK6_SpawnFleex(x, y);
				break;

			case 25:
				RF_SetScrollBlock(x, y, true);
				break;
			case 26:
				RF_SetScrollBlock(x, y, false);
				break;

				// Platforms
			case 27:
			case 28:
			case 29:
			case 30:
				CK_SpawnAxisPlatform(x, y, infoValue - 27, false);
				ck6_lumpsNeeded[Lump_Platform] = true;
				break;
			case 32:
				CK_SpawnFallPlat(x, y);
				ck6_lumpsNeeded[Lump_Platform] = true;
				break;

			case 33:
				if (ck_gameState.difficulty > D_Easy)
					break;
			case 34:
				if (ck_gameState.difficulty > D_Normal)
					break;
			case 35:
				CK_SpawnStandPlatform(x, y);
				ck6_lumpsNeeded[Lump_Platform] = true;
				break;

			case 36:
			case 37:
			case 38:
			case 39:
				CK_SpawnGoPlat(x, y, infoValue - 36, false);
				ck6_lumpsNeeded[Lump_Platform] = true;
				ck6_lumpsNeeded[Lump_PlatBip] = true;
				break;
			case 40:
				CK_SneakPlatSpawn(x, y);
				ck6_lumpsNeeded[Lump_Platform] = true;
				break;

			// Bobbas
			case 43:
				if (ck_gameState.difficulty < D_Hard)
					break;
			case 42:
				if (ck_gameState.difficulty < D_Normal)
					break;
			case 41:
				ck6_lumpsNeeded[Lump_Bobba] = true;
				CK6_SpawnBobba(x, y);
				break;

			case 44:
			case 45:
				CK6_SpawnSatelliteLoading(x, y, infoValue - 44);
				break;

			// Nospike
			case 49:
				if (ck_gameState.difficulty < D_Hard)
					break;
			case 48:
				if (ck_gameState.difficulty < D_Normal)
					break;
			case 47:
				ck6_lumpsNeeded[Lump_Nospike] = true;
				CK6_SpawnNospike(x, y);
				break;

			// Gik
			case 52:
				if (ck_gameState.difficulty < D_Hard)
					break;
			case 51:
				if (ck_gameState.difficulty < D_Normal)
					break;
			case 50:
				ck6_lumpsNeeded[Lump_Gik] = true;
				CK6_SpawnGik(x, y);
				break;

				// Turrets
			case 53:
			case 54:
			case 55:
			case 56:
				ck6_lumpsNeeded[Lump_Turret] = true;
				CK_TurretSpawn(x, y, infoValue - 53);
				break;

			case 69:
				// Spawn extra stunner if Keen has low ammo
				if (ck_gameState.numShots >= 5)
					break;
				infoValue = 68;
			case 57:
			case 58:
			case 59:
			case 60:
			case 61:
			case 62:
			case 63:
			case 64:
			case 65:
			case 66:
			case 67:
			case 68:
				CK_SpawnItem(x, y, infoValue - 57);
				ck6_lumpsNeeded[ck6_itemLumps[infoValue - 57]] = true;
				break;

			// Orbatrices
			case 72:
				if (ck_gameState.difficulty < D_Hard)
					break;
			case 71:
				if (ck_gameState.difficulty < D_Normal)
					break;
			case 70:
				ck6_lumpsNeeded[Lump_Orbatrix] = true;
				CK6_SpawnOrbatrix(x, y);
				break;

			// Bip
			case 75:
				if (ck_gameState.difficulty < D_Hard)
					break;
			case 74:
				if (ck_gameState.difficulty < D_Normal)
					break;
			case 73:
				ck6_lumpsNeeded[Lump_Bip] = true;
				ck6_lumpsNeeded[Lump_PlatBip] = true;
				ck6_lumpsNeeded[Lump_Bipship] = true;
				CK6_SpawnBipship(x, y);
				break;

			// Flects
			case 78:
				if (ck_gameState.difficulty < D_Hard)
					break;
			case 77:
				if (ck_gameState.difficulty < D_Normal)
					break;
			case 76:
				ck6_lumpsNeeded[Lump_Flect] = true;
				CK6_SpawnFlect(x, y);
				break;

			// Blorbs
			case 81:
				if (ck_gameState.difficulty < D_Hard)
					break;
			case 80:
				if (ck_gameState.difficulty < D_Normal)
					break;
			case 79:
				ck6_lumpsNeeded[Lump_Blorb] = true;
				CK6_SpawnBlorb(x, y);
				break;

			// Ceilicks
			case 84:
				if (ck_gameState.difficulty < D_Hard)
					break;
			case 83:
				if (ck_gameState.difficulty < D_Normal)
					break;
			case 82:
				ck6_lumpsNeeded[Lump_Ceilick] = true;
				CK6_SpawnCeilick(x, y);
				break;

			// Bloogguards
			case 87:
				if (ck_gameState.difficulty < D_Hard)
					break;
			case 86:
				if (ck_gameState.difficulty < D_Normal)
					break;
			case 85:
				ck6_lumpsNeeded[Lump_Bloogguard] = true;
				CK6_SpawnBloogguard(x, y);
				break;

				// Grabbiter
			case 88:
				CK6_SpawnGrabbiter(x, y);
				break;

			// Satellite
			case 89:
				CK6_SpawnSatellite(x, y);
				break;

			// Story Items
			case 99:
				ck6_lumpsNeeded[Lump_Rope] = true;
				CK6_SpawnRope(x, y);
				break;
			case 100:
				ck6_lumpsNeeded[Lump_Sandwich] = true;
				CK6_SpawnSandwich(x, y);
				break;
			case 101:
				ck6_lumpsNeeded[Lump_Passcard] = true;
				CK6_SpawnPasscard(x, y);
				break;

			// Babobbas
			case 104:
				if (ck_gameState.difficulty < D_Hard)
					break;
			case 103:
				if (ck_gameState.difficulty < D_Normal)
					break;
			case 102:
				ck6_lumpsNeeded[Lump_Babobba] = true;
				CK6_SpawnBabobba(x, y);
				break;

			case 105:
				CK6_SpawnRocket(x, y, infoValue - 105);
				break;
			}
		}
	}

	for (CK_object *obj = ck_keenObj; obj != NULL; obj = obj->next)
	{
		if (obj->active != OBJ_ALWAYS_ACTIVE)
			obj->active = OBJ_INACTIVE;
	}
	// TODO: Some more stuff (including opening elevator after breaking fuses)

	if (ck_gameState.currentLevel == 0)
	{
		//int keenYTilePos = RF_UnitToTile(ck_keenObj->posY);
	}

	for (int i = 0; i < MAXLUMPS; i++)
		if (ck6_lumpsNeeded[i])
			for (int j = ck6_lumpStarts[i]; j <= ck6_lumpEnds[i]; j++)
				CA_CacheGrChunk(j);
}
Esempio n. 4
0
void CK6_ToggleBigSwitch(CK_object *obj, bool dir)
{

	// Replace switch tiles
	int ty = dir ? obj->clipRects.tileY2 : obj->clipRects.tileY1 - 2;
	int tx = obj->clipRects.tileX1 - 1;

	uint16_t *infoTile = CA_TilePtrAtPos(tx + 1, ty + 1, 2);

	while (!*infoTile)
	{
		tx++;
		infoTile++;
	}

	uint16_t *fgTile = CA_TilePtrAtPos(tx, ty, 1);

	uint16_t tile_array[6];
	for (int y = 0; y < 3; y++)
	{
		for (int x = 0; x < 2; x++)
		{
			tile_array[2 * y + x] = *fgTile + TI_ForeAnimTile(*fgTile);
			fgTile++;
		}

		fgTile += CA_GetMapWidth() - 2;
	}

	RF_ReplaceTiles(tile_array, 1, tx, ty, 2, 3);

	// Apply the switch effect
	infoTile = CA_TilePtrAtPos(tx + 1, ty + 1, 2);
	int destX = *infoTile >> 8;
	int destY = *infoTile & 0xFF;
	SD_PlaySound(SOUND_KEENOUTOFAMMO);

	infoTile = CA_TilePtrAtPos(destX, destY, 2);

	if (*infoTile >= 0x5B && *infoTile < 0x5B + 8)
	{
		// Toggle a goplat arrow
		static uint16_t infoPlaneInverses[8] = {2, 3, 0, 1, 6, 7, 4, 5};
		*infoTile = infoPlaneInverses[(*infoTile - 0x5B)] + 0x5B;
	}
	else
	{
		fgTile = CA_TilePtrAtPos(destX, destY, 1);
		int miscValue = TI_ForeMisc(*fgTile) & 0x7F;

		if (miscValue == MISCFLAG_ACTIVEZAPPER)
		{
			uint16_t start = CA_TileAtPos(0, 0, 1);
			uint16_t mid = CA_TileAtPos(1, 0, 1);
			uint16_t end = CA_TileAtPos(2, 0, 1);

			RF_ReplaceTiles(&start, 1, destX, destY, 1, 1);
			destY++;

			while (TI_ForeMisc(CA_TileAtPos(destX, destY, 1)) == MISCFLAG_DEADLY)
			{
				RF_ReplaceTiles(&mid, 1, destX, destY, 1, 1);
				destY++;
			}

			RF_ReplaceTiles(&end, 1, destX, destY, 1, 1);
		}
		else if (miscValue == MISCFLAG_INACTIVEZAPPER)
		{
			uint16_t start = CA_TileAtPos(3, 0, 1);
			uint16_t mid = CA_TileAtPos(4, 0, 1);
			uint16_t end = CA_TileAtPos(5, 0, 1);

			RF_ReplaceTiles(&start, 1, destX, destY, 1, 1);
			destY++;

			while (TI_ForeMisc(CA_TileAtPos(destX, destY, 1)) != MISCFLAG_INACTIVEZAPPER)
			{
				RF_ReplaceTiles(&mid, 1, destX, destY, 1, 1);
				destY++;
			}

			RF_ReplaceTiles(&end, 1, destX, destY, 1, 1);
		}
		else if (miscValue == MISCFLAG_BRIDGE)
		{
			for (int y = destY; y < destY + 2; ++y)
			{
				for (int x = destX - ((y == destY) ? 0 : 1); x < CA_GetMapWidth(); ++x)
				{
					uint16_t currentTile = CA_TileAtPos(x, y, 1);
					if (!TI_ForeAnimTile(currentTile))
						break;
					uint16_t newTile = currentTile + TI_ForeAnimTile(currentTile);
					RF_ReplaceTiles(&newTile, 1, x, y, 1, 1);
				}
			}
		}
		else
		{
			// Toggle a B block
			*infoTile ^= 0x1F;
		}
	}
}