Example #1
0
/**
 * calculateTrajectory.
 * @return true when a trajectory is possible.
 */
bool Projectile::calculateTrajectory(double accuracy)
{
	Position originVoxel, targetVoxel;
	int direction;
	int dirYshift[8] = {1, 1, 8, 15, 15, 15, 8, 1 };
	int dirXshift[8] = {8, 14, 15, 15, 8, 1, 1, 1 };
	// large units : x2

	originVoxel = Position(_origin.x*16, _origin.y*16, _origin.z*24);
	originVoxel.z += -_save->getTile(_origin)->getTerrainLevel();
	BattleUnit *bu = _save->getTile(_origin)->getUnit();
	originVoxel.z += bu->isKneeled()?bu->getUnit()->getKneelHeight():bu->getUnit()->getStandHeight();
	originVoxel.z -= 3;
	if (originVoxel.z >= (_origin.z + 1)*24)
	{
		_origin.z++;
	}
	direction = bu->getDirection();
	originVoxel.x += dirXshift[direction];
	originVoxel.y += 15-dirYshift[direction];

	// determine the target voxel.
	// aim at the center of the unit, the object, the walls or the floor (in that priority)
	// if there is no LOF to the center, try elsewhere (more outward).
	// Store this target voxel.
	Tile *tile = _save->getTile(_target);
	if (tile->getUnit() != 0)
	{
		if (_origin == _target)
		{
			targetVoxel = Position(_target.x*16 + 8, _target.y*16 + 8, _target.z*24);
		}
		else
		{
			targetVoxel = Position(_target.x*16 + 8, _target.y*16 + 8, _target.z*24 + tile->getUnit()->getUnit()->getStandHeight()/2);
		}
	}
	else if (tile->getMapData(O_OBJECT) != 0)
	{
		targetVoxel = Position(_target.x*16 + 8, _target.y*16 + 8, _target.z*24 + 10);
	}
	else if (tile->getMapData(O_NORTHWALL) != 0)
	{
		targetVoxel = Position(_target.x*16 + 8, _target.y*16 + 16, _target.z*24 + 10);
	}
	else if (tile->getMapData(O_WESTWALL) != 0)
	{
		targetVoxel = Position(_target.x*16, _target.y*16 + 8, _target.z*24 + 10);
	}
	else if (tile->getMapData(O_FLOOR) != 0)
	{
		targetVoxel = Position(_target.x*16 + 8, _target.y*16 + 8, _target.z*24);
	}
	else
	{
		return false; // no line of fire
	}

	// apply some accuracy modifiers (todo: calculate this)
	// This will results in a new target voxel
	applyAccuracy(originVoxel, &targetVoxel, accuracy);

	// finally do a line calculation and store this trajectory.
	_save->getTerrainModifier()->calculateLine(originVoxel, targetVoxel, true, &_trajectory, bu);

	return true;
}
Example #2
0
/**
 * Initializes the explosion.
 * The animation and sound starts here.
 * If the animation is finished, the actual effect takes place.
 */
void ExplosionBState::init()
{
	if (_item)
	{
		_power = _item->getRules()->getPower();

		// this usually only applies to melee, but as a concession for modders i'll leave it here in case they wanna make bows or something.
		if (_item->getRules()->isStrengthApplied() && _unit)
		{
			_power += _unit->getBaseStats()->strength;
		}

		_areaOfEffect = _item->getRules()->getBattleType() != BT_MELEE &&
						_item->getRules()->getExplosionRadius() != 0 &&
						!_cosmetic;
	}
	else if (_tile)
	{
		_power = _tile->getExplosive();
		_areaOfEffect = true;
	}
	else if (_unit && (_unit->getSpecialAbility() == SPECAB_EXPLODEONDEATH || _unit->getSpecialAbility() == SPECAB_BURN_AND_EXPLODE))
	{
		_power = _parent->getMod()->getItem(_unit->getArmor()->getCorpseGeoscape())->getPower();
		_areaOfEffect = true;
	}
	else
	{
		_power = 120;
		_areaOfEffect = true;
	}

	Tile *t = _parent->getSave()->getTile(Position(_center.x/16, _center.y/16, _center.z/24));
	if (_areaOfEffect)
	{
		if (_power)
		{
			int frame = Mod::EXPLOSION_OFFSET;
			if (_item)
			{
				frame = _item->getRules()->getHitAnimation();
			}
			if (_parent->getDepth() > 0)
			{
				frame -= Explosion::EXPLODE_FRAMES;
			}
			int frameDelay = 0;
			int counter = std::max(1, (_power/5) / 5);
			_parent->getMap()->setBlastFlash(true);
			for (int i = 0; i < _power/5; i++)
			{
				int X = RNG::generate(-_power/2,_power/2);
				int Y = RNG::generate(-_power/2,_power/2);
				Position p = _center;
				p.x += X; p.y += Y;
				Explosion *explosion = new Explosion(p, frame, frameDelay, true);
				// add the explosion on the map
				_parent->getMap()->getExplosions()->push_back(explosion);
				if (i > 0 && i % counter == 0)
				{
					frameDelay++;
				}
			}
			_parent->setStateInterval(BattlescapeState::DEFAULT_ANIM_SPEED/2);
			// explosion sound
			if (_power <= 80)
				_parent->getMod()->getSoundByDepth(_parent->getDepth(), Mod::SMALL_EXPLOSION)->play();
			else
				_parent->getMod()->getSoundByDepth(_parent->getDepth(), Mod::LARGE_EXPLOSION)->play();

			_parent->getMap()->getCamera()->centerOnPosition(t->getPosition(), false);
		}
		else
		{
			_parent->popState();
		}
	}
	else
	// create a bullet hit
	{
		_parent->setStateInterval(std::max(1, ((BattlescapeState::DEFAULT_ANIM_SPEED/2) - (10 * _item->getRules()->getExplosionSpeed()))));
		int anim = _item->getRules()->getHitAnimation();
		int sound = _item->getRules()->getHitSound();
		if (_cosmetic) // Play melee animation on hitting and psiing
		{
			anim = _item->getRules()->getMeleeAnimation();
		}

		if (anim != -1)
		{
			Explosion *explosion = new Explosion(_center, anim, 0, false, _cosmetic);
			_parent->getMap()->getExplosions()->push_back(explosion);
		}

		_parent->getMap()->getCamera()->setViewLevel(_center.z / 24);

		BattleUnit *target = t->getUnit();
		if (_cosmetic && _parent->getSave()->getSide() == FACTION_HOSTILE && target && target->getFaction() == FACTION_PLAYER)
		{
			_parent->getMap()->getCamera()->centerOnPosition(t->getPosition(), false);
		}
		if (sound != -1 && !_cosmetic)
		{
			// bullet hit sound
			_parent->getMod()->getSoundByDepth(_parent->getDepth(), sound)->play(-1, _parent->getMap()->getSoundAngle(_center / Position(16,16,24)));
		}
	}
}
Example #3
0
/**
 * Check if a Tile at position (row,col) has a widget.
 * @param row :: The row to check.
 * @param col :: The column to check.
 */
