From d901ecae894baac4a9a612896b23f6a31c692660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Sun, 9 Feb 2020 15:03:15 +0100 Subject: [PATCH] Make teleports work --- assets/item_teleport.png | Bin 0 -> 1149 bytes images.h | 28 +++++++++- levels.h | 17 +++--- main.c | 118 +++++++++++++++++++++++++++++++++------ 4 files changed, 137 insertions(+), 26 deletions(-) create mode 100644 assets/item_teleport.png diff --git a/assets/item_teleport.png b/assets/item_teleport.png new file mode 100644 index 0000000000000000000000000000000000000000..4b0614c846853ab0b43208a556396438306ce892 GIT binary patch literal 1149 zcmV-@1cLjCP)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00ZSoL_t(o!^M}YcjGu1#ebbs zU>GpKAV46%puk{2K!HJlz=8n)ax&%CDD#|rl9MFK5rJ20 zptG&p-Hi$$nNqNE1fl*7U@&s+V*bGz2;K}8#Un&0iX{vd0P29;zE_i2;3BfSQN(~) z0bkxg;8M|Y5vw}PKGZ(I#^{TE>9;HeM0m zD@4BVSPAs^jJ`2!5J%wNlD|dpx?k*A%NQ{@jKV1)`qTzJ0IwE|x+P$+(uCd6^s4!8 zrGdl}bxT)>t6vbJ18;AOv-xl5+TPC27xR0BD85;vWlTzeMiO;PI+F@SWL0Fq%8U*> zKdU8VKM;fA$ArknF8tAxBz>wnb>fPtTVkIx>~rSMppoWbG$!hnXx#X4ir$?UqKi7P z8R-B3)bBdMK4^j1T))jivSg7{@mXQL_0k~9-J-@5+ZHZs@0n{s=Z`%z`NFU>!>4NsZqiKDcfv!type == SFG_LEVEL_ELEMENT_TELEPORT) + SFG_currentLevel.teleportCount++; } else { @@ -1818,10 +1828,32 @@ static inline uint8_t SFG_elementCollides( <= SFG_ELEMENT_COLLISION_DISTANCE; } -uint8_t SFG_getLevelElementSpriteIndex(uint8_t elementType) +SFG_getLevelElementSprite( + uint8_t elementType, uint8_t *spriteIndex, uint8_t *spriteSize) { - return ((elementType < SFG_LEVEL_ELEMENT_CARD0) - ? elementType : SFG_LEVEL_ELEMENT_CARD0) - 1; + *spriteSize = 0; + *spriteIndex = elementType - 1; + + switch (elementType) + { + case SFG_LEVEL_ELEMENT_TREE: + *spriteSize = 2; + break; + + case SFG_LEVEL_ELEMENT_TELEPORT: + case SFG_LEVEL_ELEMENT_FINISH: + *spriteSize = 3; + break; + + case SFG_LEVEL_ELEMENT_CARD0: + case SFG_LEVEL_ELEMENT_CARD1: + case SFG_LEVEL_ELEMENT_CARD2: + *spriteIndex = SFG_LEVEL_ELEMENT_CARD0 - 1; + break; + + default: + break; + } } /** @@ -2202,6 +2234,8 @@ void SFG_gameStep() } } + uint8_t collidesWithTeleport = 0; + // items: for (int16_t i = 0; i < SFG_currentLevel.itemRecordCount; ++i) // ^ has to be int16_t (signed) @@ -2255,6 +2289,11 @@ void SFG_gameStep() SFG_player.cards |= 1 << (e->type - SFG_LEVEL_ELEMENT_CARD0); break; + case SFG_LEVEL_ELEMENT_TELEPORT: + collidesWithTeleport = 1; + eliminate = 0; + break; + default: eliminate = 0; break; @@ -2269,14 +2308,63 @@ void SFG_gameStep() SFG_playSoundSafe(3,255); #endif } - else // collide + else { - moveOffset = SFG_resolveCollisionWithElement( - SFG_player.camera.position,moveOffset,ePos); + if (e->type != SFG_LEVEL_ELEMENT_TELEPORT) + { + // collide + moveOffset = SFG_resolveCollisionWithElement( + SFG_player.camera.position,moveOffset,ePos); + } + else if ((SFG_currentLevel.teleportCount > 1) && + !SFG_player.justTeleported) + { + // teleport to random destination teleport + + uint8_t teleportNumber = + SFG_random() % (SFG_currentLevel.teleportCount - 1) + 1; + + for (uint16_t j = 0; j < SFG_currentLevel.itemRecordCount; ++j) + { + SFG_LevelElement e2 = + SFG_currentLevel.levelPointer->elements + [SFG_currentLevel.itemRecords[j] & + ~SFG_ITEM_RECORD_ACTIVE_MASK]; + + if ((e2.type == SFG_LEVEL_ELEMENT_TELEPORT) && (j != i)) + teleportNumber--; + + if (teleportNumber == 0) + { + SFG_player.camera.position.x = + SFG_ELEMENT_COORD_TO_RCL_UNITS(e2.coords[0]); + + SFG_player.camera.position.y = + SFG_ELEMENT_COORD_TO_RCL_UNITS(e2.coords[1]); + + SFG_player.camera.height = + SFG_floorHeightAt(e2.coords[0],e2.coords[1]) + + RCL_CAMERA_COLL_HEIGHT_BELOW; + + SFG_currentLevel.itemRecords[j] |= SFG_ITEM_RECORD_ACTIVE_MASK; + /* ^ we have to make the new teleport immediately active so + that it will immediately collide */ + + SFG_player.justTeleported = 1; + + SFG_playSoundSafe(4,255); + + break; + } + } + } } } - } - } + } + } // item collision check + + if (!collidesWithTeleport) + SFG_player.justTeleported = 0; #if SFG_PREVIEW_MODE SFG_player.camera.position.x += @@ -2987,26 +3075,24 @@ void SFG_draw() worldPosition.y = SFG_ELEMENT_COORD_TO_RCL_UNITS(e.coords[1]); - uint8_t size = 0; + uint8_t spriteIndex; + uint8_t spriteSize; - if (e.type == SFG_LEVEL_ELEMENT_TREE) - size = 2; - else if (e.type == SFG_LEVEL_ELEMENT_FINISH) - size = 3; + SFG_getLevelElementSprite(e.type,&spriteIndex,&spriteSize); RCL_PixelInfo p = RCL_mapToScreen( worldPosition, SFG_floorHeightAt(e.coords[0],e.coords[1]) - + SFG_SPRITE_SIZE_TO_HEIGH_ABOVE_GROUND(size), + + SFG_SPRITE_SIZE_TO_HEIGH_ABOVE_GROUND(spriteSize), SFG_player.camera); if (p.depth > 0) { SFG_drawScaledSprite( - SFG_itemSprites[SFG_getLevelElementSpriteIndex(e.type)], + SFG_itemSprites[spriteIndex], p.position.x * SFG_RAYCASTING_SUBSAMPLE,p.position.y, - RCL_perspectiveScale(SFG_SPRITE_SIZE(size),p.depth), + RCL_perspectiveScale(SFG_SPRITE_SIZE(spriteSize),p.depth), p.depth / (RCL_UNITS_PER_SQUARE * 2),p.depth - 1000); } }