VisualObjectModel *VisualObjectModelStorage::getVisualObjectModel(const char *filename)
	{
		// TODO: optimize? is it necessary?
		LinkedListIterator iter = LinkedListIterator(models);
		while (iter.iterateAvailable())
		{
			VisualObjectModel *vom = (VisualObjectModel *)iter.iterateNext();
			if (filename == NULL && vom->getFilename() == NULL)
				return vom;
			if (vom->getFilename() != NULL && filename != NULL 
				&& strcmp(vom->getFilename(), filename) == 0)
				return vom;				
		}
		VisualObjectModel *newvom = new VisualObjectModel(filename);
		models->append(newvom);
		return newvom;
	}
示例#2
0
	bool ReconChecker::isReconAvailableAtPosition(Game *game, int player, const VC3 &position)
	{
		LinkedList *ulist = game->units->getAllUnits();
		LinkedListIterator iter = LinkedListIterator(ulist);

		while (iter.iterateAvailable())		
		{
			Unit *u = (Unit *)iter.iterateNext();
			
			// unit is friendly towards player?
			// (but player does not need to be friendly towards the unit ;)
			if (u->isActive() && !u->isDestroyed()				
				&& !game->isHostile(u->getOwner(), player)
				&& u->getReconValue() > 0
				&& u->getMoveState() != Unit::UNIT_MOVE_STATE_UNCONSCIOUS)
			{
				VC3 rayStartPosition = u->getPosition() + VC3(0, 2.0f, 0);
				VC3 target = position;
				float terrainHeight = game->gameMap->getScaledHeightAt(target.x, target.z);
				if (target.y < terrainHeight + 2.0f) target.y = terrainHeight + 2.0f;
				VC3 dir = target - rayStartPosition;
				float dirLen = dir.GetLength();
				dir.Normalize();

				if (dirLen > u->getUnitType()->getVisionRange() + 2.0f)
				{
					continue;
				}

				// TEMP!
				// ignore all small own units (1.5m)...
				// except the one we're trying to hit
				LinkedList *oul = game->units->getOwnedUnits(u->getOwner());
				LinkedListIterator iter = LinkedListIterator(oul);
				while (iter.iterateAvailable())
				{
					Unit *ou = (Unit *)iter.iterateNext();
					if (ou != u && ou->getUnitType()->getSize() <= 1.5f)
						ou->getVisualObject()->setCollidable(false);
				}

				// disable collision check for this unit
				u->getVisualObject()->setCollidable(false);

				GameCollisionInfo cinfo;
				game->getGameScene()->rayTrace(rayStartPosition, dir, (float)dirLen, cinfo, false, true);

				// collision check back
				u->getVisualObject()->setCollidable(true);				

				// TEMP!
				// restore them all...
				oul = game->units->getOwnedUnits(u->getOwner());
				iter = LinkedListIterator(oul);
				while (iter.iterateAvailable())
				{
					Unit *ou = (Unit *)iter.iterateNext();
					if (ou != u && ou->getUnitType()->getSize() <= 1.5f)
						ou->getVisualObject()->setCollidable(true);
				}

				if (cinfo.hit)
				{
					// 4 meters max dist.
					if (cinfo.range >= dirLen - 4.0f)
					{
						return true;
					}
				} else {
					return true;
				}
			}
		}
		return false;
	}
示例#3
0
  void SelectionBox::doBoxSelection(SelectionBox::BoxSelectionType type)