bool TiledWindow::hasWidget(int row, int col) const {
  Tile *tile = getTile(row, col);
  return tile->widget() != NULL;
}
Example #4
0
QVector<QVector<Tile>> Maze::setTileDistances(QVector<QVector<Tile>> maze) {

    // TODO: MACK - dedup some of this with hasNoInaccessibleLocations

    // The maze is guarenteed to be nonempty and rectangular
    int width = maze.size();
    int height = maze.at(0).size();

    // Helper lambda for retrieving and adjacent tile if one exists, nullptr if not
    // TODO: MACK - this should be in maze utilities too
    auto getNeighbor = [&maze, &width, &height](int x, int y, Direction direction) {
        switch (direction) {
            case Direction::NORTH:
                return (y < height - 1 ? &maze[x][y + 1] : nullptr);
            case Direction::EAST:
                return (x < width - 1 ? &maze[x + 1][y] : nullptr);
            case Direction::SOUTH:
                return (0 < y ? &maze[x][y - 1] : nullptr);
            case Direction::WEST:
                return (0 < x ? &maze[x - 1][y] : nullptr);
        }
    };

    // Determine all of the center tiles
    // TODO: MACK - use the maze checker function for this
    QVector<Tile*> centerTiles;
            centerTiles.push_back(&maze[(width - 1) / 2][(height - 1) / 2]);
    if (width % 2 == 0) {
            centerTiles.push_back(&maze[ width      / 2][(height - 1) / 2]);
        if (height % 2 == 0) {
            centerTiles.push_back(&maze[(width - 1) / 2][ height      / 2]);
            centerTiles.push_back(&maze[ width      / 2][ height      / 2]);
        }
    }
    else if (height % 2 == 0) {
            centerTiles.push_back(&maze[(width - 1) / 2][ height      / 2]);
    }

    // The queue for the BFS
    QQueue<Tile*> discovered;

    // Set the distances of the center tiles and push them to the queue
    for (Tile* tile : centerTiles) {
        tile->setDistance(0); 
        discovered.enqueue(tile);
    }

    // Now do a BFS
    while (!discovered.empty()){
        Tile* tile = discovered.dequeue();
        for (Direction direction : DIRECTIONS) {
            if (!tile->isWall(direction)) {
                Tile* neighbor = getNeighbor(tile->getX(), tile->getY(), direction);
                if (neighbor != nullptr && neighbor->getDistance() == -1) {
                    neighbor->setDistance(tile->getDistance() + 1);
                    discovered.enqueue(neighbor);
                }
            }
        }
    }

    return maze;
}
Example #5
0
bool WeaponDistance::useWeapon(Player* player, Item* item, Creature* target) const
{
	int32_t damageModifier = playerWeaponCheck(player, target);

	if (damageModifier == 0) {
		return false;
	}

	int32_t chance;

	if (hitChance == 0) {
		//hit chance is based on distance to target and distance skill
		uint32_t skill = player->getSkill(SKILL_DIST, SKILL_LEVEL);
		const Position& playerPos = player->getPosition();
		const Position& targetPos = target->getPosition();
		uint32_t distance = std::max<uint32_t>(Position::getDistanceX(playerPos, targetPos), Position::getDistanceY(playerPos, targetPos));

		if (maxHitChance == 75) {
			//chance for one-handed weapons
			switch (distance) {
				case 1:
					chance = std::min<uint32_t>(skill, 74) + 1;
					break;
				case 2:
					chance = (uint32_t)((float)2.4 * std::min<uint32_t>(skill, 28)) + 8;
					break;
				case 3:
					chance = (uint32_t)((float)1.55 * std::min<uint32_t>(skill, 45)) + 6;
					break;
				case 4:
					chance = (uint32_t)((float)1.25 * std::min<uint32_t>(skill, 58)) + 3;
					break;
				case 5:
					chance = (uint32_t)((float)std::min<uint32_t>(skill, 74)) + 1;
					break;
				case 6:
					chance = (uint32_t)((float)0.8 * std::min<uint32_t>(skill, 90)) + 3;
					break;
				case 7:
					chance = (uint32_t)((float)0.7 * std::min<uint32_t>(skill, 104)) + 2;
					break;
				default:
					chance = hitChance;
					break;
			}
		} else if (maxHitChance == 90) {
			//formula for two-handed weapons
			switch (distance) {
				case 1:
					chance = (uint32_t)((float)1.2 * std::min<uint32_t>(skill, 74)) + 1;
					break;
				case 2:
					chance = (uint32_t)((float)3.2 * std::min<uint32_t>(skill, 28));
					break;
				case 3:
					chance = (uint32_t)((float)2.0 * std::min<uint32_t>(skill, 45));
					break;
				case 4:
					chance = (uint32_t)((float)1.55 * std::min<uint32_t>(skill, 58));
					break;
				case 5:
					chance = (uint32_t)((float)1.2 * std::min<uint32_t>(skill, 74)) + 1;
					break;
				case 6:
					chance = (uint32_t)((float)1.0 * std::min<uint32_t>(skill, 90));
					break;
				case 7:
					chance = (uint32_t)((float)1.0 * std::min<uint32_t>(skill, 90));
					break;
				default:
					chance = hitChance;
					break;
			}
		} else if (maxHitChance == 100) {
			switch (distance) {
				case 1:
					chance = (uint32_t)((float)1.35 * std::min<uint32_t>(skill, 73)) + 1;
					break;
				case 2:
					chance = (uint32_t)((float)3.2 * std::min<uint32_t>(skill, 30)) + 4;
					break;
				case 3:
					chance = (uint32_t)((float)2.05 * std::min<uint32_t>(skill, 48)) + 2;
					break;
				case 4:
					chance = (uint32_t)((float)1.5 * std::min<uint32_t>(skill, 65)) + 2;
					break;
				case 5:
					chance = (uint32_t)((float)1.35 * std::min<uint32_t>(skill, 73)) + 1;
					break;
				case 6:
					chance = (uint32_t)((float)1.2 * std::min<uint32_t>(skill, 87)) - 4;
					break;
				case 7:
					chance = (uint32_t)((float)1.1 * std::min<uint32_t>(skill, 90)) + 1;
					break;
				default:
					chance = hitChance;
					break;
			}
		} else {
			chance = maxHitChance;
		}
	} else {
		chance = hitChance;
	}

	if (item->getWeaponType() == WEAPON_AMMO) {
		Item* bow = player->getWeapon(true);
		if (bow && bow->getHitChance() != 0) {
			chance += bow->getHitChance();
		}
	}

	if (chance >= random_range(1, 100)) {
		if (elementDamage != 0) {
			int32_t damage = getElementDamage(player, target, item);
			CombatParams eParams;
			eParams.combatType = elementType;
			eParams.isAggressive = true;
			eParams.useCharges = true;
			Combat::doCombatHealth(player, target, damage, damage, eParams);
		}

		Weapon::internalUseWeapon(player, item, target, damageModifier);
	} else {
		//miss target
		Tile* destTile = target->getTile();

		if (!Position::areInRange<1, 1, 0>(player->getPosition(), target->getPosition())) {
			std::vector<std::pair<int32_t, int32_t>> destList;
			destList.push_back(std::make_pair(-1, -1));
			destList.push_back(std::make_pair(-1, 0));
			destList.push_back(std::make_pair(-1, 1));
			destList.push_back(std::make_pair(0, -1));
			destList.push_back(std::make_pair(0, 0));
			destList.push_back(std::make_pair(0, 1));
			destList.push_back(std::make_pair(1, -1));
			destList.push_back(std::make_pair(1, 0));
			destList.push_back(std::make_pair(1, 1));

			std::random_shuffle(destList.begin(), destList.end());

			Position destPos = target->getPosition();

			for (const auto& dir : destList) {
				Tile* tmpTile = g_game.getTile(destPos.x + dir.first, destPos.y + dir.second, destPos.z);

				// Blocking tiles or tiles without ground ain't valid targets for spears
				if (tmpTile && !tmpTile->hasProperty(IMMOVABLEBLOCKSOLID) && tmpTile->ground != NULL) {
					destTile = tmpTile;
					break;
				}
			}
		}

		Weapon::internalUseWeapon(player, item, destTile);
	}

	return true;
}
Example #6
0
void Player::update(double aDelta)
{
    std::string ammoCount = "";
    std::stringstream ammoAmount;
    ammoAmount << m_Ammo;
    ammoAmount >> ammoCount;
    m_Font->setText(ammoCount.c_str());


    //update the projectile
    for(int i = 0; i < m_Projectiles.size(); i++)
    {
        if(m_Projectiles.at(i)->getIsActive() == true)
        {
            m_Projectiles.at(i)->update(aDelta);

        }
    }
    //Tower1
    for(int i = 0; i < m_Level->getNumberOfTiles(); i++)
    {
        if(m_Level->getTileTypeForIndex(i) == TileTypeTower)
        {
            TowerTile* temp = (TowerTile*) m_Level->getTileForIndex(i);
            for(int location = 0; location < temp->getProjecticle().size(); location++)
            {
                if (temp->getProjecticle().at(location)->getIsActive())
                    temp->getProjecticle().at(location)->update(aDelta);
            }
        }
    }
    //remove aby inactive projectiles from the projectiles vectors
    int index = 0;
    while(index != m_Projectiles.size())
    {
        if(m_Projectiles.at(index)->getIsActive() == false)
        {

            //delete the projectile and remove it from the vector
            delete m_Projectiles.at(index);
            m_Projectiles.erase(m_Projectiles.begin() + index);
        }
        else
        {
            index++;
        }
    }

    if (m_PathFinder->isSearchingPath() == true)
    {
        m_PathFinder->update(aDelta);
    }

    if (isAnimating() && m_AnimationPathNodeIndex > -1)
    {
        PathNode* pathNode = m_PathFinder->getPathNodeAtIndex(m_AnimationPathNodeIndex);
        Tile* tile = pathNode != NULL ? pathNode->getTile() : NULL;

        if(tile)
        {
            float centerX = tile->getX() + (tile->getWidth() - getWidth()) / 2.0f;
            float centerY = tile->getY() + (tile->getHeight() - getHeight()) / 2.0f;
            Tile * playerTile = m_Level->getTileForPosition(getX(), getY());
            float speed = playerTile->getTileSpeed();

            float playerX = animate(getX(), centerX, aDelta, speed);
            float playerY = animate(getY(), centerY, aDelta, speed);
            setPosition(playerX, playerY);

            //change G as float for slower and faster tiles

            if (playerX == centerX && playerY == centerY)
            {
                m_AnimationPathNodeIndex++;
                m_CurrentTile->setIsPath(false);
                setCurrentTile(tile);
                if (m_AnimationPathNodeIndex >= m_PathFinder->getPathSize())
                {
                    stopAnimating();
                    m_CurrentTile->setIsPath(false);
                }

                if(m_AbortAnimation)
                {
                    m_AbortAnimation = false;

                    findPath();
                }
            }
            else
            {
                if(m_AbortAnimation == true)
                {
                    m_AbortAnimation =false;
                    findPath();
                }
            }
        }

    }
}
Example #7
0
bool MainView::mouseReleased(u16 x, u16 y, MouseButton b)
{
  //gvm->push(new Blink(1000, Gfx::color(0, 0, 255), {0,0,320,200}, 220));
  /*gvm->cityView()->setCity(g->getCities().front());*/
  //gvm->switchView(VIEW_ITEM_CRAFT);
  
  Position pos = Viewport::hoveredPosition(g->world, player, x, y);
  Tile* t = g->world->get(pos);
  
  if (t)
  {
    pos = t->position;
    City* c = t->city;
    Army* a = t->army;
    
    if (b == BUTTON_RIGHT)
    {
      if (a)
      {
        bool couldBeSelected = (!c || (c && !a->isPatrolling()));
        
        if (couldBeSelected && a->getOwner() == player)
        {
          switchToUnitSelection(a);
          return true;
        }
        else if (a->getOwner() != player)
        {
          gvm->armyView()->open(a);
          return true;
        }
      }
      
      
      if (c)
      {
        if (!c->isOutpost())
        {
          gvm->cityView()->setCity(c);
          gvm->switchView(VIEW_CITY);
        }
        else
        {
          gvm->outpostView()->setCity(c);
          gvm->switchOverview(VIEW_OUTPOST);
        }
        
        player->resetArmy();
        switchToNormalState();
      }
      else
      {
        s16 upperBoundY = pos.y - Viewport::viewportH/2;
        s16 lowerBoundY = pos.y + (Viewport::viewportH  - Viewport::viewportH/2);
        s16 ty = pos.y;
        
        if (upperBoundY < 0)
          ty = Viewport::viewportH/2;
        else if (lowerBoundY >= g->world->h)
          ty = g->world->h - (Viewport::viewportH  - Viewport::viewportH/2);
        
        player->setViewport(pos.x, ty);
      }
    }
    else if (b == BUTTON_LEFT)
    {
      if (substate == SPELL_CAST && player->getSpellTarget() == Target::MAP_TILE)
        g->castSpell(t, player);
      else if (substate == SPELL_CAST && player->getSpellTarget() == Target::FRIENDLY_UNIT)
      {
        if (t->army && t->army->getOwner() == player)
        {
          // TODO: check if unit is just 1 directly cast?
          gvm->armyView()->setArmy(t->army);
          gvm->armyView()->setAcceptSpellTarget();
          gvm->switchOverview(VIEW_ARMY);
        }
      }
      else if (substate == SPELL_CAST && player->getSpellTarget() == Target::FRIENDLY_CITY)
      {
        if (t->city && t->city->getOwner() == player)
          g->castSpell(t->city, player);
      }
      else
      {
        const unit_list& selectedUnits = player->getSelectedUnits();;
        const auto& route = player->getRoute();
        const bool hasSelectedUnits = !selectedUnits.empty();
        
        if (hasSelectedUnits && !route)
          player->computeRoute(t->position);
        else if (hasSelectedUnits && !route->completed() && route->dx() == t->x() && route->dy() == t->y() && player->selectedAvailMoves() > 0)
        {
          player->consumeRoute();
          //player->push(new anims::UnitMovement(player, army, army->getRoute()->pendingPositions()));

          updateBuildButton();
        }
        else if (hasSelectedUnits)
          player->computeRoute(t->position);
        
        /*if (route != null && !route.completed())
         System.out.println(cx+" "+cy+"  "+route.dx()+" "+route.dy());*/
      }
    }
    
  }
  else
  {
    Army* army = player->getSelectedArmy();
    if (army)
    {
      for (int j = 0; j < army->size(); ++j)
      {
        int xx = (246+23*(j%3)), yy = (78+29*(j/3));
        if (x >= xx+2 && x <= xx+20+2 && y >= yy+2 && y <= yy+18+2)
        {
          // select/deselect unit in army
          if (b == BUTTON_LEFT)
          {
            Unit* unit = army->get(j);
            
            if (army->size() > 2 && player->isSelectedUnit(unit) && std::all_of(army->begin(), army->end(), [this](Unit* u) { return player->isSelectedUnit(u); }))
            {
              for (Unit* aunit : *army)
                if (aunit != unit)
                  player->deselectUnit(aunit);
            }
            else
            {
              if (player->isSelectedUnit(unit))
                player->deselectUnit(unit);
              else
                player->selectUnit(unit);
            }

            
            updateBuildButton();
            
            army->clearRoute();
          }
          // open detail view on unit
          else if (b == BUTTON_RIGHT)
          {
            gvm->unitDetailView()->setUnit(army->get(j));
            gvm->switchOverview(VIEW_UNIT);
          }
        }
      }
    }
  }
  
  return true;
}
Example #8
0
bool SceneMgr::save(xs::DataChunk* pDataChunk,bool writeOccupants)
{
	int nGridWidth = GRID_WIDTH;
	int nGridHeight = GRID_HEIGHT;

	if(!isValid())
	{
		return false;
	}

	int nGridRow = Ceil(m_nMapHeight, nGridHeight);
	int nGridCol = Ceil(m_nMapWidth, nGridWidth);

	uint *pOffsetsData = 0;
	xs::Stream *pDataStream = 0;

    //  地图版本信息;
    pDataChunk->beginChunk('MVER',&pDataStream);
    m_nMapVersion = SUPPORT_EFFECT_SCALE_AND_ANGLE_ADJUST_MAP_VERSION;
    pDataStream->write(&m_nMapVersion, sizeof(m_nMapVersion));
    pDataChunk->endChunk();

	pDataChunk->beginChunk('MINF',&pDataStream);
	pDataStream->write(&m_nMapWidth,sizeof(m_nMapWidth));
	pDataStream->write(&m_nMapHeight,sizeof(m_nMapHeight));
	pDataChunk->endChunk();

	xs::DataChunk::stChunk *pIdxChunk = pDataChunk->beginChunk('MIDX',&pDataStream);
	for(int row = 0;row < nGridRow;row++)
	for(int col = 0;col < nGridCol;col++)
	{
		uint offset = 0;
		pDataStream->write(&offset,sizeof(offset));
	}
	pDataChunk->endChunk();
	pOffsetsData = (uint*)pIdxChunk->m_pData;

	m_bWriteOccupants = writeOccupants;
	int nTileRow = nGridHeight / 32;
	int nTileCol = nGridWidth / (64 / 2);
	xs::Point ptTileLeftTop;
	xs::Point ptLeftTop;
	for(int row = 0;row < nGridRow;row++)
	for(int col = 0;col < nGridCol;col++)
	{
		pDataChunk->beginChunk('MDAT',&pDataStream);
			pOffsetsData[row * nGridCol + col] = pDataChunk->getOffset();

			ptLeftTop.x = col * nGridWidth;
			ptLeftTop.y = row * nGridHeight;

			m_SceneCo.pixel2Tile(ptLeftTop, ptTileLeftTop);
			_SaveBlock(pDataStream,ptTileLeftTop,nTileRow,nTileCol);

		pDataChunk->endChunk();
	}
	m_bWriteOccupants = false;

	m_pGround->save(pDataChunk);

	SceneBlock	mb;
	int nTileWidth = m_SceneCo.getMatrixWidth();
	int nTileHeight = m_SceneCo.getMatrixHeight();

	mb.SetMapSize(nTileWidth, nTileHeight);

	for (int row = 0; row < nTileHeight; ++row)
	{
		for (int col = 0; col < nTileWidth; ++col)
		{
			xs::Point ptTile (col, row);
			Tile *pTile = &getTile(ptTile);
			if (!pTile->isValid())
			{
				mb.SetBlock(col, row, true);
			}
			else
			{
				mb.SetBlock(col, row, pTile->isBlock() ? true: false);
			}

		}
	}			

	pDataChunk->beginChunk('MWPT',&pDataStream);
	mb.Save(pDataStream);
	pDataChunk->endChunk();

	return true;
}
Example #9
0
/**
 * Get's the TU cost to move from 1 tile to the other(ONE STEP ONLY). But also updates the endPosition, because it is possible
 * the unit goes upstairs or falls down while walking.
 * @param startPosition
 * @param direction
 * @param endPosition pointer
 * @param unit
 * @return TU cost - 255 if movement impossible
 */
