void CK6_FlectDraw(CK_object *obj) { // Hit wall walking right; turn around and go left if (obj->xDirection == IN_motion_Right && obj->leftTI != 0) { obj->posX -= obj->deltaPosX; obj->xDirection = IN_motion_Left; obj->timeUntillThink = US_RndT() / 32; CK_SetAction2(obj, obj->currentAction); } // Hit wall walking left; turn around and go right else if (obj->xDirection == IN_motion_Left && obj->rightTI != 0) { obj->posX -= obj->deltaPosX; obj->xDirection = IN_motion_Right; obj->timeUntillThink = US_RndT() / 32; CK_SetAction2(obj, obj->currentAction); } // Walked off of ledge; turn around else if (obj->topTI == 0) { obj->posX -= obj->deltaPosX; obj->xDirection = -obj->xDirection; CK_SetAction2(obj, obj->currentAction); } RF_AddSpriteDraw(&(obj->sde), obj->posX, obj->posY, obj->gfxChunk, false, obj->zLayer); }
void CK6_SatelliteCol(CK_object *a, CK_object *b) { if (b->currentAction == CK_GetActionByName("CK6_ACT_SatelliteInvisible0")) { a->user3 |= b->user1; } else if (b->type == CT_Player) { int var2 = a->user3 / 256; if (var2 == 0 || a->user4 == var2) { if (b->currentAction == CK_GetActionByName("CK6_ACT_KeenSatellite0")) { b->posX = a->posX + 0xC0; b->posY = a->posY + 0x100; CK_SetAction2(b, b->currentAction); } } else { SD_PlaySound(SOUND_KEENSATELLITE); a->user4 = var2; if (ck_keenObj->currentAction == CK_GetActionByName("CK6_ACT_KeenSatellite0")) { a = ck_keenObj->next; while (a) { if (a->type == CT6_SatelliteLoading && a->user1 == var2) { b->posX = a->posX; b->posY = a->posY; b->gfxChunk = 192; CK_SetAction2(ck_keenObj, CK_GetActionByName("CK_ACT_MapKeenStart")); b->clipped = CLIP_normal; break; } a = a->next; } } else { b->posX = a->posX + 0xC0; b->posY = a->posY + 0x100; b->clipped = CLIP_not; CK_SetAction2(ck_keenObj, CK_GetActionByName("CK6_ACT_KeenSatellite0")); } } } }
void CK6_NospikeChargeDraw(CK_object *obj) { if (obj->topTI) { obj->user1 = 0; if (obj->rightTI || obj->leftTI) { obj->posX -= obj->xDirection * 128; CK_SetAction(obj, CK_GetActionByName("CK6_ACT_NospikeSit0")); // Not Setaction2 RF_AddSpriteDraw(&(obj->sde), obj->posX, obj->posY, obj->gfxChunk, false, obj->zLayer); obj->user2 = 0; return; } } else if (++obj->user1 == 6) { CK_SetAction2(obj, CK_GetActionByName("CK6_ACT_NospikeFall0")); } if (obj->user2 & 0xFF00) { uint16_t user2 = obj->user2 & 0xFFFF; // Need to use 16-bit arithmetic here user2 -= 0x100; obj->user2 = user2; RF_AddSpriteDraw(&(obj->sde), obj->posX, obj->posY, obj->gfxChunk, true, obj->zLayer); } else { RF_AddSpriteDraw(&(obj->sde), obj->posX, obj->posY, obj->gfxChunk, false, obj->zLayer); } }
void CK6_BloogguardSmash(CK_object *obj) { SD_PlaySound(SOUND_BLOOGGUARDSMASH); ck6_smashScreenDistance = 25; if (ck_keenObj->topTI) CK_SetAction2(ck_keenObj, CK_GetActionByName("CK6_ACT_keenStunned0")); }
void CK6_BipshipCol(CK_object *a, CK_object *b) { if (b->type == CT_Stunner) { CK_ShotHit(b); CK_SetAction2(a, CK_GetActionByName("CK6_ACT_BipshipHit0")); } }
void CK6_OrbatrixCol(CK_object *a, CK_object *b) { if (b->type == CT_Stunner) { CK_ShotHit(b); CK_SetAction2(a, CK_GetActionByName("CK6_ACT_OrbatrixUncurl2")); } }
void CK6_BipshipFly(CK_object *obj) { CK_PhysAccelHorz(obj, obj->xDirection, 20); int xdir = obj->xDirection; int ycheck = ck_keenObj->clipRects.unitY2 + 0x100 - obj->clipRects.unitY2; if (ycheck <= 0x200 && ycheck >= 0) { // Fire!! xdir = (ck_keenObj->posX < obj->posX) ? IN_motion_Left : IN_motion_Right; if (obj->xDirection == xdir && US_RndT() < SD_GetSpriteSync() * 2) { SD_PlaySound(SOUND_KEENSHOOT); CK_object *shot = CK_GetNewObj(true); shot->type = CT6_EnemyShot; shot->active = OBJ_EXISTS_ONLY_ONSCREEN; shot->zLayer = PRIORITIES - 3; if (obj->xDirection == IN_motion_Right) { shot->posX = obj->posX + 0x100; shot->velX = 64; } else { shot->posX = obj->posX; shot->velX = -64; } shot->posY = obj->posY + 0xA0; shot->velY = 16; CK_SetAction(shot, CK_GetActionByName("CK6_ACT_BipShot0")); } } int startx = obj->clipRects.tileXmid + 2 * xdir; int y = obj->clipRects.tileY1; uint16_t *tile = CA_TilePtrAtPos(startx, y, 1); for (y; y <= obj->clipRects.tileY2; y++, tile += CA_GetMapWidth()) { if (TI_ForeLeft(*tile) || TI_ForeRight(*tile)) { xdir = -xdir; goto checkTurn; } } // And turn around at ledge-ends if (!TI_ForeTop(*tile)) xdir = -xdir; checkTurn: if (obj->xDirection != xdir) { obj->xDirection = xdir; CK_SetAction2(obj, CK_GetActionByName("CK6_ACT_BipshipTurn0")); } }
void CK6_BipCol(CK_object *a, CK_object *b) { if (b->type == CT_Player && b->deltaPosY == 0) { SD_PlaySound(SOUND_BIPSQUISH); a->type = CT_Friendly; CK_SetAction2(a, CK_GetActionByName("CK6_ACT_BipSquished0")); } }
void CK6_RocketFlyCol(CK_object *a, CK_object *b) { if (b->type == CT_Player) { b->posX = a->posX; b->posY = a->posY + 0x100; CK_SetAction2(b, b->currentAction); } }
void CK6_MapCliffCol(CK_object *a, CK_object *b) { if (b->type == CT_Player) { if (ck_gameState.ep.ck6.rope == 0) { CA_CacheGrChunk(0x23); US_CenterWindow(26, 8); VH_DrawBitmap(US_GetWindowX() + US_GetWindowW() - 0x30, US_GetWindowY(), 0x23); US_SetWindowW(US_GetWindowW() - 0x30); US_SetPrintY(US_GetPrintY() + 15); US_CPrint("What a tall cliff!\n" "Wish I had a rope\n" "and grappling hook.\n"); VL_Present(); SD_PlaySound(SOUND_NEEDKEYCARD); VL_DelayTics(30); // VW_WaitVBL(30); IN_ClearKeysDown(); IN_WaitButton(); RF_ForceRefresh(); ck_nextX = -b->deltaPosX; ck_nextY = -b->deltaPosY; b->xDirection = b->yDirection = IN_motion_None; CK_PhysUpdateNormalObj(b); } else if (ck_gameState.ep.ck6.rope == 1) { ck_gameState.ep.ck6.rope++; SD_PlaySound(SOUND_KEENTHROWROPE); CK_SetAction2(b, CK_GetActionByName("CK6_ACT_MapKeenThrowRope0")); b->type = CT_Friendly; } else if (ck_gameState.ep.ck6.rope == 2) { if (a->user1) { b->posY += 0x40; b->user4 = 6; b->yDirection = IN_motion_Down; } else { b->posY -= 0x40; b->user4 = 6; b->yDirection = IN_motion_Up; } CK_SetAction(b, CK_GetActionByName("CK6_ACT_MapKeenClimbRope0")); b->type = CT_Friendly; } } }
void CK6_RocketCol(CK_object *a, CK_object *b) { if (ck_gameState.ep.ck6.passcard == 0) { CA_CacheGrChunk(0x23); US_CenterWindow(26, 8); VH_DrawBitmap(US_GetWindowX() + US_GetWindowW() - 0x30, US_GetWindowY(), 0x23); US_SetWindowW(US_GetWindowW() - 0x30); US_SetPrintY(US_GetPrintY() + 5); US_CPrint("The door makes a loud\n" "blooping noise.\n" "It says,\n" "\"Passcard required\n" "for entry.\""); VL_Present(); SD_PlaySound(SOUND_NEEDKEYCARD); VL_DelayTics(30); // VW_WaitVBL(30); IN_ClearKeysDown(); IN_WaitButton(); RF_ForceRefresh(); ck_nextX = -b->deltaPosX; ck_nextY = -b->deltaPosY; b->xDirection = b->yDirection = IN_motion_None; CK_PhysUpdateNormalObj(b); } else if (ck_gameState.ep.ck6.passcard == 1) { a->user1 = 0; a->user2 = 0x100; CK_SetAction2(a, CK_GetActionByName("CK6_ACT_RocketFly0")); b->posX = a->posX; b->posY = a->posY + 0x100; b->clipped = CLIP_not; CK_SetAction2(b, CK_GetActionByName("CK6_ACT_MapKeenRocketSit0")); SD_PlaySound(SOUND_ROCKETLAUNCH); SD_WaitSoundDone(); } }
void CK6_NospikeFallDraw2(CK_object *obj) { RF_AddSpriteDraw(&(obj->sde), obj->posX, obj->posY, obj->gfxChunk, false, obj->zLayer); if (obj->topTI) { obj->user1 = obj->user2 = obj->user3; obj->user4 = obj->type; CK_SetAction2(obj, CK_GetActionByName("CK6_ACT_NospikeStunned0")); SD_PlaySound(SOUND_NOSPIKECOLLIDE); obj->type = CT6_StunnedCreature; obj->velY = -24; } }
void CK6_GrabbiterCol(CK_object *a, CK_object *b) { if (!ck_gameState.ep.ck6.sandwich) { CA_CacheGrChunk(0x23); SD_PlaySound(SOUND_GRABBITER); US_CenterWindow(26, 8); VH_DrawBitmap(US_GetWindowX() + US_GetWindowW() - 0x30, US_GetWindowY(), 0x23); US_SetWindowW(US_GetWindowW() - 0x30); US_SetPrintY(US_GetPrintY() + 5); US_CPrint("Oh no!\n" "It's a slavering\n" "Grabbiter! He says,\n" "\"Get me lunch and\n" "I'll tell ya a secret!\""); VL_Present(); VL_DelayTics(30); // VW_WaitVBL(30); IN_ClearKeysDown(); IN_WaitButton(); RF_ForceRefresh(); ck_nextX = -b->deltaPosX; ck_nextY = -b->deltaPosY; b->xDirection = b->yDirection = IN_motion_None; CK_PhysUpdateNormalObj(b); } else { ck_gameState.ep.ck6.sandwich++; CA_CacheGrChunk(0x23); US_CenterWindow(26, 8); VH_DrawBitmap(US_GetWindowX() + US_GetWindowW() - 0x30, US_GetWindowY(), 0x23); US_SetWindowW(US_GetWindowW() - 0x30); US_SetPrintY(US_GetPrintY() + 2); US_CPrint("The Grabbiter grabs\n" "the gigantic sandwich,\n" "downs it in one bite,\n" "and says,\"Here's your\n" "secret. Big meals\n" "make me sleepy!\n"); VL_Present(); VL_DelayTics(30); // VW_WaitVBL(30); IN_ClearKeysDown(); IN_WaitButton(); CK_SetAction2(a, CK_GetActionByName("CK6_ACT_GrabbiterNapping0")); RF_ForceRefresh(); } }
void CK6_SpawnSatelliteLoading(int tileX, int tileY, int dir) { CK_object *obj = CK_GetNewObj(false); obj->active = OBJ_ALWAYS_ACTIVE; obj->clipped = CLIP_not; obj->zLayer = PRIORITIES - 2; obj->type = CT6_SatelliteLoading; obj->clipRects.tileX1 = obj->clipRects.tileX2 = tileX; obj->clipRects.tileY1 = obj->clipRects.tileY2 = tileY; obj->user1 = (dir ^ 1) + 1; obj->posX = obj->clipRects.unitX1 = RF_TileToUnit(tileX); obj->clipRects.unitX2 = obj->clipRects.unitX1 + 0x100; obj->posY = obj->clipRects.unitY1 = RF_TileToUnit(tileY); obj->clipRects.unitY2 = obj->clipRects.unitY1 + 0x100; CK_SetAction2(obj, CK_GetActionByName("CK6_ACT_SatelliteInvisible0")); }
void CK6_GikJumpDraw(CK_object *obj) { if (obj->rightTI || obj->leftTI) obj->velX = 0; if (obj->bottomTI) obj->velY = 0; if (obj->topTI) { obj->velY = 0; SD_PlaySound(SOUND_GIKLAND); CK_SetAction2(obj, obj->currentAction->next); } RF_AddSpriteDraw(&(obj->sde), obj->posX, obj->posY, obj->gfxChunk, false, obj->zLayer); }
void CK6_OrbatrixBounceDraw(CK_object *obj) { RF_AddSpriteDraw(&(obj->sde), obj->posX, obj->posY, obj->gfxChunk, false, obj->zLayer); if (obj->topTI) obj->velY = -obj->velY; if (obj->topTI || obj->leftTI || obj->rightTI) { obj->velX = -obj->velX; SD_PlaySound(SOUND_ORBATRIXBOUNCE); if (obj->topTI && --obj->user1 == 0) { CK_SetAction2(obj, CK_GetActionByName("CK6_ACT_OrbatrixUncurl0")); obj->user2 = 0x180; } } }
void CK6_NospikeCol(CK_object *a, CK_object *b) { if (b->type == CT_Player) { CK_KillKeen(); } else if (b->type == CT_Stunner) { if (--a->user4 == 0) { CK_StunCreature(a, b, CK_GetActionByName("CK6_ACT_NospikeStunned0")); } else { a->xDirection = ck_keenObj->posX < a->posX ? IN_motion_Left : IN_motion_Right; a->user2 |= 0x400; a->visible = true; if (a->currentAction == CK_GetActionByName("CK6_ACT_NospikeSit0") || a->currentAction == CK_GetActionByName("CK6_ACT_NospikeWalk0")) CK_SetAction2(a, CK_GetActionByName("CK6_ACT_NospikeCharge1")); else if (a->currentAction == CK_GetActionByName("CK6_ACT_NospikeWalk1")) CK_SetAction2(a, CK_GetActionByName("CK6_ACT_NospikeCharge2")); else if (a->currentAction == CK_GetActionByName("CK6_ACT_NospikeWalk2")) CK_SetAction2(a, CK_GetActionByName("CK6_ACT_NospikeCharge3")); else if (a->currentAction == CK_GetActionByName("CK6_ACT_NospikeWalk3")) CK_SetAction2(a, CK_GetActionByName("CK6_ACT_NospikeCharge0")); CK_ShotHit(b); } } else if (b->type == CT6_Nospike) { // Two charging nospikes will stun each other if they collide head on if ((a->user2 & 0xFF) && (b->user2 & 0xFF) && a->xDirection != b->xDirection) { a->user1 = a->user2 = a->user3 = 0; b->user1 = b->user2 = b->user3 = 0; a->user4 = b->user4 = a->type; CK_SetAction2(a, CK_GetActionByName("CK6_ACT_NospikeStunned0")); CK_SetAction2(b, CK_GetActionByName("CK6_ACT_NospikeStunned0")); SD_PlaySound(SOUND_NOSPIKECOLLIDE); a->type = b->type = CT6_StunnedCreature; a->velY = b->velY = -24; } } }
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; } } } }