Make teleports work

This commit is contained in:
Miloslav Číž 2020-02-09 15:03:15 +01:00
parent 175b8526fe
commit d901ecae89
4 changed files with 137 additions and 26 deletions

BIN
assets/item_teleport.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -511,7 +511,7 @@ SFG_PROGRAM_MEMORY uint8_t SFG_itemSprites[][SFG_TEXTURE_STORE_SIZE] =
16,0,0,0,0,0,17,22,36,0,0,0,0,1,167,209,0,0,0,0,0,0,0,1,17,0,0,0,0,0,17,16,0,0,
0,0,0,0,0,0,0
},
{ // 6, finish teleport
{ // 6, finish
175,0,151,3,6,4,143,5,134,55,63,127,2,71,61,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,17,16,0,0,1,17,0,0,1,17,17,16,0,0,0,1,69,17,0,0,20,81,16,0,28,193,17,17,
0,0,0,20,119,81,16,1,71,117,17,0,21,92,28,193,0,1,17,51,51,51,17,19,51,51,49,17,
@ -534,7 +534,31 @@ SFG_PROGRAM_MEMORY uint8_t SFG_itemSprites[][SFG_TEXTURE_STORE_SIZE] =
119,81,16,1,71,117,17,0,20,124,21,81,0,0,0,1,69,17,0,0,20,81,16,0,23,81,19,49,0,
0,0,0,17,16,0,0,1,17,0,0,1,17,17,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
},
{ // 7, access card
{ // 7, teleport
175,0,151,6,3,143,5,134,4,53,55,63,127,45,71,2,0,0,0,0,17,16,0,0,1,17,0,0,0,0,0,
0,0,0,0,1,56,17,0,0,19,129,16,0,1,17,17,16,0,0,0,1,102,129,0,0,22,104,16,0,31,
241,17,17,0,0,0,1,102,129,0,0,22,104,16,0,24,143,31,241,0,1,17,17,68,68,17,17,
20,68,65,17,19,56,248,129,0,20,51,51,51,51,51,51,51,51,51,51,143,51,246,97,0,19,
68,68,34,34,34,37,85,34,34,37,17,99,134,97,0,19,68,187,178,238,165,87,82,34,137,
204,145,68,72,129,0,19,190,37,82,39,82,34,114,85,124,119,159,68,68,65,0,19,68,
39,114,85,85,87,199,204,205,215,223,152,132,65,0,19,190,39,114,85,34,89,121,220,
205,217,223,116,79,241,0,19,69,172,206,165,34,34,85,119,204,119,212,125,70,132,
0,19,68,172,202,170,190,34,85,34,217,153,148,121,70,132,0,19,74,172,203,170,226,
34,85,34,221,153,152,121,70,132,0,19,74,170,187,170,226,34,85,37,124,119,152,
121,134,132,0,19,171,235,226,85,34,37,87,119,199,217,152,121,214,132,0,19,75,
187,178,87,34,85,119,119,199,153,157,121,214,132,0,19,68,187,187,186,34,34,85,
37,119,119,157,121,214,132,0,19,69,187,187,234,178,34,114,34,156,201,152,121,
134,132,0,19,68,90,170,170,174,34,114,34,156,201,152,121,134,132,0,19,170,74,
190,229,114,37,85,119,124,204,152,121,70,132,0,19,90,87,34,37,82,89,121,156,204,
221,157,116,68,241,0,19,68,71,34,37,85,85,119,204,205,215,159,118,51,49,0,19,
165,39,34,34,114,37,114,85,87,85,159,147,54,49,0,19,170,187,178,235,162,34,85,
34,204,153,159,99,134,97,0,19,68,68,34,34,34,34,34,34,37,85,129,131,134,97,0,20,
51,51,51,51,51,51,51,51,51,51,212,99,246,97,0,1,17,17,68,68,17,17,20,68,65,17,
24,54,246,129,0,0,0,1,102,129,0,0,22,104,16,0,19,111,24,129,0,0,0,1,102,129,0,0,
22,104,16,0,22,129,20,65,0,0,0,1,56,17,0,0,19,129,16,0,1,17,17,16,0,0,0,0,17,16,
0,0,1,17,0,0,0,0,0,0
},
{ // 8, access card
175,0,21,45,44,23,46,2,19,34,69,22,68,60,131,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,17,17,17,17,0,0,0,0,0,0,0,0,1,
68,17,24,102,101,86,97,0,0,0,0,0,0,0,0,1,68,17,24,102,85,86,101,16,0,0,0,0,0,0,

View File

@ -94,15 +94,16 @@ typedef struct
#define SFG_LEVEL_ELEMENT_PLASMA 0x05
#define SFG_LEVEL_ELEMENT_TREE 0x06
#define SFG_LEVEL_ELEMENT_FINISH 0x07
#define SFG_LEVEL_ELEMENT_CARD0 0x08 ///< Access card, unlocks doors with lock.
#define SFG_LEVEL_ELEMENT_CARD1 0x09
#define SFG_LEVEL_ELEMENT_CARD2 0x0a
#define SFG_LEVEL_ELEMENT_LOCK0 0x0b /**< Special level element that must be
#define SFG_LEVEL_ELEMENT_TELEPORT 0x08
#define SFG_LEVEL_ELEMENT_CARD0 0x09 ///< Access card, unlocks doors with lock.
#define SFG_LEVEL_ELEMENT_CARD1 0x0a
#define SFG_LEVEL_ELEMENT_CARD2 0x0b
#define SFG_LEVEL_ELEMENT_LOCK0 0x0c /**< Special level element that must be
placed on a tile with door. This door is
then unlocked by taking the corresponding
access card. */
#define SFG_LEVEL_ELEMENT_LOCK1 0x0c
#define SFG_LEVEL_ELEMENT_LOCK2 0x0d
#define SFG_LEVEL_ELEMENT_LOCK1 0x0d
#define SFG_LEVEL_ELEMENT_LOCK2 0x0e
/*
Monsters have lower 4 bits zero and are only distinguished by the 4 upper
@ -295,8 +296,8 @@ SFG_PROGRAM_MEMORY SFG_Level SFG_level0 =
{SFG_LEVEL_ELEMENT_CARD2, {13, 21}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_LOCK1, {3, 21}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_FINISH, {8, 44}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_TELEPORT, {11, 12}}, {SFG_LEVEL_ELEMENT_TELEPORT, {17, 20}},
{SFG_LEVEL_ELEMENT_TELEPORT, {20, 40}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},

110
main.c
View File

@ -251,6 +251,7 @@ struct
for mouse control. */
uint8_t cards; /**< Lowest bits say which access cards have
been taken. */
uint8_t justTeleported;
} SFG_player;
uint8_t SFG_explosionSoundPlayed; /**< Prevents playing too many explosion
@ -306,6 +307,8 @@ struct
uint8_t projectileRecordCount;
uint8_t backgroundImage;
uint8_t teleportCount;
} SFG_currentLevel;
#if SFG_DITHERED_SHADOW
@ -980,6 +983,8 @@ void SFG_initPlayer()
SFG_player.cards = 0;
SFG_player.justTeleported = 0;
for (uint8_t i = 0; i < SFG_AMMO_TOTAL; ++i)
SFG_player.ammo[i] = 0;
}
@ -1033,6 +1038,8 @@ void SFG_setAndInitLevel(const SFG_Level *level)
SFG_currentLevel.projectileRecordCount = 0;
SFG_currentLevel.teleportCount = 0;
for (uint8_t j = 0; j < SFG_MAP_SIZE; ++j)
{
for (uint8_t i = 0; i < SFG_MAP_SIZE; ++i)
@ -1101,6 +1108,9 @@ void SFG_setAndInitLevel(const SFG_Level *level)
SFG_LOG("adding item");
SFG_currentLevel.itemRecords[SFG_currentLevel.itemRecordCount] = i;
SFG_currentLevel.itemRecordCount++;
if (e->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
{
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);
}
}