TWINE: hide min/max values of inventory items

also extract the max life points of an actor into a constant
This commit is contained in:
Martin Gerhardy 2021-02-26 11:03:23 +01:00
parent 9743f36d95
commit 9275999d9b
10 changed files with 126 additions and 102 deletions

View file

@ -243,7 +243,7 @@ bool TwinEConsole::doGiveKey(int argc, const char **argv) {
if (argc >= 2) {
amount = atoi(argv[1]);
}
_engine->_gameState->setKeys(_engine->_gameState->inventoryNumKeys + amount);
_engine->_gameState->addKeys(amount);
return true;
}
@ -252,7 +252,7 @@ bool TwinEConsole::doGiveGas(int argc, const char **argv) {
if (argc >= 2) {
amount = atoi(argv[1]);
}
_engine->_gameState->setGas(_engine->_gameState->inventoryNumGas + amount);
_engine->_gameState->addGas(amount);
return true;
}
@ -261,7 +261,7 @@ bool TwinEConsole::doGiveKashes(int argc, const char **argv) {
if (argc >= 2) {
amount = atoi(argv[1]);
}
_engine->_gameState->setKashes(_engine->_gameState->inventoryNumKashes + amount);
_engine->_gameState->addKashes(amount);
return true;
}
@ -401,25 +401,12 @@ bool TwinEConsole::doGiveAllItems(int argc, const char **argv) {
if (argc >= 2) {
amount = atoi(argv[1]);
}
state->inventoryNumKeys += amount;
state->inventoryNumKashes += amount;
state->inventoryNumLeafsBox += amount;
state->inventoryNumLeafs += amount;
state->inventoryMagicPoints += amount;
state->setGas(state->inventoryNumGas + amount);
state->setKashes(state->inventoryNumKashes + amount);
if (state->inventoryNumLeafsBox > 10) {
state->inventoryNumLeafsBox = 10;
}
if (state->inventoryNumLeafs > state->inventoryNumLeafsBox) {
state->inventoryNumLeafs = state->inventoryNumLeafsBox;
}
if (state->inventoryMagicPoints > state->magicLevelIdx * 20) {
state->inventoryMagicPoints = state->magicLevelIdx * 20;
}
state->addKeys(amount);
state->addLeafBoxes(amount);
state->addKashes(amount);
state->addLeafs(amount);
state->addMagicPoints(amount);
state->addGas(amount);
return true;
}
@ -429,10 +416,7 @@ bool TwinEConsole::doSetLife(int argc, const char **argv) {
debugPrintf("Expected to get the life points as parameter\n");
return true;
}
_engine->_scene->sceneHero->life = atoi(argv[1]);
if (_engine->_scene->sceneHero->life > 50) {
_engine->_scene->sceneHero->life = 50;
}
_engine->_scene->sceneHero->setLife(atoi(argv[1]));
return true;
}

View file

