QList<unsigned char> cPathfinding::find(P_CHAR pChar, const Coord &from, const Coord &to) { QList<unsigned char> result; int i; // We can only calculate a path on the normal maps and if the destination is not out of range if (from.isInternalMap() || from.distance(to) > (unsigned int)areaSize) { return result; } memset(touched, 0, sizeof(bool) * nodeCount); // Clear the touched nodes this->goal = to; // Save the goal // Actually th�s should be the x/y offset of our area xoffset = (from.x + to.x - areaSize) / 2; yoffset = (from.y + to.y - areaSize) / 2; int fromNode = getNodeIndex(from.x, from.y, from.z); int toNode = getNodeIndex(to.x, to.y, to.z); openlist = fromNode; // Where are we // Initialize the node nodes[fromNode].cost = 0; nodes[fromNode].total = heuristic(from.x - xoffset, from.y - yoffset, from.z); nodes[fromNode].parent = -1; nodes[fromNode].next = -1; nodes[fromNode].prev = -1; nodes[fromNode].z = from.z; // We touched this node onopen[fromNode] = true; touched[fromNode] = true; int depth = 0; int newTotal, newCost; // This is controlled by the npc moving. Some npcs can fly (move over impassables) // others can open doors ignoreDoors = false; ignoreMovableImpassables = false; int successors[8]; // List of successor nodes used in subsequent iterations. Never more than 8 int successorCount; // Number of successors found while (openlist != -1) { if (++depth > maxDepth) break; // Break if we would exceed the maximum iteration count int bestnode = findBest(openlist); // Get adjacent nodes that we can walk to successorCount = getSuccessors(bestnode, pChar, successors); if (successorCount == 0) { break; // We've run into a situation where we'll never find a suitable successor } // Follow every possible successor for (i = 0; i < successorCount; ++i) { int successor = successors[i]; if (touched[successor]) { continue; // If we worked on the node already, skip this part } // calculate the cost of the successor based on the currents node cost newCost = nodes[bestnode].cost + 1; newTotal = newCost + heuristic(successor % areaSize, (successor / areaSize) % areaSize, nodes[successor].z); // Always execute, !wasTouched was always true here // if ( !wasTouched || m_Nodes[newNode].total > newTotal ) nodes[successor].parent = bestnode; nodes[successor].cost = newCost; nodes[successor].total = newTotal; addToChain(successor); // We found our target if (successor == toNode) { int pathCount = 0; // Stack allocation speed isn't a concern here anymore int parent = nodes[successor].parent; // Record the path in reverse order while (parent != -1) { path[pathCount++] = getDirection(parent % areaSize, (parent / areaSize) % areaSize, successor % areaSize, (successor / areaSize) % areaSize); successor = parent; // Track back parent = nodes[successor].parent; if (successor == fromNode) { break; } } int backtrack = 0; while (pathCount != 0) { result.append( path[--pathCount] ); } return result; // Immediately return } } } return result; // Nothing found }
int checkPattern( int rule, char *arg ) { int ret=0; char term1[MEMORY_ELEMENT_SIZE+1]; char term2[MEMORY_ELEMENT_SIZE+1]; memoryElementType *antecedent = ruleSet[rule].antecedent; /* Build a replacement string (based upon the '?' element) */ while (antecedent) { sscanf( antecedent->element, "(%s %s)", term1, term2); if (term2[strlen(term2)-1] == ')') term2[strlen(term2)-1] = 0; /* If the antecedent element is variable, find the matches * in the working memory and store the matched terms. */ if (term2[0] == '?') { int i; char wm_term1[MEMORY_ELEMENT_SIZE+1]; char wm_term2[MEMORY_ELEMENT_SIZE+1]; for (i = 0 ; i < MAX_MEMORY_ELEMENTS ; i++) { if (workingMemory[i].active) { sscanf( workingMemory[i].element, "(%s %s)", wm_term1, wm_term2 ); if (wm_term2[strlen(wm_term2)-1] == ')') wm_term2[strlen(wm_term2)-1] = 0; if (!strncmp(term1, wm_term1, strlen(term1))) addToChain(wm_term2); } } } antecedent = antecedent->next; } /* Now that we have the replacement strings, walk through the rules trying * the replacement string when necessary. */ do { memoryElementType *curRulePtr, *temp; curRulePtr = ruleSet[rule].antecedent; while (curRulePtr) { sscanf( curRulePtr->element, "(%s %s)", term1, term2 ); if (term2[strlen(term2)-1] == ')') term2[strlen(term2)-1] = 0; if (!strncmp( term1, "true", strlen(term1))) { ret = 1; break; } else { if ((term2[0] == '?') && (chain)) strcpy(term2, chain->element); } ret = searchWorkingMemory( term1, term2 ); if (!ret) break; curRulePtr = curRulePtr->next; } if (ret) { /* Cleanup the replacement string chain */ while (chain) { temp = chain; chain = chain->next; free(temp); } strcpy(arg, term2); } else { if (chain) { temp = chain; chain = chain->next; free(temp); } } } while (chain); return ret; }