void KyraEngine_HoF::handleInput(int x, int y) { setNextIdleAnimTimer(); if (_unk5) { _unk5 = 0; return; } if (!_screen->isMouseVisible()) return; if (_savedMouseState == -2) { snd_playSoundEffect(13); return; } setNextIdleAnimTimer(); if (x <= 6 || x >= 312 || y <= 6 || y >= 135) { bool exitOk = false; assert(_savedMouseState + 6 >= 0); switch (_savedMouseState + 6) { case 0: if (_sceneExit1 != 0xFFFF) exitOk = true; break; case 1: if (_sceneExit2 != 0xFFFF) exitOk = true; break; case 2: if (_sceneExit3 != 0xFFFF) exitOk = true; break; case 3: if (_sceneExit4 != 0xFFFF) exitOk = true; break; default: break; } if (exitOk) { inputSceneChange(x, y, 1, 1); return; } } if (checkCharCollision(x, y) && _savedMouseState >= -1) { runSceneScript2(); return; } else if (pickUpItem(x, y)) { return; } else { int skipHandling = 0; if (checkItemCollision(x, y) == -1) { resetGameFlag(0x1EF); skipHandling = handleInputUnkSub(x, y) ? 1 : 0; if (queryGameFlag(0x1EF)) { resetGameFlag(0x1EF); return; } if (_unk5) { _unk5 = 0; return; } } if (_deathHandler > -1) skipHandling = 1; if (skipHandling) return; if (checkCharCollision(x, y)) { runSceneScript2(); return; } if (_itemInHand >= 0) { if (y > 136) return; dropItem(0, _itemInHand, x, y, 1); } else { if (_savedMouseState == -2 || y > 135) return; if (!_unk5) { inputSceneChange(x, y, 1, 1); return; } _unk5 = 0; } } }
void KyraEngine_MR::updateMouse() { int shape = 0, offsetX = 0, offsetY = 0; Common::Point mouse = getMousePos(); bool hasItemCollision = checkItemCollision(mouse.x, mouse.y) != -1; if (mouse.y > 187) { bool setItemCursor = false; if (_mouseState == -6) { if (mouse.x < 311) setItemCursor = true; } else if (_mouseState == -5) { if (mouse.x < _sceneMinX || mouse.x > _sceneMaxX) setItemCursor = true; } else if (_mouseState == -4) { if (mouse.x > 8) setItemCursor = true; } if (setItemCursor) { setItemMouseCursor(); return; } } if (_inventoryState) { if (mouse.y >= 144) return; hideInventory(); } if (hasItemCollision && _mouseState < -1 && _itemInHand < 0) { _mouseState = kItemNone; _itemInHand = kItemNone; _screen->setMouseCursor(0, 0, _gameShapes[0]); } int type = 0; if (mouse.y <= 199) { if (mouse.x <= 8) { if (_sceneExit4 != 0xFFFF) { type = -4; shape = 4; offsetX = 0; offsetY = 0; } } else if (mouse.x >= 311) { if (_sceneExit2 != 0xFFFF) { type = -6; shape = 2; offsetX = 13; offsetY = 8; } } else if (mouse.y >= 171) { if (_sceneExit3 != 0xFFFF) { if (mouse.x >= _sceneMinX && mouse.x <= _sceneMaxX) { type = -5; shape = 3; offsetX = 8; offsetY = 13; } } } else if (mouse.y <= 8) { if (_sceneExit1 != 0xFFFF) { type = -7; shape = 1; offsetX = 8; offsetY = 0; } } } for (int i = 0; i < _specialExitCount; ++i) { if (checkSpecialSceneExit(i, mouse.x, mouse.y)) { switch (_specialExitTable[20+i]) { case 0: type = -7; shape = 1; offsetX = 8; offsetY = 0; break; case 2: type = -6; shape = 2; offsetX = 13; offsetY = 8; break; case 4: type = -5; shape = 3; offsetX = 8; offsetY = 13; break; case 6: type = -4; shape = 4; offsetX = 0; offsetY = 8; break; default: break; } } } if (type != 0 && type != _mouseState && !hasItemCollision) { _mouseState = type; _screen->setMouseCursor(offsetX, offsetY, _gameShapes[shape]); } else if (type == 0 && _mouseState != _itemInHand && mouse.x > 8 && mouse.x < 311 && mouse.y < 171 && mouse.y > 8) { setItemMouseCursor(); } else if (mouse.y > 187 && _mouseState > -4 && type == 0 && !_inventoryState) { showInventory(); } }
void KyraEngine_MR::handleInput(int x, int y) { if (_inventoryState) return; setNextIdleAnimTimer(); if (_unk5) { _unk5 = 0; return; } if (!_screen->isMouseVisible()) return; if (_savedMouseState == -3) { snd_playSoundEffect(0x0D, 0x80); return; } setNextIdleAnimTimer(); int skip = 0; if (checkCharCollision(x, y) && _savedMouseState >= -1 && runSceneScript2()) { return; } else if (_itemInHand != 27 && pickUpItem(x, y, 1)) { return; } else if (checkItemCollision(x, y) == -1) { resetGameFlag(1); skip = runSceneScript1(x, y); if (queryGameFlag(1)) { resetGameFlag(1); return; } else if (_unk5) { _unk5 = 0; return; } } if (_deathHandler >= 0) skip = 1; if (skip) return; if (checkCharCollision(x, y)) { if (runSceneScript2()) return; } else if (_itemInHand >= 0 && _savedMouseState >= 0) { if (_itemInHand == 27) { makeCharFacingMouse(); } else if (y <= 187) { if (_itemInHand == 43) removeHandItem(); else dropItem(0, _itemInHand, x, y, 1); } return; } else if (_savedMouseState == -3) { return; } else { if (y > 187 && _savedMouseState > -4) return; if (_unk5) { _unk5 = 0; return; } } inputSceneChange(x, y, 1, 1); }
void BattleItem::update(GameState &state, unsigned int ticks) { item->update(state, ticks); // May have exploded if (!tileObject) { return; } if (ticksUntilCollapse > 0) { if (ticksUntilCollapse > ticks) { ticksUntilCollapse -= ticks; } else { ticksUntilCollapse = 0; collapse(); } } if (!falling) { return; } if (ownerInvulnerableTicks > 0) { if (ownerInvulnerableTicks > ticks) { ownerInvulnerableTicks -= ticks; } else { ownerInvulnerableTicks = 0; } } if (collisionIgnoredTicks > 0) { if (collisionIgnoredTicks > ticks) { collisionIgnoredTicks -= ticks; } else { collisionIgnoredTicks = 0; } } int remainingTicks = ticks; auto previousPosition = position; auto newPosition = position; while (remainingTicks-- > 0) { velocity.z -= FALLING_ACCELERATION_ITEM; newPosition += this->velocity / (float)TICK_SCALE / VELOCITY_SCALE_BATTLE; } // Check if new position is valid // FIXME: Collide with units but not with us bool collision = false; auto c = checkItemCollision(previousPosition, newPosition); if (c) { collision = true; // If colliding with anything but ground, bounce back once switch (c.obj->getType()) { case TileObject::Type::Unit: case TileObject::Type::LeftWall: case TileObject::Type::RightWall: case TileObject::Type::Feature: if (!bounced) { // If bounced do not try to find support this time collision = false; bounced = true; newPosition = previousPosition; velocity.x = -velocity.x / 4; velocity.y = -velocity.y / 4; velocity.z = std::abs(velocity.z / 4); break; } // Intentional fall-through case TileObject::Type::Ground: // Let item fall so that it can collide with scenery or ground if falling on top of // it newPosition = {previousPosition.x, previousPosition.y, std::min(newPosition.z, previousPosition.z)}; break; default: LogError("What the hell is this item colliding with? Type is %d", (int)c.obj->getType()); break; } } // If moved but did not find support - check if within level bounds and set position if (newPosition != previousPosition) { auto mapSize = this->tileObject->map.size; // Collision with ceiling if (newPosition.z >= mapSize.z) { collision = true; newPosition.z = mapSize.z - 0.01f; velocity = {0.0f, 0.0f, 0.0f}; } // Collision with map edge if (newPosition.x < 0 || newPosition.y < 0 || newPosition.y >= mapSize.y || newPosition.x >= mapSize.x || newPosition.y >= mapSize.y) { collision = true; velocity.x = -velocity.x / 4; velocity.y = -velocity.y / 4; velocity.z = 0; newPosition = previousPosition; } // Fell below 0??? if (newPosition.z < 0) { LogError("Item at %f %f fell off the end of the world!?", newPosition.x, newPosition.y); die(state, false); return; } setPosition(newPosition); } if (collision) { if (findSupport()) { getSupport(); auto tile = tileObject->getOwningTile(); if (tile->objectDropSfx) { fw().soundBackend->playSample(tile->objectDropSfx, getPosition(), 0.25f); } } } }