1
0
mirror of https://github.com/blupi-games/planetblupi synced 2024-12-30 10:15:36 +01:00
planetblupi/src/decmove.cxx

1436 lines
27 KiB
C++
Raw Permalink Normal View History

2017-08-03 22:51:40 +02:00
/*
* This file is part of the planetblupi source code
* Copyright (C) 1997, Daniel Roux & EPSITEC SA
* Copyright (C) 2017, Mathieu Schroeter
* http://epsitec.ch; http://www.blupi.org; http://github.com/blupi-games
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
2017-01-21 17:27:46 +01:00
2017-08-04 00:21:47 +02:00
#include "decmove.h"
2017-02-11 21:43:47 +01:00
#include "decor.h"
#include "misc.h"
2017-08-04 00:21:47 +02:00
// clang-format off
/**
* Movements to shake a tree
* (synchronized with ACTION_PIOCHE).
*/
static Sint16 table_move1[] =
2017-01-21 17:27:46 +01:00
{
9 * 4, // nb
2017-02-24 18:07:03 +01:00
0, 0,
0, 0,
0, 0,
0, 0,
-2, 0,
+2, 0,
-1, 0,
+1, 0,
0, 0,
0, 0,
0, 0,
0, 0,
-2, 0,
+2, 0,
-1, 0,
+1, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
-2, 0,
+2, 0,
-1, 0,
+1, 0,
0, 0,
0, 0,
0, 0,
0, 0,
-2, 0,
+2, 0,
-1, 0,
+1, 0,
2017-01-21 17:27:46 +01:00
};
/**
* Movements to jump an object (east) on Blupi
* (synchronized with ACTION_TAKE).
*/
static Sint16 table_move2[] =
2017-01-21 17:27:46 +01:00
{
9 + 19, // nb
2017-02-24 18:07:03 +01:00
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, -10,
0, -20,
0, -30,
0, -40,
-1, -50,
-3, -60,
-7, -70,
-15, -80,
-22, -70,
-30, -56,
-30, -56,
-30, -56,
-30, -56,
-30, -56,
-30, -56,
-30, -56,
-30, -56,
-30, -56,
-30, -56,
2017-01-21 17:27:46 +01:00
};
/**
* Movements to jump an object (south) on Blupi
* (synchronized with ACTION_TAKE2).
*/
static Sint16 table_move3[] =
2017-01-21 17:27:46 +01:00
{
9 + 19, // nb
2017-02-24 18:07:03 +01:00
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, -10,
0, -20,
0, -30,
0, -40,
1, -50,
3, -60,
7, -70,
15, -80,
22, -70,
30, -56,
30, -56,
30, -56,
30, -56,
30, -56,
30, -56,
30, -56,
30, -56,
30, -56,
30, -56,
2017-01-21 17:27:46 +01:00
};
/**
* Movements to drop and object (east) on Blupi
* (synchronized with ACTION_DEPOSE).
*/
static Sint16 table_move4[] =
2017-01-21 17:27:46 +01:00
{
10, // nb
-30, -60,
-22, -70,
-15, -80,
2017-02-24 18:07:03 +01:00
-7, -70,
-3, -60,
-1, -50,
0, -40,
0, -30,
0, -20,
0, -10,
2017-01-21 17:27:46 +01:00
};
/**
* Movements to drop an object (south) on Blupi
* (synchronized with ACTION_DEPOSE2).
*/
static Sint16 table_move5[] =
2017-01-21 17:27:46 +01:00
{
10, // nb
30, -60,
22, -70,
15, -80,
2017-02-24 18:07:03 +01:00
7, -70,
3, -60,
1, -50,
0, -40,
0, -30,
0, -20,
0, -10,
2017-01-21 17:27:46 +01:00
};
/**
* Movements to push a bridge to the east.
*/
static Sint16 table_move6[] =
2017-01-21 17:27:46 +01:00
{
40, // nb
2017-02-24 18:07:03 +01:00
+2, +1,
+4, +2,
+6, +3,
+8, +4,
+10, +5,
+12, +6,
+14, +7,
+16, +8,
+18, +9,
+20, +10,
+22, +11,
+24, +12,
+26, +13,
+28, +14,
+30, +15,
+32, +16,
+34, +17,
+36, +18,
+38, +19,
+40, +20,
+42, +21,
+44, +22,
+46, +23,
+48, +24,
+50, +25,
+52, +26,
+54, +27,
+56, +28,
+58, +29,
+60, +30,
+60, +30,
+60, +30,
+60, +30,
+60, +30,
+60, +30,
+60, +30,
+60, +30,
+60, +30,
+60, +30,
+60, +30,
2017-01-21 17:27:46 +01:00
};
/**
* Movements to push a bridge to the west.
*/
static Sint16 table_move7[] =
2017-01-21 17:27:46 +01:00
{
40, // nb
2017-02-24 18:07:03 +01:00
-2, -1,
-4, -2,
-6, -3,
-8, -4,
-10, -5,
-12, -6,
-14, -7,
-16, -8,
-18, -9,
-20, -10,
-22, -11,
-24, -12,
-26, -13,
-28, -14,
-30, -15,
-32, -16,
-34, -17,
-36, -18,
-38, -19,
-40, -20,
-42, -21,
-44, -22,
-46, -23,
-48, -24,
-50, -25,
-52, -26,
-54, -27,
-56, -28,
-58, -29,
-60, -30,
-60, -30,
-60, -30,
-60, -30,
-60, -30,
-60, -30,
-60, -30,
-60, -30,
-60, -30,
-60, -30,
-60, -30,
2017-01-21 17:27:46 +01:00
};
/**
* Movements to push a bridge to the south.
*/
static Sint16 table_move8[] =
2017-01-21 17:27:46 +01:00
{
40, // nb
2017-02-24 18:07:03 +01:00
-2, +1,
-4, +2,
-6, +3,
-8, +4,
-10, +5,
-12, +6,
-14, +7,
-16, +8,
-18, +9,
-20, +10,
-22, +11,
-24, +12,
-26, +13,
-28, +14,
-30, +15,
-32, +16,
-34, +17,
-36, +18,
-38, +19,
-40, +20,
-42, +21,
-44, +22,
-46, +23,
-48, +24,
-50, +25,
-52, +26,
-54, +27,
-56, +28,
-58, +29,
-60, +30,
-60, +30,
-60, +30,
-60, +30,
-60, +30,
-60, +30,
-60, +30,
-60, +30,
-60, +30,
-60, +30,
-60, +30,
2017-01-21 17:27:46 +01:00
};
/**
* Movements to push a bridge to the north.
*/
static Sint16 table_move9[] =
2017-01-21 17:27:46 +01:00
{
40, // nb
2017-02-24 18:07:03 +01:00
+2, -1,
+4, -2,
+6, -3,
+8, -4,
+10, -5,
+12, -6,
+14, -7,
+16, -8,
+18, -9,
+20, -10,
+22, -11,
+24, -12,
+26, -13,
+28, -14,
+30, -15,
+32, -16,
+34, -17,
+36, -18,
+38, -19,
+40, -20,
+42, -21,
+44, -22,
+46, -23,
+48, -24,
+50, -25,
+52, -26,
+54, -27,
+56, -28,
+58, -29,
+60, -30,
+60, -30,
+60, -30,
+60, -30,
+60, -30,
+60, -30,
+60, -30,
+60, -30,
+60, -30,
+60, -30,
+60, -30,
2017-01-21 17:27:46 +01:00
};
/**
* Movements to shake a laboratory.
*/
static Sint16 table_move10[] =
2017-01-21 17:27:46 +01:00
{
16 * 4, // nb
2017-02-24 18:07:03 +01:00
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-2, 0,
+2, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
2017-01-21 17:27:46 +01:00
};
/**
* Movements to shake a mine.
*/
static Sint16 table_move11[] =
2017-01-21 17:27:46 +01:00
{
20 * 4, // nb
2017-02-24 18:07:03 +01:00
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, -1,
0, +1,
0, -1,
0, +1,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
0, -1,
0, +1,
2017-01-21 17:27:46 +01:00
};
/**
* Movements to shake a factory.
*/
static Sint16 table_move12[] =
2017-01-21 17:27:46 +01:00
{
20 * 4, // nb
2017-02-24 18:07:03 +01:00
-1, 0,
+1, 0,
-1, 0,
+1, 0,
0, -1,
0, +1,
0, -1,
0, +1,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
-2, 0,
+2, 0,
0, +1,
0, +1,
-2, 0,
+2, 0,
0, +1,
0, +1,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
-2, 0,
+2, 0,
0, +1,
0, +1,
0, 0,
0, 0,
0, 0,
0, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
0, -1,
0, +1,
0, -2,
0, +2,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
0, 0,
0, 0,
0, 0,
0, 0,
-1, 0,
+1, 0,
-1, 0,
+1, 0,
-2, 0,
+2, 0,
0, +1,
0, +1,
-2, 0,
+2, 0,
0, +1,
0, +1,
0, 0,
0, 0,
0, 0,
0, 0,
-2, 0,
+2, 0,
0, +1,
0, +1,
2017-01-21 17:27:46 +01:00
};
2017-08-04 00:21:47 +02:00
// clang-format on
2017-01-21 17:27:46 +01:00
Sint16 *
GetListMoves (Sint32 rank)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
switch (rank)
{
case 1:
return table_move1;
case 2:
return table_move2;
case 3:
return table_move3;
case 4:
return table_move4;
case 5:
return table_move5;
case 6:
return table_move6;
case 7:
return table_move7;
case 8:
return table_move8;
case 9:
return table_move9;
case 10:
return table_move10;
case 11:
return table_move11;
case 12:
return table_move12;
}
return nullptr;
2017-01-21 17:27:46 +01:00
}
2017-08-04 00:21:47 +02:00
// clang-format off
/**
* Small fire.
*/
static Sint16 table_icon1[] =
2017-01-21 17:27:46 +01:00
{
8 * 3,
49, 50, 51, 52, 50, 49, 51, 52,
49, 52, 51, 50, 49, 52, 50, 49,
52, 51, 50, 49, 51, 52, 49, 51,
2017-01-21 17:27:46 +01:00
};
/**
* Large fire.
*/
static Sint16 table_icon2[] =
2017-01-21 17:27:46 +01:00
{
8 * 3,
45, 46, 47, 48, 46, 45, 48, 47,
46, 45, 48, 47, 45, 48, 47, 48,
46, 45, 48, 47, 45, 48, 47, 46,
2017-01-21 17:27:46 +01:00
};
// Eclairs de la dalle nurserie.
static Sint16 table_icon3[] =
2017-01-21 17:27:46 +01:00
{
4, // nb
53, 54, 55, 56,
2017-01-21 17:27:46 +01:00
};
// Eclairs n-s entre les tours.
static Sint16 table_icon4[] =
2017-01-21 17:27:46 +01:00
{
8 * 4, // nb
74, 76, 78, 76, 74, 78, 74, 76,
78, 76, 74, 76, 74, 76, 78, 76,
74, 78, 76, 74, 76, 78, 74, 76,
78, 74, 76, 78, 74, 76, 74, 78,
2017-01-21 17:27:46 +01:00
};
// Eclairs e-o entre les tours.
static Sint16 table_icon5[] =
2017-01-21 17:27:46 +01:00
{
8 * 4, // nb
75, 77, 75, 79, 75, 77, 79, 75,
79, 77, 75, 77, 75, 79, 75, 79,
75, 77, 79, 75, 75, 77, 79, 75,
79, 75, 77, 79, 75, 79, 75, 79,
2017-01-21 17:27:46 +01:00
};
// Explosion de la dynamite.
static Sint16 table_icon6[] =
2017-01-21 17:27:46 +01:00
{
7 + 30, // nb
91, 90, 89, 88, 89, 90, 91,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
2017-01-21 17:27:46 +01:00
};
2017-02-12 00:44:46 +01:00
// Mèche de la dynamite.
static Sint16 table_icon7[] =
2017-01-21 17:27:46 +01:00
{
12 * 4, // nb
86, 87, 86, 87, 86, 87, 86, 87, 86, 87, 86, 87,
86, 87, 86, 87, 86, 87, 86, 87, 86, 87, 86, 87,
86, 87, 86, 87, 86, 87, 86, 87, 86, 87, 86, 87,
86, 87, 86, 87, 86, 87, 86, 87, 86, 87, 86, 87,
2017-01-21 17:27:46 +01:00
};
2017-02-12 00:44:46 +01:00
// Rayons de l'électrocuteur.
static Sint16 table_icon8[] =
2017-01-21 17:27:46 +01:00
{
10 * 10, // nb
75, -1, -1, 74, -1, 75, -1, 74, 75, -1,
74, 73, -1, 75, 74, 73, 72, 74, -1, 72,
73, 74, 72, 73, 75, 73, 72, 73, 74, 72,
75, 72, 73, 72, -1, 74, 73, 72, 75, 74,
-1, 73, 74, 75, -1, 74, 75, -1, 75, -1,
74, 75, -1, -1, 74, -1, -1, -1, 75, -1,
-1, -1, -1, -1, -1, 74, -1, -1, -1, 75,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 75, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 74,
2017-01-21 17:27:46 +01:00
};
2017-02-12 00:44:46 +01:00
// Blupi écrasé.
static Sint16 table_icon9[] =
2017-01-21 17:27:46 +01:00
{
10 * 10, // nb
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
2017-01-21 17:27:46 +01:00
};
2017-02-12 00:44:46 +01:00
// Blupi malade écrasé.
static Sint16 table_icon10[] =
2017-01-21 17:27:46 +01:00
{
10 * 10, // nb
77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
2017-01-21 17:27:46 +01:00
};
2017-02-12 00:44:46 +01:00
// Eclairs de la dalle téléporteur.
static Sint16 table_icon11[] =
2017-01-21 17:27:46 +01:00
{
4, // nb
81, 82, 83, 84,
2017-01-21 17:27:46 +01:00
};
2017-08-04 00:21:47 +02:00
// clang-format on
2017-01-21 17:27:46 +01:00
Sint16 *
GetListIcons (Sint32 rank)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
switch (rank)
{
case 1:
return table_icon1;
case 2:
return table_icon2;
case 3:
return table_icon3;
case 4:
return table_icon4;
case 5:
return table_icon5;
case 6:
return table_icon6;
case 7:
return table_icon7;
case 8:
return table_icon8;
case 9:
return table_icon9;
case 10:
return table_icon10;
case 11:
return table_icon11;
}
return nullptr;
2017-01-21 17:27:46 +01:00
}
/**
* \brief Remove all animated environments.
*/
void
CDecor::MoveFlush ()
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 i, x, y;
2017-08-04 00:21:47 +02:00
for (i = 0; i < MAXMOVE; i++)
m_move[i].bExist = false;
2017-08-04 00:21:47 +02:00
for (x = 0; x < MAXCELX / 2; x++)
{
for (y = 0; y < MAXCELY / 2; y++)
m_decor[x][y].rankMove = -1;
}
2017-01-21 17:27:46 +01:00
}
/**
* \brief Get the fire duration.
*
* \returns the duration.
*/
Sint32
CDecor::MoveMaxFire ()
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
if (m_skill >= 1)
return (MAXFIRE / 4) * 3;
return MAXFIRE;
2017-01-21 17:27:46 +01:00
}
/**
* \brief Initialize all environment perpetual movements.
*/
void
CDecor::MoveFixInit ()
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 x, y;
2017-08-04 00:21:47 +02:00
MoveFlush ();
2017-08-04 00:21:47 +02:00
for (x = 0; x < MAXCELX; x += 2)
{
for (y = 0; y < MAXCELY; y += 2)
{
2017-08-04 00:21:47 +02:00
// Démarre le feu.
if (
m_decor[x / 2][y / 2].fire > 0 &&
m_decor[x / 2][y / 2].fire < MoveMaxFire ())
MoveStartFire (GetCel (x, y));
// Démarre les éclairs entre les tours.
if (m_decor[x / 2][y / 2].objectIcon == 10000) // éclair n-s
{
if (MoveCreate (
GetCel (x, y), -1, false, CHOBJECT, -1, -1, -1, 9999, 1, 0, true))
{
2017-08-04 00:21:47 +02:00
MoveAddIcons (GetCel (x, y), 4, true); // éclairs n-s
}
2017-08-04 00:21:47 +02:00
}
if (m_decor[x / 2][y / 2].objectIcon == 10001) // éclair e-o
{
if (MoveCreate (
GetCel (x, y), -1, false, CHOBJECT, -1, -1, -1, 9999, 1, 0, true))
{
MoveAddIcons (GetCel (x, y), 5, true); // éclairs e-o
}
}
}
2017-08-04 00:21:47 +02:00
}
2017-01-21 17:27:46 +01:00
}
/**
* \brief Create a new animated environment.
*
* If \p bMisc is true, we keep 10 movements back for important
* actions (\p bMisc == false).
*
* \param[in] cel - ?
* \param[in] rankBlupi - ?
* \param[in] bFloor - ?
* \param[in] channel - ?
* \param[in] icon - ?
* \param[in] maskChannel - ?
* \param[in] maskIcon - ?
* \param[in] total - ?
* \param[in] delai - ?
* \param[in] stepY - ?
* \param[in] bMisc - ?
* \param[in] bNotIfExist - ?
* \returns true on success.
*/
bool
CDecor::MoveCreate (
2017-08-21 22:08:25 +02:00
Point cel, Sint32 rankBlupi, bool bFloor, Sint32 channel, Sint32 icon,
2017-08-04 00:21:47 +02:00
Sint32 maskChannel, Sint32 maskIcon, Sint32 total, Sint32 delai, Sint32 stepY,
bool bMisc, bool bNotIfExist)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 rank, max;
2017-08-04 00:21:47 +02:00
for (rank = 0; rank < MAXMOVE; rank++)
{
if (
m_move[rank].bExist && m_move[rank].cel.x == cel.x &&
m_move[rank].cel.y == cel.y)
{
2017-08-04 00:21:47 +02:00
if (bNotIfExist)
return false;
goto create;
}
2017-08-04 00:21:47 +02:00
}
2017-08-04 00:21:47 +02:00
max = 0;
for (rank = 0; rank < MAXMOVE; rank++)
{
if (!m_move[rank].bExist)
{
2017-08-04 00:21:47 +02:00
if (bMisc && max > MAXMOVE - 10)
return false;
goto create;
}
2017-08-04 00:21:47 +02:00
max++;
}
return false;
create:
2017-08-04 00:21:47 +02:00
m_move[rank].bExist = true;
m_move[rank].cel = cel;
m_move[rank].rankBlupi = rankBlupi;
m_move[rank].bFloor = bFloor;
m_move[rank].channel = channel;
m_move[rank].icon = icon;
m_move[rank].maskChannel = maskChannel;
m_move[rank].maskIcon = maskIcon;
m_move[rank].total = total;
m_move[rank].delai = delai;
m_move[rank].stepY = stepY;
m_move[rank].cTotal = 0;
m_move[rank].cDelai = 0;
m_move[rank].rankMoves = 0;
m_move[rank].rankIcons = 0;
m_move[rank].phase = 0;
m_decor[cel.x / 2][cel.y / 2].rankMove = rank;
return true;
2017-01-21 17:27:46 +01:00
}
// Ajoute un mouvement.
bool
2017-08-21 22:08:25 +02:00
CDecor::MoveAddMoves (Point cel, Sint32 rankMoves)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 rank;
2017-08-04 00:21:47 +02:00
for (rank = 0; rank < MAXMOVE; rank++)
{
if (
m_move[rank].bExist && m_move[rank].cel.x == cel.x &&
m_move[rank].cel.y == cel.y)
{
2017-08-04 00:21:47 +02:00
m_move[rank].rankMoves = rankMoves;
m_move[rank].phase = 0;
2017-08-04 00:21:47 +02:00
return true;
}
2017-08-04 00:21:47 +02:00
}
2017-08-04 00:21:47 +02:00
return false;
2017-01-21 17:27:46 +01:00
}
// Ajoute un mouvement.
bool
2017-08-21 22:08:25 +02:00
CDecor::MoveAddIcons (Point cel, Sint32 rankIcons, bool bContinue)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 rank;
2017-08-04 00:21:47 +02:00
for (rank = 0; rank < MAXMOVE; rank++)
{
if (
m_move[rank].bExist && m_move[rank].cel.x == cel.x &&
m_move[rank].cel.y == cel.y)
{
2017-08-04 00:21:47 +02:00
m_move[rank].rankIcons = rankIcons;
if (!bContinue)
m_move[rank].phase = 0;
2017-08-04 00:21:47 +02:00
if (rankIcons == 4 || rankIcons == 5) // éclairs entre tours ?
m_move[rank].cTotal = Random (0, 10);
2017-08-04 00:21:47 +02:00
return true;
}
2017-08-04 00:21:47 +02:00
}
2017-08-04 00:21:47 +02:00
return false;
2017-01-21 17:27:46 +01:00
}
2017-02-24 18:38:06 +01:00
/**
* \brief Start the fire on a cell.
*
* \param[in] cel - Position.
* \returns true if possible.
*/
bool
2017-08-21 22:08:25 +02:00
CDecor::MoveStartFire (Point cel)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 channel, icon;
cel.x = (cel.x / 2) * 2;
cel.y = (cel.y / 2) * 2;
channel = m_decor[cel.x / 2][cel.y / 2].objectChannel;
icon = m_decor[cel.x / 2][cel.y / 2].objectIcon;
if (
channel == CHOBJECT && ((icon >= 6 && icon <= 11) // trees ?
|| (icon >= 65 && icon <= 71) // palissade ?
|| icon == 61 // cabane ?
|| icon == 36 // planches ?
|| icon == 60 // tomatoes ?
|| icon == 63 // eggs ?
|| icon == 113 // house ?
|| icon == 121 // mine de fer ?
|| icon == 122 // mine de fer ?
))
{
if (!MoveCreate (cel, -1, false, CHOBJECT, -1, -1, -1, 9999, 1, 0, true))
return false;
MoveAddIcons (cel, 1, true); // small fire
m_decor[cel.x / 2][cel.y / 2].fire = 2;
return true;
}
2017-08-04 00:21:47 +02:00
// If there is an other object, then no fire.
if (channel >= 0)
return false;
2017-08-04 00:21:47 +02:00
channel = m_decor[cel.x / 2][cel.y / 2].floorChannel;
icon = m_decor[cel.x / 2][cel.y / 2].floorIcon;
2017-08-04 00:21:47 +02:00
if (
channel == CHFLOOR && (icon == 20 || // herbe foncée ?
(icon >= 59 && icon <= 64))) // bridge ?
{
if (!MoveCreate (cel, -1, false, CHOBJECT, -1, -1, -1, 9999, 1, 0, true))
return false;
2017-08-04 00:21:47 +02:00
MoveAddIcons (cel, 1, true); // small fire
m_decor[cel.x / 2][cel.y / 2].fire = 2;
return true;
}
2017-08-04 00:21:47 +02:00
return false;
2017-01-21 17:27:46 +01:00
}
2017-02-12 00:44:46 +01:00
// Démarre le feu si c'est possible par proximité.
2017-01-21 17:27:46 +01:00
void
2017-08-21 22:08:25 +02:00
CDecor::MoveProxiFire (Point cel)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 cx, cy, xx, yy, x, y, channel, icon;
static Sint16 tableInd[5] = {2, 1, 3, 0, 4};
// clang-format off
static Sint16 tablePos[5 * 5 * 2] =
{
0, 0, -1, -2, 0, -2, +1, -2, 0, 0,
-2, -1, -1, -1, 0, -1, +1, -1, +2, -1,
-2, 0, -1, 0, 0, 0, +1, 0, +2, 0,
-2, +1, -1, +1, 0, +1, +1, +1, +2, +1,
0, 0, -1, +2, 0, +2, +1, +2, 0, 0,
};
// clang-format on
for (cx = 0; cx < 5; cx++)
{
for (cy = 0; cy < 5; cy++)
{
2017-08-04 00:21:47 +02:00
xx = tablePos[(tableInd[cx] + tableInd[cy] * 5) * 2 + 0];
yy = tablePos[(tableInd[cx] + tableInd[cy] * 5) * 2 + 1];
if (xx == 0 && yy == 0)
continue;
x = cel.x + xx * 2;
y = cel.y + yy * 2;
if (x < 0 || x >= MAXCELX || y < 0 || y >= MAXCELX)
continue;
if (m_decor[x / 2][y / 2].fire != 0)
continue; // brule déjà ?
x = ((cel.x + xx) / 2) * 2;
y = ((cel.y + yy) / 2) * 2;
// Mur ou rochers entre le feu et l'objet ?
channel = m_decor[x / 2][y / 2].objectChannel;
icon = m_decor[x / 2][y / 2].objectIcon;
if (
channel == CHOBJECT &&
((icon >= 20 && icon <= 26) || (icon >= 37 && icon <= 43)))
continue;
x = cel.x + xx * 2;
y = cel.y + yy * 2;
// Mur ou rochers entre le feu et l'objet ?
channel = m_decor[x / 2][y / 2].objectChannel;
icon = m_decor[x / 2][y / 2].objectIcon;
if (
channel == CHOBJECT &&
((icon >= 20 && icon <= 26) || (icon >= 37 && icon <= 43)))
continue;
// Démarre éventuellement un seul foyer.
if (MoveStartFire (GetCel (x, y)))
return;
}
2017-08-04 00:21:47 +02:00
}
2017-01-21 17:27:46 +01:00
}
2017-02-12 00:44:46 +01:00
// Fait évoluer le feu.
2017-01-21 17:27:46 +01:00
void
CDecor::MoveFire (Sint32 rank)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 x, y, icon, newIcon;
2017-08-21 22:08:25 +02:00
Point pos;
2017-08-04 00:21:47 +02:00
x = (m_move[rank].cel.x / 2) * 2;
y = (m_move[rank].cel.y / 2) * 2;
2017-08-04 00:21:47 +02:00
if (
m_decor[x / 2][y / 2].fire == 0 ||
m_decor[x / 2][y / 2].fire >= MoveMaxFire ())
return;
2017-08-04 00:21:47 +02:00
m_decor[x / 2][y / 2].fire++;
2017-08-04 00:21:47 +02:00
pos = ConvCelToPos (GetCel (x, y));
2017-08-10 00:02:23 +02:00
m_pSound->PlayImage (SOUND_FIRE, pos);
2017-08-04 00:21:47 +02:00
if (m_decor[x / 2][y / 2].objectIcon >= 0) // objet qui brule ?
{
if (
m_decor[x / 2][y / 2].fire > MoveMaxFire () / 2 &&
m_decor[x / 2][y / 2].fire % 50 == 0) // pas trop souvent !
{
2017-08-04 00:21:47 +02:00
MoveProxiFire (GetCel (x, y)); // boutte le feu
}
2017-08-04 00:21:47 +02:00
// Début petites flammes.
if (m_decor[x / 2][y / 2].fire == 2)
MoveStartFire (GetCel (x, y));
2017-08-04 00:21:47 +02:00
// Début grandes flammes.
if (m_decor[x / 2][y / 2].fire == (MoveMaxFire () - DIMOBJY * 2) / 2)
{
MoveAddIcons (GetCel (x, y), 2, true); // grandes flammes
}
2017-08-04 00:21:47 +02:00
// Début objet squelette.
if (m_decor[x / 2][y / 2].fire == MoveMaxFire () - DIMOBJY * 2)
{
icon = m_decor[x / 2][y / 2].floorIcon;
if (icon == 20) // herbe foncée ?
{
PutFloor (GetCel (x, y), CHFLOOR, 19); // herbe brulée
}
icon = m_decor[x / 2][y / 2].objectIcon;
newIcon = -1;
if (icon >= 6 && icon <= 11)
newIcon = icon - 6 + 30; // arbres ?
if (icon == 61)
newIcon = 62; // cabane ?
if (icon == 113)
newIcon = 15; // maison ?
if (icon == 121)
newIcon = 126; // mine de fer ?
if (icon == 122)
newIcon = 126; // mine de fer ?
MoveCreate (
GetCel (x, y), -1, false, CHOBJECT, newIcon, -1, -1, DIMOBJY * 2, 1,
-1 * 50);
MoveAddIcons (GetCel (x, y), 2, true); // grandes flammes
}
2017-08-04 00:21:47 +02:00
// Fin grandes flammes.
if (m_decor[x / 2][y / 2].fire == MoveMaxFire () - DIMOBJY)
{
MoveAddIcons (GetCel (x, y), 1, true); // petites flammes
}
2017-08-04 00:21:47 +02:00
// Fin feu.
if (m_decor[x / 2][y / 2].fire == MoveMaxFire () - 1)
{
MoveFinish (GetCel (x, y));
icon = m_decor[x / 2][y / 2].objectIcon;
if (
icon == 36 || // planches ?
icon == 60 || // tomates ?
icon == 63 || // oeufs ?
icon == 113 || // maison ?
(icon >= 65 && icon <= 71)) // palissade ?
{
m_decor[x / 2][y / 2].objectChannel = -1;
m_decor[x / 2][y / 2].objectIcon = -1;
}
m_decor[x / 2][y / 2].fire = MoveMaxFire (); // déjà brulé
}
2017-08-04 00:21:47 +02:00
}
else // sol qui brule ?
{
if (
m_decor[x / 2][y / 2].fire > DIMOBJY &&
m_decor[x / 2][y / 2].fire % 50 == 0) // pas trop souvent !
{
2017-08-04 00:21:47 +02:00
MoveProxiFire (GetCel (x, y)); // boutte le feu
}
2017-08-04 00:21:47 +02:00
// Début petites flammes.
if (m_decor[x / 2][y / 2].fire == 2)
MoveStartFire (GetCel (x, y));
2017-08-04 00:21:47 +02:00
// Milieu feu.
if (m_decor[x / 2][y / 2].fire == DIMOBJY)
{
icon = m_decor[x / 2][y / 2].floorIcon;
switch (icon)
{
case 20: // herbe foncée ?
PutFloor (GetCel (x, y), CHFLOOR, 19); // herbe brulée
break;
case 59: // pont ?
PutFloor (GetCel (x, y), CHFLOOR, 2); // rivage
break;
case 61: // pont ?
PutFloor (GetCel (x, y), CHFLOOR, 4); // rivage
break;
case 62: // pont ?
PutFloor (GetCel (x, y), CHFLOOR, 3); // rivage
break;
case 64: // pont ?
PutFloor (GetCel (x, y), CHFLOOR, 5); // rivage
break;
case 60:
case 63: // pont ?
PutFloor (GetCel (x, y), CHFLOOR, 14); // eau
break;
}
}
2017-08-04 00:21:47 +02:00
// Fin feu.
if (m_decor[x / 2][y / 2].fire == DIMOBJY * 2 - 1)
{
MoveFinish (GetCel (x, y));
m_decor[x / 2][y / 2].objectChannel = -1;
m_decor[x / 2][y / 2].objectIcon = -1;
m_decor[x / 2][y / 2].fire = MoveMaxFire (); // déjà brulé
}
2017-08-04 00:21:47 +02:00
}
2017-01-21 17:27:46 +01:00
}
2017-02-12 00:44:46 +01:00
// Fait évoluer tous les décors animés.
2017-01-21 17:27:46 +01:00
void
CDecor::MoveStep (bool bFirst)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 rank, rankBlupi;
2017-08-04 00:21:47 +02:00
for (rank = 0; rank < MAXMOVE; rank++)
{
if (m_move[rank].bExist)
{
2017-08-04 00:21:47 +02:00
if (
!bFirst && (m_move[rank].rankIcons == 4 || // éclair entre tours ?
m_move[rank].rankIcons == 5))
continue;
MoveFire (rank);
// Si le blupi travaillant ici est stoppé, on
// arrête aussi la construction.
rankBlupi = m_move[rank].rankBlupi;
if (rankBlupi != -1)
{
if (
m_blupi[rankBlupi].action == ACTION_STOP ||
m_blupi[rankBlupi].action == ACTION_STOPTIRED)
2017-08-04 00:21:47 +02:00
continue;
}
m_move[rank].phase++;
if (m_move[rank].phase > 32000)
m_move[rank].phase = 0;
m_move[rank].cDelai++;
if (m_move[rank].cDelai >= m_move[rank].delai) // délai écoulé ?
{
m_move[rank].cDelai = 0;
m_move[rank].cTotal++;
if (m_move[rank].cTotal > 32000)
m_move[rank].cTotal = 0;
if (
m_move[rank].total != 9999 &&
m_move[rank].cTotal >= m_move[rank].total)
MoveFinish (m_move[rank].cel);
}
}
2017-08-04 00:21:47 +02:00
}
2017-01-21 17:27:46 +01:00
}
2017-02-12 00:44:46 +01:00
// Termine un mouvement pour une cellule donnée.
2017-01-21 17:27:46 +01:00
void
2017-08-21 22:08:25 +02:00
CDecor::MoveFinish (Point cel)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 rank;
2017-08-04 00:21:47 +02:00
for (rank = 0; rank < MAXMOVE; rank++)
{
if (
m_move[rank].bExist && m_move[rank].cel.x == cel.x &&
m_move[rank].cel.y == cel.y)
{
2017-08-04 00:21:47 +02:00
if (m_move[rank].channel >= 0 && m_move[rank].icon >= 0)
{
if (m_move[rank].bFloor)
PutFloor (cel, m_move[rank].channel, m_move[rank].icon);
else
PutObject (cel, m_move[rank].channel, m_move[rank].icon);
}
m_decor[cel.x / 2][cel.y / 2].rankMove = -1;
m_move[rank].bExist = false;
}
2017-08-04 00:21:47 +02:00
}
2017-01-21 17:27:46 +01:00
}
2017-02-12 00:44:46 +01:00
// Termine un mouvement, d'après le rang du blupi.
2017-01-21 17:27:46 +01:00
void
CDecor::MoveFinish (Sint32 rankBlupi)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 rank;
2017-08-04 00:21:47 +02:00
for (rank = 0; rank < MAXMOVE; rank++)
{
if (m_move[rank].bExist && m_move[rank].rankBlupi == rankBlupi)
MoveFinish (m_move[rank].cel);
}
2017-01-21 17:27:46 +01:00
}
2017-02-12 00:44:46 +01:00
// Vérifie si une cellule est déjà utilisée.
2017-01-21 17:27:46 +01:00
bool
2017-08-21 22:08:25 +02:00
CDecor::MoveIsUsed (Point cel)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 rank;
2017-08-04 00:21:47 +02:00
for (rank = 0; rank < MAXMOVE; rank++)
{
if (
m_move[rank].bExist && m_move[rank].cel.x == cel.x &&
m_move[rank].cel.y == cel.y)
return true;
}
2017-08-04 00:21:47 +02:00
return false;
2017-01-21 17:27:46 +01:00
}
2017-02-12 00:44:46 +01:00
// Retourne l'objet en construction à un endroit donné.
2017-01-21 17:27:46 +01:00
bool
2017-08-21 22:08:25 +02:00
CDecor::MoveGetObject (Point cel, Sint32 & channel, Sint32 & icon)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 rank;
2017-08-04 00:21:47 +02:00
for (rank = 0; rank < MAXMOVE; rank++)
{
if (
m_move[rank].bExist && m_move[rank].cel.x == cel.x &&
m_move[rank].cel.y == cel.y && m_move[rank].bFloor == false)
{
2017-08-04 00:21:47 +02:00
channel = m_move[rank].channel;
icon = m_move[rank].icon;
return true;
}
2017-08-04 00:21:47 +02:00
}
2017-08-04 00:21:47 +02:00
return false;
2017-01-21 17:27:46 +01:00
}
2017-02-12 00:44:46 +01:00
// Modifie un objet en construction à un endroit donné.
2017-01-21 17:27:46 +01:00
bool
2017-08-21 22:08:25 +02:00
CDecor::MovePutObject (Point cel, Sint32 channel, Sint32 icon)
2017-01-21 17:27:46 +01:00
{
2017-08-04 00:21:47 +02:00
Sint32 rank;
2017-08-04 00:21:47 +02:00
for (rank = 0; rank < MAXMOVE; rank++)
{
if (
m_move[rank].bExist && m_move[rank].cel.x == cel.x &&
m_move[rank].cel.y == cel.y && m_move[rank].bFloor == false)
{
2017-08-04 00:21:47 +02:00
m_move[rank].channel = channel;
m_move[rank].icon = icon;
return true;
}
2017-08-04 00:21:47 +02:00
}
2017-08-04 00:21:47 +02:00
return false;
2017-01-21 17:27:46 +01:00
}