int Pathfinding::getTUCost(const Position &startPosition, int direction, Position *endPosition, BattleUnit *unit)
{
	_unit = unit;
	directionToVector(direction, endPosition);
	*endPosition += startPosition;
	bool fellDown = false;
	bool triedStairs = false;
	int size = _unit->getUnit()->getArmor()->getSize() - 1;
	int cost = 0;


	for (int x = size; x >= 0; x--)
	{
		for (int y = size; y >= 0; y--)
		{

			Tile *startTile = _save->getTile(startPosition + Position(x,y,0));
			Tile *destinationTile = _save->getTile(*endPosition + Position(x,y,0));

			cost = 0;
			// this means the destination is probably outside the map
			if (!destinationTile)
				return 255;

			// check if the destination tile can be walked over
			if (isBlocked(destinationTile, MapData::O_FLOOR) || isBlocked(destinationTile, MapData::O_OBJECT))
				return 255;


			if (direction < DIR_UP)
			{
				// check if we can go this way
				if (isBlocked(startTile, destinationTile, direction))
					return 255;
				if (startTile->getTerrainLevel() - destinationTile->getTerrainLevel() > 8 && x==0 && y==0)
					return 255;

			}
			else
			{
				// check if we can go up or down through gravlift or fly
				if (validateUpDown(unit, startPosition, direction))
				{
					cost += 4; // vertical movement
				}
				else
				{
					return 255;
				}
			}


			// if we are on a stairs try to go up a level
			if (startTile->getTerrainLevel() < -12 && x==0 && y==0)
			{
				endPosition->z++;
				destinationTile = _save->getTile(*endPosition);
				triedStairs = true;
			}

			// this means the destination is probably outside the map
			if (!destinationTile)
				return 255;

			// check if we have floor, else fall down
			while (canFallDown(destinationTile) && (_movementType != MT_FLY || triedStairs) && x==0 && y==0)
			{
				endPosition->z--;
				destinationTile = _save->getTile(*endPosition);
				fellDown = true;
			}

			// if we don't want to fall down and there is no floor, it ends here
			if (!fellDown && destinationTile->hasNoFloor() && x==0 && y==0)
			{
				if (_movementType != MT_FLY)
					return 255;
				else
					cost = 4;
			}

			// check if the destination tile can be walked over
			if ((isBlocked(destinationTile, MapData::O_FLOOR) || isBlocked(destinationTile, MapData::O_OBJECT)) && !fellDown)
			{
				return 255;
			}

			// calculate the cost by adding floor walk cost and object walk cost
			cost += destinationTile->getTUCost(MapData::O_FLOOR, _movementType);
			if (!fellDown)
			{
				cost += destinationTile->getTUCost(MapData::O_OBJECT, _movementType);
			}

			// diagonal walking (uneven directions) costs 50% more tu's
			if (direction & 1)
			{
				cost = (int)((double)cost * 1.5);
			}

		}
	}

	// for bigger sized units, check the path between part 1,1 and part 0,0 at end position
	if (size)
	{
			Tile *startTile = _save->getTile(*endPosition + Position(1,1,0));
			Tile *destinationTile = _save->getTile(*endPosition);
			int tmpDirection = 7;
			if (isBlocked(startTile, destinationTile, tmpDirection))
				return 255;
	}

	return cost;
}
Example #10
0
int main()
{
	int scale = 3;
	int counter = 0;
	int counter2 = 0;
	int currentDirection = 0;
	int ballIndex = 0;
	int score = 0;
	int outOfBoxCounter = 0;
	const int maxBallCount = 245;
	bool wait = true;
	int positionGhost = 280;
	bool pinkOutBox = false;
	Clock boxClock;
	Clock introClock;
	Clock afraidClock;

	enum Status
	{
		Stopped,
		Paused,
		Playing
	};
	sf::RenderWindow window(sf::VideoMode(224 * scale, 288 *scale), "Pacman");
	window.setFramerateLimit(30);
				
				
	//***************************************************
	sf::Texture whiteGhost;

	if (!whiteGhost.loadFromFile("Images/whiteGhost.png"))
	{
		cout << "Error\n";
	}

	//pinky:
	std::vector<Ghost>::iterator ghostIter;
	std::vector<Ghost> ghostArray;

	Ghost pink;
	sf::IntRect rectPinkSprite(0, 0, 24, 24);
	sf::Texture pinkText;

	if (!pinkText.loadFromFile("Images/redGhost.png"))
	{
		std::cout << "Error\n";
	}
	pink.sprite.setTexture(pinkText);
	pink.sprite2.setTexture(whiteGhost);
	pink.sprite.setTextureRect(rectPinkSprite);
	pink.sprite2.setTextureRect(rectPinkSprite);
	pink.setPosition(positionGhost, 410);

	ghostArray.push_back(pink);


	Ghost inky;
	sf::IntRect rectInkySprite(0, 0, 24, 24);
	sf::Texture inkyText;
	inky.setPosition(positionGhost + 30, 410);

	if (!inkyText.loadFromFile("Images/blueGhost2.png"))
	{
		std::cout << "Error\n";
	}

	inky.sprite.setTexture(inkyText);
	inky.sprite2.setTexture(whiteGhost);
	inky.sprite2.setTextureRect(rectInkySprite);
	inky.sprite.setTextureRect(rectInkySprite);
	ghostArray.push_back(inky);


	Ghost blinky;
	sf::IntRect rectBlinkySprite(0, 0, 24, 24);
	sf::Texture blinkyText;
	blinky.setPosition(positionGhost + 60, 410);

	if (!blinkyText.loadFromFile("Images/pinkGhost.png"))
	{
		std::cout << "Error\n";
	}

	blinky.sprite.setTexture(blinkyText);
	blinky.sprite2.setTexture(whiteGhost);
	blinky.sprite2.setTextureRect(rectBlinkySprite);
	blinky.sprite.setTextureRect(rectBlinkySprite);
	ghostArray.push_back(blinky);


	Ghost clyde;
	sf::IntRect rectClydeSprite(0, 0, 24, 24);
	sf::Texture clydeText;
	clyde.setPosition(positionGhost + 90, 410);

	if (!clydeText.loadFromFile("Images/orangeGhost.png"))
	{
		std::cout << "Error\n";
	}

	clyde.sprite.setTexture(clydeText);
	clyde.sprite2.setTexture(whiteGhost);
	clyde.sprite2.setTextureRect(rectClydeSprite);
	clyde.sprite.setTextureRect(rectClydeSprite);
	ghostArray.push_back(clyde);




	//****************************************************

	//***************************************************
	//Loading in Map to position the walls
	std::ifstream fin;
	fin.open("level.txt");
	int val;
	if (fin.fail())
	{
		cout << "Error couldn't load file" << endl;
	}
	//***************************************************
	//balls:
	
	Ball ball;
	std::vector<Ball>::iterator ballIter;
	std::vector<Ball> ballArray;


	sf::IntRect rectBallSprite(0, 0, 24, 24);
	sf::Texture ballText;

	sf::Texture largePalletText;

	if (!ballText.loadFromFile("Images/pellets.png"))
	{
		std::cout << "Error\n";
	}
	if (!largePalletText.loadFromFile("Images/largePellet.png"))
	{
		std::cout << "Error\n";
	}

	
	
	//***************************************************
	// Setting up the tile that represent the walls
	//Positioning the walls in the map
	std::vector<Tile>::const_iterator tileIter;
	std::vector<Tile> tileArray;

	Tile tile;

	sf::Vector2i Grid(28 * scale, 36 * scale);

	for (int y = 0; y < 36; y++)
	{
		for (int x = 0; x < 28; x++)
		{
			fin >> val;
			cout << val;
			if (val == 1)
			{
				tile.update(x, y);
				tileArray.push_back(tile);
			}
			//setting coordinates for 250 ball objects in array
			
			if (((y >= 4 && y < 12) || (y >= 12 && (x == 6 || x == 21)) || (y >= 23 && y < 34))
				&& (val == 0) && (ballIndex < maxBallCount))
			{
				ball.setXYPosition(x * 24 + 3, y * 24 + 3);
				ball.sprite.setTexture(ballText);
				ball.sprite.setTextureRect(rectBallSprite);
				ball.setLargePellet(false);
				ballArray.push_back(ball);
				ballIndex++;
			}
			else if (val == 3)
			{
				ball.setXYPosition(x * 24 + 3, y * 24 + 3);
				ball.sprite.setTexture(largePalletText);
				ball.sprite.setTextureRect(rectBallSprite);
				ball.setLargePellet(true);
				ballArray.push_back(ball);
				ballIndex++;

			}
			
		}
	}
	//Setting up the walls for when pacman goes through the tunnel
	tile.update(-1, 16);
	tileArray.push_back(tile);
	tile.update(28, 16);
	tileArray.push_back(tile);

	tile.update(-1, 18);
	tileArray.push_back(tile);
	tile.update(28, 18);
	tileArray.push_back(tile);

	fin.close();
	//****************************************************
	//Background Setup:
	sf::Texture background;

	if (!background.loadFromFile("Images/pacmanMap.png"))
	{
		std::cout << "Error\n";
	}
	sf::Sprite map(background);
	map.scale(scale, scale);

	//******************************************************
	//Loading up the waka waka sound
	sf::SoundBuffer playsiren;
	if (!playsiren.loadFromFile("Sound/Pacman_Siren.wav"))
	{
		std::cout << "Couldn't load sound file.\n";
	}
	Sound siren;
	siren.setBuffer(playsiren);

	//******************************************************
	//Loading up the starting music
	sf::SoundBuffer buffer;
	if (!buffer.loadFromFile("Sound/PacmanIntro.wav"))
	{
		std::cout << "Couldn't load sound file.\n";
	}
	Sound introMusic;
	introMusic.setBuffer(buffer);
	//*******************************************************
	//Loading up the waka waka sound
	sf::SoundBuffer wakaWaka;
	if (!wakaWaka.loadFromFile("Sound/Pacman_Waka_WakaV2.wav"))
	{
		std::cout << "Couldn't load sound file.\n";
	}
	Sound waka;
	waka.setBuffer(wakaWaka);

	//********************************************************
	//Player setup and Loading up the pacman image
	//Setting up the demensions of the sprite
	sf::IntRect rectSourceSprite(0, 0, 24, 24);

	Player player;
	sf::Texture pacText;
	if ( !pacText.loadFromFile( "Images/pacmanDirections.png" ) )
	{
		std::cout << "Error\n";
	}

	player.sprite.setTexture(pacText);
	player.sprite.setTextureRect(rectSourceSprite);
	//********************************************************
	//Lives
	sf::IntRect rectLiveSprite(24, 0, 24, 24);
	sf::Sprite live1;


	live1.setTexture(pacText);
	live1.setTextureRect(rectLiveSprite);
	live1.setOrigin(-600, -45);

	sf::Sprite live2;
	live2.setTexture(pacText);
	live2.setTextureRect(rectLiveSprite);
	live2.setOrigin(-624, -45);
	//********************************************************
	sf::IntRect recCherrieSprite(0, 0, 24, 24);
	sf::Texture cherrieText;
	if (!cherrieText.loadFromFile("Images/Cherrie2.png"))
	{
		std::cout << "Error\n";
	}
	Character cherrie;
	cherrie.sprite.setTexture(cherrieText);
	cherrie.sprite.setTextureRect(recCherrieSprite);
	cherrie.sprite.setOrigin(-100, -90);

	//********************************************************
	//Set Tiles to Grid 
	sf::Texture setGridTexture;
	sf::Sprite setGridSprite;
	setGridSprite.setTexture(setGridTexture);
	setGridSprite.setColor(sf::Color::Black);

	//*******************************************************
	//Creating a Grid
	//Creating a Texture and a sprite
	sf::RectangleShape tempGridSpriteOutline;
	tempGridSpriteOutline.setOutlineColor(sf::Color::White);
	tempGridSpriteOutline.setOutlineThickness(0.5);
	tempGridSpriteOutline.setFillColor(sf::Color::Transparent);
	tempGridSpriteOutline.setSize(sf::Vector2f(8 * scale, 8 * scale));

	sf::Font font;
	if (!font.loadFromFile("pacfont.ttf"))
	{
		cout << "fail" << endl;


	}
	sf::Font font2;
	if (!font2.loadFromFile("consola.ttf"))
	{
		cout << "fail" << endl;


	}
	sf::Text text;
	text.setFont(font);
	text.setString("score");
	text.setCharacterSize(43);
	text.setColor(sf::Color::White);
	text.setOrigin(-40, 0);
	
	Menu menu(window.getSize().x, window.getSize().y);
	Gameover gameover(window.getSize().x, window.getSize().y);

	while (window.isOpen())
	{
		sf::Event event;
		while (window.pollEvent(event) || menu.getIsMenuOn())
		{
			if (event.type == sf::Event::Closed)
				window.close();
			//********************************************************************
			//Creating the menu 
			if (menu.getIsMenuOn())
			{
				window.clear();
				menu.draw(window);
				window.display();
				switch (event.type)
				{
					case sf::Event::KeyReleased:
						switch (event.key.code)
						{
						case sf::Keyboard::Up:
							menu.moveUp();
							break;
						case sf::Keyboard::Down:
							menu.moveDown();
							break;
						case sf::Keyboard::Return:
							switch (menu.getPressedItem())
							{
							case 0:
								wait = true;
								introMusic.play();
								introClock.restart();
								menu.setIsMenuOn(false);
								break;
							case 1:
								window.close();
								break;
							}
						}

				}

			}// end of menu if statement
		} // of event for loop
		//***********************************************************************

		//Display the gameover screen once the player runs out of lives
		if (player.getLives() <= 1)
		{
			sf::RenderWindow window2(sf::VideoMode(224 * scale, 288 * scale), "Game Over");
			while (window2.isOpen())
			{
				window.close();

				while (window2.pollEvent(event))
				{
					if (event.type == sf::Event::Closed)
						window2.close();
					//********************************************************************
					//Creating the menu 

					//window2.clear();
					gameover.draw(window2);
					window2.display();



				}
			}
		}


		window.clear();

		//drawing background
		window.draw(map);
		// this font is for the number, since the other font i downloaded didnt have numbers in it
		sf::Text mytext;
		mytext.setFont(font2);//set the object to the new text
		std::stringstream ss;//converts a interger into a string
		ss << score;
		mytext.setString(ss.str().c_str());
		mytext.setColor(sf::Color::White);
		mytext.setCharacterSize(55);
		mytext.setOrigin(-80, 0);
		window.draw(mytext);
		//window.draw(cherrie.sprite);


		//Draw Grid
		for (int i = 0; i < Grid.x; i++)
		{
			for (int j = 0; j < Grid.y; j++)
			{
				tempGridSpriteOutline.setPosition(i * 8 * scale, j * 8 * scale);
				//window.draw(tempGridSpriteOutline);
			}
		}
		counter = 0;
		//******************************************************
		//Draws tiles throughout the map
		for (tileIter = tileArray.begin(); tileIter != tileArray.end(); tileIter++)
		{
			//window.draw(tileArray[counter].rect);
			counter++;
		}

		//***************************************************
		//Allows the player to move

		player.updateMovement();
		player.update();

		//*****************************************************
		//This gets the ghost out of the box at the start of the game.
		for (ghostIter = ghostArray.begin(); ghostIter < ghostArray.end(); ghostIter++)
		{
			if (outOfBoxCounter < 4)
			{
				switch (outOfBoxCounter)
					{
				case (0) : if (boxClock.getElapsedTime().asSeconds() > 4 &&
								boxClock.getElapsedTime().asSeconds() < 4.6 &&
								!ghostArray[outOfBoxCounter].getOutOfBox())
							{
								ghostArray[outOfBoxCounter].setDirec(2);
							}

						   else if (boxClock.getElapsedTime().asSeconds() > 4.6
							   && boxClock.getElapsedTime().asSeconds() < 4.7
							   && !pinkOutBox)
						   {
							   ghostArray[outOfBoxCounter].setDirec(4);
							   //ghostArray[outOfBoxCounter].setOutOfBox(true);
							   boxClock.restart();
							   outOfBoxCounter++;
						   }
						break;
				case(1) : if (boxClock.getElapsedTime().asSeconds() > 4 &&
								boxClock.getElapsedTime().asSeconds() < 4.2 &&
								!ghostArray[outOfBoxCounter].getOutOfBox())
						{
								ghostArray[outOfBoxCounter].setDirec(2);
						}

						else if (boxClock.getElapsedTime().asSeconds() > 4.2
							&& boxClock.getElapsedTime().asSeconds() < 4.4
							&& !pinkOutBox)
						{
							ghostArray[outOfBoxCounter].setDirec(4);
							//ghostArray[outOfBoxCounter].setOutOfBox(true);
							boxClock.restart();
							outOfBoxCounter++;
						}
						break;

				case(2) : if (boxClock.getElapsedTime().asSeconds() > 4 &&
							boxClock.getElapsedTime().asSeconds() < 4.2 &&
							!ghostArray[outOfBoxCounter].getOutOfBox())
						{
							ghostArray[outOfBoxCounter].setDirec(3);
						}

						 else if (boxClock.getElapsedTime().asSeconds() > 4.2
							  && boxClock.getElapsedTime().asSeconds() < 4.4
							  && !pinkOutBox)
						 {
							  ghostArray[outOfBoxCounter].setDirec(4);
							  //ghostArray[outOfBoxCounter].setOutOfBox(true);
							  boxClock.restart();
							  outOfBoxCounter++;
						 }
						break;
				case(3) : if (boxClock.getElapsedTime().asSeconds() > 4 &&
							boxClock.getElapsedTime().asSeconds() < 4.5 &&
							!ghostArray[outOfBoxCounter].getOutOfBox())
						{
							ghostArray[outOfBoxCounter].setDirec(3);
						}

						 else if (boxClock.getElapsedTime().asSeconds() > 4.5
							  && boxClock.getElapsedTime().asSeconds() < 4.7
							  && !pinkOutBox)
						 {
							  ghostArray[outOfBoxCounter].setDirec(4);
							  //ghostArray[outOfBoxCounter].setOutOfBox(true);
							  boxClock.restart();
							  outOfBoxCounter++;
						 }
						break;
					}
			}

		}


		

		//*************************************************
		//Tunnel mirror
		if (player.rect.getPosition().x <= -14)
		{
			//cout << "Out of the box" << endl;
			player.rect.setPosition(682, player.rect.getPosition().y);
		}
		else if (player.rect.getPosition().x >= 680)
		{
			player.rect.setPosition(-15, player.rect.getPosition().y);
		}

		//***************************************************
		// Wall detection when player collides with a wall
		counter = 0;
		for (tileIter = tileArray.begin(); tileIter != tileArray.end(); tileIter++)
		{
			if ((player.sprite.getPosition().x >= 300 && player.sprite.getPosition().x <= 360) &&
				(player.sprite.getPosition().y <= 370 && player.sprite.getPosition().y >= 351) && player.getDirection() == 2)
			{
				if (player.getDirection() == 2)
				{
					player.rect.move(0, -7);
					break;
				}
			}

			if (player.rect.getGlobalBounds().intersects(tileArray[counter].rect.getGlobalBounds()))
			{
				//cout << "Wall HIT AT: "<< tileArray[counter].rect.getPosition().x << "," << tileArray[counter].rect.getPosition().y << endl;
				currentDirection = player.getDirection();
				switch (currentDirection)
				{
				case 1: player.rect.move(0, 3);
					break;
				case 2: player.rect.move(0, -3);
					break;
				case 3: player.rect.move(3, 0);
					break;
				case 4:	player.rect.move(-3, 0);
					break;
				default:
					break;
				}
			}

			counter++;
		}//end for loop
		

		//********************************************************************
		//Changes the direction of the ghost once it hits a wall.
		counter = 0;
		counter2 = 0;
		bool hit = false;
		for (ghostIter = ghostArray.begin(); ghostIter != ghostArray.end(); ghostIter++)
		{
			ghostArray[counter].setHitWall(false);
			ghostArray[counter].isDownDirectBlock = false;
			ghostArray[counter].isUpDirectBlock = false;
			ghostArray[counter].isLeftDirectBlock = false;
			ghostArray[counter].isRightDirectBlock = false;

			for (tileIter = tileArray.begin(); tileIter != tileArray.end(); tileIter++)
			{
				if(ghostArray[counter].dirRect.getGlobalBounds().intersects(tileArray[counter2].rect.getGlobalBounds()))
				{
					ghostArray[counter].setHitWall(true);
					
					if (ghostArray[counter].rect.getGlobalBounds().intersects(tileArray[counter2].rect.getGlobalBounds()) && ghostArray[counter].getOutOfBox())
					{
					//cout << "Wall hit" << counter << endl;
					//currentDirection = player.getDirection();
					switch (ghostArray[counter].getDirection2())
					{
						case 1: ghostArray[counter].rect.move(0, -3);
						//ghostArray[counter].setDirec(4);
							break;
						case 2: ghostArray[counter].rect.move(-3, 0);
						//ghostArray[counter].setDirec(3);
							break;
						case 3: ghostArray[counter].rect.move(3, 0);
						//ghostArray[counter].setDirec(2);
							break;
						case 4:	ghostArray[counter].rect.move(0, 3);
						//ghostArray[counter].setDirec(1);
							break;
						default:
							break;
					}
					}
				}

				if (ghostArray[counter].upRect.getGlobalBounds().intersects(tileArray[counter2].rect.getGlobalBounds()) &&
					(ghostArray[counter].dirRect.getGlobalBounds().intersects(tileArray[counter2].rect.getGlobalBounds())))
				{
					ghostArray[counter].isUpDirectBlock = true;
					ghostArray[counter].setOutOfBox(true);
					hit = true;
					//ghostArray[counter].rect.move(0, 3);
				}
				if (ghostArray[counter].downRect.getGlobalBounds().intersects(tileArray[counter2].rect.getGlobalBounds()) &&
					(/*ghostArray[counter].rect.getGlobalBounds().intersects(tileArray[counter2].rect.getGlobalBounds())) &&*/ ghostArray[counter].getOutOfBox()))
				{
					ghostArray[counter].isDownDirectBlock = true;
					//ghostArray[counter].rect.move(0, -3);
				}
				if (ghostArray[counter].rightRect.getGlobalBounds().intersects(tileArray[counter2].rect.getGlobalBounds()) &&
					(/*ghostArray[counter].rect.getGlobalBounds().intersects(tileArray[counter2].rect.getGlobalBounds())) &&*/ ghostArray[counter].getOutOfBox()))
				{
					ghostArray[counter].isRightDirectBlock = true;
					//ghostArray[counter].rect.move(-3, 0);
				}
				if (ghostArray[counter].leftRect.getGlobalBounds().intersects(tileArray[counter2].rect.getGlobalBounds()) &&
					(/*ghostArray[counter].rect.getGlobalBounds().intersects(tileArray[counter2].rect.getGlobalBounds())) &&*/ ghostArray[counter].getOutOfBox()))
				{
					ghostArray[counter].isLeftDirectBlock = true;
					//ghostArray[counter].rect.move(3, 0);
				}
				ghostArray[counter].update();

				if (ghostArray[counter].getOutOfBox() && ghostArray[counter].getHitWall())
				{
					//cout << "Wall hit" << endl;
					ghostArray[counter].randomMovement();
				}
							
				counter2++;
			}//end inside for loop
			
			/*
			window.draw(ghostArray[counter].rect);
			window.draw(ghostArray[counter].upRect);
			window.draw(ghostArray[counter].downRect);
			window.draw(ghostArray[counter].leftRect);
			window.draw(ghostArray[counter].rightRect);
			
			window.draw(ghostArray[counter].dirRect);
			*/

			counter2 = 0;
			counter++;
		}// end for loop
		//***************************************************
		//This where the ghost are allowed to move.
		counter = 0;
		for (ghostIter = ghostArray.begin(); ghostIter != ghostArray.end(); ghostIter++)
		{
			ghostArray[counter].moving1();

			counter++;
		}
		//***************************************************
		// If the ghost are blue and eaten by pacman, then the ghost are placed back inside the box
		counter = 0;
		if (ghostArray[0].getIsAfraid())
		{
			for (ghostIter = ghostArray.begin(); ghostIter != ghostArray.end(); ghostIter++)
			{
				//send the ghost back inside the box
				if (player.sprite.getGlobalBounds().intersects(ghostArray[counter].sprite.getGlobalBounds()))
				{
					ghostArray[counter].setOutOfBox(false);
					ghostArray[counter].setPosition(positionGhost + 60, 410);
					score = score + 100;
					break;
				}
				counter++;
			}
		}
		//***************************************************
		//player touches ghost decrease the lifes by one
		int counter = 0;
		for (ghostIter = ghostArray.begin(); ghostIter != ghostArray.end(); ghostIter++)
		{
			//decrements lives if pacman hits ghost
			if (player.sprite.getGlobalBounds().intersects(ghostArray[counter].sprite.getGlobalBounds()) &&
				!ghostArray[counter].getIsAfraid())
			{
				player.sprite.setPosition(sf::Vector2f(14 * 24, 20 * 24 + 4));
				player.rect.setPosition(sf::Vector2f(14 * 24, 20 * 24 + 4));
				if (player.getLives() == 2)
				{
					live1.setOrigin(30, 0);
					player.setLives(player.getLives() - 1);

				}
				//player.sprite.setOrigin(14 * 24, 20 * 24 + 4);

				else if (player.getLives()>  1)
				{
					live2.setOrigin(30, 0);

					//player.sprite.setOrigin(14 * 24, 20 * 24 + 4);
					player.setLives(player.getLives() - 1);
				}

			}
			counter++;
		}

		//GameOver Display
		if (player.getLives() <= 0)
		{
			window.close();
			window.clear();
			gameover.draw(window);
			window.display();


		}// end of menu if statement

		//***************************************************
		// If player intersects with ball:
		counter = 0;
		counter2 = 0;
		for (ballIter = ballArray.begin(); ballIter != ballArray.end(); ballIter++)
		{
			if (player.rect.getGlobalBounds().intersects(ballArray[counter].rect.getGlobalBounds()))
			{
				ballArray[counter].setIsShowing(false);
				//Turn the ghost blue if the pacman eats a large pallet
				if (ballArray[counter].getIsLargePellet())
				{
					afraidClock.restart();
					for (ghostIter = ghostArray.begin(); ghostIter != ghostArray.end(); ghostIter++)
					{
						ghostArray[counter2].setIsAfraid(true);
						counter2++;
					}
					counter2 = 0;

				}
				if (introClock.getElapsedTime().asSeconds() >= 0.41)//introClock restarts
				{
					waka.play();
					//siren.stop();
					introClock.restart();
				}
				score++;
			}
			counter++;
		}// end for loop


		//This deletes the ball from the map
		counter = 0;
		for (ballIter = ballArray.begin(); ballIter != ballArray.end(); ballIter++)
		{
			if (!ballArray[counter].getIsShowing())
			{
				ballArray.erase(ballIter);
				break;
			}
			counter++;
		}// end for loop
		//**************************************************
	


		//**************************************************
		//reset ghost to their original sprite once time runs out
		counter = 0;
		if (afraidClock.getElapsedTime().asSeconds() > 8.0)
		{
			for (ghostIter = ghostArray.begin(); ghostIter != ghostArray.end(); ghostIter++)
			{
				ghostArray[counter].setIsAfraid(false);
				counter++;
			}
		}
		//**************************************************
		// If the siren is paused, unpause it
		if (siren.getStatus() == 0 && introClock.getElapsedTime().asSeconds() > 0.47)
		{
			siren.play();
		}
		//***************************************************
		//cherrie
		if (player.rect.getGlobalBounds().intersects(cherrie.sprite.getGlobalBounds()))
		{
			score += 100;
			cherrie.sprite.setPosition(-100, -50);
		}
		//ball drawn to screen:
		counter = 0;
		for (ballIter = ballArray.begin(); ballIter != ballArray.end(); ballIter++)
		{
			if (ballArray[counter].getIsShowing() == true)
			{
				window.draw(ballArray[counter].sprite);
				ballArray[counter].update();

				//window.draw(ballArray[ix].rect);
			}
			counter ++;
				
		}
		
		//**************************************************************
		//window.draw(player.rect2);
		//drawing the player sprite
		window.draw(player.sprite);
		//drawint the lives
		window.draw(live1);
		window.draw(live2);
		window.draw(cherrie.sprite);
		//window.draw(player.rect);
		//cout << "Player position: " << player.rect.getPosition().x << ", " << player.rect.getPosition().y << endl;
		//****************************************************************
		//Draws ghost to the screen. If they are afraid then the blue sprite shows up instead
		counter = 0;
		for (ghostIter = ghostArray.begin(); ghostIter != ghostArray.end(); ghostIter++)
		{
			if (!ghostArray[counter].getIsAfraid())
			{
				window.draw(ghostArray[counter].sprite);
			}
			else
			{
				window.draw(ghostArray[counter].sprite2);
			}
			//window.draw(ghostArray[counter].rect);
			counter++;
		}

		//*********************************************************
		
		//*********************************************************	
		window.display();
		while (introClock.getElapsedTime().asSeconds() <= 4.0 && wait)
		{
			boxClock.restart();
		}
		if (introClock.getElapsedTime().asSeconds() >= 4.1  && wait)
		{
			siren.setLoop(true);
			siren.play();
		}
		wait = false;

		if (player.getLives() < 1)
		{
			introClock.restart();
			while (introClock.getElapsedTime().asSeconds() < 6.0)
			{
				gameover.draw(window);
				window.display();
			}
			wait = true;
		}
		//cout << ballArray.size() << endl;
		
	}

	return 0;
}
Example #11
0
/**
 * Draws the minimap.
 */
