aboutsummaryrefslogtreecommitdiff
path: root/engines/fullpipe/motion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/fullpipe/motion.cpp')
-rw-r--r--engines/fullpipe/motion.cpp678
1 files changed, 647 insertions, 31 deletions
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index 2ff2c002e0..a6d32cfb48 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -116,13 +116,13 @@ void MctlCompound::freeItems() {
warning("STUB: MctlCompound::freeItems()");
}
-MessageQueue *MctlCompound::method34(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId) {
+MessageQueue *MctlCompound::method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
warning("STUB: MctlCompound::method34()");
return 0;
}
-MessageQueue *MctlCompound::method4C(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId) {
+MessageQueue *MctlCompound::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
int match1 = -1;
int match2 = -1;
@@ -154,14 +154,14 @@ MessageQueue *MctlCompound::method4C(StaticANIObject *subj, int xpos, int ypos,
return 0;
if (match1 == match2)
- return _motionControllers[match1]->_motionControllerObj->method4C(subj, xpos, ypos, flag, staticsId);
+ return _motionControllers[match1]->_motionControllerObj->doWalkTo(subj, xpos, ypos, fuzzyMatch, staticsId);
MctlConnectionPoint *closestP = findClosestConnectionPoint(subj->_ox, subj->_oy, match1, xpos, ypos, match2, &match2);
if (!closestP)
return 0;
- MessageQueue *mq = _motionControllers[match1]->_motionControllerObj->method4C(subj, closestP->_connectionX, closestP->_connectionY, 1, closestP->_field_14);
+ MessageQueue *mq = _motionControllers[match1]->_motionControllerObj->doWalkTo(subj, closestP->_connectionX, closestP->_connectionY, 1, closestP->_field_14);
ExCommand *ex;
@@ -174,7 +174,7 @@ MessageQueue *MctlCompound::method4C(StaticANIObject *subj, int xpos, int ypos,
ex = new ExCommand(subj->_id, 51, 0, xpos, ypos, 0, 1, 0, 0, 0);
- ex->_field_20 = flag;
+ ex->_field_20 = fuzzyMatch;
ex->_keyCode = subj->_okeyCode;
ex->_excFlags |= 2;
@@ -285,7 +285,7 @@ int MovGraph::method2C() {
return 0;
}
-MessageQueue *MovGraph::method34(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId) {
+MessageQueue *MovGraph::method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
warning("STUB: MovGraph::method34()");
return 0;
@@ -309,8 +309,8 @@ int MovGraph::method44() {
return 0;
}
-MessageQueue *MovGraph::method4C(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId) {
- warning("STUB: MovGraph::method4C()");
+MessageQueue *MovGraph::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ warning("STUB: MovGraph::doWalkTo()");
return 0;
}
@@ -321,7 +321,7 @@ int MovGraph::method50() {
return 0;
}
-double MovGraph::calcDistance(Common::Point *point, MovGraphLink *link, int flag) {
+double MovGraph::calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch) {
int n1x = link->_movGraphNode1->_x;
int n1y = link->_movGraphNode1->_y;
int n2x = link->_movGraphNode2->_x;
@@ -336,7 +336,7 @@ double MovGraph::calcDistance(Common::Point *point, MovGraphLink *link, int flag
double res = sqrt(1.0 - dist2 * dist2) * dist1;
if (dist2 <= 0.0 || distm >= link->_distance) {
- if (flag) {
+ if (fuzzyMatch) {
if (dist2 > 0.0) {
if (distm >= link->_distance) {
point->x = n2x;
@@ -365,6 +365,29 @@ int MovGraph2::getItemIndexByGameObjectId(int objectId) {
return -1;
}
+int MovGraph2::getItemSubIndexByStaticsId(int idx, int staticsId) {
+ for (int i = 0; i < 4; i++)
+ if (_items[idx]->_subItems[i]._staticsId1 == staticsId || _items[idx]->_subItems[i]._staticsId2 == staticsId)
+ return i;
+
+ return -1;
+}
+
+int MovGraph2::getItemSubIndexByMovementId(int idx, int movId) {
+ for (int i = 0; i < 4; i++)
+ if (_items[idx]->_subItems[i]._walk[0]._movementId == movId || _items[idx]->_subItems[i]._turn[0]._movementId == movId ||
+ _items[idx]->_subItems[i]._turnS[0]._movementId == movId)
+ return i;
+
+ return -1;
+}
+
+int MovGraph2::getItemSubIndexByMGM(int idx, StaticANIObject *ani) {
+ warning("STUB: MovGraph2::getItemSubIndexByMGM()");
+
+ return -1;
+}
+
bool MovGraph2::initDirections(StaticANIObject *obj, MovGraph2Item *item) {
item->_obj = obj;
item->_objectId = obj->_id;
@@ -401,7 +424,7 @@ bool MovGraph2::initDirections(StaticANIObject *obj, MovGraph2Item *item) {
return false;
for (int act = 0; act < 3; act++) {
- int idx;
+ int idx = 0;
switch(act) {
case 0:
@@ -428,7 +451,7 @@ bool MovGraph2::initDirections(StaticANIObject *obj, MovGraph2Item *item) {
}
for (int act = 0; act < 4; act++) {
- int idx;
+ int idx = 0;
switch(act) {
case 0:
@@ -458,7 +481,7 @@ bool MovGraph2::initDirections(StaticANIObject *obj, MovGraph2Item *item) {
}
for (int act = 0; act < 4; act++) {
- int idx;
+ int idx = 0;
switch(act) {
case 0:
@@ -512,6 +535,121 @@ void MovGraph2::addObject(StaticANIObject *obj) {
}
}
+void MovGraph2::buildMovInfo1SubItems(MovInfo1 *movinfo, Common::Array<MovGraphLink *> *linkList, LinkInfo *lnkSrc, LinkInfo *lnkDst) {
+ MovInfo1Sub *elem;
+ Common::Point point;
+ Common::Rect rect;
+
+ int subIndex = movinfo->subIndex;
+
+ movinfo->items.clear();
+
+ elem = new MovInfo1Sub;
+ elem->subIndex = subIndex;
+ elem->x = movinfo->pt1.x;
+ elem->y = movinfo->pt1.y;
+ elem->distance = -1;
+
+ movinfo->items.push_back(elem);
+
+ int prevSubIndex = movinfo->subIndex;
+
+ for (uint i = 0; i < linkList->size(); i++) {
+ int idx1;
+
+ if (linkList->size() <= 1) {
+ if (linkList->size() == 1)
+ idx1 = getShortSide((*linkList)[0], movinfo->pt2.x - movinfo->pt1.x, movinfo->pt2.y - movinfo->pt1.y);
+ else
+ idx1 = getShortSide(0, movinfo->pt2.x - movinfo->pt1.x, movinfo->pt2.y - movinfo->pt1.y);
+
+ point.y = -1;
+ rect.bottom = -1;
+ rect.right = -1;
+ rect.top = -1;
+ rect.left = -1;
+ } else {
+ idx1 = findLink(linkList, i, &rect, &point);
+ }
+
+ if (idx1 != prevSubIndex) {
+ prevSubIndex = idx1;
+ subIndex = idx1;
+
+ elem = new MovInfo1Sub;
+ elem->subIndex = subIndex;
+ elem->x = rect.left;
+ elem->y = rect.top;
+ elem->distance = -1;
+
+ movinfo->items.push_back(elem);
+ }
+
+ if (i != linkList->size() - 1) {
+ while (1) {
+ i++;
+ if (findLink(linkList, i, &rect, 0) != prevSubIndex) {
+ i--;
+ findLink(linkList, i, &rect, &point);
+
+ break;
+ }
+
+ if (i == linkList->size() - 1)
+ break;
+ }
+ }
+
+ if (movinfo->items.back()->subIndex != 10) {
+ subIndex = prevSubIndex;
+
+ elem = new MovInfo1Sub;
+ elem->subIndex = 10;
+ elem->x = -1;
+ elem->y = -1;
+ elem->distance = -1;
+
+ movinfo->items.push_back(elem);
+
+ if (i == linkList->size()) {
+ elem = new MovInfo1Sub;
+ elem->subIndex = prevSubIndex;
+ elem->x = movinfo->pt2.x;
+ elem->y = movinfo->pt2.y;
+ elem->distance = movinfo->distance2;
+
+ movinfo->items.push_back(elem);
+ } else {
+ elem = new MovInfo1Sub;
+ elem->subIndex = prevSubIndex;
+ elem->x = rect.right;
+ elem->y = rect.bottom;
+ elem->distance = point.y;
+
+ movinfo->items.push_back(elem);
+ }
+ }
+ }
+
+ if (subIndex != movinfo->item1Index) {
+ elem = new MovInfo1Sub;
+ elem->subIndex = movinfo->item1Index;
+ elem->x = movinfo->pt2.x;
+ elem->y = movinfo->pt2.y;
+ elem->distance = movinfo->distance2;
+
+ movinfo->items.push_back(elem);
+ }
+
+ movinfo->itemsCount = movinfo->items.size();
+}
+
+MessageQueue *MovGraph2::buildMovInfo1MessageQueue(MovInfo1 *movInfo) {
+ warning("STUB: MovGraph2::buildMovInfo1MessageQueue()");
+
+ return 0;
+}
+
int MovGraph2::removeObject(StaticANIObject *obj) {
warning("STUB: MovGraph2::removeObject()");
@@ -522,18 +660,469 @@ void MovGraph2::freeItems() {
warning("STUB: MovGraph2::freeItems()");
}
-MessageQueue *MovGraph2::method34(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId) {
+MessageQueue *MovGraph2::method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
warning("STUB: MovGraph2::method34()");
return 0;
}
-MessageQueue *MovGraph2::method4C(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId) {
- warning("STUB: MovGraph2::method4C()");
+MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ LinkInfo linkInfoDest;
+ LinkInfo linkInfoSource;
+ MovInfo1 movInfo1;
+ PicAniInfo picAniInfo;
+ Common::Point point;
+
+ int idx = getItemIndexByGameObjectId(obj->_id);
+
+ if (idx < 0)
+ return 0;
+
+ linkInfoSource.link = 0;
+ linkInfoSource.node = 0;
+
+ linkInfoDest.link = 0;
+ linkInfoDest.node = 0;
+
+ point.x = 0;
+
+ obj->getPicAniInfo(&picAniInfo);
+
+ int idxsub;
+
+ if (obj->_movement)
+ idxsub = getItemSubIndexByMovementId(idx, obj->_movement->_id);
+ else
+ idxsub = getItemSubIndexByStaticsId(idx, obj->_statics->_staticsId);
+
+ bool subMgm = false;
+
+ if (idxsub == -1) {
+ idxsub = getItemSubIndexByMGM(idx, obj);
+ subMgm = true;
+
+ if (idxsub == -1)
+ return 0;
+ }
+
+ if (obj->_movement) {
+ int newx, newy;
+
+ if (subMgm) {
+ obj->_messageQueueId = 0;
+ obj->changeStatics2(_items[idx]->_subItems[idxsub]._staticsId1);
+ newx = obj->_ox;
+ newy = obj->_oy;
+ } else {
+ obj->_movement->calcSomeXY(point, 0);
+ newx = obj->_movement->_ox - point.x;
+ newy = obj->_movement->_oy - point.y;
+ if (idxsub != 1 && idxsub) {
+ if (idxsub == 2 || idxsub == 3) {
+ newy = obj->_movement->_oy;
+ }
+ } else {
+ newx = obj->_movement->_ox;
+ }
+ }
+
+ obj->_movement = 0;
+ obj->setOXY(newx, newy);
+ }
+
+ if (obj->_ox == xpos && obj->_oy == ypos) {
+ g_fullpipe->_globalMessageQueueList->compact();
+
+ MessageQueue *mq = new MessageQueue();
+
+ if (staticsId && obj->_statics->_staticsId != staticsId) {
+ int idxwalk = getItemSubIndexByStaticsId(idx, staticsId);
+ if (idxwalk == -1) {
+ obj->setPicAniInfo(&picAniInfo);
+
+ delete mq;
+
+ return 0;
+ }
+
+ ExCommand *ex = new ExCommand(picAniInfo.objectId, 1, _items[idx]->_subItems[idxsub]._walk[idxwalk]._movementId, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_field_24 = 1;
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 2;
+
+ mq->_exCommands.push_back(ex);
+ } else {
+ ExCommand *ex = new ExCommand(picAniInfo.objectId, 22, obj->_statics->_staticsId, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 3;
+ mq->_exCommands.push_back(ex);
+
+ ex = new ExCommand(picAniInfo.objectId, 5, -1, obj->_ox, obj->_oy, 0, 1, 0, 0, 0);
+
+ ex->_field_14 = -1;
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 3;
+ mq->_exCommands.push_back(ex);
+ }
+
+ obj->setPicAniInfo(&picAniInfo);
+
+ return mq;
+ }
+
+ linkInfoSource.node = findNode(obj->_ox, obj->_oy, 0);
+
+ if (!linkInfoSource.node) {
+ linkInfoSource.link = findLink1(obj->_ox, obj->_oy, idxsub, 0);
+
+ if (!linkInfoSource.link) {
+ linkInfoSource.link = findLink2(obj->_ox, obj->_oy);
+
+ if (!linkInfoSource.link) {
+ obj->setPicAniInfo(&picAniInfo);
+
+ return 0;
+ }
+ }
+ }
+
+ linkInfoDest.node = findNode(xpos, ypos, fuzzyMatch);
+
+ if (!linkInfoDest.node) {
+ linkInfoDest.link = findLink1(xpos, ypos, idxsub, fuzzyMatch);
+
+ if (!linkInfoDest.link) {
+ obj->setPicAniInfo(&picAniInfo);
+
+ return 0;
+ }
+ }
+
+ Common::Array<MovGraphLink *> tempLinkList;
+ double minPath = findMinPath(&linkInfoSource, &linkInfoDest, &tempLinkList);
+
+ debug(0, "MovGraph2::doWalkTo(): path: %lf parts: %d", minPath, tempLinkList.size());
+
+ if (minPath < 0.0 || ((linkInfoSource.node != linkInfoDest.node || !linkInfoSource.node) && !tempLinkList.size()))
+ return 0;
+
+ movInfo1.subIndex = idxsub;
+ movInfo1.pt1.x = obj->_ox;
+ movInfo1.pt1.y = obj->_oy;
+
+ int dx1 = obj->_ox;
+ int dy1 = obj->_oy;
+ int dx2, dy2;
+
+ if (linkInfoSource.node)
+ movInfo1.distance1 = linkInfoSource.node->_distance;
+ else
+ movInfo1.distance1 = linkInfoSource.link->_movGraphNode1->_distance;
+
+ if (linkInfoDest.node) {
+ dx2 = linkInfoDest.node->_x;
+ dy2 = linkInfoDest.node->_y;
+
+ movInfo1.pt2.x = linkInfoDest.node->_x;
+ movInfo1.pt2.y = linkInfoDest.node->_y;
+
+ movInfo1.distance2 = linkInfoDest.node->_distance;
+ } else {
+ movInfo1.pt2.x = xpos;
+ movInfo1.pt2.y = ypos;
+
+ MovGraphNode *nod = linkInfoDest.link->_movGraphNode1;
+ double dst1 = sqrt((double)((ypos - nod->_y) * (ypos - nod->_y) + (xpos - nod->_x) * (xpos - nod->_x)));
+ int dst = linkInfoDest.link->_movGraphNode2->_distance - nod->_distance;
+
+ movInfo1.distance2 = nod->_distance + (dst1 * (double)dst / linkInfoDest.link->_distance);
+
+ calcDistance(&movInfo1.pt2, linkInfoDest.link, 1);
+
+ dx1 = movInfo1.pt1.x;
+ dy1 = movInfo1.pt1.y;
+ dx2 = movInfo1.pt2.x;
+ dy2 = movInfo1.pt2.y;
+ }
+
+ if (staticsId) {
+ movInfo1.item1Index = getItemSubIndexByStaticsId(idx, staticsId);
+ } else if (tempLinkList.size() <= 1) {
+ if (tempLinkList.size() == 1)
+ movInfo1.item1Index = getShortSide(tempLinkList[0], dx2 - dx1, dy2 - dy1);
+ else
+ movInfo1.item1Index = getShortSide(0, dx2 - dx1, dy2 - dy1);
+ } else {
+ movInfo1.item1Index = findLink(&tempLinkList, tempLinkList.size() - 1, 0, 0);
+ }
+
+ movInfo1.flags = fuzzyMatch != 0;
+
+ if (_items[idx]->_subItems[idxsub]._staticsId1 != obj->_statics->_staticsId)
+ movInfo1.flags |= 2;
+
+ buildMovInfo1SubItems(&movInfo1, &tempLinkList, &linkInfoSource, &linkInfoDest);
+
+ MessageQueue *mq = buildMovInfo1MessageQueue(&movInfo1);
+
+ linkInfoDest.node = findNode(movInfo1.pt2.x, movInfo1.pt2.y, fuzzyMatch);
+
+ if (!linkInfoDest.node)
+ linkInfoDest.link = findLink1(movInfo1.pt2.x, movInfo1.pt2.y, movInfo1.item1Index, fuzzyMatch);
+
+ if (fuzzyMatch || linkInfoDest.link || linkInfoDest.node) {
+ if (mq && mq->getCount() > 0 && picAniInfo.movementId) {
+ ExCommand *ex = mq->getExCommandByIndex(0);
+
+ if (ex && (ex->_messageKind == 1 || ex->_messageKind == 20)
+ && picAniInfo.movementId == ex->_messageNum
+ && picAniInfo.someDynamicPhaseIndex == ex->_field_14) {
+ mq->deleteExCommandByIndex(0, 1);
+ } else {
+ ex = new ExCommand(picAniInfo.objectId, 5, ex->_messageNum, obj->_ox, obj->_oy, 0, 1, 0, 0, 0);
+ ex->_field_14 = -1;
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 2;
+ mq->addExCommand(ex);
+
+ ex = new ExCommand(picAniInfo.objectId, 22, _items[idx]->_subItems[idxsub]._staticsId1, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 3;
+ mq->addExCommand(ex);
+ }
+ }
+ } else {
+ if (mq)
+ delete mq;
+ mq = 0;
+ }
+
+ obj->setPicAniInfo(&picAniInfo);
+
+ return mq;
+}
+
+MovGraphNode *MovGraph2::findNode(int x, int y, int fuzzyMatch) {
+ for (ObList::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphNode);
+
+ MovGraphNode *node = (MovGraphNode *)*i;
+
+ if (fuzzyMatch) {
+ if (abs(node->_x - x) < 15 && abs(node->_y - y) < 15)
+ return node;
+ } else {
+ if (node->_x == x && node->_y == y)
+ return node;
+ }
+ }
+
+ return 0;
+}
+
+int MovGraph2::getShortSide(MovGraphLink *lnk, int x, int y) {
+ warning("STUB: MovGraph2::getShortSide()");
return 0;
}
+int MovGraph2::findLink(Common::Array<MovGraphLink *> *linkList, int idx, Common::Rect *rect, Common::Point *point) {
+ MovGraphNode *node1 = (*linkList)[idx]->_movGraphNode1;
+ MovGraphNode *node2 = (*linkList)[idx]->_movGraphNode2;
+ MovGraphNode *node3 = node1;
+
+ if (idx != 0) {
+ MovGraphLink *lnk = (*linkList)[idx - 1];
+
+ if (lnk->_movGraphNode2 != node1) {
+ if (lnk->_movGraphNode1 != node1) {
+ if (lnk->_movGraphNode2 == node2 || lnk->_movGraphNode1 == node2) {
+ node3 = node2;
+ node2 = node1;
+ }
+ goto LABEL_7;
+ }
+ }
+ node3 = node1;
+ } else if (idx != linkList->size() - 1) {
+ MovGraphLink *lnk = (*linkList)[idx + 1];
+
+ if (lnk->_movGraphNode1 == node1 || lnk->_movGraphNode1 == node1) {
+ node3 = node2;
+ node2 = node1;
+ } else if (lnk->_movGraphNode2 == node2 || lnk->_movGraphNode1 == node2) {
+ node3 = node1;
+ }
+ }
+
+ LABEL_7:
+ if (rect) {
+ rect->left = node3->_x;
+ rect->top = node3->_y;
+ rect->right = node2->_x;
+ rect->bottom = node2->_y;
+ }
+ if (point) {
+ point->x = node3->_distance;
+ point->y = node2->_distance;
+ }
+
+ if (abs(node3->_x - node2->_x) <= abs(node3->_y - node2->_y))
+ return (node3->_y < node2->_x) + 2;
+ else
+ return node3->_x >= node2->_x;
+}
+
+MovGraphLink *MovGraph2::findLink1(int x, int y, int idx, int fuzzyMatch) {
+ Common::Point point;
+ MovGraphLink *res = 0;
+
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink);
+
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ if (fuzzyMatch) {
+ point.x = x;
+ point.y = y;
+ double dst = calcDistance(&point, lnk, 0);
+
+ if (dst >= 0.0 && dst < 2.0)
+ return lnk;
+ } else if (!(lnk->_flags & 0x20000000)) {
+ if (lnk->_movGraphReact->pointInRegion(x, y)) {
+ if (abs(lnk->_movGraphNode1->_x - lnk->_movGraphNode2->_x) <= abs(lnk->_movGraphNode1->_y - lnk->_movGraphNode2->_y)) {
+ if (idx == 2 || idx == 3)
+ return lnk;
+ res = lnk;
+ } else {
+ if (idx == 1 || !idx)
+ return lnk;
+ res = lnk;
+ }
+ }
+ }
+ }
+
+ return res;
+}
+
+MovGraphLink *MovGraph2::findLink2(int x, int y) {
+ double mindist = 1.0e20;
+ MovGraphLink *res;
+
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink);
+
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ if (!(lnk->_flags & 0x20000000)) {
+ double n1x = lnk->_movGraphNode1->_x;
+ double n1y = lnk->_movGraphNode1->_y;
+ double n2x = lnk->_movGraphNode2->_x;
+ double n2y = lnk->_movGraphNode2->_y;
+ double n1dx = n1x - x;
+ double n1dy = n1y - y;
+ double dst1 = sqrt(n1dy * n1dy + n1dx * n1dx);
+ double coeff1 = ((n1y - n2y) * n1dy + (n2x - n1x) * n1dx) / lnk->_distance / dst1;
+ double dst3 = coeff1 * dst1;
+ double dst2 = sqrt(1.0 - coeff1 * coeff1) * dst1;
+
+ if (coeff1 * dst1 < 0.0) {
+ dst3 = 0.0;
+ dst2 = sqrt(n1dy * n1dy + n1dx * n1dx);
+ }
+ if (dst3 > lnk->_distance) {
+ dst3 = lnk->_distance;
+ dst2 = sqrt((n2x - x) * (n2x - x) + (n2y - y) * (n2y - y));
+ }
+ if (dst3 >= 0.0 && dst3 <= lnk->_distance && dst2 < mindist) {
+ mindist = dst2;
+ res = lnk;
+ }
+ }
+ }
+
+ if (mindist < 1.0e20)
+ return res;
+ else
+ return 0;
+}
+
+double MovGraph2::findMinPath(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, Common::Array<MovGraphLink *> *listObj) {
+ LinkInfo linkInfoWorkSource;
+
+ if (linkInfoSource->link != linkInfoDest->link || linkInfoSource->node != linkInfoDest->node) {
+ double minDistance = -1.0;
+
+ if (linkInfoSource->node) {
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ if ((lnk->_movGraphNode1 == linkInfoSource->node || lnk->_movGraphNode2 == linkInfoSource->node) && !(lnk->_flags & 0xA0000000)) {
+ linkInfoWorkSource.node = 0;
+ linkInfoWorkSource.link = lnk;
+
+ Common::Array<MovGraphLink *> tmpList;
+
+ lnk->_flags |= 0x80000000;
+
+ double newDistance = findMinPath(&linkInfoWorkSource, linkInfoDest, &tmpList);
+
+ if (newDistance >= 0.0 && (minDistance < 0.0 || newDistance + lnk->_distance < minDistance)) {
+ listObj->clear();
+ listObj->push_back(tmpList);
+
+ minDistance = newDistance + lnk->_distance;
+ }
+
+ lnk->_flags &= 0x7FFFFFFF;
+ }
+ }
+ } else if (linkInfoSource->link) {
+ linkInfoWorkSource.node = linkInfoSource->link->_movGraphNode1;
+ linkInfoWorkSource.link = 0;
+
+ Common::Array<MovGraphLink *> tmpList;
+
+ double newDistance = findMinPath(&linkInfoWorkSource, linkInfoDest, &tmpList);
+
+ if (newDistance >= 0.0) {
+ listObj->clear();
+
+ listObj->push_back(linkInfoSource->link);
+ listObj->push_back(tmpList);
+
+ minDistance = newDistance;
+ }
+
+ linkInfoWorkSource.link = 0;
+ linkInfoWorkSource.node = linkInfoSource->link->_movGraphNode2;
+
+ tmpList.clear();
+
+ newDistance = findMinPath(&linkInfoWorkSource, linkInfoDest, &tmpList);
+
+ if (newDistance >= 0 && (minDistance < 0.0 || newDistance < minDistance)) {
+ listObj->push_back(linkInfoSource->link);
+ listObj->push_back(tmpList);
+
+ minDistance = newDistance;
+ }
+ }
+
+ return minDistance;
+ } else {
+ if (linkInfoSource->link)
+ listObj->push_back(linkInfoSource->link);
+
+ return 0.0;
+ }
+}
+
MovGraphNode *MovGraph::calcOffset(int ox, int oy) {
warning("STUB: MovGraph::calcOffset()");
@@ -610,6 +1199,8 @@ MovGraphLink::MovGraphLink() {
_field_38 = 0;
_movGraphReact = 0;
_name = 0;
+
+ _objtype = kObjTypeMovGraphLink;
}
bool MovGraphLink::load(MfcArchive &file) {
@@ -652,7 +1243,6 @@ ReactParallel::ReactParallel() {
_x2 = 0;
_dy = 0;
_dx = 0;
- _points = 0;
_y1 = 0;
_y2 = 0;
}
@@ -688,12 +1278,13 @@ void ReactParallel::createRegion() {
_points[1]->x = (int16)(_x2 - _dx * cs);
_points[1]->y = (int16)(_y2 - _dx * sn);
- _points[2]->x = (int16)(_x1 + _dy * cs);
+ _points[2]->x = (int16)(_x2 + _dy * cs);
_points[2]->y = (int16)(_y2 + _dy * sn);
_points[3]->x = (int16)(_x1 + _dy * cs);
_points[3]->y = (int16)(_y1 + _dy * sn);
+ _pointCount = 4;
// GdiObject::Attach(_rgn, CreatePolygonRgn(_points, 4, 2);
}
@@ -701,18 +1292,8 @@ void ReactParallel::method14() {
warning("STUB: ReactParallel::method14()");
}
-bool ReactParallel::pointInRegion(int x, int y) {
- warning("STUB: ReactParallel::pointInRegion()");
-
- warning("%d %d, %d %d, %d %d, %d %d", _points[0]->x, _points[0]->y, _points[1]->x, _points[1]->y, _points[2]->x, _points[2]->y, _points[3]->x, _points[3]->y);
-
- return false;
-}
-
ReactPolygonal::ReactPolygonal() {
_field_C = 0;
- _points = 0;
- _pointCount = 0;
_field_10 = 0;
}
@@ -751,10 +1332,45 @@ void ReactPolygonal::method14() {
warning("STUB: ReactPolygonal::method14()");
}
-bool ReactPolygonal::pointInRegion(int x, int y) {
- warning("STUB: ReactPolygonal::pointInRegion()");
+bool MovGraphReact::pointInRegion(int x, int y) {
+ if (_pointCount < 3) {
+ return false;
+ }
+
+ int counter = 0;
+ double xinters;
+ Common::Point p, p1, p2;
+
+ p.x = (double)x;
+ p.y = (double)y;
+
+ p1.x = (double)_points[0]->x;
+ p1.y = (double)_points[0]->y;
+
+ for (int i = 1; i <= _pointCount; i++) {
+ p2.x = (double)_points[i % _pointCount]->x;
+ p2.y = (double)_points[i % _pointCount]->y;
+
+ if (p.y > MIN(p1.y, p2.y)) {
+ if (p.y <= MAX(p1.y, p2.y)) {
+ if (p.x <= MAX(p1.x, p2.x)) {
+ if (p1.y != p2.y) {
+ xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
+ if (p1.x == p2.x || p.x <= xinters) {
+ counter++;
+ }
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
- return false;
+ if (counter % 2 == 0) {
+ return false;
+ } else {
+ return true;
+ }
}
int startWalkTo(int objId, int objKey, int x, int y, int a5) {