void SimpleMUD::WorkshopHandler::Enter() { // Welcome to the workshop. // List of current levels - and cost up upgrade them. // Cost could be 1 to get the item. And then a lot higher after that? Start at 1000? // Commands that you can use here. int woodLvl = m_player->GetItemLevels()[ResourceType::WOOD]; int stoneLvl = m_player->GetItemLevels()[ResourceType::STONE]; int ironLvl = m_player->GetItemLevels()[ResourceType::IRON]; int goldLvl = m_player->GetItemLevels()[ResourceType::GOLD]; m_player->SendString(SocketLib::white + "Welcome to the Workshop!\r\n" + "Here you can upgrade your items for collecting resources.\r\n" + "This will increase the number of resources you receive while collecting.\r\n" + "Current Item Levels and upgrade costs:\r\n" + "Wood lvl: \t" + std::to_string(woodLvl) + " -- Upgrade Cost: " + std::to_string(CalculateCost(woodLvl + 1)) + " wood" + "\r\n" + "Stone lvl:\t" + std::to_string(stoneLvl) + " -- Upgrade Cost: " + std::to_string(CalculateCost(stoneLvl +1)) + " stone" + "\r\n" + "Iron lvl:\t" + std::to_string(ironLvl) + " -- Upgrade Cost: " + std::to_string(CalculateCost(ironLvl + 1)) + " iron" + "\r\n" + "Gold lvl:\t" + std::to_string(goldLvl) + " -- Upgrade Cost: " + std::to_string(CalculateCost(goldLvl + 1)) + " gold" + "\r\n" + "To upgrade use the format: " + SocketLib::yellow + "upgrade <type>" + SocketLib::white + " -- Eg. 'upgrade gold', 'upgrade wood'\r\n" "Enter '" + SocketLib::yellow + "done" + SocketLib::white + "' to stop upgrading."); // Gonna need a function to figure out the price of the upgrade for a particular level. }
void Reducer::Reduce() { CostEntry* cur = firstCost; CostEntry* next = firstCost->nextId; CostEntry* prev = firstCost->prevId; UnlinkCost(cur); UnlinkId(cur); UnlinkCost(next); next->cost = CalculateCost(next); LinkCost(next); UnlinkCost(prev); prev->cost = CalculateCost(prev); LinkCost(prev); --numPoints; delete cur; }
void SimpleMUD::WorkshopHandler::Handle(string p_data) { // Handle the commands for the workshop. if (p_data == "done") { m_player->Conn()->RemoveHandler(); return; } if (BasicLib::ParseWord(p_data, 0) == "upgrade") { string second = ""; second = BasicLib::ParseWord(p_data, 1); if (second == "") { m_player->SendString(SocketLib::red + "Could not detect valid <resource> type!"); return; } // Find type ResourceType type; bool valid = false; for (int i = 0; i < NumResourceType; i++) { if (BasicLib::LowerCase(ResourceTypeStrings[i]) == second) { type = static_cast<ResourceType>(i); valid = true; } } if (!valid) { m_player->SendString(SocketLib::red + "Did not detect valid <resource> type."); return; } // Check price resource price = CalculateCost(m_player->GetItemLevels()[type] + 1); // Check if they have enough money if (m_player->GetResources()[type] < price) { m_player->SendString(SocketLib::red + "You don't have enough resources to complete this upgrade!"); return; } // Transaction m_player->GetResources()[type] -= price; m_player->GetItemLevels()[type] += 1; // Confirm message. m_player->SendString(SocketLib::green + "Upgrade Complete!"); } else { m_player->SendString(SocketLib::red + "Invalid Command!"); return; } }
/** Fill the graph with cost */ void Graph::FillGraph() { GraphCoordinateList listStartingCoordinates(GetDimension()); GraphCoordinateListPosition i, ei; size_t* coordinate = NULL; StartingCoordinates(listStartingCoordinates); i = listStartingCoordinates.GetBeginPosition(); ei = listStartingCoordinates.GetEndPosition(); while(i != ei) { if(coordinate) delete [] coordinate; coordinate = listStartingCoordinates.GetAt(i); if(!m_MapCost->IsCostCalculatedFor(coordinate)) m_MapCost->SetCostFor(coordinate, CalculateCost(coordinate)); listStartingCoordinates.NextPosition(i); } // Start cleaning memory if(coordinate) delete [] coordinate; listStartingCoordinates.RemoveAll(); // End cleaning memory }
void Reducer::CalculateCosts() { int pointNum = points.size(); if (pointNum < 3) return; CostEntry* cur = firstId; firstCost = cur; lastCost = cur; cur->cost = CalculateCost(cur); cur = cur->nextId; while (cur) { cur->cost = CalculateCost(cur); LinkCost(cur); if (cur == lastId) break; cur = cur->nextId; } }
void PathFinder::_AddIfPassable(const IE::point& point, const point_node& current, std::list<point_node*>& openList, std::list<point_node*>& closedList) { if (point.x < 0 || point.y < 0 || !_IsPassable(point)) return; // Check if point is in closed list std::list<point_node*>::const_iterator i = std::find_if(closedList.begin(), closedList.end(), FindPoint(point)); if (i != closedList.end()) { point_node* node = *i; const int newCost = CalculateCost(current.point, node->point) + current.cost; if (newCost < node->cost) { node->parent = ¤t; node->cost = newCost; } return; } i = std::find_if(openList.begin(), openList.end(), FindPoint(point)); if (i != openList.end()) { point_node* node = *i; // Point is already on the open list. // Check if getting through the point from this point // is cheaper. If so, set this as parent. const int newCost = CalculateCost(current.point, node->point) + current.cost; if (newCost < node->cost) { node->parent = ¤t; node->cost = newCost; } } else { const int cost = CalculateCost(point, current.point) + current.cost; point_node* newNode = new point_node(point, ¤t, cost); openList.push_back(newNode); } }
/** Calculate the cost for the coordinate */ int Graph::CalculateCost(size_t* curcoord) { GraphCoordinateList listprevs(GetDimension()); PreviousCoordinates(listprevs, curcoord); if(listprevs.isEmpty()) { // It's a first one listprevs.RemoveAll(); return 0; } GraphCoordinateListPosition i, ei; int mincost = C_UNCALCULATED, cost; size_t* coordinate = NULL; i = listprevs.GetBeginPosition(); ei = listprevs.GetEndPosition(); while(i != ei) { coordinate = listprevs.GetAt(i); cost = m_MapCost->GetCostFor(coordinate); if(cost == C_UNCALCULATED) { cost = CalculateCost(coordinate); m_MapCost->SetCostFor(coordinate, cost); } if(mincost == C_UNCALCULATED) { mincost = cost + GetTransitionCost(curcoord, coordinate); } else { int CostTransCost = cost + GetTransitionCost(curcoord, coordinate); if(CostTransCost < mincost) mincost = CostTransCost; } listprevs.NextPosition(i); if(coordinate) delete [] coordinate; } // Start cleaning memory listprevs.RemoveAll(); // End cleaning memory return mincost; }
/***************************************************************** * FindClosestNode() Finds the closest graph node to a spesified * position by going through all nodes. * Ins: XMFLOAT3 * * Outs: int * * Returns: Float * * Mod. Date: 08/16/2015 * Mod. Initials: NS *****************************************************************/ int CPathFinding::FindClosestNode(const XMFLOAT3* _position) { // remember the closes node float fShortestDistance = FLT_MAX; int nClosestNode = -1; // Loop through all the nodes on the graph for (size_t nNode = 0; nNode < m_pGraph->GetNodes().size(); nNode++) { // Calculate the distance from the node to the target float fCurDistance = CalculateCost(*_position, m_pGraph->GetNodes()[nNode]->GetPosition()); if (fCurDistance < fShortestDistance || nClosestNode < 0.0f) { // Update the closest node nClosestNode = (int)nNode; // Update the distance to the closest node fShortestDistance = fCurDistance; } } return nClosestNode; }
/***************************************************************** * GeneratePath() Uses A* PathFinding to generate a path from * the start position to the goal position * * Ins: int * int * * Outs: None * * Returns: vector<CNode*> * * Mod. Date: 08/16/2015 * Mod. Initials: NS *****************************************************************/ vector<XMFLOAT3> CPathFinding::GeneratePath(int _start, int _goal, bool smoothed) { GetReadyForNewSearch(); // Create the first PathNode CPathNode* curPathNode = new CPathNode(m_pGraph->GetNodes()[_start]); m_pqNodeQue.push(curPathNode); m_umVisitedNodes[_start] = curPathNode; // Create all local variables here for attempt at optimization CPathNode* theNode = nullptr; CPathNode* visitedNode = nullptr; CPathNode* nextPathNode = nullptr; CNode* curNode; CNode* adjNode; CEdge* curEdge; float newFinalCost; float newCost; float oldCost; float curCost; float newHeuristic; int adjNodeIndex; int curNodeIndex; vector<XMFLOAT3> path; // Loop while there are edges to explore while (!m_pqNodeQue.empty()) { // Get the next node. curPathNode = m_pqNodeQue.front(); m_pqNodeQue.pop(); // Access the node and it's index for future use curNode = curPathNode->GetNode(); curNodeIndex = curNode->GetIndex(); // If the destination is found if (curNodeIndex == _goal) { // Clear the old path m_lPath.clear(); // Build the path theNode = m_umVisitedNodes[curNode->GetIndex()]; // Untill we trace back to the _start node while (theNode != nullptr) { // Add the node to the path m_lPath.push_back(theNode->GetNode()); // Advance to the next connected node theNode = theNode->m_cpParent; } if (smoothed) path = SmoothPath(m_lPath); else { for (size_t currNode = 0; currNode < m_lPath.size(); currNode++) path.push_back(m_lPath[currNode]->GetPosition()); } /*m_umVisitedNodes.clear(); ^^^^^^^^^^^^^^^^^^^^^^^^^^ This stupid line of code caused us so many headaches that I can't bring myself to actually delete it. Forever it shall live in the belly of our pathfinding code*/ return path; } // For each edge the node has for (size_t edge = 0; edge < curNode->GetEdges().size(); edge++) { // Get the current Edge and the node attatched to it curEdge = curNode->GetEdges()[edge]; adjNodeIndex = curEdge->GetAdjNode(); adjNode = m_pGraph->GetNodes()[adjNodeIndex]; // Calculate the cost to the adj Node from _start Node (Total cost so far) curCost = curNode->GetCost() + curEdge->GetEdgeCost(); // If the node has been visited if (m_umVisitedNodes[adjNodeIndex] != nullptr) { visitedNode = m_umVisitedNodes[adjNodeIndex]; // The cost it took previously to get to the node oldCost = visitedNode->GetNode()->GetCost(); // If the new cost is less the the old one if (curCost < oldCost) { m_pqNodeQue.remove(visitedNode); visitedNode->GetNode()->SetCost(curCost); newFinalCost = visitedNode->GetNode()->GetCost() + visitedNode->GetNode()->GetHeuristic() * m_fHeuristicWeight; visitedNode->GetNode()->SetFinalCost(newFinalCost); visitedNode->m_cpParent = curPathNode; m_pqNodeQue.push(visitedNode); } } else // If it has not been visited { // Set the cost adj notes cost (Total of what it takes to get here) newCost = curNode->GetCost() + curEdge->GetEdgeCost(); adjNode->SetCost(newCost); // Set the HeuristicCost newHeuristic = CalculateCost(m_pGraph->GetNodes()[_goal]->GetPosition(), adjNode->GetPosition()); adjNode->SetHeuristic(newHeuristic); // Set the new FinalCost // ?? newFinalCost = newCost + newHeuristic * m_fHeuristicWeight; adjNode->SetFinalCost(newFinalCost); // Create a PathNode for the adj node (Note adj to the one I'm on) nextPathNode = new CPathNode(adjNode); // Set it's parent to the one I'm on (Coming from) nextPathNode->m_cpParent = curPathNode; // Add it to the que to be checked. m_pqNodeQue.push(nextPathNode); // Mark it as visited m_umVisitedNodes[adjNodeIndex] = nextPathNode; } } } return path; }