void MiniMapView::draw()
{
	int _startX = _camera->getCenterPosition().x - ((getWidth() / CELL_WIDTH) / 2);
	int _startY = _camera->getCenterPosition().y - ((getHeight() / CELL_HEIGHT) / 2);

	InteractiveSurface::draw();
	if (!_set)
	{
		return;
	}
	drawRect(0, 0, getWidth(), getHeight(), 0);
	this->lock();
	for (int lvl = 0; lvl <= _camera->getCenterPosition().z; lvl++)
	{
		int py = _startY;
		for (int y = Surface::getY(); y < getHeight() + Surface::getY(); y += CELL_HEIGHT)
		{
			int px = _startX;
			for (int x = Surface::getX(); x < getWidth() + Surface::getX(); x += CELL_WIDTH)
			{
				MapData * data = 0;
				Tile * t = 0;
				Position p (px, py, lvl);
				t = _battleGame->getTile(p);
				if (!t)
				{
					px++;
					continue;
				}
				if (t->isDiscovered(2))
				{
					for (int i = 0; i < 4; i++)
					{
						data = t->getMapData(i);

						Surface * s = 0;
						if (data && data->getMiniMapIndex())
						{
							s = _set->getFrame (data->getMiniMapIndex()+35);
						}
						if (s)
						{
							s->blitNShade(this, x, y, t->getShade());
						}
					}
				}
				// alive units
				if (t->getUnit() && t->getUnit()->getVisible())
				{
					int frame = t->getUnit()->getMiniMapSpriteIndex();
					int size = t->getUnit()->getArmor()->getSize();
					frame += (t->getPosition().y - t->getUnit()->getPosition().y) * size;
					frame += t->getPosition().x - t->getUnit()->getPosition().x;
					frame += _frame * size * size;
					Surface * s = _set->getFrame(frame);
					s->blitNShade(this, x, y, 0);
				}
				// perhaps (at least one) item on this tile?
				if (t->isDiscovered(2) && !t->getInventory()->empty())
				{
					int frame = 9 + _frame;
					Surface * s = _set->getFrame(frame);
					s->blitNShade(this, x, y, 0);
				}

				px++;
			}
			py++;
		}
	}
	this->unlock();
	int centerX = getWidth() / 2 - 1;
	int centerY = getHeight() / 2 - 1;
	Uint8 color = 1 + _frame * 3;
	int xOffset = CELL_WIDTH / 2;
	int yOffset = CELL_HEIGHT / 2;
	drawLine(centerX - CELL_WIDTH, centerY - CELL_HEIGHT,
		 centerX - xOffset, centerY - yOffset,
		 color); // top left
	drawLine(centerX + xOffset, centerY - yOffset,
		 centerX + CELL_WIDTH, centerY - CELL_HEIGHT,
		 color); // top right
	drawLine(centerX - CELL_WIDTH, centerY + CELL_HEIGHT,
		 centerX - xOffset, centerY + yOffset,
		 color); // bottom left
	drawLine(centerX + CELL_WIDTH, centerY + CELL_HEIGHT,
		 centerX + xOffset, centerY + yOffset,
		 color); //bottom right
}
Example #12
0
    void Tileset::Parse(const tinyxml2::XMLNode *tilesetNode, const std::string& file_path)
    {
        const tinyxml2::XMLElement *tilesetElem = tilesetNode->ToElement();

        // Read all the attributes into local variables.

        // The firstgid and source attribute are kept in the TMX map,
        // since they are map specific.
        first_gid = tilesetElem->IntAttribute("firstgid");

        // If the <tileset> node contains a 'source' tag,
        // the tileset config should be loaded from an external
        // TSX (Tile Set XML) file. That file has the same structure
        // as the <tileset> element in the TMX map.
        const char* source_name = tilesetElem->Attribute("source");
        tinyxml2::XMLDocument tileset_doc;
        if ( source_name )
        {
            std::string fileName = file_path + source_name;
            tileset_doc.LoadFile( fileName.c_str() );

            if ( tileset_doc.ErrorID() != 0)
            {
                fprintf(stderr, "failed to load tileset file '%s'\n", fileName.c_str());
                return;
            }

            // Update node and element references to the new node
            tilesetNode = tileset_doc.FirstChildElement("tileset");
            tilesetElem = tilesetNode->ToElement();
        }

        tile_width = tilesetElem->IntAttribute("tilewidth");
        tile_height = tilesetElem->IntAttribute("tileheight");
        margin = tilesetElem->IntAttribute("margin");
        spacing = tilesetElem->IntAttribute("spacing");
        name = tilesetElem->Attribute("name");

        // Parse the tile offset, if it exists.
        const tinyxml2::XMLNode *tileOffsetNode = tilesetNode->FirstChildElement("tileoffset");
        if (tileOffsetNode)
        {
            tileOffset = new TileOffset();
            tileOffset->Parse(tileOffsetNode);
        }

        // Parse the terrain types if any.
        const tinyxml2::XMLNode *terrainTypesNode = tilesetNode->FirstChildElement("terraintypes");
        if (terrainTypesNode) 
        {
            TerrainArray terrainArray;
            terrainArray.Parse(&terrainTypes, terrainTypesNode);
        }

        // Parse the image.
        const tinyxml2::XMLNode *imageNode = tilesetNode->FirstChildElement("image");
        if (imageNode) 
        {
            image = new Image();
            image->Parse(imageNode);
        }

        // Iterate through all of the tile elements and parse each.
        const tinyxml2::XMLNode *tileNode = tilesetNode->FirstChildElement("tile");
        for (int tId = 0; tileNode; ++tId)
        {
            Tile* tile = new Tile(tId);
            tile->Parse(tileNode);
            tiles.push_back(tile);

            tileNode = tileNode->NextSiblingElement("tile");
        }

        // Parse the properties if any.
        const tinyxml2::XMLNode *propertiesNode = tilesetNode->FirstChildElement("properties");
        if (propertiesNode)
        {
            properties.Parse(propertiesNode);
        }
    }
