// Update position void Car::updatePosition() { // Did we arrive to the next position? switch (mDirection) { case Tile::EAST: if (getCenterPosition().x >= mNextCheckpoint.x) { nextTile(); } break; case Tile::SOUTH: if (getCenterPosition().y >= mNextCheckpoint.y) { nextTile(); } break; case Tile::WEST: if (getCenterPosition().x <= mNextCheckpoint.x) { nextTile(); } break; case Tile::NORTH: if (getCenterPosition().y <= mNextCheckpoint.y) { nextTile(); } break; default: break; } // Traffic light check TrafficLight* light = mNextTile->getTrafficLight(); // Resetting greenlight (avoid stopping IN an intersection) if (mCurrentIntersection) { // Gone past intersection if (!mCurrentIntersection->isInside(getRect())) { mCurrentIntersection = NULL; mGreenlit = false; } } // Do not drive past a red light // (Drive if: no light, green light or not yet inside next tile) if (!light || light->getStatus(mDirection) || !mNextTile->isInside(getRect()) || mGreenlit) { // Set greenlight (avoid stopping IN an intersection) if (light && mNextTile->isInside(getRect()) && light->getStatus(mDirection)) { mCurrentIntersection = mNextTile; mGreenlit = true; } move(mDirection); } }
// Computes m_dist[x][y] = ground distance from (startX, startY) to (x,y) // Uses BFS, since the map is quite large and DFS may cause a stack overflow void DistanceMap::computeDistanceMap(CCBot & m_bot, const sc2::Point2D & startTile) { m_startTile = startTile; m_width = m_bot.Map().width(); m_height = m_bot.Map().height(); m_dist = std::vector<std::vector<int>>(m_width, std::vector<int>(m_height, -1)); m_sortedTilePositions.reserve(m_width * m_height); // the fringe for the BFS we will perform to calculate distances std::vector<sc2::Point2D> fringe; fringe.reserve(m_width * m_height); fringe.push_back(startTile); m_sortedTilePositions.push_back(startTile); m_dist[(int)startTile.x][(int)startTile.y] = 0; for (size_t fringeIndex=0; fringeIndex<fringe.size(); ++fringeIndex) { const sc2::Point2D & tile = fringe[fringeIndex]; // check every possible child of this tile for (size_t a=0; a<LegalActions; ++a) { sc2::Point2D nextTile(tile.x + actionX[a], tile.y + actionY[a]); // if the new tile is inside the map bounds, is walkable, and has not been visited yet, set the distance of its parent + 1 if (m_bot.Map().isWalkable(nextTile) && getDistance(nextTile) == -1) { m_dist[(int)nextTile.x][(int)nextTile.y] = m_dist[(int)tile.x][(int)tile.y] + 1; fringe.push_back(nextTile); m_sortedTilePositions.push_back(nextTile); } } } }
static void writeAlpha16( doeE env, dcPathFiller pf, u16* alpha, i32 xstride, i32 ystride, i32 pix0offset) { dcPathFillerData* p = (dcPathFillerData*)pf; dcLLFiller ll; if (!stateCheck(p, setOutputAreaDone)) { doeError_set(env, dcPRError, dcPRError_UNEX_writeAlpha); return; } if (alpha == NULL || xstride <= 0 || ystride <= 0 || pix0offset < 0) { doeError_set(env, dcPRError, dcPRError_BAD_alphadest); return; } ll = dcLLFiller_get(env); if (doeError_occurred(env)) return; if (p->fastOutput) { FastOutputPC fopc = p->fastOutputPC; dcFastPathProducer fpp = p->thisFPP; (*ll)->setParams(env, ll, p->fillmode, p->outW, p->outH); (*fopc)->setUpAlpha16( env, fopc, ll, -p->outLoX, -p->outLoY, alpha, xstride, ystride, pix0offset); (*fpp)->sendTo(env, fpp, (dcPathConsumer)fopc); } else { i32 tilew = MIN(p->outW - ((p->tileXI - 1) << dcPathFiller_tileSizeL2S), dcPathFiller_tileSize); (*ll)->setParams(env, ll, p->fillmode, tilew, p->rowH); sendTileToLLFiller(env, pf, ll); (*ll)->writeAlpha16(env, ll, alpha, xstride, ystride, pix0offset); } dcLLFiller_release(env, ll); nextTile(env,pf); }
void doCursor() { char name[MAX_VALUE_LENGTH]; int x, y; cursor.x = input.mouseX; cursor.y = input.mouseY; if (cursor.type == TILES || cursor.snapToGrid == 1) { cursor.x /= TILE_SIZE; cursor.y /= TILE_SIZE; cursor.x *= TILE_SIZE; cursor.y *= TILE_SIZE; } if (cursor.y >= SCREEN_HEIGHT - TILE_SIZE) { cursor.y = SCREEN_HEIGHT - TILE_SIZE * 2; } if (input.left == 1) { mapStartXNext(-TILE_SIZE); } else if (input.right == 1) { mapStartXNext(TILE_SIZE); } if (input.up == 1) { mapStartYNext(-TILE_SIZE); } else if (input.down == 1) { mapStartYNext(TILE_SIZE); } if (input.snap == 1) { cursor.snapToGrid = 1 - cursor.snapToGrid; input.snap = 0; } if (input.activate == 1) { cursor.entity.face = (cursor.entity.face == RIGHT ? LEFT : RIGHT); input.activate = 0; } if (input.block == 1) { if (cursor.type == TILES) { x = (getMapStartX() + cursor.x) / TILE_SIZE; y = (getMapStartY() + cursor.y) / TILE_SIZE; while (mapTileAt(x, y) == BLANK_TILE && x >= 0) { setTileAt(x, y, cursor.tileID); x--; } x = (getMapStartX() + cursor.x) / TILE_SIZE; x++; while (mapTileAt(x, y) == BLANK_TILE && x < MAX_MAP_X) { setTileAt(x, y, cursor.tileID); x++; } } } if (input.add == 1) { if (cursor.type == TILES) { setTileAt((getMapStartX() + cursor.x) / TILE_SIZE, (getMapStartY() + cursor.y) / TILE_SIZE, cursor.tileID); } else { /* Entities can only be placed in blank spaces */ if (isValidOnMap(&cursor.entity) == 1 && isSpaceEmpty(&cursor.entity) == NULL) { if (cursor.entityType == 0) { setPlayerLocation(getMapStartX() + cursor.x, getMapStartY() + cursor.y); } else { if (strcmpignorecase(cursor.entity.name, "lift/lift_target") == 0) { snprintf(name, sizeof(name), "NEW_TARGET_%03d", targetID); addTarget(getMapStartX() + cursor.x, getMapStartY() + cursor.y, name); targetID++; } else { cursor.entity.startX = getMapStartX() + cursor.x; cursor.entity.startY = getMapStartY() + cursor.y; cursor.entity.endX = getMapStartX() + cursor.x; cursor.entity.endY = getMapStartY() + cursor.y; addEntity(cursor.entity, getMapStartX() + cursor.x, getMapStartY() + cursor.y); } } } input.add = 0; } } else if (input.remove == 1) { if (cursor.type == TILES) { setTileAt((getMapStartX() + cursor.x) / TILE_SIZE, (getMapStartY() + cursor.y) / TILE_SIZE, BLANK_TILE); } else { self = isSpaceEmpty(&cursor.entity); if (self != NULL) { self->inUse = FALSE; } } } if (input.cut == 1) { if (cursor.type != TILES) { self = isSpaceEmpty(&cursor.entity); if (self != NULL) { cursor.entity = *self; self->inUse = FALSE; } } input.cut = 0; } if (input.previous == 1) { if (cursor.type == TILES) { cursor.tileID = prevTile(cursor.tileID); } else { cursor.entityType--; if (cursor.entityType < 0) { cursor.entityType = entityNamesLength - 1; } memset(&cursor.entity, 0, sizeof(Entity)); cursor.entity.draw = &drawLoopingAnimationToMap; cursor.entity.weight = 0; cursor.entity.originalWeight = 0; cursor.entity.inUse = TRUE; loadProperties(entityNames[cursor.entityType], &cursor.entity); cursor.entity.active = TRUE; cursor.entity.alpha = 255; if (cursor.entity.weight == 0) { cursor.entity.weight = 1; cursor.entity.originalWeight = 1; } } input.previous = 0; } else if (input.next == 1) { if (cursor.type == TILES) { cursor.tileID = nextTile(cursor.tileID); } else { cursor.entityType++; if (cursor.entityType >= entityNamesLength) { cursor.entityType = 0; } memset(&cursor.entity, 0, sizeof(Entity)); cursor.entity.draw = &drawLoopingAnimationToMap; cursor.entity.weight = 0; cursor.entity.originalWeight = 1; cursor.entity.inUse = TRUE; loadProperties(entityNames[cursor.entityType], &cursor.entity); cursor.entity.active = TRUE; cursor.entity.alpha = 255; if (cursor.entity.weight == 0) { cursor.entity.weight = 1; cursor.entity.originalWeight = 1; } } input.next = 0; } if (input.save == 1) { if (saveMap() == TRUE) { setStatusPanelMessage("Saved"); } else { setStatusPanelMessage("Saving Failed"); } input.save = 0; } /* if (input.load == 1) { loadMap(map.filename); printf("Loaded\n"); input.load = 0; } */ if (input.left == 1 || input.right == 1 || input.up == 1 || input.down == 1) { SDL_Delay(30); } if (input.toggle == 1) { if (cursor.type == TILES) { cursor.type = ENTITIES; } else { cursor.type = TILES; } input.toggle = 0; } centerMapOnEntity(NULL); }
// Start route void Car::startRoute() { mFinished = false; mCurrentTile = mRoute.back(); nextTile(); }