Example #1
0
TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY) {
	init(Point32(zoomX, zoomY),
		angle,
		Point32(hotspotX, hotspotY),
		true,
		BLEND_NORMAL,
		kDefaultRgbaMod,
		false, false,
		Point32(kDefaultOffsetX, kDefaultOffsetY));
}
Example #2
0
TransformStruct::TransformStruct() {
	init(Point32(kDefaultZoomX, kDefaultZoomY),
		kDefaultAngle,
		Point32(kDefaultHotspotX, kDefaultHotspotY),
		true,
		BLEND_NORMAL,
		kDefaultRgbaMod,
		false, false,
		Point32(kDefaultOffsetX, kDefaultOffsetY));
}
Example #3
0
TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, int32 offsetX, int32 offsetY) {
	init(Point32(zoomX, zoomY),
		angle,
		Point32(hotspotX, hotspotY),
		false,
		blendMode,
		rgbaMod,
		mirrorX, mirrorY,
		Point32(offsetX, offsetY));
}
Example #4
0
TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY) {
	init(Point32(zoomX, zoomY),
		kDefaultAngle,
		Point32(kDefaultHotspotX, kDefaultHotspotY),
		false,
		blendMode,
		rgbaMod,
		mirrorX,
		mirrorY,
		Point32(kDefaultOffsetX, kDefaultOffsetY));
}
Example #5
0
TransformStruct::TransformStruct(float zoomX, float zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, int32 offsetX, int32 offsetY) {
	init(Point32((int32)(zoomX / 100.0 * kDefaultZoomX),
		     (int32)(zoomY / 100.0 * kDefaultZoomY)),
		angle,
		Point32(hotspotX, hotspotY),
		false,
		blendMode,
		rgbaMod,
		mirrorX, mirrorY,
		Point32(offsetX, offsetY));
}
Example #6
0
TransformStruct::TransformStruct(int32 numTimesX, int32 numTimesY) {
	init(Point32(kDefaultZoomX, kDefaultZoomY),
		kDefaultAngle,
		Point32(kDefaultHotspotX, kDefaultHotspotY),
		false,
		BLEND_NORMAL,
		kDefaultRgbaMod,
		false, false,
		Point32(kDefaultOffsetX, kDefaultOffsetY));
	_numTimesX = numTimesX;
	_numTimesY = numTimesY;
}
Example #7
0
void Unit::Order_NukeGround()
{
    unk_move_waypoint = order_target_pos;
    int sight_range = GetSightRange(false) * 32;
    int dist = Distance(exact_position, Point32(order_target_pos) * 256 + Point32(128, 128)) / 256;
    if (ai && dist <= sight_range * 3)
        Ai_Cloak();
    if (dist > sight_range)
    {
        if (move_target_update_timer == 0)
            ChangeMovementTarget(order_target_pos); // What, it is not moving?
    }
    else
    {
        bw::StopMoving(this);
        if (position != unk_move_waypoint)
        {
            auto pos = sprite->position;
            int diff = facing_direction -
                bw::GetFacingDirection(pos.x, pos.y, unk_move_waypoint.x, unk_move_waypoint.y);
            if (diff < -1 || diff > 1)
                return;
        }
        Unit *silo = nullptr;
        for (Unit *unit : bw::first_player_unit[player])
        {
            if (unit->Type() == UnitId::NuclearSilo && unit->silo.has_nuke)
            {
                silo = unit;
                break;
            }
        }
        if (!silo)
        {
            OrderDone();
            return;
        }
        Unit *nuke = silo->silo.nuke;
        silo->silo.nuke = nullptr;
        silo->silo.has_nuke = 0;
        bw::PlaySound(Sound::NukeLaser, this, 1, 0);
        nuke->IssueOrderTargetingGround(OrderId::NukeLaunch, order_target_pos);
        related = nuke;
        nuke->related = this;
        nuke->sprite->SetDirection32(0);
        bw::ShowUnit(nuke);
        IssueOrderTargetingGround(OrderId::NukeTrack, sprite->position);
        if (!IsDisabled() || Type().IsBuilding()) // Huh?
            buttons = 0xed;
        RefreshUi();
    }
}
Example #8
0
/**
 * Moves relevant windows if they've been moved offscreen by a window resize.
 * Also forces the bottom toolbar to be moved, as that will always be in the wrong position.
 * @param new_width New width of the display.
 * @param new_height New height of the display.
 */