Example #13
0
void IOMapBin::loadOTM(Map* map)
{
  int op;
  bool end = false;
  while(!feof(fh) || !end)
  {
		op = fgetc(fh);
		switch(op) 
		{
			case 0x10: // Information of the map
			{
				char name[100], author[100];
				int pos;
				int len;

				// Map Name
				len = fgetc(fh);
				for (pos = 0; pos < len; pos++)
					name[pos] = fgetc(fh);
				name[pos] = '\0';
				std::cout << ":: Map Name: " << name << std::endl;
				
				// Map Author
				len = fgetc(fh);
				for (pos = 0; pos < len; pos++)
					author[pos] = fgetc(fh);
				author[pos] = '\0';
				std::cout << ":: Map Author: " << author << std::endl;
				
				
			} break;
			case 0x20: // Map dimensions
			{
				int width, height;
				width = fgetc(fh);
				width += fgetc(fh)<<8;
				height = fgetc(fh);
				height += fgetc(fh)<<8;
				map->mapwidth = width;
				map->mapheight = height;
				std::cout << ":: Map dimensions: " << width << "x" << height << std::endl;
			} break; 
			case 0x30: // Global Temple Position
			{
				PositionEx templePos;

				templePos.x = fgetc(fh);
				templePos.x += fgetc(fh);	// X
				templePos.y = fgetc(fh);
				templePos.y += fgetc(fh);	// Y
				templePos.z = fgetc(fh);	// Z
				int radius = fgetc(fh);						// Radius

				// TODO: use the temple point and radius
				std::cout << ":: Global Temple Position: " << templePos.x << " " << templePos.y << " " << templePos.z << " Radius: " << radius << std::endl;
			} break; 
			case 0x40: // Tiles and items
			{
				Tile *t;
				int x, y, z, id, total = 0;
				while(true)
				{
					// tile pos
					x = fgetc(fh); x += fgetc(fh) << 8;    
					y = fgetc(fh); y += fgetc(fh) << 8;    
					z = fgetc(fh);
					
					// end the loop
					if (x == 0xFFFF && y == 0xFFFF && z == 0xFF) 
						break;
		           			             
					id = fgetc(fh) + 100; 
					id += fgetc(fh) << 8; 
			        total += 1;
			        
					map->setTile(x, y, z, id);
					t = map->getTile(x, y, z);
					
					// check if the tile is pz
					if (fgetc(fh) == 1)
						t->setPz();
					
					int op2;
					int tmpid;
					do 
					{
						op2 = fgetc(fh);  
						switch (op2)
						{
							case 0x10: // Action Id
								fgetc(fh); // len
								tmpid = fgetc(fh);
								tmpid += fgetc(fh) << 8;
								// t->ground->setActionId(tmpid);
								break;
							case 0x20: // Unique Id
								fgetc(fh); // len
								tmpid = fgetc(fh);
								tmpid += fgetc(fh) << 8;
								//t ->ground->setUniqueId(tmpid);
								break; 
							case 0x30: // Target Id
								fgetc(fh); // len
								tmpid = fgetc(fh);
								tmpid += fgetc(fh) << 8;
								// TODO: implement target ids
								break; 
							case 0xA0: // Item
							{
								int itemcount = fgetc(fh);
								for (int count = 0; count < itemcount; count++)
								{
									int itemid = fgetc(fh) + 100;
									itemid += fgetc(fh) << 8;
									
									Item *item = Item::CreateItem(itemid);
									int op3;
									do
									{
										op3 = fgetc(fh);
										switch (op3)
										{
											case 0x10: // Count
												fgetc(fh); //len
									   			item->setItemCountOrSubtype((unsigned char)fgetc(fh));
												break;                 
											case 0x20: // Action Id
												fgetc(fh); //len
												tmpid = fgetc(fh);
												tmpid += fgetc(fh) << 8;
												// item->setActionId(tmpid);
												break; 
											case 0x30: // Unique Id
												fgetc(fh); //len
												tmpid = fgetc(fh);
												tmpid += fgetc(fh) << 8;
												// item->setUniqueId(tmpid);
												break; 
											case 0x40: // Target Id
												fgetc(fh); //len
												tmpid = fgetc(fh);
												tmpid += fgetc(fh) << 8;
												// item->setTargetId(tmpid);
												break; 
											case 0x70: //Teleport
											{
												Teleport *tele = dynamic_cast<Teleport*>(item);
												Position toPos;
												fgetc(fh); //len

												toPos.x = fgetc(fh); toPos.x += fgetc(fh)<<8;
												toPos.y = fgetc(fh); toPos.y += fgetc(fh)<<8;
												toPos.z = fgetc(fh);

												if (tele)
													tele->setDestPos(toPos);
											} break;
											case 0x80: // Fluids
												fgetc(fh);
												if (item->isFluidContainer())
													item->setItemCountOrSubtype((unsigned char)fgetc(fh));
												else
													fgetc(fh);
											break;                      
											case 0xFF: // End
												break;
											default: // Unknow/New operators
											{
												printf("WARNING: Unknown operator loading items: 0x%X!\n",op3);
												int len = fgetc(fh);
												for (int i = 0; i < len; i++)
													fgetc(fh);     
											} break;
										}                             
									} while (op3 < 0xFF);
									
									//item->pos.x = x;
									//item->pos.y = y;
									//item->pos.z = z;

									if (item->isAlwaysOnTop())
										t->topItems.push_back(item);
									else
										t->downItems.push_back(item);
								}
							} break;
							case 0xFF: // End
								break;
							default: // Unknow/New operators
							{
								printf("WARNING: Unknown operator loading tiles: 0x%X!\n",op2);
								int len = fgetc(fh);
								for (int i = 0;i < len; i++)
									fgetc(fh);  
							} break;
						}
					} while (op2 < 0xFF);
				}
				std::cout << ":: Total of tiles loaded is " << total << std::endl;
			} break;
			case 0x50: // Spawns
			{
				SpawnManager::initialize(&g_game);
				Position pos;
				int cx, cy, radius, total=0;
				long int secs;
				std::string cname;
				int num = fgetc(fh); num+=fgetc(fh)<<8;

				for (int i = 0; i < num; i++)
				{
					int len = fgetc(fh);
					int count;
					cname = "";

					for (int j = 0;j < len; j++)
						cname.push_back(fgetc(fh)); // get the creature name

					//std::cout << cname.c_str() << std::endl;

					pos.x = fgetc(fh); pos.x += fgetc(fh) << 8;
					pos.y = fgetc(fh); pos.y += fgetc(fh) << 8;
					pos.z = fgetc(fh); 
					radius = fgetc(fh) + 1;
			             
					count = fgetc(fh); // number of creatures in this respawn
					total += count;
					secs = fgetc(fh); secs += fgetc(fh) << 8;
			             
					Spawn *spawn = new Spawn(&g_game, pos, radius);
					SpawnManager::instance()->addSpawn(spawn);
		             
					for (int j = 0; j < count; j++)
					{
						cx = (rand() % (radius * 2)) - radius;
						cy = (rand() % (radius * 2)) - radius;
						spawn->addMonster(cname, NORTH, cx, cy, secs * 1000);
					}

					fgetc(fh); // 1 = check for players near, 0 = dont check
				}
		           
				std::cout << ":: Loaded spawns: " << total << std::endl;
				SpawnManager::instance()->startup();
			} break;
			case 0xF0:
				end = true;
				break;
		}
  }
  fclose(fh);
  return;
}
Example #14
0
void Build::_updatePreviewTiles( bool force )
{
  __D_REF(d,Build);
  Tile* curTile = _camera()->at( _lastCursorPos(), true );

  if( !curTile )
    return;

  if( !force && d.lastTilePos == curTile->epos() )
    return;

  if( !d.multiBuilding )
  {
    _setStartCursorPos( _lastCursorPos() );
    d.startTilePos = curTile->pos();
  }

  d.lastTilePos = curTile->epos();

  _discardPreview();
  d.money4Construction = 0;

  if( d.borderBuilding )
  {
    Tile* startTile = _camera()->at( d.startTilePos );  // tile under the cursor (or NULL)
    Tile* stopTile  = _camera()->at( _lastCursorPos(),  true );

    TilesArray pathTiles = RoadPropagator::createPath( _city()->tilemap(),
                                                       startTile->epos(), stopTile->epos(),
                                                       d.roadAssignment, d.kbShift );
    Tilemap& tmap = _city()->tilemap();
    TilePos leftUpCorner = pathTiles.leftUpCorner();
    TilePos rigthDownCorner = pathTiles.rightDownCorner();
    TilePos leftDownCorner( leftUpCorner.i(), rigthDownCorner.j() );
    TilesArray ret;

    int mmapSize = std::max<int>( leftUpCorner.j() - rigthDownCorner.j() + 1,
                                  rigthDownCorner.i() - leftUpCorner.i() + 1 );
    for( int y=0; y < mmapSize; y++ )
    {
      for( int t=0; t <= y; t++ )
      {
        TilePos tpos = leftDownCorner + TilePos( t, mmapSize - 1 - ( y - t ) );
        if( pathTiles.contain( tpos ) )
          ret.push_back( &tmap.at( tpos ) );
      }
    }

    for( int x=1; x < mmapSize; x++ )
    {
      for( int t=0; t < mmapSize-x; t++ )
      {
        TilePos tpos = leftDownCorner + TilePos( x + t, t );
        if( pathTiles.contain( tpos ) )
          ret.push_back( &tmap.at( tpos ) );
      }
    }

    pathTiles = ret;
    for( auto tile : pathTiles )
      _checkPreviewBuild( tile->epos() );
  }
  else
  {
    TilesArray tiles = _getSelectedArea( d.startTilePos );

    for( auto tile : tiles )
      _checkPreviewBuild( tile->epos() );
  }

  d.sortBuildTiles();

  d.text.image.fill( ColorList::clear, Rect() );
  d.text.font.setColor( ColorList::red );
  d.text.font.draw( d.text.image, fmt::format( "{} Dn", d.money4Construction ), Point() );
}
bool IOMapSerialize::loadItem(PropStream& propStream, Cylinder* parent)
{
	uint16_t id;
	if (!propStream.read<uint16_t>(id)) {
		return false;
	}

	Tile* tile = nullptr;
	if (parent->getParent() == nullptr) {
		tile = parent->getTile();
	}

	const ItemType& iType = Item::items[id];
	if (iType.moveable || !tile) {
		//create a new item
		Item* item = Item::CreateItem(id);
		if (item) {
			if (item->unserializeAttr(propStream)) {
				Container* container = item->getContainer();
				if (container && !loadContainer(propStream, container)) {
					delete item;
					return false;
				}

				parent->internalAddThing(item);
				item->startDecaying();
			} else {
				std::cout << "WARNING: Unserialization error in IOMapSerialize::loadItem()" << id << std::endl;
				delete item;
				return false;
			}
		}
	} else {
		// Stationary items like doors/beds/blackboards/bookcases
		Item* item = nullptr;
		if (const TileItemVector* items = tile->getItemList()) {
			for (Item* findItem : *items) {
				if (findItem->getID() == id) {
					item = findItem;
					break;
				} else if (iType.isDoor() && findItem->getDoor()) {
					item = findItem;
					break;
				} else if (iType.isBed() && findItem->getBed()) {
					item = findItem;
					break;
				}
			}
		}

		if (item) {
			if (item->unserializeAttr(propStream)) {
				Container* container = item->getContainer();
				if (container && !loadContainer(propStream, container)) {
					return false;
				}

				g_game.transformItem(item, id);
			} else {
				std::cout << "WARNING: Unserialization error in IOMapSerialize::loadItem()" << id << std::endl;
			}
		} else {
			//The map changed since the last save, just read the attributes
			std::unique_ptr<Item> dummy(Item::CreateItem(id));
			if (dummy) {
				dummy->unserializeAttr(propStream);
				Container* container = dummy->getContainer();
				if (container) {
					if (!loadContainer(propStream, container)) {
						return false;
					}
				} else if (BedItem* bedItem = dynamic_cast<BedItem*>(dummy.get())) {
					uint32_t sleeperGUID = bedItem->getSleeper();
					if (sleeperGUID != 0) {
						g_game.removeBedSleeper(sleeperGUID);
					}
				}
			}
		}
	}
	return true;
}
Example #16
0
Tile* Tile::queryDestination(int32_t&, const Thing&, Item** destItem, uint32_t& flags)
{
	Tile* destTile = nullptr;
	*destItem = nullptr;

	if (floorChangeDown()) {
		uint16_t dx = tilePos.x;
		uint16_t dy = tilePos.y;
		uint8_t dz = tilePos.z + 1;

		Tile* southDownTile = g_game.map.getTile(dx, dy - 1, dz);
		if (southDownTile && southDownTile->floorChange(DIRECTION_SOUTH_ALT)) {
			dy -= 2;
			destTile = g_game.map.getTile(dx, dy, dz);
		} else {
			Tile* eastDownTile = g_game.map.getTile(dx - 1, dy, dz);
			if (eastDownTile && eastDownTile->floorChange(DIRECTION_EAST_ALT)) {
				dx -= 2;
				destTile = g_game.map.getTile(dx, dy, dz);
			} else {
				Tile* downTile = g_game.map.getTile(dx, dy, dz);
				if (downTile) {
					if (downTile->floorChange(DIRECTION_NORTH)) {
						++dy;
					}

					if (downTile->floorChange(DIRECTION_SOUTH)) {
						--dy;
					}

					if (downTile->floorChange(DIRECTION_SOUTH_ALT)) {
						dy -= 2;
					}

					if (downTile->floorChange(DIRECTION_EAST)) {
						--dx;
					}

					if (downTile->floorChange(DIRECTION_EAST_ALT)) {
						dx -= 2;
					}

					if (downTile->floorChange(DIRECTION_WEST)) {
						++dx;
					}

					destTile = g_game.map.getTile(dx, dy, dz);
				}
			}
		}
	} else if (floorChange()) {
		uint16_t dx = tilePos.x;
		uint16_t dy = tilePos.y;
		uint8_t dz = tilePos.z - 1;

		if (floorChange(DIRECTION_NORTH)) {
			--dy;
		}

		if (floorChange(DIRECTION_SOUTH)) {
			++dy;
		}

		if (floorChange(DIRECTION_EAST)) {
			++dx;
		}

		if (floorChange(DIRECTION_WEST)) {
			--dx;
		}

		if (floorChange(DIRECTION_SOUTH_ALT)) {
			dy += 2;
		}

		if (floorChange(DIRECTION_EAST_ALT)) {
			dx += 2;
		}

		destTile = g_game.map.getTile(dx, dy, dz);
	}

	if (destTile == nullptr) {
		destTile = this;
	} else {
		flags |= FLAG_NOLIMIT;    //Will ignore that there is blocking items/creatures
	}

	if (destTile) {
		Thing* destThing = destTile->getTopDownItem();
		if (destThing) {
			*destItem = destThing->getItem();
		}
	}

	return destTile;
}
void CivilianBAIState::setupEscape()
{
	int unitsSpottingMe = getSpottingUnits(_unit->getPosition());
	int currentTilePreference = 15;
	int tries = 0;
	bool coverFound = false;
	selectNearestTarget();

	int dist = _aggroTarget ? _save->getTileEngine()->distance(_unit->getPosition(), _aggroTarget->getPosition()) : 0;

	int bestTileScore = -100000;
	int score = -100000;
	Position bestTile(0, 0, 0);

	Tile *tile = 0;
	
	// weights of various factors in choosing a tile to which to withdraw
	const int EXPOSURE_PENALTY = 10;
	const int FIRE_PENALTY = 40;
	const int BASE_SYSTEMATIC_SUCCESS = 100;
	const int BASE_DESPERATE_SUCCESS = 110;
	const int FAST_PASS_THRESHOLD = 100; // a score that's good engouh to quit the while loop early; it's subjective, hand-tuned and may need tweaking

	int tu = _unit->getTimeUnits() / 2;

	std::vector<int> reachable = _save->getPathfinding()->findReachable(_unit, tu);
	std::vector<Position> randomTileSearch = _save->getTileSearch();
	RNG::shuffle(randomTileSearch);
	
	while (tries < 150 && !coverFound)
	{
		_escapeAction->target = _unit->getPosition(); // start looking in a direction away from the enemy
					
		if (!_save->getTile(_escapeAction->target))
		{
			_escapeAction->target = _unit->getPosition(); // cornered at the edge of the map perhaps? 
		}
		
		score = 0;

		if (tries < 121) 
		{
			// looking for cover
			_escapeAction->target.x += randomTileSearch[tries].x;
			_escapeAction->target.y += randomTileSearch[tries].y;
			score = BASE_SYSTEMATIC_SUCCESS;
			if (_escapeAction->target == _unit->getPosition()) 
			{
				if (unitsSpottingMe > 0)
				{
					// maybe don't stay in the same spot? move or something if there's any point to it?
					_escapeAction->target.x += RNG::generate(-20,20);
					_escapeAction->target.y += RNG::generate(-20,20);
				} else
				{
					score += currentTilePreference;
				}
			}
		}
		else
		{
			
			if (tries == 121) 
			{ 
				if (_traceAI) 
				{
					Log(LOG_INFO) << "best score after systematic search was: " << bestTileScore; 
				}
			}
						
			score = BASE_DESPERATE_SUCCESS; // ruuuuuuun
			_escapeAction->target = _unit->getPosition();
			_escapeAction->target.x += RNG::generate(-10,10);
			_escapeAction->target.y += RNG::generate(-10,10);
			_escapeAction->target.z = _unit->getPosition().z + RNG::generate(-1,1);
			if (_escapeAction->target.z < 0)
			{
				_escapeAction->target.z = 0;
			}
			else if (_escapeAction->target.z >= _save->getMapSizeZ()) 
			{
				_escapeAction->target.z = _unit->getPosition().z;
			}
		}

		tries += 10; // civilians shouldn't have any tactical sense anyway so save some CPU cycles here

		// THINK, DAMN YOU
		tile = _save->getTile(_escapeAction->target);
		int distanceFromTarget = _aggroTarget ? _save->getTileEngine()->distance(_aggroTarget->getPosition(), _escapeAction->target) : 0;
		if (dist >= distanceFromTarget)
		{
			score -= (distanceFromTarget - dist) * 10;
		}
		else
		{
			score += (distanceFromTarget - dist) * 10;
		}
		int spotters = 0;
		if (!tile) 
		{
			score = -100001; // no you can't quit the battlefield by running off the map. 
		}
		else
		{
			spotters = getSpottingUnits(_escapeAction->target);
			if (std::find(reachable.begin(), reachable.end(), _save->getTileIndex(tile->getPosition()))  == reachable.end()) continue; // just ignore unreachable tiles
					
			if (_spottingEnemies || spotters)
			{
				if (_spottingEnemies <= spotters)
				{
					score -= (1 + spotters - _spottingEnemies) * EXPOSURE_PENALTY; // that's for giving away our position
				}
				else
				{
					score += (_spottingEnemies - spotters) * EXPOSURE_PENALTY;
				}
			}
			if (tile->getFire())
			{
				score -= FIRE_PENALTY;
			}
			if (_traceAI)
			{
				tile->setMarkerColor(score < 0 ? 3 : (score < FAST_PASS_THRESHOLD/2 ? 8 : (score < FAST_PASS_THRESHOLD ? 9 : 5)));
				tile->setPreview(10);
				tile->setTUMarker(score);
			}

		}

		if (tile && score > bestTileScore)
		{
			// calculate TUs to tile; we could be getting this from findReachable() somehow but that would break something for sure...
			_save->getPathfinding()->calculate(_unit, _escapeAction->target, 0, tu);
			if (_escapeAction->target == _unit->getPosition() || _save->getPathfinding()->getStartDirection() != -1)
			{
				bestTileScore = score;
				bestTile = _escapeAction->target;
				_escapeTUs = _save->getPathfinding()->getTotalTUCost();
				if (_escapeAction->target == _unit->getPosition())
				{
					_escapeTUs = 1;
				}
				if (_traceAI)
				{
					tile->setMarkerColor(score < 0 ? 7 : (score < FAST_PASS_THRESHOLD/2 ? 10 : (score < FAST_PASS_THRESHOLD ? 4 : 5)));
					tile->setPreview(10);
					tile->setTUMarker(score);
				}
			}
			_save->getPathfinding()->abortPath();
			if (bestTileScore > FAST_PASS_THRESHOLD) coverFound = true; // good enough, gogogo
		}
	}
	_escapeAction->target = bestTile;
	if (_traceAI)
	{
		_save->getTile(_escapeAction->target)->setMarkerColor(13);
	}
				
	if (bestTileScore <= -100000) 
	{
		if (_traceAI)
		{
			Log(LOG_INFO) << "Escape estimation failed.";
		}
		_escapeAction->type = BA_RETHINK; // do something, just don't look dumbstruck :P
		return;
	}
	else
	{
		if (_traceAI)
		{
			Log(LOG_INFO) << "Escape estimation completed after " << tries << " tries, " << _save->getTileEngine()->distance(_unit->getPosition(), bestTile) << " squares or so away.";
		}
		_escapeAction->type = BA_WALK;
	}
}
Example #18
0
int Projectile::calculateTrajectory(double accuracy, Position originVoxel)
{
	Tile *targetTile = _save->getTile(_action.target);
	BattleUnit *bu = _action.actor;
	
	int test = _save->getTileEngine()->calculateLine(originVoxel, _targetVoxel, false, &_trajectory, bu);
	if (test != V_EMPTY &&
		!_trajectory.empty() &&
		_action.actor->getFaction() == FACTION_PLAYER &&
		_action.autoShotCounter == 1 &&
		((SDL_GetModState() & KMOD_CTRL) == 0 || !Options::forceFire) &&
		_save->getBattleGame()->getPanicHandled() &&
		_action.type != BA_LAUNCH)
	{
		Position hitPos = Position(_trajectory.at(0).x/16, _trajectory.at(0).y/16, _trajectory.at(0).z/24);
		if (test == V_UNIT && _save->getTile(hitPos) && _save->getTile(hitPos)->getUnit() == 0) //no unit? must be lower
		{
			hitPos = Position(hitPos.x, hitPos.y, hitPos.z-1);
		}

		if (hitPos != _action.target && _action.result.empty())
		{
			if (test == V_NORTHWALL)
			{
				if (hitPos.y - 1 != _action.target.y)
				{
					_trajectory.clear();
					return V_EMPTY;
				}
			}
			else if (test == V_WESTWALL)
			{
				if (hitPos.x - 1 != _action.target.x)
				{
					_trajectory.clear();
					return V_EMPTY;
				}
			}
			else if (test == V_UNIT)
			{
				BattleUnit *hitUnit = _save->getTile(hitPos)->getUnit();
				BattleUnit *targetUnit = targetTile->getUnit();
				if (hitUnit != targetUnit)
				{
					_trajectory.clear();
					return V_EMPTY;
				}
			}
			else
			{
				_trajectory.clear();
				return V_EMPTY;
			}
		}
	}

	_trajectory.clear();

	bool extendLine = true;
	// even guided missiles drift, but how much is based on
	// the shooter's faction, rather than accuracy.
	if (_action.type == BA_LAUNCH)
	{
		if (_action.actor->getFaction() == FACTION_PLAYER)
		{
			accuracy = 0.60;
		}
		else
		{
			accuracy = 0.55;
		}
		extendLine = _action.waypoints.size() <= 1;
	}

	// apply some accuracy modifiers.
	// This will results in a new target voxel
	applyAccuracy(originVoxel, &_targetVoxel, accuracy, false, targetTile, extendLine);

	// finally do a line calculation and store this trajectory.
	return _save->getTileEngine()->calculateLine(originVoxel, _targetVoxel, true, &_trajectory, bu);
}
std::shared_ptr<TileData> ClientGeoJsonSource::parse(const Tile& _tile, std::vector<char>& _rawData) const {

    if (!m_store) { return nullptr; }

    auto data = std::make_shared<TileData>();

    auto id = _tile.getID();

    auto tile = m_store->getTile(id.z, id.x, id.y); // uses a mutex lock internally for thread-safety

    Layer layer(""); // empty name will skip filtering by 'collection'

    for (auto& it : tile.features) {

        Feature feat(m_id);

        const auto& geom = it.tileGeometry;
        const auto type = it.type;

        switch (type) {
            case geojsonvt::TileFeatureType::Point: {
                feat.geometryType = GeometryType::points;
                for (const auto& pt : geom) {
                    const auto& point = pt.get<geojsonvt::TilePoint>();
                    feat.points.push_back(transformPoint(point));
                }
                break;
            }
            case geojsonvt::TileFeatureType::LineString: {
                feat.geometryType = GeometryType::lines;
                for (const auto& r : geom) {
                    Line line;
                    for (const auto& pt : r.get<geojsonvt::TileRing>().points) {
                        line.push_back(transformPoint(pt));
                    }
                    feat.lines.emplace_back(std::move(line));
                }
                break;
            }
            case geojsonvt::TileFeatureType::Polygon: {
                feat.geometryType = GeometryType::polygons;
                for (const auto& r : geom) {
                    Line line;
                    for (const auto& pt : r.get<geojsonvt::TileRing>().points) {
                        line.push_back(transformPoint(pt));
                    }
                    // Polygons are in a flat list of rings, with ccw rings indicating
                    // the beginning of a new polygon
                    if (signedArea(line) >= 0 || feat.polygons.empty()) {
                        feat.polygons.emplace_back();
                    }
                    feat.polygons.back().push_back(std::move(line));
                }
                break;
            }
            default: break;
        }

        feat.props = *it.tags.map;
        layer.features.emplace_back(std::move(feat));

    }

    data->layers.emplace_back(std::move(layer));

    return data;

}
Example #20
0
bool WeaponDistance::useWeapon(Player* player, Item* item, Creature* target) const
{
	int32_t damageModifier;
	const ItemType& it = Item::items[id];
	if (it.weaponType == WEAPON_AMMO) {
		Item* mainWeaponItem = player->getWeapon(true);
		const Weapon* mainWeapon = g_weapons->getWeapon(mainWeaponItem);
		if (mainWeapon) {
			damageModifier = mainWeapon->playerWeaponCheck(player, target, mainWeaponItem->getShootRange());
		} else {
			damageModifier = playerWeaponCheck(player, target, mainWeaponItem->getShootRange());
		}
	} else {
		damageModifier = playerWeaponCheck(player, target, item->getShootRange());
	}

	if (damageModifier == 0) {
		return false;
	}

	int32_t chance;
	if (it.hitChance == 0) {
		//hit chance is based on distance to target and distance skill
		uint32_t skill = player->getSkillLevel(SKILL_DISTANCE);
		const Position& playerPos = player->getPosition();
		const Position& targetPos = target->getPosition();
		uint32_t distance = std::max<uint32_t>(Position::getDistanceX(playerPos, targetPos), Position::getDistanceY(playerPos, targetPos));

		uint32_t maxHitChance;
		if (it.maxHitChance != -1) {
			maxHitChance = it.maxHitChance;
		} else if (it.ammoType != AMMO_NONE) {
			//hit chance on two-handed weapons is limited to 90%
			maxHitChance = 90;
		} else {
			//one-handed is set to 75%
			maxHitChance = 75;
		}

		if (maxHitChance == 75) {
			//chance for one-handed weapons
			switch (distance) {
				case 1:
				case 5:
					chance = std::min<uint32_t>(skill, 74) + 1;
					break;
				case 2:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 28) * 2.40f) + 8;
					break;
				case 3:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 45) * 1.55f) + 6;
					break;
				case 4:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 58) * 1.25f) + 3;
					break;
				case 6:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 90) * 0.80f) + 3;
					break;
				case 7:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 104) * 0.70f) + 2;
					break;
				default:
					chance = it.hitChance;
					break;
			}
		} else if (maxHitChance == 90) {
			//formula for two-handed weapons
			switch (distance) {
				case 1:
				case 5:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 74) * 1.20f) + 1;
					break;
				case 2:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 28) * 3.20f);
					break;
				case 3:
					chance = std::min<uint32_t>(skill, 45) * 2;
					break;
				case 4:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 58) * 1.55f);
					break;
				case 6:
				case 7:
					chance = std::min<uint32_t>(skill, 90);
					break;
				default:
					chance = it.hitChance;
					break;
			}
		} else if (maxHitChance == 100) {
			switch (distance) {
				case 1:
				case 5:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 73) * 1.35f) + 1;
					break;
				case 2:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 30) * 3.20f) + 4;
					break;
				case 3:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 48) * 2.05f) + 2;
					break;
				case 4:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 65) * 1.50f) + 2;
					break;
				case 6:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 87) * 1.20f) - 4;
					break;
				case 7:
					chance = static_cast<uint32_t>(std::min<uint32_t>(skill, 90) * 1.10f) + 1;
					break;
				default:
					chance = it.hitChance;
					break;
			}
		} else {
			chance = maxHitChance;
		}
	} else {
		chance = it.hitChance;
	}

	if (item->getWeaponType() == WEAPON_AMMO) {
		Item* bow = player->getWeapon(true);
		if (bow && bow->getHitChance() != 0) {
			chance += bow->getHitChance();
		}
	}

	if (chance >= uniform_random(1, 100)) {
		Weapon::internalUseWeapon(player, item, target, damageModifier);
	} else {
		//miss target
		Tile* destTile = target->getTile();

		if (!Position::areInRange<1, 1, 0>(player->getPosition(), target->getPosition())) {
			static std::vector<std::pair<int32_t, int32_t>> destList {
				{-1, -1}, {0, -1}, {1, -1},
				{-1,  0}, {0,  0}, {1,  0},
				{-1,  1}, {0,  1}, {1,  1}
			};
			std::shuffle(destList.begin(), destList.end(), getRandomGenerator());

			Position destPos = target->getPosition();

			for (const auto& dir : destList) {
				// Blocking tiles or tiles without ground ain't valid targets for spears
				Tile* tmpTile = g_game.map.getTile(destPos.x + dir.first, destPos.y + dir.second, destPos.z);
				if (tmpTile && !tmpTile->hasProperty(CONST_PROP_IMMOVABLEBLOCKSOLID) && tmpTile->ground != nullptr) {
					destTile = tmpTile;
					break;
				}
			}
		}

		Weapon::internalUseWeapon(player, item, destTile);
	}
	return true;
}
void
OSGTerrainEngineNode::addImageLayer( ImageLayer* layerAdded )
{
    if ( !layerAdded || !layerAdded->getTileSource() )
        return;

    // visit all existing terrain tiles and inform each one of the new image layer:
    TileVector tiles;
    _terrain->getTiles( tiles );

    for( TileVector::iterator itr = tiles.begin(); itr != tiles.end(); ++itr )
    {
        Tile* tile = itr->get();

        StreamingTile* streamingTile = 0L;

        GeoImage geoImage;
        bool needToUpdateImagery = false;
        int imageLOD = -1;

        if ( !_isStreaming || tile->getKey().getLevelOfDetail() == 1 )
        {
            // in standard mode, or at the first LOD in seq/pre mode, fetch the image immediately.
            TileKey geoImageKey = tile->getKey();
            _tileFactory->createValidGeoImage( layerAdded, tile->getKey(), geoImage, geoImageKey );
            imageLOD = tile->getKey().getLevelOfDetail();
        }
        else
        {
            // in seq/pre mode, set up a placeholder and mark the tile as dirty.
            geoImage = GeoImage(ImageUtils::createEmptyImage(), tile->getKey().getExtent() );
            needToUpdateImagery = true;
            streamingTile = static_cast<StreamingTile*>(tile);
        }

        if (geoImage.valid())
        {
            const MapInfo& mapInfo = _update_mapf->getMapInfo();

            double img_min_lon, img_min_lat, img_max_lon, img_max_lat;
            geoImage.getExtent().getBounds(img_min_lon, img_min_lat, img_max_lon, img_max_lat);

            //Specify a new locator for the color with the coordinates of the TileKey that was actually used to create the image
            osg::ref_ptr<GeoLocator> img_locator = tile->getKey().getProfile()->getSRS()->createLocator( 
                img_min_lon, img_min_lat, img_max_lon, img_max_lat, 
                !mapInfo.isGeocentric() );
            
            //Set the CS to geocentric if we are dealing with a geocentric map
            if ( mapInfo.isGeocentric() )
            {
                img_locator->setCoordinateSystemType( osgTerrain::Locator::GEOCENTRIC );
            }

            tile->setCustomColorLayer( CustomColorLayer(
                layerAdded,
                geoImage.getImage(),
                img_locator.get(), imageLOD,  tile->getKey() ) );

            // if necessary, tell the tile to queue up a new imagery request (since we
            // just installed a placeholder)
            if ( needToUpdateImagery )
            {
                streamingTile->updateImagery( layerAdded, *_update_mapf, _tileFactory.get() );
            }
        }
        else
        {
            // this can happen if there's no data in the new layer for the given tile.
            // we will rely on the driver to dump out a warning if this is an error.
        }

        tile->applyImmediateTileUpdate( TileUpdate::ADD_IMAGE_LAYER, layerAdded->getUID() );
    }

    updateTextureCombining();
}
Example #22
0
bool C3Sav::Impl::loadCity( std::fstream& f, Game& game )
{
    uint32_t tmp;

    // need to rewrite better
    std::vector<short int> graphicGrid;
    graphicGrid.resize( 26244, 0 );
    std::vector<unsigned char> edgeGrid;
    edgeGrid.resize( 26244, 0 );
    std::vector<short int> terrainGrid;
    terrainGrid.resize( 26244, 0 );
    std::vector<unsigned char> rndmTerGrid;
    rndmTerGrid.resize(26244, 0);
    std::vector<unsigned char> randomGrid;
    randomGrid.resize( 26244, 0 );
    std::vector<unsigned char> zeroGrid;
    zeroGrid.resize( 26244, 0 );

    if( !f.is_open() )
    {
        Logger::warning( "GameLoaderC3Sav: can't open file " );
        return false;
    }

    f.read( (char*)&tmp, 4); // read dummy

    std::string cityName = LoaderHelper::getDefaultCityName( tmp );
    game.city()->setName( cityName );

    f.read((char*)&tmp, 4); // read scenario flag

    try
    {
        f.read((char*)&tmp, 4); // read length of compressed chunk
        Logger::warning( "GameLoaderC3Sav: length of compressed ids is %d", tmp );
        PKWareInputStream *pk = new PKWareInputStream(&f, false, tmp);
        for (int i = 0; i < 162 * 162; i++)
        {
            graphicGrid[i] = pk->readShort();
        }
        pk->empty();
        delete pk;

        f.read((char*)&tmp, 4); // read length of compressed chunk
        Logger::warning( "GameLoaderC3Sav: length of compressed egdes is %d", tmp );
        pk = new PKWareInputStream(&f, false, tmp);
        for (int i = 0; i < 162 * 162; i++)
        {
            edgeGrid[i] = pk->readByte();
        }
        pk->empty();
        delete pk;

        SkipCompressed(f); // skip building ids

        f.read((char*)&tmp, 4); // read length of compressed chunk
        Logger::warning( "GameLoaderC3Sav: length of compressed terraindata is %d", tmp );
        pk = new PKWareInputStream(&f, false, tmp);
        for (int i = 0; i < 162 * 162; i++)
        {
            terrainGrid[i] = pk->readShort();
        }
        pk->empty();
        delete pk;

        SkipCompressed(f);
        SkipCompressed(f);
        SkipCompressed(f);
        SkipCompressed(f);

        f.read((char*)&randomGrid[0], 26244);

        SkipCompressed(f);
        SkipCompressed(f);
        SkipCompressed(f);
        SkipCompressed(f);
        SkipCompressed(f);

        // here goes walkers array
        f.read((char*)&tmp, 4); // read length of compressed chunk
        Logger::warning( "GameLoaderC3Sav: length of compressed walkers data is %d", tmp );
        pk = new PKWareInputStream(&f, false, tmp);
        for (int j = 0; j < 1000; j++)
        {
            pk->skip(10);
            pk->readShort();
            pk->skip(8);
            pk->readByte();
            pk->readByte();
            pk->skip(106);
        }
        pk->empty();
        delete pk;
        int length;
        f.read((char*)&length, 4); // read next length :-)

        if (length <= 0)
            f.seekg(1200, std::ios::cur);
        else
            f.seekg(length, std::ios::cur);

        SkipCompressed(f);
        SkipCompressed(f);

        // 3x int
        f.read((char*)&tmp, 4);
        f.read((char*)&tmp, 4);
        f.read((char*)&tmp, 4);
        SkipCompressed(f);
        f.seekg(70, std::ios::cur);
        SkipCompressed(f); // skip building list
        f.seekg(208, std::ios::cur);
        SkipCompressed(f); // skip unknown
        f.seekg(788, std::ios::cur); // skip unused data
        f.read((char*)&tmp, 4); //mapsize

        int size = tmp;
        PlayerCityPtr oCity = game.city();
        Tilemap& oTilemap = oCity->tilemap();

        oCity->resize(size);
        oCity->setCameraPos( TilePos( 0, 0 ) );

        initEntryExit( f, game.city() );

        f.seekg(1312, std::ios::cur);
        char climate;
        f.read(&climate, 1);
        oCity->setClimate((ClimateType)climate);

        // here goes the WORK!


        // loads the graphics map
        int border_size = (162 - size) / 2;

        std::map< int, std::map< int, unsigned char > > edgeData;

        game.city()->setCameraPos( TilePos( size/2, size/2 ) );

        for (int itA = 0; itA < size; ++itA)
        {
            for (int itB = 0; itB < size; ++itB)
            {
                int i = itB;
                int j = size - itA - 1;

                int index = 162 * (border_size + itA) + border_size + itB;

                Tile& tile = oTilemap.at(i, j);

                unsigned int imgId = graphicGrid[index];
                Picture pic = imgid::toPicture( imgId );

                if( pic.isValid() )
                {
                    tile.setPicture( pic );
                    tile.setOriginalImgId( imgId );
                }
                else
                {
                    TileOverlay::Type ovType = LoaderHelper::convImgId2ovrType( imgId );
                    if( ovType == constants::objects::unknown )
                    {
                        Logger::warning( "!!! GameLoaderC3Sav: Unknown building %x at [%d,%d]", imgId, i, j );
                    }

                    baseBuildings[ tile.pos() ] = imgId;
                    pic = Picture::load( ResourceGroup::land1a, 230 + math::random( 57 ) );
                    tile.setPicture( pic );
                    tile.setOriginalImgId( imgid::fromResource( pic.name() ) );
                }

                edgeData[ i ][ j ] = edgeGrid[index];
                tile::decode( tile, terrainGrid[index] );
                tile::fixPlateauFlags( tile );
            }
        }

        for (int i = 0; i < size; ++i)
        {
            for (int j = 0; j < size; ++j)
            {
                unsigned char ed = edgeData[ i][ j ];
                if( ed == 0x00)
                {
                    int size = 1;

                    {
                        int dj;
                        try
                        {
                            // find size, 5 is maximal size for building
                            for (dj = 0; dj < 5; ++dj)
                            {
                                int edd = edgeData[ i ][ j - dj ];
                                // find bottom left corner
                                if (edd == 8 * dj + 0x40)
                                {
                                    size = dj + 1;
                                    break;
                                }
                            }
                        }
                        catch(...)
                        {
                            size = dj + 1;
                        }
                    }

                    Tile& master = oTilemap.at(i, j - size + 1);

                    //Logger::warning( "Master will be at (%d,%d)", master.i(), master.j() );
                    for (int di = 0; di < size; ++di)
                    {
                        for (int dj = 0; dj < size; ++dj)
                        {
                            oTilemap.at(master.i() + di, master.j() + dj).setMasterTile(&master);
                        }
                    }
                }

                // Check if it is building and type of building
                //if (ttile.getMasterTile() == NULL)
                std::map<TilePos, unsigned int>::iterator bbIt = baseBuildings.find( TilePos( i, j ) );
                unsigned int bbImgId = bbIt == baseBuildings.end() ? 0 : bbIt->second;

                Tile& tile = oTilemap.at( i, j );
                Tile* masterTile = tile.masterTile();
                if( !masterTile )
                    masterTile = &tile;

                if( masterTile->overlay().isNull() )
                {
                    LoaderHelper::decodeTerrain( *masterTile, oCity, bbImgId );
                }
            }
        }

    }
    catch(PKException)
    {
        THROW("fatal error when unpacking");
    }

    return true;
}
Example #23
0
void River::initTerrain(Tile& terrain)
{
  terrain.setFlag( Tile::clearAll, true );
  terrain.setFlag( Tile::tlWater, true );
}
Example #24
0
bool IOMapSerialize::loadItems(Database* db, DBResult* result, Cylinder* parent, bool depotTransfer/* = false*/)
{
	ItemMap itemMap;
	Tile* tile = NULL;
	if(!parent->getItem())
		tile = parent->getTile();


	Item* item = NULL;
	int32_t sid, pid, id, count;
	do
	{
		sid = result->getDataInt("sid");
		pid = result->getDataInt("pid");
		id = result->getDataInt("itemtype");
		count = result->getDataInt("count");

		item = NULL;
		uint64_t attrSize = 0;
		const char* attr = result->getDataStream("attributes", attrSize);

		PropStream propStream;
		propStream.init(attr, attrSize);

		const ItemType& iType = Item::items[id];
		if(iType.moveable || iType.forceSerialize || pid)
		{
			if(!(item = Item::CreateItem(id, count)))
				continue;

			if(item->unserializeAttr(propStream))
			{
				if(!pid)
				{
					parent->__internalAddThing(item);
					item->__startDecaying();
				}
			}
			else
				std::cout << "[Warning - IOMapSerialize::loadItems] Unserialization error [0] for item type " << id << std::endl;
		}
		else if(tile)
		{
			//find this type in the tile
			Item* findItem = NULL;
			for(uint32_t i = 0; i < tile->getThingCount(); ++i)
			{
				if(!(findItem = tile->__getThing(i)->getItem()))
					continue;

				if(findItem->getID() == id)
				{
					item = findItem;
					break;
				}

				if(iType.isDoor() && findItem->getDoor())
				{
					item = findItem;
					break;
				}

				if(iType.isBed() && findItem->getBed())
				{
					item = findItem;
					break;
				}
			}
		}

		if(item)
		{
			if(item->unserializeAttr(propStream))
			{
				if((item = g_game.transformItem(item, id)))
					itemMap[sid] = std::make_pair(item, pid);
			}
			else
				std::cout << "[Warning - IOMapSerialize::loadItems] Unserialization error [1] for item type " << id << std::endl;
		}
		else if((item = Item::CreateItem(id)))
		{
			item->unserializeAttr(propStream);
			if(!depotTransfer)
				std::cout << "[Warning - IOMapSerialize::loadItems] NULL item at "
				<< tile->getPosition() << " (type = " << id << ", sid = "
				<< sid << ", pid = " << pid << ")" << std::endl;
			else
				itemMap[sid] = std::make_pair(parent->getItem(), pid);

			delete item;
			item = NULL;
		}
	}
	while(result->next());

	ItemMap::iterator it;
	for(ItemMap::reverse_iterator rit = itemMap.rbegin(); rit != itemMap.rend(); ++rit)
	{
		if(!(item = rit->second.first))
			continue;

		int32_t pid = rit->second.second;
		it = itemMap.find(pid);
		if(it == itemMap.end())
			continue;

		if(Container* container = it->second.first->getContainer())
		{
			container->__internalAddThing(item);
			g_game.startDecay(item);
		}
	}

	return true;
}
Example #25
0
/**
 * Calculates the effects of the explosion.
 */