@ -819,11 +819,6 @@ void Menu::drawHealthBar(int32 left, int32 right, int32 top, int32 barLeftPaddin
}
void Menu::drawCloverLeafs(int32 newBoxLeft, int32 boxRight, int32 top) {
// prevent
if (_engine->_gameState->inventoryNumLeafs > _engine->_gameState->inventoryNumLeafsBox) {
_engine->_gameState->inventoryNumLeafs = _engine->_gameState->inventoryNumLeafsBox;
}
// Clover leaf boxes
for (int32 i = 0; i < _engine->_gameState->inventoryNumLeafsBox; i++) {
const int32 leftSpritePos = _engine->_screens->crossDot(newBoxLeft, boxRight, 10, i);

View file

@ -363,9 +363,7 @@ void Renderer::setLightVector(int32 angleX, int32 angleY, int32 angleZ) {
applyRotation(&shadeMatrix, &baseMatrix);
translateGroup(0, 0, 59);
lightPos.x = destPos.x;
lightPos.y = destPos.y;
lightPos.z = destPos.z;
lightPos = destPos;
}
FORCEINLINE int16 clamp(int16 x, int16 a, int16 b) {

View file

@ -381,7 +381,7 @@ void Actor::resetActor(int16 actorIdx) {
memset(&actor->dynamicFlags, 0, sizeof(DynamicFlagsStruct));
memset(&actor->bonusParameter, 0, sizeof(BonusParameter));
actor->life = 50;
actor->life = kActorMaxLife;
actor->armor = 1;
actor->hitBy = -1;
actor->lastRotationAngle = ANGLE_0;

View file

@ -157,6 +157,8 @@ struct BonusParameter {
// but don't take the current state in account
#define kAnimationType_4 4
#define kActorMaxLife 50
/**
* Actors structure
*
@ -214,6 +216,10 @@ public:
int32 armor = 0; // field_14
int32 life = 0;
void addLife(int32 val);
void setLife(int32 val);
Vec3 collisionPos;
int32 positionInMoveScript = 0;
@ -246,6 +252,17 @@ public:
AnimTimerDataStruct animTimerData;
};
inline void ActorStruct::addLife(int32 val) {
setLife(life + val);
}
inline void ActorStruct::setLife(int32 val) {
life = val;
if (life > kActorMaxLife) {
life = kActorMaxLife;
}
}
class TwinEEngine;
class Actor {

View file

@ -696,7 +696,7 @@ void Extra::processExtras() {
_engine->_redraw->addOverlay(OverlayType::koSprite, SPRITEHQR_KEY, 10, 30, 0, OverlayPosType::koNormal, 2);
_engine->_gameState->inventoryNumKeys += extraKey->info1;
_engine->_gameState->addKeys(extraKey->info1);
extraKey->info0 = -1;
extra->info0 = -1;
@ -729,7 +729,7 @@ void Extra::processExtras() {
_engine->_redraw->addOverlay(OverlayType::koSprite, SPRITEHQR_KEY, 10, 30, 0, OverlayPosType::koNormal, 2);
_engine->_gameState->inventoryNumKeys += extraKey->info1;
_engine->_gameState->addKeys(extraKey->info1);
extraKey->info0 = -1;
extra->info0 = -1;
@ -774,12 +774,12 @@ void Extra::processExtras() {
}
// process extra collision with scene ground
if (extra->type & ExtraType::UNK3) {
int32 process = 0;
bool process = false;
if (_engine->_collision->checkExtraCollisionWithBricks(currentExtraX, currentExtraY, currentExtraZ, extra->pos.x, extra->pos.y, extra->pos.z)) {
// if not touch the ground
if (!(extra->type & ExtraType::WAIT_NO_COL)) {
process = 1;
process = true;
}
} else {
// if touch the ground
@ -841,12 +841,12 @@ void Extra::processExtras() {
}
// extra stop moving while collision with bricks
if (extra->type & ExtraType::STOP_COL) {
int32 process = 0;
bool process = false;
if (_engine->_collision->checkExtraCollisionWithBricks(currentExtraX, currentExtraY, currentExtraZ, extra->pos.x, extra->pos.y, extra->pos.z)) {
// if not touch the ground
if (!(extra->type & ExtraType::WAIT_NO_COL)) {
process = 1;
process = true;
}
} else {
// if touch the ground
@ -877,30 +877,15 @@ void Extra::processExtras() {
_engine->_redraw->addOverlay(OverlayType::koSprite, extra->info0, 10, 30, 0, OverlayPosType::koNormal, 2);
if (extra->info0 == SPRITEHQR_KASHES) {
_engine->_gameState->inventoryNumKashes += extra->info1;
if (_engine->_gameState->inventoryNumKashes > 999) {
_engine->_gameState->inventoryNumKashes = 999;
}
if (_engine->_gameState->inventoryNumKashes >= 500) {
_engine->unlockAchievement("LBA_ACH_011");
}
_engine->_gameState->addKashes(extra->info1);
} else if (extra->info0 == SPRITEHQR_LIFEPOINTS) {
_engine->_scene->sceneHero->life += extra->info1;
if (_engine->_scene->sceneHero->life > 50) {
_engine->_scene->sceneHero->life = 50;
}
_engine->_scene->sceneHero->addLife(extra->info1);
} else if (extra->info0 == SPRITEHQR_MAGICPOINTS && _engine->_gameState->magicLevelIdx) {
_engine->_gameState->inventoryMagicPoints += extra->info1 * 2;
if (_engine->_gameState->inventoryMagicPoints > _engine->_gameState->magicLevelIdx * 20) {
_engine->_gameState->inventoryMagicPoints = _engine->_gameState->magicLevelIdx * 20;
}
_engine->_gameState->addMagicPoints(extra->info1 * 2);
} else if (extra->info0 == SPRITEHQR_KEY) {
_engine->_gameState->inventoryNumKeys += extra->info1;
_engine->_gameState->addKeys(extra->info1);
} else if (extra->info0 == SPRITEHQR_CLOVERLEAF) {
_engine->_gameState->inventoryNumLeafs += extra->info1;
if (_engine->_gameState->inventoryNumLeafs > _engine->_gameState->inventoryNumLeafsBox) {
_engine->_gameState->inventoryNumLeafs = _engine->_gameState->inventoryNumLeafsBox;
}
_engine->_gameState->addLeafs(extra->info1);
}
extra->info0 = -1;

View file

@ -100,7 +100,7 @@ void GameState::initHeroVars() {
usingSabre = false;
_engine->_scene->sceneHero->body = BodyType::btNormal;
_engine->_scene->sceneHero->life = 50;
_engine->_scene->sceneHero->life = kActorMaxLife;
_engine->_scene->sceneHero->talkColor = COLOR_BRIGHT_BLUE;
}
@ -187,11 +187,11 @@ bool GameState::loadGame(Common::SeekableReadStream *file) {
_engine->_actor->heroBehaviour = (HeroBehaviourType)file->readByte();
_engine->_actor->previousHeroBehaviour = _engine->_actor->heroBehaviour;
_engine->_scene->sceneHero->life = file->readByte();
inventoryNumKashes = file->readSint16LE();
_engine->_scene->sceneHero->setLife(file->readByte());
setKashes(file->readSint16LE());
magicLevelIdx = file->readByte();
inventoryMagicPoints = file->readByte();
inventoryNumLeafsBox = file->readByte();
setMagicPoints(file->readByte());
setLeafBoxes(file->readByte());
_engine->_scene->newHeroPos.x = file->readSint16LE();
_engine->_scene->newHeroPos.y = file->readSint16LE();
_engine->_scene->newHeroPos.z = file->readSint16LE();
@ -206,7 +206,7 @@ bool GameState::loadGame(Common::SeekableReadStream *file) {
}
file->read(holomapFlags, NUM_LOCATIONS);
inventoryNumGas = file->readByte();
setGas(file->readByte());
const byte numInventoryFlags = file->readByte(); // number of used inventory items, always 28
if (numInventoryFlags != NUM_INVENTORY_ITEMS) {
@ -215,7 +215,7 @@ bool GameState::loadGame(Common::SeekableReadStream *file) {
}
file->read(inventoryFlags, NUM_INVENTORY_ITEMS);
inventoryNumLeafs = file->readByte();
setLeafs(file->readByte());
usingSabre = file->readByte();
if (saveFileVersion == 4) {
@ -554,18 +554,72 @@ void GameState::giveUp() {
}
int16 GameState::setGas(int16 value) {
inventoryNumGas = MIN<int16>(100, value);
inventoryNumGas = CLIP<int16>(value, 0, 100);
return inventoryNumGas;
}
void GameState::addGas(int16 value) {
setGas(inventoryNumGas + value);
}
int16 GameState::setKashes(int16 value) {
inventoryNumKashes = MIN<int16>(999, value);
inventoryNumKashes = CLIP<int16>(value, 0, 999);
if (_engine->_gameState->inventoryNumKashes >= 500) {
_engine->unlockAchievement("LBA_ACH_011");
}
return inventoryNumKashes;
}
int16 GameState::setKeys(int16 value) {
inventoryNumKeys = value;
inventoryNumKeys = MAX<int16>(0, value);
return inventoryNumKeys;
}
void GameState::addKeys(int16 val) {
setKeys(inventoryNumKeys + val);
}
void GameState::addKashes(int16 val) {
setKashes(inventoryNumKashes + val);
}
int16 GameState::setMagicPoints(int16 val) {
inventoryMagicPoints = val;
if (inventoryMagicPoints > magicLevelIdx * 20) {
inventoryMagicPoints = magicLevelIdx * 20;
}
return inventoryMagicPoints;
}
void GameState::addMagicPoints(int16 val) {
setMagicPoints(inventoryMagicPoints + val);
}
int16 GameState::setLeafs(int16 val) {
inventoryNumLeafs = val;
if (inventoryNumLeafs > inventoryNumLeafsBox) {
inventoryNumLeafs = inventoryNumLeafsBox;
}
return inventoryNumLeafs;
}
void GameState::addLeafs(int16 val) {
setLeafs(inventoryNumLeafs + val);
}
int16 GameState::setLeafBoxes(int16 val) {
inventoryNumLeafsBox = val;
if (inventoryNumLeafsBox > 10) {
inventoryNumLeafsBox = 10;
}
if (inventoryNumLeafsBox == 5) {
_engine->unlockAchievement("LBA_ACH_003");
}
return inventoryNumLeafsBox;
}
void GameState::addLeafBoxes(int16 val) {
setLeafBoxes(inventoryNumLeafsBox + val);
}
} // namespace TwinE

View file

@ -190,7 +190,17 @@ public:
int16 setKeys(int16 value);
int16 setGas(int16 value);
int16 setLeafs(int16 value);
int16 setKashes(int16 value);
int16 setMagicPoints(int16 val);
int16 setLeafBoxes(int16 val);
void addGas(int16 value);
void addKeys(int16 val);
void addKashes(int16 val);
void addMagicPoints(int16 val);
void addLeafs(int16 val);
void addLeafBoxes(int16 val);
/** Its using FunFrock Sabre */
bool usingSabre = false;

View file

@ -828,12 +828,7 @@ static int32 lSUICIDE(TwinEEngine *engine, LifeScriptContext &ctx) {
* @note Opcode @c 0x27
*/
static int32 lUSE_ONE_LITTLE_KEY(TwinEEngine *engine, LifeScriptContext &ctx) {
engine->_gameState->inventoryNumKeys--;
if (engine->_gameState->inventoryNumKeys < 0) {
engine->_gameState->inventoryNumKeys = 0;
}
engine->_gameState->addKeys(-1);
engine->_redraw->addOverlay(OverlayType::koSprite, SPRITEHQR_KEY, 0, 0, 0, OverlayPosType::koFollowActor, 1);
return 0;
@ -848,10 +843,7 @@ static int32 lGIVE_GOLD_PIECES(TwinEEngine *engine, LifeScriptContext &ctx) {
bool hideRange = false;
int16 kashes = ctx.stream.readSint16LE();
engine->_gameState->inventoryNumKashes -= kashes;
if (engine->_gameState->inventoryNumKashes < 0) {
engine->_gameState->inventoryNumKashes = 0;
}
engine->_gameState->addKashes(-kashes);
engine->_redraw->addOverlay(OverlayType::koSprite, SPRITEHQR_KASHES, 10, 15, 0, OverlayPosType::koNormal, 3);
@ -1237,12 +1229,7 @@ static int32 lPLAY_MIDI(TwinEEngine *engine, LifeScriptContext &ctx) {
* @note Opcode @c 0x42
*/
static int32 lINC_CLOVER_BOX(TwinEEngine *engine, LifeScriptContext &ctx) {
if (engine->_gameState->inventoryNumLeafsBox < 10) {
engine->_gameState->inventoryNumLeafsBox++;
if (engine->_gameState->inventoryNumLeafsBox == 5) {
engine->unlockAchievement("LBA_ACH_003");
}
}
engine->_gameState->addLeafBoxes(1);
return 0;
}
@ -1349,10 +1336,7 @@ static int32 lCLR_HOLO_POS(TwinEEngine *engine, LifeScriptContext &ctx) {
* @note Opcode @c 0x4A
*/
static int32 lADD_FUEL(TwinEEngine *engine, LifeScriptContext &ctx) {
engine->_gameState->inventoryNumGas += ctx.stream.readByte();
if (engine->_gameState->inventoryNumGas > 100) {
engine->_gameState->inventoryNumGas = 100;
}
engine->_gameState->addGas(ctx.stream.readByte());
return 0;
}
@ -1361,10 +1345,7 @@ static int32 lADD_FUEL(TwinEEngine *engine, LifeScriptContext &ctx) {
* @note Opcode @c 0x4B
*/
static int32 lSUB_FUEL(TwinEEngine *engine, LifeScriptContext &ctx) {
engine->_gameState->inventoryNumGas -= ctx.stream.readByte();
if (engine->_gameState->inventoryNumGas < 0) {
engine->_gameState->inventoryNumGas = 0;
}
engine->_gameState->addGas(-(int16)ctx.stream.readByte());
return 0;
}
@ -1414,7 +1395,7 @@ static int32 lSAY_MESSAGE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
* @note Opcode @c 0x4F
*/
static int32 lFULL_POINT(TwinEEngine *engine, LifeScriptContext &ctx) {
engine->_scene->sceneHero->life = 50;
engine->_scene->sceneHero->life = kActorMaxLife;
engine->_gameState->inventoryMagicPoints = engine->_gameState->magicLevelIdx * 20;
return 0;
}
@ -1662,7 +1643,7 @@ static int32 lGAME_OVER(TwinEEngine *engine, LifeScriptContext &ctx) {
static int32 lTHE_END(TwinEEngine *engine, LifeScriptContext &ctx) {
engine->quitGame = 1;
engine->_gameState->inventoryNumLeafs = 0;
engine->_scene->sceneHero->life = 50;
engine->_scene->sceneHero->life = kActorMaxLife;
engine->_gameState->inventoryMagicPoints = 80;
engine->_scene->currentSceneIdx = LBA1SceneId::Polar_Island_Final_Battle;
engine->_actor->heroBehaviour = engine->_actor->previousHeroBehaviour;

View file

@ -644,7 +644,7 @@ void TwinEEngine::processInventoryAction() {
_movements->rotateActor(0, 800, pinguin->angle);
if (!_collision->checkCollisionWithActors(_scene->mecaPinguinIdx)) {
pinguin->life = 50;
pinguin->life = kActorMaxLife;
pinguin->body = BodyType::btNone;
_actor->initModelActor(BodyType::btNormal, _scene->mecaPinguinIdx);
pinguin->dynamicFlags.bIsDead = 0; // &= 0xDF
@ -663,9 +663,9 @@ void TwinEEngine::processInventoryAction() {
break;
}
case kiCloverLeaf:
if (_scene->sceneHero->life < 50) {
if (_scene->sceneHero->life < kActorMaxLife) {
if (_gameState->inventoryNumLeafs > 0) {
_scene->sceneHero->life = 50;
_scene->sceneHero->life = kActorMaxLife;
_gameState->inventoryMagicPoints = _gameState->magicLevelIdx * 20;
_gameState->inventoryNumLeafs--;
_redraw->addOverlay(OverlayType::koInventoryItem, InventoryItems::kiCloverLeaf, 0, 0, 0, OverlayPosType::koNormal, 3);
@ -939,7 +939,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_scene->heroPositionType = ScenePositionType::kReborn;
_scene->sceneHero->life = 50;
_scene->sceneHero->life = kActorMaxLife;
_redraw->reqBgRedraw = true;
_screens->lockPalette = true;
_gameState->inventoryNumLeafs--;
@ -950,7 +950,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_gameState->inventoryMagicPoints = _gameState->magicLevelIdx * 20;
_actor->heroBehaviour = _actor->previousHeroBehaviour;
actor->angle = _actor->previousHeroAngle;
actor->life = 50;
actor->life = kActorMaxLife;
if (_scene->previousSceneIdx != _scene->currentSceneIdx) {
_scene->newHeroPos.x = -1;