//		                                VC2& a, VC2& b, VC2& c, VC2& d) 
	{
    //int now = Timer::getTime();
		IStorm3D_Scene *scene = game->getGameScene()->getStormScene();
		IStorm3D_Camera *cam = scene->GetCamera();

		float minX;
		float maxX;
		float minY;
		float maxY;
		if (boxStartX < currentX)
		{
			minX = (float)boxStartX;
			maxX = (float)currentX;
		} else {
			minX = (float)currentX;
			maxX = (float)boxStartX;
		}
		if (boxStartY < currentY)
		{
			minY = (float)boxStartY;
			maxY = (float)currentY;
		} else {
			minY = (float)currentY;
			maxY = (float)boxStartY;
		}
		minX /= 1024.0f;
		maxX /= 1024.0f;
		minY /= 768.0f;
		maxY /= 768.0f;

    LinkedListIterator iter = LinkedListIterator(
      game->units->getOwnedUnits(player));

		switch(type) {
		case SelectionBox::BOX_SELECT:

			//unitsSelected=0;
 			//for (i = 0; i < COMBATW_UNITS; i++) {
			//	Unit *u = solveUnitForNumber(i);

      game->unitSelections[player]->selectAllUnits(false);

      while (iter.iterateAvailable())
      {
        Unit *u = (Unit *)iter.iterateNext();

				VC3 position=u->getPosition();

				if(!u->isDestroyed() && u->isActive()) 
				{
					//bool isInside1=util::isPointInsideTriangle(VC2(position.x,position.z),a,b,c);
					//bool isInside2=util::isPointInsideTriangle(VC2(position.x,position.z),b,c,d);
					//if( isInside1 || isInside2 ) {

					bool unitInsideBox = false;
					VC3 result = VC3(0,0,0);
					float rhw = 0;
					float real_z = 0;
					bool infront = cam->GetTransformedToScreen(position, result, rhw, real_z);
					if (infront)
					{
						if (result.x >= minX && result.x <= maxX
							&& result.y >= minY && result.y <= maxY
							&& real_z < 200)
						{
							unitInsideBox = true;
						}
					}

					if (unitInsideBox)
					{
            game->unitSelections[player]->selectUnit(u, true);
            //u->setSelected(true);
						//unitButs[i]->SetImage(unitBackSelectedImage);
						//unitsSelected++;
						//unitSelectTime[i]=now;
					//} else { // Outside
            //game->unitSelections[player]->selectUnit(u, false);
						//u->setSelected(false);
						//unitButs[i]->SetImage(unitBackImage);
					}
				}
			}
			break;

		case SelectionBox::BOX_ADD_SELECTION:
      while (iter.iterateAvailable())
      {
        Unit *u = (Unit *)iter.iterateNext();
 			//for (i = 0; i < COMBATW_UNITS; i++) {
			//	Unit *u = solveUnitForNumber(i);
				VC3 position=u->getPosition();

				bool unitInsideBox = false;
				VC3 result = VC3(0,0,0);
				float rhw = 0;
				float real_z = 0;
				bool infront = cam->GetTransformedToScreen(position, result, rhw, real_z);
				if (infront)
				{
					if (result.x >= minX && result.x <= maxX
						&& result.y >= minY && result.y <= maxY
						&& real_z < 200)
					{
						unitInsideBox = true;
					}
				}

				if(!u->isSelected() && !u->isDestroyed() && u->isActive()) 
				{
					//bool isInside1=util::isPointInsideTriangle(VC2(position.x,position.z),a,b,c);
					//bool isInside2=util::isPointInsideTriangle(VC2(position.x,position.z),b,c,d);
					//if( isInside1 || isInside2 ) {
					if (unitInsideBox)
					{
            game->unitSelections[player]->selectUnit(u, true);
						//u->setSelected(true);
						//unitButs[i]->SetImage(unitBackSelectedImage);
						//unitsSelected++;
						//unitSelectTime[i]=now;
					} 
				}
			}
			break;

		case SelectionBox::BOX_SUB_SELECTION:
			// TODO: do we need this?
			break;
		default:
			/* euh, shouldn't happen */
      // thus, assert ;)
      assert(0);
			break;
		}
	}