void ExplosionBState::explode()
{
	bool terrainExplosion = false;
	SavedBattleGame *save = _parent->getSave();
	// after the animation is done, the real explosion/hit takes place
	if (_item)
	{
		if (!_unit && _item->getPreviousOwner())
		{
			_unit = _item->getPreviousOwner();
		}

		BattleUnit *victim = 0;

		if (_areaOfEffect)
		{
			save->getTileEngine()->explode(_center, _power, _item->getRules()->getDamageType(), _item->getRules()->getExplosionRadius(), _unit);
		}
		else if (!_cosmetic)
		{
			ItemDamageType type = _item->getRules()->getDamageType();

			victim = save->getTileEngine()->hit(_center, _power, type, _unit);
		}
		// check if this unit turns others into zombies
		if (!_item->getRules()->getZombieUnit().empty()
			&& victim
			&& victim->getArmor()->getSize() == 1
			&& (victim->getGeoscapeSoldier() || victim->getUnitRules()->getRace() == "STR_CIVILIAN")
			&& victim->getSpawnUnit().empty())
		{
			// converts the victim to a zombie on death
			victim->setRespawn(true);
			victim->setSpawnUnit(_item->getRules()->getZombieUnit());
		}
	}
	if (_tile)
	{
		ItemDamageType DT;
		switch (_tile->getExplosiveType())
		{
		case 0:
			DT = DT_HE;
			break;
		case 5:
			DT = DT_IN;
			break;
		case 6:
			DT = DT_STUN;
			break;
		default:
			DT = DT_SMOKE;
			break;
		}
		if (DT != DT_HE)
		{
			_tile->setExplosive(0,0,true);
		}
		save->getTileEngine()->explode(_center, _power, DT, _power/10);
		terrainExplosion = true;
	}
	if (!_tile && !_item)
	{
		int radius = 6;
		// explosion not caused by terrain or an item, must be by a unit (cyberdisc)
		if (_unit && (_unit->getSpecialAbility() == SPECAB_EXPLODEONDEATH || _unit->getSpecialAbility() == SPECAB_BURN_AND_EXPLODE))
		{
			radius = _parent->getMod()->getItem(_unit->getArmor()->getCorpseGeoscape())->getExplosionRadius();
		}
		save->getTileEngine()->explode(_center, _power, DT_HE, radius);
		terrainExplosion = true;
	}

	if (!_cosmetic)
	{
		// now check for new casualties
		_parent->checkForCasualties(_item, _unit, false, terrainExplosion);
	}

	// if this explosion was caused by a unit shooting, now it's the time to put the gun down
	if (_unit && !_unit->isOut() && _lowerWeapon)
	{
		_unit->aim(false);
		_unit->setCache(0);
	}
	_parent->getMap()->cacheUnits();
	_parent->popState();

	// check for terrain explosions
	Tile *t = save->getTileEngine()->checkForTerrainExplosions();
	if (t)
	{
		Position p = Position(t->getPosition().x * 16, t->getPosition().y * 16, t->getPosition().z * 24);
		p += Position(8,8,0);
		_parent->statePushFront(new ExplosionBState(_parent, p, 0, _unit, t));
	}

	if (_item && (_item->getRules()->getBattleType() == BT_GRENADE || _item->getRules()->getBattleType() == BT_PROXIMITYGRENADE))
	{
		for (std::vector<BattleItem*>::iterator j = _parent->getSave()->getItems()->begin(); j != _parent->getSave()->getItems()->end(); ++j)
		{
			if (_item->getId() == (*j)->getId())
			{
				_parent->getSave()->removeItem(_item);
				break;
			}
		}
	}
}
Example #26
0
bool IOMapSerialize::loadItem(PropStream& propStream, Cylinder* parent, bool depotTransfer/* = false*/)
{
	Tile* tile = NULL;
	if(!parent->getItem())
		tile = parent->getTile();

	uint16_t id = 0;
	propStream.GET_USHORT(id);
	Item* item = NULL;

	const ItemType& iType = Item::items[id];
	if(iType.moveable || iType.forceSerialize || (!depotTransfer && !tile))
	{
		if(!(item = Item::CreateItem(id)))
			return true;

		if(!item->unserializeAttr(propStream))
		{
			std::cout << "[Warning - IOMapSerialize::loadItem] Unserialization error [0] for item type " << id << std::endl;
			delete item;
			return false;
		}

		if(Container* container = item->getContainer())
		{
			if(!loadContainer(propStream, container))
			{
				delete item;
				return false;
			}
		}

		if(parent)
		{
			parent->__internalAddThing(item);
			item->__startDecaying();
		}
		else
			delete item;

		return true;
	}

	if(tile)
	{
		//Stationary items
		Item* findItem = NULL;
		for(uint32_t i = 0; i < tile->getThingCount(); ++i)
		{
			if(!(findItem = tile->__getThing(i)->getItem()))
				continue;

			if(findItem->getID() == id)
			{
				item = findItem;
				break;
			}

			if(iType.isDoor() && findItem->getDoor())
			{
				item = findItem;
				break;
			}

			if(iType.isBed() && findItem->getBed())
			{
				item = findItem;
				break;
			}
		}
	}

	if(item)
	{
		if(item->unserializeAttr(propStream))
		{
			Container* container = item->getContainer();
			if(container && !loadContainer(propStream, container))
				return false;

			item = g_game.transformItem(item, id);
		}
		else
			std::cout << "[Warning - IOMapSerialize::loadItem] Unserialization error [1] for item type " << id << std::endl;

		return true;
	}

	//The map changed since the last save, just read the attributes
	if(!(item = Item::CreateItem(id)))
		return true;

	item->unserializeAttr(propStream);
	if(Container* container = item->getContainer())
	{
		if(!loadContainer(propStream, container))
		{
			delete item;
			return false;
		}

		if(depotTransfer)
		{
			for(ItemList::const_iterator it = container->getItems(); it != container->getEnd(); ++it)
				parent->__addThing(NULL, (*it));

			container->itemlist.clear();
		}
	}

	delete item;
	return true;
}
Example #27
0
 void updateSpeedMultiplier( const Tile& tile ) 
 {
   speedMultiplier = (tile.getTerrain().isRoad() || tile.getTerrain().isGarden()) ? 1.f : 0.5f;
 }
