diff options
Diffstat (limited to 'engines/fullpipe/motion.cpp')
-rw-r--r-- | engines/fullpipe/motion.cpp | 678 |
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) { |