void FilePath::Initialize(const String &_pathname) { String pathname = NormalizePathname(_pathname); pathType = GetPathType(pathname); if (pathType == PATH_EMPTY) { absolutePathname = String(); } else if(pathType == PATH_IN_RESOURCES || pathType == PATH_IN_MEMORY) { absolutePathname = pathname; } else if(pathType == PATH_IN_DOCUMENTS) { absolutePathname = GetSystemPathname(pathname, pathType); } else if(IsAbsolutePathname(pathname)) { absolutePathname = pathname; } else { Logger::FrameworkDebug("[FilePath::Initialize] FilePath was initialized from relative path name (%s)", _pathname.c_str()); #if defined(__DAVAENGINE_ANDROID__) absolutePathname = pathname; #else //#if defined(__DAVAENGINE_ANDROID__) FilePath path = FileSystem::Instance()->GetCurrentWorkingDirectory() + pathname; absolutePathname = path.GetAbsolutePathname(); #endif //#if defined(__DAVAENGINE_ANDROID__) } }
void FilePath::ReplaceDirectory(const String &directory) { DVASSERT(!IsEmpty()); const String filename = GetFilename(); absolutePathname = NormalizePathname((MakeDirectory(directory) + filename)); pathType = GetPathType(absolutePathname); }
/** * Walk over a queue path from the given entry edge at the given position. * If it leads to a new voxel edge, the provided position and edge is update with the exit point. * @param voxel_pos [inout] Start voxel position before the queue path, updated to last voxel position. * @param entry Direction used for entry to the path, updated to last edge exit direction. * @return Whether a (possibly) new last voxel could be found, \c false means the path leads to nowhere. * @note Parameter values may get changed during the call, do not rely on their values except when \c true is returned. */ bool TravelQueuePath(XYZPoint16 *voxel_pos, TileEdge *entry) { XYZPoint16 new_pos = *voxel_pos; TileEdge edge = *entry; /* Check that entry voxel actually exists. */ if (!IsVoxelstackInsideWorld(new_pos.x, new_pos.y)) return false; for (;;) { new_pos.x += _tile_dxy[edge].x; new_pos.y += _tile_dxy[edge].y; if (!IsVoxelstackInsideWorld(new_pos.x, new_pos.y)) return false; const Voxel *vx = _world.GetVoxel(new_pos); if (vx == nullptr || !HasValidPath(vx)) { /* No path here, check the voxel below. */ if (new_pos.z == 0) return true; // Path ends here. new_pos.z--; vx = _world.GetVoxel(new_pos); if (vx == nullptr || !HasValidPath(vx)) return true; // Path ends here. } if (new_pos == *voxel_pos) return false; // Cycle detected. /* Stop if we found a non-queue path. */ if (_sprite_manager.GetPathStatus(GetPathType(vx->GetInstanceData())) != PAS_QUEUE_PATH) return true; /* At this point: * voxel_pos, edge (and *entry) contain the last valid voxel edge. * new_pos, vx is the next queue path tile position. */ uint8 exits = GetPathExits(vx); /* Check that the new tile can go back to our last tile. */ uint8 rev_edge = (edge + 2) % 4; if (!((exits & (0x01 << rev_edge)) != 0 && new_pos.z == voxel_pos->z) && !((exits & (0x10 << rev_edge)) != 0 && new_pos.z == voxel_pos->z - 1)) { return false; } /* Find exit to the next path tile. */ for (edge = EDGE_BEGIN; edge < EDGE_COUNT; edge++) { if (edge == rev_edge) continue; // Skip the direction we came from. if ((exits & (0x01 << edge)) != 0) break; if ((exits & (0x10 << edge)) != 0) { new_pos.z++; break; } } if (edge == EDGE_COUNT) return false; // Queue path doesn't have a second exit. *voxel_pos = new_pos; *entry = edge; } }
FilePath& FilePath::operator+=(const String & path) { absolutePathname = AddPath(*this, path); if (pathType == PATH_EMPTY) { pathType = GetPathType(absolutePathname); } return (*this); }
FilePath FilePath::operator+(const String &path) const { FilePath pathname(AddPath(*this, path)); pathname.pathType = this->pathType; if (this->pathType == PATH_EMPTY) { pathname.pathType = GetPathType(pathname.absolutePathname); } return pathname; }
/** * Examine, and perhaps modify a neighbouring path edge or ride connection, to make it connect (or not if not \a add_edges) * to the centre examined tile. * @param voxel_pos Coordinate of the neighbouring voxel. * @param edge Edge to examine, and/or connected to. * @param add_edges If set, add edges (else, remove them). * @param at_bottom Whether a path connection is expected at the bottom (if \c false, it should be at the top). * @param dest_voxel [out] %Voxel containing the neighbouring path, or \c nullptr. * @param dest_inst_data [out] New instance of the voxel. Only valid if \a dest_voxel is not \c nullptr. * @param dest_status [out] Status of the neighbouring path. * @return Neighbouring voxel was (logically) connected to the centre tile. */ static bool ExamineNeighbourPathEdge(const XYZPoint16 &voxel_pos, TileEdge edge, bool add_edges, bool at_bottom, Voxel **dest_voxel, uint16 *dest_inst_data, PathStatus *dest_status) { Voxel *v; *dest_voxel = nullptr; *dest_status = PAS_UNUSED; *dest_inst_data = PATH_INVALID; v = _world.GetCreateVoxel(voxel_pos, false); if (v == nullptr) return false; uint16 fences = v->GetFences(); FenceType fence_type = GetFenceType(fences, edge); if (fence_type != FENCE_TYPE_INVALID) return false; uint16 number = v->GetInstance(); if (number == SRI_PATH) { uint16 instance_data = v->GetInstanceData(); if (!HasValidPath(instance_data)) return false; uint8 slope = GetImplodedPathSlope(instance_data); if (at_bottom) { if (slope >= PATH_FLAT_COUNT && slope != _path_up_from_edge[edge]) return false; } else { if (slope != _path_down_from_edge[edge]) return false; } PathStatus status = _sprite_manager.GetPathStatus(GetPathType(instance_data)); if (add_edges && status == PAS_QUEUE_PATH) { // Only try to connect to queue paths if they are not yet connected to 2 (or more) neighbours. if (GetQuePathEdgeConnectCount(slope) > 1) return false; } slope = SetPathEdge(slope, edge, add_edges); *dest_status = status; *dest_voxel = v; *dest_inst_data = SetImplodedPathSlope(instance_data, slope); return true; } else if (number >= SRI_FULL_RIDES) { // A ride instance. Does it have an entrance here? if ((v->GetInstanceData() & (1 << edge)) != 0) { *dest_status = PAS_QUEUE_PATH; return true; } } return false; }
void PathGenerator::ReducePathLenghtByDist(float dist) { if (GetPathType() == PATHFIND_BLANK) { TC_LOG_ERROR("maps", "PathGenerator::ReducePathLenghtByDist called before path was built"); return; } if (_pathPoints.size() < 2) // path building failure return; uint32 i = _pathPoints.size(); G3D::Vector3 nextVec = _pathPoints[--i]; while (i > 0) { G3D::Vector3 currVec = _pathPoints[--i]; G3D::Vector3 diffVec = (nextVec - currVec); float len = diffVec.length(); if (len > dist) { float step = dist / len; // same as nextVec _pathPoints[i + 1] -= diffVec * step; _sourceUnit->UpdateAllowedPositionZ(_pathPoints[i + 1].x, _pathPoints[i + 1].y, _pathPoints[i + 1].z); _pathPoints.resize(i + 2); break; } else if (i == 0) // at second point { _pathPoints[1] = _pathPoints[0]; _pathPoints.resize(2); break; } dist -= len; nextVec = currVec; // we're going backwards } }
void ConvertPathType(char *Source, char *Dest, tPathFormat DestFormat) { TRACEENTER(); tPathFormat SourceFormat; if(!Source || !Dest) { TRACEEXIT(); return; } SourceFormat = GetPathType(Source); //A shortcut if source and destination formats are the same if(SourceFormat == DestFormat) { strcpy(Dest, Source); if((DestFormat == PF_TAPPathOnly) || (DestFormat == PF_LinuxPathOnly)) { if(Dest[strlen(Dest) - 1] != '/') strcat(Dest, "/"); } TRACEEXIT(); return; } switch(SourceFormat) { case PF_FileNameOnly: { switch(DestFormat) { case PF_FileNameOnly: break; case PF_TAPPathOnly: { //Simply return the current TAP directory HDD_TAP_GetCurrentDir(Dest); if(!StringEndsWith(Dest, "/")) strcat(Dest, "/"); break; } case PF_LinuxPathOnly: { //Return the Linux path to the TAP's current directory strcpy(Dest, "/mnt/hd"); HDD_TAP_GetCurrentDir(&Dest[7]); if(!StringEndsWith(Dest, "/")) strcat(Dest, "/"); break; } case PF_FullTAPPath: { //Return the current TAP directory including the file name from Source HDD_TAP_GetCurrentDir(Dest); if(!StringEndsWith(Dest, "/")) strcat(Dest, "/"); strcat(Dest, Source); break; } case PF_FullLinuxPath: { //Return the Linux path to the TAP's current directory plus the file name passed in Source strcpy(Dest, "/mnt/hd"); HDD_TAP_GetCurrentDir(&Dest[7]); if(!StringEndsWith(Dest, "/")) strcat(Dest, "/"); strcat(Dest, Source); break; } } break; } case PF_TAPPathOnly: { switch(DestFormat) { case PF_FileNameOnly: { //If Source contains only a path, there is no file name to extract Dest[0] = '\0'; break; } case PF_TAPPathOnly: break; case PF_LinuxPathOnly: { //Check if Source contains an absolute or relative path if(Source[0] == '/') { //Insert the mount point at the beginning TAP_SPrint(Dest, "/mnt/hd%s", Source); } else { //As the path is relative, we need to get the current path to make it absolute char CurrentPath[FBLIB_DIR_SIZE]; HDD_TAP_GetCurrentDir(CurrentPath); if(!StringEndsWith(CurrentPath, "/")) strcat(CurrentPath, "/"); strcat(CurrentPath, Source); if(!StringEndsWith(CurrentPath, "/")) strcat(CurrentPath, "/"); TAP_SPrint(Dest, "/mnt/hd%s", CurrentPath); } if(!StringEndsWith(Dest, "/")) strcat(Dest, "/"); break; } case PF_FullTAPPath: { //Not possible, there is no file name in source Dest[0] = '\0'; break; } case PF_FullLinuxPath: { //Not possible, there is no file name in source Dest[0] = '\0'; break; } } break; } case PF_LinuxPathOnly: { switch(DestFormat) { case PF_FileNameOnly: { //Not possible, there is no file name in source Dest[0] = '\0'; break; } case PF_TAPPathOnly: { //Cut away the mount point if(strncmp(Source, TAPFSROOT, strlen(TAPFSROOT)) == 0) { strcpy(Dest, &Source[7]); if(!StringEndsWith(Dest, "/")) strcat(Dest, "/"); } else Dest[0] = '\0'; break; } case PF_LinuxPathOnly: break; case PF_FullTAPPath: { //Not possible, there is no file name in source Dest[0] = '\0'; break; } case PF_FullLinuxPath: { //Not possible, there is no file name in source Dest[0] = '\0'; break; } } break; } case PF_FullTAPPath: { switch(DestFormat) { case PF_FileNameOnly: { char *LastSlash; //Just copy the file name, which starts after the last / LastSlash = strrchr(Source, '/'); strcpy(Dest, LastSlash + 1); break; } case PF_TAPPathOnly: { char *LastSlash; dword i; //Copy from the beginning up to the last slash LastSlash = strrchr(Source, '/'); i = (dword)LastSlash - (dword)Source; strncpy(Dest, Source, i); Dest[i] = '\0'; if(!StringEndsWith(Dest, "/")) strcat(Dest, "/"); break; } case PF_LinuxPathOnly: { char *LastSlash; dword i; //To calculate the Linux path, we need to determine if this is a relative or absolute path if(Source[0] == '/') { //Just insert the mount point, then copy everything up to the last slash strcpy(Dest, "/mnt/hd"); LastSlash = strrchr(Source, '/'); i = (dword)LastSlash - (dword)Source; strncpy(&Dest[7], Source, i); Dest[i+7] = '\0'; } else { //As the path is relative, we need to get the current path to make it absolute char CurrentPath[FBLIB_DIR_SIZE]; HDD_TAP_GetCurrentDir(CurrentPath); if(!StringEndsWith(CurrentPath, "/")) strcat(CurrentPath, "/"); strcat(CurrentPath, Source); strcpy(Dest, "/mnt/hd"); LastSlash = strrchr(CurrentPath, '/'); i = (dword)LastSlash - (dword)CurrentPath; strncpy(&Dest[7], CurrentPath, i); Dest[i+7] = '\0'; } if(!StringEndsWith(Dest, "/")) strcat(Dest, "/"); break; } case PF_FullTAPPath: break; case PF_FullLinuxPath: { //To calculate the Linux path, we need to determine if this is a relative or absolute path if(Source[0] == '/') { //Simply insert the mount point TAP_SPrint(Dest, "/mnt/hd%s", Source); } else { //As the path is relative, we need to get the current path to make it absolute char CurrentPath[FBLIB_DIR_SIZE]; HDD_TAP_GetCurrentDir(CurrentPath); if(!StringEndsWith(CurrentPath, "/")) strcat(CurrentPath, "/"); strcat(CurrentPath, Source); TAP_SPrint(Dest, "/mnt/hd%s", CurrentPath); } break; } } break; } case PF_FullLinuxPath: { switch(DestFormat) { case PF_FileNameOnly: { char *LastSlash; //Just copy the file name, which starts after the last / LastSlash = strrchr(Source, '/'); strcpy(Dest, LastSlash + 1); break; } case PF_TAPPathOnly: { char *LastSlash; dword i; //Copy from the beginning up to the last slash, but skip the mount point if(strncmp(Source, TAPFSROOT, strlen(TAPFSROOT)) == 0) { LastSlash = strrchr(Source, '/'); i = (dword)LastSlash - (dword)&Source[7]; strncpy(Dest, &Source[7], i); Dest[i] = '\0'; if(!StringEndsWith(Dest, "/")) strcat(Dest, "/"); } else Dest[0] = '\0'; break; } case PF_LinuxPathOnly: { char *LastSlash; dword i; //Copy from the beginning up to the last slash LastSlash = strrchr(Source, '/'); i = (dword)LastSlash - (dword)Source; strncpy(Dest, Source, i); Dest[i] = '\0'; if(!StringEndsWith(Dest, "/")) strcat(Dest, "/"); break; } case PF_FullTAPPath: { //Copy everything except the mount point if(strncmp(Source, TAPFSROOT, strlen(TAPFSROOT)) == 0) strcpy(Dest, &Source[7]); else Dest[0] = '\0'; break; } case PF_FullLinuxPath: break; } break; } } TRACEEXIT(); }