Example #28
0
Map* Parseur::doParsing()
{
	Field* fieldLayer;
	std::vector<ObjectLayers*> layersObjects;
	xml_node mapXml = doc_.child("map");
	int mapWidth = mapXml.attribute("width").as_int();
	int mapHeight = mapXml.attribute("height").as_int();
	std::string orientation(mapXml.attribute("orientation").value());
	//"Header" TMX file parsing (tileset tags)
	xml_node firstTileSetXml = mapXml.child("tileset");
	std::vector<TileSet*> ensTileSet;
	for(xml_node aTileSet = firstTileSetXml; aTileSet; aTileSet = aTileSet.next_sibling("tileset"))
	{
		//create new tileSetImage
		xml_node tilsetImageXml = aTileSet.child("image");
		TileSetImage* tsi = createTileSetImage(tilsetImageXml.attribute("source").value(), tilsetImageXml.attribute("width").as_int(), tilsetImageXml.attribute("height").as_int());
		
		//create new tileSet with given attributs.
		TileSet* ts = createTileSet(aTileSet.attribute("firstgid").as_int(), aTileSet.attribute("name").value(), aTileSet.attribute("tilewidth").as_int(), aTileSet.attribute("tileheight").as_int(), tsi);
		
		//get tile tags
		xml_node firstTileXml = aTileSet.child("tile");
		for(xml_node aTile = firstTileXml; aTile; aTile = aTile.next_sibling("tile"))
		{
			//foreach tile tags create new tile
			Tile* tile = createTile(aTile.attribute("id").as_int(), ts, ts->getNbTilePerRow());
//			std::cout << "tileId : " << aTile.attribute("id").as_int() << " :" << std::endl;
			xml_node firstTileProperty = aTile.child("properties").child("property");
			for(xml_node aProperty = firstTileProperty; aProperty; aProperty = aProperty.next_sibling("property"))
			{
				//get property tags and add it to tile object
				char* name;
				name = new char[strlen(aProperty.attribute("name").value())+1];
				strcpy(name, aProperty.attribute("name").value());
				char* value;
				value = new char[strlen(aProperty.attribute("value").value())];
				strcpy(value, aProperty.attribute("value").value());
				tile->addProperty(name, value);
//				std::cout << "\t property " << name << " = " << value << std::endl;
			}
			ts->addTile(tile);
			ensTileSet.push_back(ts);
		}
	}
	
	//parsing layers
	xml_node firstLayerXml = mapXml.child("layer");
	Field* field;
	int x;
	int y;
	for(xml_node aLayer = firstLayerXml; aLayer; aLayer = aLayer.next_sibling("layer"))
	{
//		std::cout << aLayer.attribute("name").value() << std::endl;
		ensCells cellsMap;
		xml_node firstCellXml = aLayer.child("data").child("tile");
		x = 0;
		y = 0;
		for(xml_node aCellXml = firstCellXml; aCellXml; aCellXml = aCellXml.next_sibling("tile"))
		{
			
			int gid = aCellXml.attribute("gid").as_int();
			//get Tile with the current gid
			Tile* t;
			bool get = false;
			TileSet* currentTileSet;
			std::vector<TileSet*>::iterator it = ensTileSet.begin();
			Obstacle* obstacle;
			while(it != ensTileSet.end() && !get)
			{
				t = (*it)->getTile(gid-(*it)->getFirstGid());
				currentTileSet = (*it);
				if((*t)!=Tile())
				{
					obstacle = mapFactory_->createObstacle(t, t->getTileId(), t->getPropertyValue("type"), t->getProperties());
					get = true;
//					std::cout << t->getTileId() << std::endl;
				}
				++it;
			}
			if(!get)
			{
				obstacle = new Obstacle();
			}
			
			//pour créer un obstacle il faut un TileSet, un tileId, le type (Field, object, fixed), les propriété
			//Pour récupérer les Cells du layers, il faut un Obstacle et la position de la cellule
			Cell* cell = mapFactory_->createCell(x, y, obstacle);
			
//			std::cout << *cell << std::endl;
			cellsMap.insert(std::pair< std::pair<int, int>, Cell*>(std::pair<int, int>(x,y), cell));
//			std::cout << "(" << x << ", " << y << ") : tileId = " << t->getTileId() << std::endl;
//			
////			
			x++;
			if(x >= mapWidth)
			{
				x=0;
				y++;
			}
//			//normaly, when x=mapWidth and y=mapHeight we have finished to parse this layer
		}
		
		//pour le layer, il faut la taille du layer, et un ensemble de Cell
		std::string layerName(aLayer.attribute("name").value());
		if(layerName.compare("Field")==0)
		{
			fieldLayer = mapFactory_->createField(mapWidth, mapHeight, cellsMap);
		}
		else if(layerName.compare("Object")==0)
		{
			layersObjects.push_back(mapFactory_->createObjectLayers(mapWidth, mapHeight, cellsMap));
		}
	}
	Map::MAPORIENTATION mapOrient;
	if(orientation.compare("orthogonal")==0)
	{
		mapOrient = Map::MAPORIENTATION_ORTHOGONAL;
	}
	else
	{
		mapOrient = Map::MAPORIENTATION_ORTHOGONAL;
	}
    Map* theMap = mapFactory_->createMap(new Background(), fieldLayer, mapWidth, mapHeight, mapOrient);
	
	std::vector<ObjectLayers*>::iterator itm;
	for(itm = layersObjects.begin(); itm != layersObjects.end(); ++itm)
	{
		theMap->addObjectLayers((*itm));
	}

    theMap->addTileSets(ensTileSet);
	
//	std::cout << *theMap << std::endl;
	
	return theMap;
}
Example #29
0
/**
 * Get a widget at a position in the layout.
 * @param row :: The row of the tile
 * @param col :: The column of the tile
 * @return :: A pointer to the MdiSubWindow at this position or NULL if the tile
 * is empty.
 */
