Initial commit
This commit is contained in:
187
engines/ultima/ultima8/gumps/item_relative_gump.cpp
Normal file
187
engines/ultima/ultima8/gumps/item_relative_gump.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima8/gumps/item_relative_gump.h"
|
||||
#include "ultima/ultima8/gumps/game_map_gump.h"
|
||||
#include "ultima/ultima8/world/container.h"
|
||||
#include "ultima/ultima8/world/get_object.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
DEFINE_RUNTIME_CLASSTYPE_CODE(ItemRelativeGump)
|
||||
|
||||
ItemRelativeGump::ItemRelativeGump() : Gump(), _ix(0), _iy(0) {
|
||||
}
|
||||
|
||||
ItemRelativeGump::ItemRelativeGump(int32 x, int32 y, int32 width, int32 height,
|
||||
uint16 owner, uint32 flags, int32 layer)
|
||||
: Gump(x, y, width, height, owner, flags, layer), _ix(0), _iy(0) {
|
||||
}
|
||||
|
||||
ItemRelativeGump::~ItemRelativeGump(void) {
|
||||
}
|
||||
|
||||
void ItemRelativeGump::InitGump(Gump *newparent, bool take_focus) {
|
||||
Gump::InitGump(newparent, take_focus);
|
||||
|
||||
GetItemLocation(0);
|
||||
|
||||
if (!newparent && _parent)
|
||||
MoveOnScreen();
|
||||
}
|
||||
|
||||
void ItemRelativeGump::MoveOnScreen() {
|
||||
assert(_parent);
|
||||
Common::Rect32 sd = _parent->getDims();
|
||||
|
||||
// first move back to our desired location
|
||||
_x = 0;
|
||||
_y = 0;
|
||||
|
||||
// get rectangle that gump occupies in desktops's coordinate space
|
||||
int32 left, right, top, bottom;
|
||||
left = -_dims.left;
|
||||
right = left + _dims.width();
|
||||
top = -_dims.top;
|
||||
bottom = top + _dims.height();
|
||||
GumpToParent(left, top);
|
||||
GumpToParent(right, bottom);
|
||||
|
||||
int32 movex = 0, movey = 0;
|
||||
|
||||
if (left < -sd.left)
|
||||
movex = -sd.left - left;
|
||||
else if (right > -sd.left + sd.width())
|
||||
movex = -sd.left + sd.width() - right;
|
||||
|
||||
if (top < -sd.top)
|
||||
movey = -sd.top - top;
|
||||
else if (bottom > -sd.top + sd.height())
|
||||
movey = -sd.top + sd.height() - bottom;
|
||||
|
||||
Move(left + movex, top + movey);
|
||||
}
|
||||
|
||||
// Paint the Gump (RenderSurface is relative to parent).
|
||||
// Calls PaintThis and PaintChildren
|
||||
void ItemRelativeGump::Paint(RenderSurface *surf, int32 lerp_factor, bool scaled) {
|
||||
GetItemLocation(lerp_factor);
|
||||
Gump::Paint(surf, lerp_factor, scaled);
|
||||
}
|
||||
|
||||
|
||||
// Convert a parent relative point to a gump point
|
||||
void ItemRelativeGump::ParentToGump(int32 &px, int32 &py, PointRoundDir r) {
|
||||
px -= _ix;
|
||||
py -= _iy;
|
||||
Gump::ParentToGump(px, py, r);
|
||||
}
|
||||
|
||||
// Convert a gump point to parent relative point
|
||||
void ItemRelativeGump::GumpToParent(int32 &gx, int32 &gy, PointRoundDir r) {
|
||||
Gump::GumpToParent(gx, gy, r);
|
||||
gx += _ix;
|
||||
gy += _iy;
|
||||
}
|
||||
|
||||
void ItemRelativeGump::GetItemLocation(int32 lerp_factor) {
|
||||
Gump *gump = nullptr;
|
||||
|
||||
Item *it = getItem(_owner);
|
||||
|
||||
if (!it) {
|
||||
// This shouldn't ever happen, the GumpNotifyProcess should
|
||||
// close us before we get here
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
Item *next;
|
||||
Item *prev = nullptr;
|
||||
while ((next = it->getParentAsContainer()) != nullptr) {
|
||||
prev = it;
|
||||
it = next;
|
||||
gump = getGump(it->getGump());
|
||||
if (gump) break;
|
||||
}
|
||||
|
||||
int32 gx, gy;
|
||||
bool found;
|
||||
|
||||
if (!gump) {
|
||||
gump = GetRootGump()->FindGump<GameMapGump>();
|
||||
|
||||
if (!gump) {
|
||||
warning("ItemRelativeGump::GetItemLocation(): Unable to find GameMapGump");
|
||||
return;
|
||||
}
|
||||
|
||||
found = gump->GetLocationOfItem(_owner, gx, gy, lerp_factor);
|
||||
} else {
|
||||
assert(prev);
|
||||
found = gump->GetLocationOfItem(prev->getObjId(), gx, gy, lerp_factor);
|
||||
}
|
||||
|
||||
if (found) {
|
||||
// Convert the GumpSpaceCoord relative to the world/item gump
|
||||
// into screenspace coords
|
||||
gy = gy - it->getShapeInfo()->_z * 8 - 16;
|
||||
} else {
|
||||
// If location not found show near bottom center
|
||||
Common::Rect32 r = gump->getDims();
|
||||
gx = (r.left + r.right) / 2;
|
||||
gy = r.bottom - 8;
|
||||
}
|
||||
|
||||
gump->GumpToScreenSpace(gx, gy);
|
||||
|
||||
// Convert the screenspace coords into the coords of us
|
||||
if (_parent)
|
||||
_parent->ScreenSpaceToGump(gx, gy);
|
||||
|
||||
// Set x and y, and center us over it
|
||||
_ix = gx - _dims.width() / 2;
|
||||
_iy = gy - _dims.height();
|
||||
|
||||
|
||||
if (_flags & FLAG_KEEP_VISIBLE)
|
||||
MoveOnScreen();
|
||||
}
|
||||
|
||||
void ItemRelativeGump::Move(int32 x, int32 y) {
|
||||
ParentToGump(x, y);
|
||||
_x += x;
|
||||
_y += y;
|
||||
}
|
||||
|
||||
void ItemRelativeGump::saveData(Common::WriteStream *ws) {
|
||||
Gump::saveData(ws);
|
||||
}
|
||||
|
||||
bool ItemRelativeGump::loadData(Common::ReadStream *rs, uint32 version) {
|
||||
if (!Gump::loadData(rs, version)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
Reference in New Issue
Block a user