示例#4
0
  void CommandWindow::startMission()
  {
    // WARNING: COPY & PASTE PROGRAMMING AHEAD (SEE Game.cpp)

    bool noArmor = false;
    bool notPaid = false;
    bool incompleteArmor = false;
    bool notAnyArmor = true;
    LinkedList *ulist = game->units->getOwnedUnits(player);
    LinkedListIterator iter = LinkedListIterator(ulist);
    while (iter.iterateAvailable())
    {
      Unit *u = (Unit *)iter.iterateNext();
      if (u->getRootPart() == NULL && u->getCharacter() != NULL)
      {
        noArmor = true;
      } else {
        bool wasOk = true;
        if (u->getCharacter() == NULL)
        {
          wasOk = false;
        } else {
          if (game->calculatePurchasePrice(u->getRootPart()) > 0)
          {
            notPaid = true;
            wasOk = false;
          }
          int slotAmount = u->getRootPart()->getType()->getSlotAmount();
          for (int i = 0; i < slotAmount; i++) 
          {
            if (u->getRootPart()->getSubPart(i) == NULL)
            {
              if (
                u->getRootPart()->getType()->getSlotType(i)->getPartTypeId() 
                == PARTTYPE_ID_STRING_TO_INT("Head")
                || u->getRootPart()->getType()->getSlotType(i)->getPartTypeId() 
                == PARTTYPE_ID_STRING_TO_INT("Arm")
                || u->getRootPart()->getType()->getSlotType(i)->getPartTypeId() 
                == PARTTYPE_ID_STRING_TO_INT("Leg")
                || u->getRootPart()->getType()->getSlotType(i)->getPartTypeId() 
                == PARTTYPE_ID_STRING_TO_INT("Reac")
                )
              {
                incompleteArmor = true;
                wasOk = false;
              }
            }
          }
        }
        if (wasOk) 
        {
          // at least one armor is complete and purchased!
          notAnyArmor = false;
        }
      }
    }
    if (noArmor || notPaid || incompleteArmor || notAnyArmor)
    {
      game->gameUI->openArmorIncompleteConfirm(player, notAnyArmor,
        incompleteArmor, noArmor, notPaid); 
    } else {
      // TODO: open loading window for players on this client in netgame...
      game->gameUI->openLoadingWindow(game->singlePlayerNumber); 
      hide();
    }
	}
  void CombatRadar::update()
  {
		if (game->isPaused())
			return;

    int oldAmount = radarUnitsAmount;
    radarUnitsAmount = 0;

		LinkedList *ulist;

		if (SimpleOptions::getBool(DH_OPT_B_GUI_RADAR_SHOW_ALL))
		{
			ulist = game->units->getAllUnits();
		} else {
			ulist = game->units->getOwnedUnits(1);
		}

    LinkedListIterator iter = LinkedListIterator(ulist);

    while (iter.iterateAvailable())
    {
      Unit *u = (Unit *)iter.iterateNext();
      if (u->isActive() && !u->isDestroyed()
        && u->visibility.isInRadarByPlayer(player)
//        && u->visibility.isSeenByPlayer(player)
        && u->getUnitType()->getSize() >= RADAR_MIN_SIZE)
      {
        VC3 pos = u->getPosition();
        pos.x -= radarX;
        pos.z -= radarY;
        float distSq = pos.x * pos.x + pos.z * pos.z;
        if (distSq < RADAR_RANGE * RADAR_RANGE)
        {
          float dist = sqrtf(distSq);
          radarUnitDist[radarUnitsAmount] = dist * (RADAR_SIZE/2-RADAR_EDGE) / RADAR_RANGE;
					float angle;
					if (dist == 0)
						angle = 0;
					else
            angle = (float)acos(pos.x / dist);
          if (pos.z < 0) angle = -angle;
          radarUnitAngle[radarUnitsAmount] = angle;
          radarUnits[radarUnitsAmount] = u;

          OguiButton *b;
          if (radarUnitButs[radarUnitsAmount] == NULL)
          {
            b = ogui->CreateSimpleImageButton(win, 
              RADAR_SIZE/2-5, RADAR_SIZE/2-5, 9, 9, 
              NULL, NULL, NULL, COMBATW_RADARUNIT_START + radarUnitsAmount);
#ifdef PROJECT_SURVIVOR
						OguiAligner::align(b, OguiAligner::WIDESCREEN_FIX_RIGHT, ogui);
#endif
            radarUnitButs[radarUnitsAmount] = b;
          } else {
            b = radarUnitButs[radarUnitsAmount];
          }
          b->SetListener(this);
          b->SetReactMask(0);
          b->SetEventMask(OGUI_EMASK_CLICK);
					b->SetDisabled(true);
          if (game->isHostile(player, u->getOwner()))
          {
            if (u->getUnitType()->getSize() >= RADAR_BIG_SIZE)
            {
              b->SetDisabledImage(hostile2Image);
              radarUnitType[radarUnitsAmount] = RADAR_UNITTYPE_HOSTILE_BIG;
            } else {
              b->SetDisabledImage(hostile1Image);
              radarUnitType[radarUnitsAmount] = RADAR_UNITTYPE_HOSTILE_SMALL;
            }
          } else {
						if (u->getOwner() == player)
						{
							b->SetDisabledImage(NULL);
							radarUnitType[radarUnitsAmount] = RADAR_UNITTYPE_FRIENDLY_SMALL;
						} else {
							if (u->getUnitType()->getSize() >= RADAR_BIG_SIZE)
							{
								b->SetDisabledImage(friendly2Image);
								radarUnitType[radarUnitsAmount] = RADAR_UNITTYPE_FRIENDLY_BIG;
							} else {
								b->SetDisabledImage(friendly1Image);
								radarUnitType[radarUnitsAmount] = RADAR_UNITTYPE_FRIENDLY_SMALL;
							}
						}
          }

          radarUnitsAmount++;
          if (radarUnitsAmount >= COMBAT_RADAR_MAX_UNITS) break;
        }
      }
    }

    for (int i = radarUnitsAmount; i < oldAmount; i++)
    {
      delete radarUnitButs[i];
      radarUnitButs[i] = NULL;
    }

		if (radarScanBut != NULL)
		{
			int gt = (game->gameTimer % RADAR_SWEEP_TICK_INTERVAL);
			float ratio = (float)gt / RADAR_SWEEP_TICK_DURATION;

			if (ratio > 1.0f) ratio = 1.0f;
			int perc = (int)(ratio * 100.0f);

			int curSweep = game->gameTimer / RADAR_SWEEP_TICK_INTERVAL;
			if (curSweep > radarSweepNumber
				|| curSweep < radarSweepNumber - 5)
			{
				radarSweepNumber = curSweep;
				radarBeeped = false;

				if (win->IsVisible())
				{
#ifdef LEGACY_FILES
#ifndef PROJECT_SURVIVOR
					game->gameUI->playGUISound("Data/Sounds/Defaultfx/Radar/radar_sweep.wav");
#endif
#else
					game->gameUI->playGUISound("data/audio/sound/gui/hud/radar/radar_sweep.wav");
#endif
				}
			}

			int x = 1024 - (int)(RADAR_SIZE * (0.5f + ratio * 0.5f));
			int y = (int)(RADAR_SIZE * (0.5f - ratio * 0.5f));
			int sizeX = (int)(RADAR_SIZE * ratio);
			int sizeY = (int)(RADAR_SIZE * ratio);
			radarScanBut->Move(x, y);
			radarScanBut->Resize(sizeX, sizeY);
			radarScanBut->SetTransparency(perc);
#ifdef PROJECT_SURVIVOR
			OguiAligner::align(radarScanBut, OguiAligner::WIDESCREEN_FIX_RIGHT, ogui);
#endif
		}

    drawImpl();

		updateDirectionPointer();
  }