MdiSubWindow *TiledWindow::getWidget(int row, int col) {
  Tile *tile = getTile(row, col);
  return tile->widget();
}
Example #30
0
void UnitWalkBState::think()
{
	bool unitspotted = false;

	// during a walking cycle we make step sounds
	if (_unit->getStatus() == STATUS_WALKING || _unit->getStatus() == STATUS_FLYING)
	{

		if (_unit->getVisible() && _unit->getStatus() == STATUS_WALKING)
		{
			// play footstep sound 1
			if (_unit->getWalkingPhase() == 3)
			{
				Tile *tile = _unit->getTile();
				if (tile->getFootstepSound())
				{
					_parent->getGame()->getResourcePack()->getSoundSet("BATTLE.CAT")->getSound(22 + (tile->getFootstepSound()*2))->play();
				}
			}
			// play footstep sound 2
			if (_unit->getWalkingPhase() == 7)
			{
				Tile *tile = _unit->getTile();
				if (tile->getFootstepSound())
				{
					_parent->getGame()->getResourcePack()->getSoundSet("BATTLE.CAT")->getSound(23 + (tile->getFootstepSound()*2))->play();
				}
			}
		}

		_unit->keepWalking(); // advances the phase

		// unit moved from one tile to the other, update the tiles
		if (_unit->getPosition() != _unit->getLastPosition())
		{
			_parent->getGame()->getSavedGame()->getBattleGame()->getTile(_unit->getLastPosition())->setUnit(0); //don't change these
			_parent->getGame()->getSavedGame()->getBattleGame()->getTile(_unit->getPosition())->setUnit(_unit); //don't change these
			// if the unit changed level, camera changes level with
			_parent->getMap()->getCamera()->setViewHeight(_unit->getPosition().z);
		}

		// is the step finished?
		if (_unit->getStatus() == STATUS_STANDING)
		{
			_terrain->calculateUnitLighting();
			unitspotted = _terrain->calculateFOV(_unit);
			if (unitspotted)
			{
				_pf->abortPath();
				if (_unit->getFaction() == FACTION_HOSTILE)
				{
					AggroBAIState *aggro = dynamic_cast<AggroBAIState*>(_unit->getCurrentAIState());
					if (aggro == 0)
					{
						_unit->setAIState(new AggroBAIState(_parent->getGame()->getSavedGame()->getBattleGame(), _unit));
					}
					_parent->handleAI(_unit);
				}
				return;
			}
			BattleAction action;
			if (_terrain->checkReactionFire(_unit, &action))
			{
				_parent->statePushBack(new ProjectileFlyBState(_parent, action));
				// unit got fired upon - stop walking
				_pf->abortPath();
				return;
			}
		}
		else
		{
			// make sure the unit sprites are up to date
			_parent->getMap()->cacheUnit(_unit);
		}
	}

	// we are just standing around, shouldn't we be walking?
	if (_unit->getStatus() == STATUS_STANDING)
	{
		if (_unit->getVisible())
		{
			setNormalWalkSpeed();
		}
		else
		{
			_parent->setStateInterval(1);
		}
		int dir = _pf->getStartDirection();
		if (dir != -1)
		{
			Position destination;
			int tu = _pf->getTUCost(_unit->getPosition(), dir, &destination, _unit); // gets tu cost, but also gets the destination position.

			if (tu > _unit->getTimeUnits() && !_parent->dontSpendTUs())
			{
				_result = "STR_NOT_ENOUGH_TIME_UNITS";
				_pf->abortPath();
				return;
			}

			if (_parent->checkReservedTU(_unit, tu) == false)
			{
				_pf->abortPath();
				return;
			}

			// we are looking in the wrong way, turn first
			// we are not using the turn state, because turning during walking costs no tu
			if (dir != _unit->getDirection() && dir < Pathfinding::DIR_UP)
			{
				_unit->lookAt(dir);
				return;
			}

			// now open doors (if any)
			int door = _terrain->unitOpensDoor(_unit);
			if (door == 3)
			{
				return; // don't start walking yet, wait for the ufo door to open
			}
			if (door == 0)
			{
				_parent->getGame()->getResourcePack()->getSoundSet("BATTLE.CAT")->getSound(3)->play(); // normal door
			}
			if (door == 1)
			{
				_parent->getGame()->getResourcePack()->getSoundSet("BATTLE.CAT")->getSound(20)->play(); // ufo door
				return; // don't start walking yet, wait for the ufo door to open
			}

			// now start moving
			dir = _pf->dequeuePath();
			if (_unit->spendTimeUnits(tu, _parent->dontSpendTUs()))
			{
				if (_unit->spendEnergy(tu, _parent->dontSpendTUs()))
				{
					_unit->startWalking(dir, destination);
				}
				else
				{
					_result = "STR_NOT_ENOUGH_ENERGY";
					_parent->popState();
				}
			}
			else
			{
				_result = "STR_NOT_ENOUGH_TIME_UNITS";
				_parent->popState();
			}
			// make sure the unit sprites are up to date
			_parent->getMap()->cacheUnit(_unit);
		}
		else
		{
			postPathProcedures();
			return;
		}
	}

	// turning during walking costs no tu
	if (_unit->getStatus() == STATUS_TURNING)
	{
		_unit->turn();
		unitspotted = _terrain->calculateFOV(_unit);
		// make sure the unit sprites are up to date
		_parent->getMap()->cacheUnit(_unit);
		if (unitspotted)
		{
			_pf->abortPath();
			return;
		}
	}
}