void WindowManager::RepositionAllWindows(uint new_width, uint new_height)
{
	Rectangle32 rect(0, 0, new_width, new_height);
	for (Window *w = this->top; w != nullptr; w = w->lower) {
		if (w->wtype == WC_MAINDISPLAY) {
			w->SetSize(new_width, new_height);

		/* Add an arbitrary amount for closebox/titlebar, so the window is still actually accessible. */
		} else if (!rect.IsPointInside(Point32(w->rect.base.x + 20, w->rect.base.y + 20)) || w->wtype == WC_BOTTOM_TOOLBAR) {
			w->SetPosition(w->OnInitialPosition());
		}
	}
}
Example #9
0
/**
 * Moves relevant windows if they've been moved offscreen by a window resize.
 * Also forces the bottom toolbar to be moved, as that will always be in the wrong position.
 */
void WindowManager::RepositionAllWindows()
{
	Viewport *vp = GetViewport();
	if (vp == nullptr) return;
	Rectangle32 vp_rect = vp->rect;
	for (Window *w = this->top; w != nullptr; w = w->lower) {
		if (w->wtype == WC_MAINDISPLAY) continue;
		/* Add an arbitrary amount for closebox/titlebar,
		 * so the window is still actually accessible. */
		if (!vp_rect.IsPointInside(Point32(w->rect.base.x + 20, w->rect.base.y + 20)) || w->wtype == WC_BOTTOM_TOOLBAR) {
			w->SetPosition(w->OnInitialPosition());
		}
	}
}
Example #10
0
People::People(SherlockEngine *vm) : _vm(vm) {
	_holmesOn = true;
	_allowWalkAbort = true;
	_portraitLoaded = false;
	_portraitsOn = true;
	_clearingThePortrait = false;
	_talkPics = nullptr;
	_portraitSide = 0;
	_speakerFlip = false;
	_holmesFlip = false;
	_holmesQuotient = 0;
	_savedPos = Point32(-1, -1);
	_savedPos._facing = -1;
	_forceWalkReload = false;
	_useWalkLib = false;
	_walkControl = 0;

	_portrait._sequences = new byte[32];
}
Example #11
0
OpcodeReturn TattooTalk::cmdWalkHolmesToCoords(const byte *&str) {
	People &people = *_vm->_people;
	++str;

	int xp = (str[0] - 1) * 256 + str[1] - 1;
	if (xp > 16384)
		// Negative X
		xp = -1 * (xp - 16384);
	int yp = (str[2] - 1) * 256 + str[3] - 1;
	
	people[HOLMES].walkToCoords(Point32(xp * FIXED_INT_MULTIPLIER, yp * FIXED_INT_MULTIPLIER),
		DIRECTION_CONVERSION[str[4] - 1]);

	if (_talkToAbort)
		return RET_EXIT;

	str += 4;
	return RET_SUCCESS;
}
Example #12
0
OpcodeReturn TattooTalk::cmdSetNPCPosition(const byte *&str) {
	int npcNum = *++str - 1;
	++str;
	TattooPeople &people = *(TattooPeople *)_vm->_people;
	TattooPerson &person = people[npcNum];
	int32 posX = (str[0] - 1) * 256 + str[1] - 1;
	if (posX > 16384)
		posX = -1 * (posX - 16384);
	int32 posY = (str[2] - 1) * 256 + str[3] - 1;
	
	people[npcNum]._position = Point32(posX * FIXED_INT_MULTIPLIER, posY * FIXED_INT_MULTIPLIER);
	if (person._seqTo && person._walkLoaded) {
		person._walkSequences[person._sequenceNumber]._sequences[person._frameNumber] = person._seqTo;
		person._seqTo = 0;
	}

	assert(str[4] - 1 < 16);
	person._sequenceNumber = DIRECTION_CONVERSION[str[4] - 1];
	person._frameNumber = 0;

	if (person._walkLoaded)
		person.checkWalkGraphics();

	if (person._walkLoaded && person._type == CHARACTER &&
		person._sequenceNumber >= STOP_UP && person._sequenceNumber <= STOP_UPLEFT) {
		bool done = false;
		do {
			person.checkSprite();
			for (int x = 0; x < person._frameNumber; x++) {
				if (person._walkSequences[person._sequenceNumber]._sequences[x] == 0) {
					done = true;
					break;
				}
			}
		} while(!done);
	}

	str += 4;

	return RET_SUCCESS;
}
Example #13
0
OpcodeReturn TattooTalk::cmdWalkNPCToCoords(const byte *&str) {
	int npcNum = *++str;
	str++;
	TattooPeople &people = *(TattooPeople *)_vm->_people;
	TattooPerson &person = people[npcNum];

	if (person._pathStack.empty())
		person.pushNPCPath();
	person._npcMoved = true;

	int xp = (str[0] - 1) * 256 + str[1] - 1;
	if (xp > 16384)
		xp = -1 * (xp - 16384);
	int yp = (str[2] - 1) * 256 + str[3] - 1;

	person.walkToCoords(Point32(xp * FIXED_INT_MULTIPLIER, yp * FIXED_INT_MULTIPLIER),
		DIRECTION_CONVERSION[str[4] - 1]);
	if (_talkToAbort)
		return RET_EXIT;

	str += 4;
	return RET_SUCCESS;
}
Example #14
0
void People::reset() {
	SaveManager &saves = *_vm->_saves;
	Talk &talk = *_vm->_talk;
	_data[HOLMES]->_description = "Sherlock Holmes!";

	// Note: Serrated Scalpel only uses a single Person slot for Sherlock.. Watson is handled by scene sprites
	int count = IS_SERRATED_SCALPEL ? 1 : MAX_CHARACTERS;
	for (int idx = 0; idx < count; ++idx) {
		Person &p = *_data[idx];

		if (IS_SERRATED_SCALPEL) {
			p._type = CHARACTER;
			p._position = Point32(100 * FIXED_INT_MULTIPLIER, 110 * FIXED_INT_MULTIPLIER);
		} else if (!talk._scriptMoreFlag && !saves._justLoaded) {
			p._type = (idx == 0) ? CHARACTER : INVALID;
			p._position = Point32(36 * FIXED_INT_MULTIPLIER, 29 * FIXED_INT_MULTIPLIER);
			p._use[0]._verb = "";
			p._use[1]._verb = "";
		}

		p._sequenceNumber = IS_SERRATED_SCALPEL ? (int)Tattoo::STOP_DOWNRIGHT : (int)Tattoo::STOP_DOWNRIGHT;
		p._imageFrame = nullptr;
		p._frameNumber = 1;
		p._startSeq = 0;
		p._delta = Point32(0, 0);
		p._oldPosition = Common::Point(0, 0);
		p._oldSize = Common::Point(0, 0);
		p._misc = 0;
		p._pickUp = "";
		p._allow = 0;
		p._noShapeSize = Common::Point(0, 0);
		p._goto = Common::Point(0, 0);
		p._status = 0;
		p._seqTo = 0;
		p._seqCounter = p._seqCounter2 = 0;
		p._seqStack = 0;
		p._gotoSeq = p._talkSeq = 0;
		p._restoreSlot = 0;
		p._startSeq = 0;
		p._altImages = nullptr;
		p._altSeq = 0;
		p._centerWalk = true;
		p._adjust = Common::Point(0, 0);

		// Load the default walk sequences
		p._walkCount = 0;
		p._walkTo.clear();
		p._oldWalkSequence = -1;
		p._walkSequences.clear();
		if (IS_SERRATED_SCALPEL) {
			p._walkSequences.resize(MAX_HOLMES_SEQUENCE);
			for (int seqIdx = 0; seqIdx < MAX_HOLMES_SEQUENCE; ++seqIdx) {
				p._walkSequences[seqIdx]._sequences.clear();

				const byte *pSrc = &CHARACTER_SEQUENCES[seqIdx][0];
				do {
					p._walkSequences[seqIdx]._sequences.push_back(*pSrc);
				} while (*pSrc++);
			}
		}
	}
}
Example #15
0
void ScalpelPerson::setWalking() {
	Map &map = *_vm->_map;
	Scene &scene = *_vm->_scene;
	int oldDirection, oldFrame;
	Common::Point speed, delta;

	// Flag that player has now walked in the scene
	scene._walkedInScene = true;

	// Stop any previous walking, since a new dest is being set
	_walkCount = 0;
	oldDirection = _sequenceNumber;
	oldFrame = _frameNumber;

	// Set speed to use horizontal and vertical movement
	if (map._active) {
		speed = Common::Point(MWALK_SPEED, MWALK_SPEED);
	} else {
		speed = Common::Point(XWALK_SPEED, YWALK_SPEED);
	}

	// If the player is already close to the given destination that no
	// walking is needed, move to the next straight line segment in the
	// overall walking route, if there is one
	for (;;) {
		// Since we want the player to be centered on the destination they
		// clicked, but characters draw positions start at their left, move
		// the destination half the character width to draw him centered
		int temp;
		if (_walkDest.x >= (temp = _imageFrame->_frame.w / 2))
			_walkDest.x -= temp;

		delta = Common::Point(
			ABS(_position.x / FIXED_INT_MULTIPLIER - _walkDest.x),
			ABS(_position.y / FIXED_INT_MULTIPLIER - _walkDest.y)
		);

		// If we're ready to move a sufficient distance, that's it. Otherwise,
		// move onto the next portion of the walk path, if there is one
		if ((delta.x > 3 || delta.y > 0) || _walkTo.empty())
			break;

		// Pop next walk segment off the walk route stack
		_walkDest = _walkTo.pop();
	}

	// If a sufficient move is being done, then start the move
	if (delta.x > 3 || delta.y) {
		// See whether the major movement is horizontal or vertical
		if (delta.x >= delta.y) {
			// Set the initial frame sequence for the left and right, as well
			// as setting the delta x depending on direction
			if (_walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) {
				_sequenceNumber = (map._active ? (int)MAP_LEFT : (int)WALK_LEFT);
				_delta.x = speed.x * -FIXED_INT_MULTIPLIER;
			} else {
				_sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)WALK_RIGHT);
				_delta.x = speed.x * FIXED_INT_MULTIPLIER;
			}

			// See if the x delta is too small to be divided by the speed, since
			// this would cause a divide by zero error
			if (delta.x >= speed.x) {
				// Det the delta y
				_delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x / speed.x);
				if (_walkDest.y < (_position.y / FIXED_INT_MULTIPLIER))
					_delta.y = -_delta.y;

				// Set how many times we should add the delta to the player's position
				_walkCount = delta.x / speed.x;
			} else {
				// The delta x was less than the speed (ie. we're really close to
				// the destination). So set delta to 0 so the player won't move
				_delta = Point32(0, 0);
				_position = Point32(_walkDest.x * FIXED_INT_MULTIPLIER, _walkDest.y * FIXED_INT_MULTIPLIER);

				_walkCount = 1;
			}

			// See if the sequence needs to be changed for diagonal walking
			if (_delta.y > 150) {
				if (!map._active) {
					switch (_sequenceNumber) {
					case WALK_LEFT:
						_sequenceNumber = WALK_DOWNLEFT;
						break;
					case WALK_RIGHT:
						_sequenceNumber = WALK_DOWNRIGHT;
						break;
					}
				}
			} else if (_delta.y < -150) {
				if (!map._active) {
					switch (_sequenceNumber) {
					case WALK_LEFT:
						_sequenceNumber = WALK_UPLEFT;
						break;
					case WALK_RIGHT:
						_sequenceNumber = WALK_UPRIGHT;
						break;
					}
				}
			}
		} else {
			// Major movement is vertical, so set the sequence for up and down,
			// and set the delta Y depending on the direction
			if (_walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) {
				_sequenceNumber = WALK_UP;
				_delta.y = speed.y * -FIXED_INT_MULTIPLIER;
			} else {
				_sequenceNumber = WALK_DOWN;
				_delta.y = speed.y * FIXED_INT_MULTIPLIER;
			}

			// If we're on the overhead map, set the sequence so we keep moving
			// in the same direction
			if (map._active)
				_sequenceNumber = (oldDirection == -1) ? MAP_RIGHT : oldDirection;

			// Set the delta x
			_delta.x = (delta.x * FIXED_INT_MULTIPLIER) / (delta.y / speed.y);
			if (_walkDest.x < (_position.x / FIXED_INT_MULTIPLIER))
				_delta.x = -_delta.x;

			_walkCount = delta.y / speed.y;
		}
	}

	// See if the new walk sequence is the same as the old. If it's a new one,
	// we need to reset the frame number to zero so its animation starts at
	// its beginning. Otherwise, if it's the same sequence, we can leave it
	// as is, so it keeps the animation going at wherever it was up to
	if (_sequenceNumber != _oldWalkSequence)
		_frameNumber = 0;
	_oldWalkSequence = _sequenceNumber;

	if (!_walkCount)
		gotoStand();

	// If the sequence is the same as when we started, then Holmes was
	// standing still and we're trying to re-stand him, so reset Holmes'
	// rame to the old frame number from before it was reset to 0
	if (_sequenceNumber == oldDirection)
		_frameNumber = oldFrame;
}
Example #16
0
void UserInterface::checkAction(ActionType &action, int objNum, FixedTextActionId fixedTextActionId) {
	Events &events = *_vm->_events;
	FixedText &fixedText = *_vm->_fixedText;
	People &people = *_vm->_people;
	Scene &scene = *_vm->_scene;
	Screen &screen = *_vm->_screen;
	Talk &talk = *_vm->_talk;
	Point32 pt(-1, -1);

	if (action._useFlag)
		// Automatically set the given flag
		_vm->setFlags(action._useFlag);

	if (IS_SERRATED_SCALPEL && objNum >= 1000)
		// Ignore actions done on characters
		return;

	if (IS_SERRATED_SCALPEL && !action._cAnimSpeed) {
		// Invalid action, to print error message
		_infoFlag = true;
		clearInfo();
		Common::String errorMessage = fixedText.getActionMessage(fixedTextActionId, action._cAnimNum);
		screen.print(Common::Point(0, INFO_LINE + 1), COL_INFO_FOREGROUND, "%s", errorMessage.c_str());
		_infoFlag = true;

		// Set how long to show the message
		_menuCounter = 30;
	} else {
		BaseObject *obj;
		if (objNum >= 1000)
			obj = &people[objNum - 1000];
		else
			obj = &scene._bgShapes[objNum];

		int cAnimNum;
		if (action._cAnimNum == 0)
			// Really a 10
			cAnimNum = 9;
		else
			cAnimNum = action._cAnimNum - 1;

		int dir = -1;
		if (action._cAnimNum != 99) {
			CAnim &anim = scene._cAnim[cAnimNum];

			if (action._cAnimNum != 99) {
				if (action._cAnimSpeed & REVERSE_DIRECTION) {
					pt = anim._teleport[0];
					dir = anim._teleport[0]._facing;
				} else {
					pt = anim._goto[0];
					dir = anim._goto[0]._facing;
				}
			}
		} else {
			pt = Point32(-1, -1);
			dir = -1;
		}

		// Has a value, so do action
		// Show wait cursor whilst walking to object and doing action
		events.setCursor(WAIT);
		bool printed = false;

		for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) {
			if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2
					&& toupper(action._names[nameIdx][1]) == 'W') {
				if (obj->checkNameForCodes(Common::String(action._names[nameIdx].c_str() + 2), fixedTextActionId)) {
					if (!talk._talkToAbort)
						printed = true;
				}
			}
		}

		bool doCAnim = true;
		for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) {
			if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2) {
				char ch = toupper(action._names[nameIdx][1]);

				if (ch == 'T' || ch == 'B') {
					printed = true;
					if (pt.x != -1)
						// Holmes needs to walk to object before the action is done
						people[HOLMES].walkToCoords(pt, dir);

					if (!talk._talkToAbort) {
						// Ensure Holmes is on the exact intended location
						people[HOLMES]._position = pt;
						people[HOLMES]._sequenceNumber = dir;
						people[HOLMES].gotoStand();

						talk.talkTo(action._names[nameIdx].c_str() + 2);
						if (ch == 'T')
							doCAnim = false;
					}
				}
			}
		}

		if (doCAnim && !talk._talkToAbort) {
			if (pt.x != -1)
				// Holmes needs to walk to object before the action is done
				people[HOLMES].walkToCoords(pt, dir);
		}

		for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) {
			if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2
					&& toupper(action._names[nameIdx][1]) == 'F') {
				if (obj->checkNameForCodes(action._names[nameIdx].c_str() + 2, fixedTextActionId)) {
					if (!talk._talkToAbort)
						printed = true;
				}
			}
		}

		if (doCAnim && !talk._talkToAbort && action._cAnimNum != 99)
			scene.startCAnim(cAnimNum, action._cAnimSpeed);

		if (!talk._talkToAbort) {
			for (int nameIdx = 0; nameIdx < NAMES_COUNT && !talk._talkToAbort; ++nameIdx) {
				if (obj->checkNameForCodes(action._names[nameIdx], fixedTextActionId)) {
					if (!talk._talkToAbort)
						printed = true;
				}
			}

			// Unless we're leaving the scene, print a "Done" message unless the printed flag has been set
			if (IS_SERRATED_SCALPEL && scene._goToScene != 1 && !printed && !talk._talkToAbort) {
				_infoFlag = true;
				clearInfo();
				screen.print(Common::Point(0, INFO_LINE + 1), COL_INFO_FOREGROUND, "Done...");

				// Set how long to show the message
				_menuCounter = 30;
			}
		}
	}

	// Reset cursor back to arrow
	events.setCursor(ARROW);
}