int GameConfig::handler(void* user, const char* section, const char* name, const char* value) { auto self = static_cast<GameConfig*>(user); #define MATCH(_s, _n) (strcmp(_s, section) == 0 && strcmp(_n, name) == 0) if (MATCH("game", "path")) { self->m_gamePath = value; } else if (MATCH("input", "invert_y")) { self->m_inputInvertY = atoi(value) > 0; } else { RW_MESSAGE("Unhandled config entry [" << section << "] " << name << " = " << value); return 0; } return 1; #undef MATCH }
AnimGroup AnimGroup::getBuiltInAnimGroup(AnimationSet &animations, const std::string &name) { auto findgroup = [&]() { auto it = std::find_if(kBuiltInAnimGroups.begin(), kBuiltInAnimGroups.end(), [&](const AnimGroup &g) { return g.name_ == name; }); if (it != kBuiltInAnimGroups.end()) { return *it; } else { RW_MESSAGE("No such animation group: " + name + ". Returning first animation group"); return kBuiltInAnimGroups[0]; } }; auto group = AnimGroup(findgroup()); uint32_t id = 0; for (auto &a : group.animations_) { // Copy from the first animgroup if this entry is empty /// @todo check if this is realy how we should do this if (a.name.empty()) { a = kBuiltInAnimGroups[0].animations_[id]; } a.id = static_cast<AnimCycle>(id++); a.anim = animations[a.name]; } return group; }
void AIGraph::createPathNodes(const glm::vec3& position, const glm::quat& rotation, PathData& path) { auto startIndex = static_cast<std::uint32_t>(nodes.size()); std::vector<AIGraphNode*> pathNodes; pathNodes.reserve(path.nodes.size()); nodes.reserve(path.nodes.size()); for (auto n = 0u; n < path.nodes.size(); ++n) { bool external = false; auto& node = path.nodes[n]; glm::vec3 nodePosition = position + (rotation * node.position); if (node.type == PathNode::EXTERNAL) { for (auto& realNode : externalNodes) { auto d = glm::distance2(realNode->position, nodePosition); if (d < 1.f) { pathNodes.push_back(realNode); external = true; break; } } } if (!external) { auto ainode = std::make_unique<AIGraphNode>(); auto ptr = ainode.get(); ainode->type = (path.type == PathData::PATH_PED ? NodeType::Pedestrian : NodeType::Vehicle); ainode->nextIndex = node.next >= 0 ? startIndex + node.next : -1; ainode->flags = AIGraphNode::None; ainode->size = node.size; ainode->leftLanes = node.leftLanes; ainode->rightLanes = node.rightLanes; ainode->position = nodePosition; ainode->external = node.type == PathNode::EXTERNAL; ainode->disabled = false; pathNodes.push_back(ptr); nodes.push_back(std::move(ainode)); if (ptr->external) { externalNodes.push_back(ptr); // Determine which grid cell this node falls into float lowerCoord = -(WORLD_GRID_SIZE) / 2.f; auto gridrel = glm::vec2(ptr->position) - glm::vec2(lowerCoord, lowerCoord); auto gridcoord = glm::floor(gridrel / glm::vec2(WORLD_CELL_SIZE)); if (gridcoord.x < 0 || gridcoord.y < 0 || gridcoord.x >= WORLD_GRID_WIDTH || gridcoord.y >= WORLD_GRID_WIDTH) { RW_MESSAGE("Warning: Node outside of grid at coord " << gridcoord.x << " " << gridcoord.y); } auto index = static_cast<std::size_t>( (gridcoord.x * WORLD_GRID_WIDTH) + gridcoord.y); gridNodes[index].push_back(ptr); } } } for (auto pn = 0u; pn < path.nodes.size(); ++pn) { if (path.nodes[pn].next >= 0 && static_cast<unsigned>(path.nodes[pn].next) < pathNodes.size()) { auto node = pathNodes[pn]; auto next = pathNodes[path.nodes[pn].next]; node->connections.push_back(next); next->connections.push_back(node); } } }