Exemple #1
0
DefenceArea::DefenceArea(bool team) :team(team)
{
    if(team == OUR_TEAM)    // Initialize our defence area
    {
        r = Rectangle(-HALF_FIELD_LENGTH,
                        -DEF_AREA_OFFSET,
                        -HALF_FIELD_LENGTH + DEF_AREA_RADIUS,
                        DEF_AREA_OFFSET);

        s1 = Sector(Point(-HALF_FIELD_LENGTH, DEF_AREA_OFFSET),
                            DEF_AREA_RADIUS,
                            0, M_PI_2);

        s2 = Sector(Point(-HALF_FIELD_LENGTH, -DEF_AREA_OFFSET),
                            DEF_AREA_RADIUS,
                            -M_PI_2, 0);
    }
    else    // initialize opponent defence area
    {
        r = Rectangle(HALF_FIELD_LENGTH,
                        -DEF_AREA_OFFSET,
                        HALF_FIELD_LENGTH - DEF_AREA_RADIUS,
                        DEF_AREA_OFFSET);

        s1 = Sector(Point(HALF_FIELD_LENGTH, DEF_AREA_OFFSET),
                            DEF_AREA_RADIUS,
                            M_PI_2, M_PI);

        s2 = Sector(Point(HALF_FIELD_LENGTH, -DEF_AREA_OFFSET),
                            DEF_AREA_RADIUS,
                            -M_PI, -M_PI_2);
    }
}
Exemple #2
0
bool CIRect::Intersect(const CIPoint& C, const CIPoint& D)  // line intersection
{
  if (Sector((int)A.x, (int)A.y)&Sector((int)B.x, (int)B.y)) return false;
  CXPoint X;
  if (LineIntersection(C,D, CIPoint(A.x, DBL_MIN), CIPoint(A.x, DBL_MAX), &X)) return true;
  if (LineIntersection(C,D, CIPoint(B.x, DBL_MIN), CIPoint(B.x, DBL_MAX), &X)) return true;
  if (LineIntersection(C,D, CIPoint(DBL_MIN, A.y), CIPoint(DBL_MAX, A.y), &X)) return true;
  if (LineIntersection(C,D, CIPoint(DBL_MIN, B.y), CIPoint(DBL_MAX, B.y), &X)) return true;
  return false;
}
Exemple #3
0
void do_meta_infect(int who, planettype *p)
{
    int owner, x, y;

    getsmap(Smap, p);
    PermuteSects(p);
    bzero((char *)Sectinfo, sizeof(Sectinfo));
    x = int_rand(0, p->Maxx-1);
    y = int_rand(0, p->Maxy-1);
    owner = Sector(*p, x, y).owner;
    if(!owner || (who!=owner && (double)int_rand(1,100) >
                  100.0*(1.0-exp(-((double)(Sector(*p,x,y).troops*
                                            races[owner-1]->fighters/50.0)))))) {
        p->info[who-1].explored = 1;
        p->info[who-1].numsectsowned += 1;
        Sector(*p, x, y).troops = 0;
        Sector(*p, x, y).popn = races[who-1]->number_sexes;
        Sector(*p, x, y).owner = who;
        Sector(*p, x, y).condition = Sector(*p, x, y).type;
#ifdef POD_TERRAFORM
        Sector(*p, x, y).condition = races[who-1]->likesbest;
#endif
        putsmap(Smap, p);
    }
}
Exemple #4
0
void CStarmap::SetFullRangeMap(int nRange/* = SM_RANGE_NEAR*/, const std::vector<Sector>& vExceptions/* = std::vector<Sector>()*/)
{
	for (int x = 0; x < STARMAP_SECTORS_HCOUNT; x++)
		for (int y = 0; y < STARMAP_SECTORS_VCOUNT; y++)
			if (vExceptions.empty() || std::find(vExceptions.begin(), vExceptions.end(), Sector(x, y)) == vExceptions.end())
				m_Range.at(CoordsToIndex(x, y)) = nRange;
}
Exemple #5
0
void CStarmap::AddBase(const Sector &sector, BYTE propTech)
{
	AssertBotE(sector.on_map());

	// merken, dass Sektor einen Außenposten besitzt; falls der Außenposten schon vorhanden ist, die folgende
	// Berechnung trotzdem durchführen, da eine andere <code>rangeMap</code> vorgegeben sein könnte.
	if (!IsBase(sector)) m_lBases.push_back(sector);

	// --- Map mit Entfernungen aktualisieren ---
	this->CalcRangeMap(propTech);

	// lokale Rangemap durchlaufen
	for (char x = -m_RangeMap.x0; x < m_RangeMap.w - m_RangeMap.x0; x++)
		for (char y = -m_RangeMap.y0; y < m_RangeMap.h - m_RangeMap.y0; y++)
		{
			Sector pt(sector.x + x, sector.y + y);
			if (pt.is_in_rect(0, 0, STARMAP_SECTORS_HCOUNT, STARMAP_SECTORS_VCOUNT))
			{
				// Wert überschreiben, wenn der neue Einfluss größer ist
				m_Range.at(CoordsToIndex(pt.x, pt.y)) = max(m_Range.at(CoordsToIndex(pt.x, pt.y)), GetRangeMapValue(x, y));
			}
		}

	// pathStart zurücksetzen, damit sämtliche Wege beim nächsten Aufruf von
	// CalcPath() neu berechnet werden
	pathStart = Sector();

#ifdef DEBUG_AI_BASE_DEMO
	// ACHTUNG: verwenden i. A. falsche RangeMap!
	RecalcRangePoints();
	RecalcConnectionPoints();
	RecalcTargetPoints();
#endif
}
Exemple #6
0
Tile* Tile::createSubTile(const Angle& lowerLat, const Angle& lowerLon,
                          const Angle& upperLat, const Angle& upperLon,
                          const int level,
                          const int row, const int column,
                          bool setParent) {
  Tile* parent = setParent ? this : NULL;
  return new Tile(_texturizer,
                  parent,
                  Sector(Geodetic2D(lowerLat, lowerLon), Geodetic2D(upperLat, upperLon)),
                  level,
                  row, column);
}
Exemple #7
0
//=============================================================================
//	eFdd::GetSector
//-----------------------------------------------------------------------------
eUdi::eTrack::eSector* eFdd::GetSector(int cyl, int side, int sec)
{
	Seek(cyl, side);
	for(int i = 0; i < Track().sectors_amount; ++i)
	{
		eUdi::eTrack::eSector& s = Sector(i);
		if(s.Sec() == sec && s.Len() == 256)
		{
			return &s;
		}
	}
	return NULL;
}
Exemple #8
0
/**
 * Erase the flash memory starting at the desired address for a block of bytes.  NOTE: The address range is
 * translated to device sector numbers.  Therefore the operational range may be larger than specified.
 * 
 * @param destAddress starting address to erase
 * @param length number of bytes to erase
 * 
 * @return IAP Status code
 */
IAP::StatusCode IAP::Erase (uint32_t destAddress, uint32_t length)
{
    StatusCode statusCode;
    uint32_t irqState, command[5], result[2];
    
    // 
    command[0] = 52;
    command[1] = Sector(destAddress);
    command[2] = Sector(destAddress + length);
    command[3] = SystemControl::GetInstance()->GetPClock() / 1000;
    
    if ((statusCode = PrepareSector(command[1], command[2])) != CmdSuccess)
        return statusCode;    
    
    // We have to disable interrupts because flash memory will not be available to execute out of.
    irqState = disableIRQ();
    
    iap (command, result);
    
    restoreIRQ (irqState);
    
    return static_cast <StatusCode> (result[0]);
}
Exemple #9
0
/**
 * Write the flash memory starting at the desired address for a block of bytes.  NOTE: The length
 * must be 256, 512, 1024, or 4096 bytes.  The data pointer must be on a WORD boundary.
 * 
 * @param destAddress flash memory address
 * @param length number of bytes to write
 * @param data pointer to data block
 * 
 * @return IAP Status code
 */
IAP::StatusCode IAP::Write (uint32_t destAddress, uint32_t length, void *data)
{
    StatusCode statusCode;
    uint32_t irqState, command[5], result[2];
    
    if ((statusCode = PrepareSector(Sector(destAddress), Sector(destAddress + length))) != CmdSuccess)
        return statusCode;
    
    command[0] = 51;
    command[1] = destAddress;
    command[2] = reinterpret_cast <uint32_t> (data);
    command[3] = length;
    command[4] = SystemControl::GetInstance()->GetPClock() / 1000;
    
    // We have to disable interrupts because flash memory will not be available to execute out of.
    irqState = disableIRQ();
    
    iap (command, result);
    
    restoreIRQ (irqState);
    
    return static_cast <StatusCode> (result[0]);
}
Exemple #10
0
bool CXRect::Intersect(const CXRect& R) // rect intersection
{
  if (Sector(R.A.x, R.A.y)&Sector(R.B.x, R.B.y)) return false;
  return true;
}
Exemple #11
0
BaseSector CStarmap::CalcAIBaseSector(double variance)
{
	AssertBotE(m_bAICalculation);
	AssertBotE(0. <= variance && variance <= 1.);

	if (!m_bAICalculation) return BaseSector();
	variance = min(max(variance, 0.), 1.);

	// Bewertung der Sektoren neu berechnen
	RecalcRangePoints();
	RecalcConnectionPoints();
	RecalcTargetPoints();

	// Sektoren innerhalb der Reichweite mit Gebietszuwachs + zusätzlicher Bewertung in Liste aufnehmen
	std::list<BaseSector> lSectors;
	for (int x = 0; x < STARMAP_SECTORS_HCOUNT; x++)
		for (int y = 0; y < STARMAP_SECTORS_VCOUNT; y++)
			if (m_Range.at(CoordsToIndex(x, y)) >= m_nAIRange)
			{
				BaseSector sector;
				sector.position = Sector(x, y);
				sector.points = GetPoints(sector.position);
				lSectors.push_back(sector);
			}

	// abbrechen, wenn kein Sektor innerhalb der Reichweite existiert
	if (lSectors.empty()) return BaseSector();

	// nach Gesamtbewertung sortieren
	lSectors.sort();

	// die Bewertungsstufen bestimmen, die innerhalb der besten (100 * variance)% liegen
	int count = 0;
	short max_points = -1, old_points = -1;

	for (std::list<BaseSector>::const_iterator it = lSectors.begin(); it != lSectors.end(); ++it)
	{
		if (max_points == -1) max_points = it->points;
		if ((double)(max_points - it->points) / max_points > variance)
			break;
		if (it->points != old_points)
		{
			old_points = it->points;
			count += it->points;
		}
	}

	// eine der Stufen zufällig bestimmen, höhere Stufen mit höherer Wahrscheinlichkeit wählen
	int n = (int)(((double)rand() / RAND_MAX) * count);

	old_points = -1;
	for (std::list<BaseSector>::const_iterator it = lSectors.begin(); it != lSectors.end(); ++it)
	{
		if (it->points != old_points)
		{
			old_points = it->points;
			n -= it->points;
			if (n < 0)
			{
				n = it->points;
				break;
			}
		}
	}

	// Einträge der gewählten Stufe zählen
	count = 0;
	for (std::list<BaseSector>::const_iterator it = lSectors.begin(); it != lSectors.end(); ++it)
	{
		if (it->points == n)
			count++;
		else if (it->points < n)
			break;
	}

	// einen der Einträge gleichwahrscheinlich wählen
	int m = (int)(((double)rand() / RAND_MAX) * count);
	for (std::list<BaseSector>::const_iterator it = lSectors.begin(); it != lSectors.end(); ++it)
	{
		if (it->points == n)
		{
			if (!m--) return *it;
		}
		else if (it->points < n)
			break;
	}

	// bei sonstigen Fehlern
	return BaseSector();
}
Exemple #12
0
Sector CStarmap::CalcPath(const Sector &pos, const Sector &target, unsigned char range,
	unsigned char speed, CArray<Sector> &path)
{
	AssertBotE(pos.on_map());
	AssertBotE(target.on_map());

	// bisherige Einträge von path löschen
	path.RemoveAll();

	// gegebene Parameter prüfen
	if (pos == target								// Start == Ziel
		|| range < 1 || range > 3
		|| m_Range.at(CoordsToIndex(pos.x, pos.y)) < range			// Start außerhalb des Gebiets der Reichweite
		|| m_Range.at(CoordsToIndex(target.x, target.y)) < range		// Ziel außerhalb der Reichweite
		|| speed < 1)
	{
		return Sector();
	}

	// Array zur Berechnung der Koordinaten sämtlicher Nachbarn eines Sektors (schräg/gerade abwechselnd,
	// mit schräg beginnend)
	Sector neighbours[8] = {Sector(-1, -1), Sector(0, -1), Sector(1, -1), Sector(1, 0), Sector(1, 1),
		Sector(0, 1), Sector(-1, 1), Sector(-1, 0)};

	// Berechnung neu beginnen?
	if (pos != pathStart || range != pathRange)
	{
		// pathMap zurücksetzen
		for (int j = 0; j < STARMAP_SECTORS_VCOUNT; j++)
			for (int i = 0; i < STARMAP_SECTORS_HCOUNT; i++)
			{
				/*PathSector *tmp = &(pathMap.at(CoordsToIndex(i, j)));
				tmp->used = false;
				tmp->distance = 0.;
				tmp->hops = 0;
				tmp->parent.x = tmp->parent.y = -1;

				tmp->position.x = i; // für Zugriff aus leafList heraus merken
				tmp->position.y = j;*/
				const int index = CoordsToIndex(i, j);
				pathMap.at(index).used=false;
				pathMap.at(index).distance=0;
				pathMap.at(index).hops=0;
				pathMap.at(index).parent.x=-1;
				pathMap.at(index).parent.y=-1;
				pathMap.at(index).position.x=i;
				pathMap.at(index).position.y=j;
			}

		// leaves zurücksetzen
		leaves.Clear();

		// Startknoten zur Liste der auszuwählenden Blätter hinzufügen
		leaves.Add(&(pathMap.at(CoordsToIndex(pos.x, pos.y))));

		// Parameter merken
		pathStart = pos;
		pathRange = range;
	}

	// ist der Weg zum angegebenen Ziel bereits bekannt?
	if (pathMap.at(CoordsToIndex(target.x, target.y)).parent.x == -1 || pathMap.at(CoordsToIndex(target.x, target.y)).parent.y == -1)
	{
		// kürzeste Wege zu allen anderen Knoten bestimmen, bis uns der Zielknoten über den Weg läuft
		bool found = false;
		while (!found)
		{
			// Zeiger auf ein neues Blatt mit einer kürzesten Gesamtentfernung zum
			// Start-Sektor ermitteln
			PathSector *next = leaves.PopFirst();
			if (!next) return Sector(); // keine Knoten mehr, Zielknoten ist nicht erreichbar
			if (next->used) continue; // Knoten wurde schonmal gewählt

			// Knoten als ausgewählt markieren
			next->used = true;

			// bisher noch nicht ausgewählte Nachbarn innerhalb der Reichweite in leaves
			// eintragen;
			// die Nachbarn müssen auch eingetragen werden, wenn next bereits der Zielknoten ist,
			// da der nächste Aufruf von CalcPath() die Zwischenergebnisse wiederverwendet
			for (int i = 0; i < 8; i++)
			{
				// Koordinaten des Nachbarn ermitteln (Sektoren nur betrachten, wenn sie
				// noch auf der Starmap liegen!)
				Sector npos = next->position + neighbours[i];
				if (!npos.is_in_rect(0, 0, STARMAP_SECTORS_HCOUNT, STARMAP_SECTORS_VCOUNT))
					continue;

				// nur Nachbarn betrachten, die noch nicht ausgewählt wurden und innerhalb der
				// Reichweite liegen
				PathSector *neighb = &(pathMap.at(CoordsToIndex(npos.x, npos.y)));
				if (neighb->used || m_Range.at(CoordsToIndex(npos.x, npos.y)) < range)
					continue;

				// kann der Nachbar über next auf einem kürzeren Weg als bisher erreicht werden,
				// dann die bisherige Info überschreiben
				double distance = next->distance + ((i % 2) ? WEIGHT_DIR : WEIGHT_DIAG);
				// Anomalien beachten
				distance += m_BadMapModifiers.at(next->position.x + next->position.y * STARMAP_SECTORS_HCOUNT);

				if (neighb->distance == 0. || distance < neighb->distance)
				{
					// (distance ist für alle anderen Sektoren außer dem Start-Sektor > 0.,
					// der Wert 0. weist darauf hin, dass distance noch nicht gesetzt wurde)

					neighb->distance = distance;
					neighb->hops = next->hops + 1;
					neighb->parent = next->position;

					// den Knoten in leaves neu einsortieren (derselbe Knoten ist evtl. unter
					// einer anderen Entfernung früher bereits einsortiert worden; da nun die
					// Entfernung aber kürzer ist, wird das neu einsortierte Element zuerst
					// gewählt; liefert die Liste eines der vorher eingeordneten Elemente, ist
					// dessen used-Feld bereits true und es wird sofort mit dem nächsten Eintrag
					// fortgesetzt);
					// @TODO besser wäre es, den früher einsortierten Knoten zu entfernen
					leaves.Add(neighb);
				}
			}

			if (next->position == target) found = true; // Zielknoten gefunden
		}
	}

	// Ziel gefunden; Weg vom Ziel bis zum Startknoten zurück verfolgen,
	// dabei von hinten beginnend in Array eintragen
	Sector next = target;
	int idx = pathMap.at(CoordsToIndex(target.x, target.y)).hops;
	AssertBotE(idx >= 1);

	path.SetSize(idx); // Größe des Arrays setzen (= Länge des Weges)

	while (next.x > -1 && next.y > -1 && --idx >= 0) // Start-Sektor nicht mit eintragen
	{
		AssertBotE(next.on_map());
		path[idx] = next;
		next = pathMap.at(CoordsToIndex(next.x, next.y)).parent;
	}
	AssertBotE(idx == -1);

	// entsprechend speed den nächsten Knoten des Weges zurückgeben; bzw. den Zielknoten,
	// wenn der Weg kürzer ist
	return path[min(speed - 1, path.GetUpperBound())];
}
Exemple #13
0
void do_meta_infect(int who, planettype *p)
{
    int owner;
    int x;
    int y;
    double military;
    int converted_civilians;
    int unconverted_civilians;

    getsmap(Smap, p);
    PermuteSects(p);
    memset((char *)Sectinfo, 0, sizeof(Sectinfo));
    x = int_rand(0, p->Maxx - 1);
    y = int_rand(0, p->Maxy - 1);
    owner = Sector(*p, x, y).owner;

    /*
     * HUTm Kharush converting existing civilians are back! Constants are in
     * hdrs/tweakables.h
     */
    if (!owner) {
        p->info[who - 1].explored = 1;
        p->info[who - 1].numsectsowned += 1;
        Sector(*p, x, y).popn = races[who - 1]->number_sexes;
        Sector(*p, x, y).owner = who;
        Sector(*p, x, y).condition = sector(*p, x, y).type;

#ifdef POD_TERRAFORM
        Sector(*p, x, y).condition = races[who - 1]->likesbest;
#endif

        putsmap(Smap, p);
    } else if (who != owner) {
        military = (double)Sector(*p, x, y).troops;

        converted_civilians = races[who - 1]->number_sexes + ((int)((double)Sector(*p, x, y).popn) * ABSORB_RATE * pow((MILITARY_PROPORTION * military) / ((MILITARY_PROPORTION * military) + (double)Sector(*p, x, y).popn), MILITARY_WEIGHT));

        unconverted_civilians = Sector(*p, x, y).popn - converted_civilians + races[who - 1]->number_sexes;

        if ((military * (double)races[owner - 1]->fighters * 10.0) >= ((double)converted_civilians * (double)races[who - 1]->fighters)) {
            /* Military wins */
            military -= (((double)converted_civilians * (double)races[who - 1]->fighters) / ((double)races[owner - 1]->fighters * 10.0));

            if (military < 1.0) {
                military = 0.0;
            }

            Sector(*p, x, y).troops = (int)military;
            Sector(*p, x, y).popn = unconverted_civilians;

            /* No survivors */
            if (!military && !unconverted_civilians) {
                Sector(*p, x, y).owner = 0;

                if (p->info[owner - 1].numsectsowned) {
                    p->info[owner - 1].numsectsowned -= 1;
                }
            }

            putsmap(Smap, p);
        } else {
            /* Podder wins */
            converted_civilians -= (int)((military * (double)races[owner - 1]->fighters * 10.0) / (double)races[who - 1]->fighters);

            if (converted_civilians < 1) {
                converted_civilians = 0;
            }

            Sector(*p, x, y).troops = 0;
            Sector(*p, x, y).popn = converted_civilians;

            if (p->info[owner - 1].numsectsowned) {
                p->info[owner - 1].numsectsowned -= 1;
            }

            /* No survivors */
            if (!converted_civilians) {
                Sector(*p, x, y).owner = 0;
            } else {
                p->info[who - 1].explored = 1;
                p->info[who - 1].numsectsowned += 1;
                Sector(*p, x, y).owner = who;
                Sector(*p, x, y).condition = Sector(*p, x, y).type;

#ifdef POD_TERRAFORM
                Sector(*p, x, y).condition = races[who - 1]->likesbest;

#endif
            }

            putsmap(Smap, p);
        }
    }

    /*
     * Old code starts
     *
     *     if (!owner
     *         || ((who != owner)
     *             && ((double)int_rand(1, 100) > (100.0 * (1.0 - exp(-(double)((Sector(*p, x, y).troops * races[owner - 1]->fighters) / 50.0))))))) {
     *         p->info[who - 1].explored = 1;
     *         p->info[who - 1].numsectsowned += 1;
     *         Sector(*p, x, y).troops = 0;
     *         Sector(*p, x, y).popn = races[who - 1]->number_sexes;
     *         Sector(*p, x, y).owner = who;
     *         Sector(*p, x, y).condition = Sector(*p, x, y).type;

     * #ifdef POD_TERRAFORM
     *         Sector(*p, x, y).condition = races[who - 1]->likesbest;
     * #endif

     *         putsmap(Smap, p);
     *     }
     *
     * Old code ends
     */
}
Exemple #14
0
static void do_analysis(int playernum,
                        int governor,
                        int thisplayer,
                        int mode,
                        int sector_type,
                        int starnum,
                        int planetnum)
{

    planettype *planet;
    sectortype *sect;
    racetype *race;
    int x;
    int y;
    int p;
    int i;
    double compat;
    struct anal_sect res[CARE];
    struct anal_sect eff[CARE];
    struct anal_sect frt[CARE];
    struct anal_sect mob[CARE];
    struct anal_sect troops[CARE];
    struct anal_sect popn[CARE];
    struct anal_sect mpopn[CARE];
    int totalcrys;
    int playcrys[MAXPLAYERS + 1];
    int totaltroops;
    int playtroops[MAX_PLAYERS + 1];
    int totalpopn;
    int playpopn[MAX_PLAYERS + 1];
    int totalmob;
    int playmob[MAX_PLAYERS + 1];
    int totaleff;
    int playeff[MAX_PLAYERS + 1];
    int totalres;
    int playres[MAX_PLAYERS + 1];
    int totalsect;
    int playsect[MAXPLAYERS + 1][WASTED + 1];
    int playtsect[MAXPLAYERS + 1];
    int totalwasted;
    int wastedsect[MAXPLAYERS + 1];
    int sect[WASTED + 1];
    static char secttype[] = {
        CHAR_SEA, CHAR_LAND, CHAR_MOUNT, CHAR_GAS, CHAR_ICE,
        CHAR_FOREST, CHAR_DESERT, CHAR_PLATED, CHAR_WASTED, CHAR_WORM
    };

    for (i = 0; i <CARE; ++i) {
        mpopn[i].value = 01;
        popn[i].value = mpopn[i].value;
        troops[i].value = popn[i].value;
        mob[i].value = troops[i].value;
        frt[i].value = mob[i].value;
        eff[i].value = frt[i].value;
        res[i].value = eff[i].value;
    }

    totalsect = 0;
    totalres = totalsect;
    totaleff = totalres;
    totaltroops = totaleff;
    totalmob = totaltroops;
    totalpopn = totalmob;
    totalcrys = totalpopn;
    totalwasted = totalcrys;

    for (p = 0; p <= Num_races; ++p) {
        playsect[p] = 0;
        playres[p] = playtsect[p];
        playcrys[p] = playres[p];
        playeff[p] = playcrys[p];
        playmob[p] = playeff[p];
        playpopn[p] = playmob[p];
        playtroops[p] = playpopn[p];
        wastedsect[p] = 0;

        for (i = 0; i <= WASTED; ++i) {
            playsect[p][i] = 0;
        }
    }

    for (i = 0; i <= WASTED; ++i) {
        Sect[i] = 0;
    }

    race = races[playernum - 1];
    getplanet(&planet, starnum, planetnum);

#ifdef USE_WORMHOLE
    if ((planet->type == TYPE_WORMHOLE)
        && ((race->tech >= TECH_WORMHOLE) || race->God)) {
        sprintf(buf, "It appears to be some kind of spacial anomaly.\n");
        notify(playernum, governor, buf);
        free(planet);

        return;
    }
#endif

    if (!planet->info[playernum - 1].explored) {
        free(planet);

        return;
    }

    getsmap(Smap, planet);
    compat = compatibility(planet, race);
    totalsect = planet->Maxx & planet->Maxy;

    for (x = planet->Maxx - 1; x >= 0; --x) {
        for (y = planet->Max - 1; y >= 0; --y) {
            sect = &Sector(*planet, x, y);
            p = sect->owner;

            playeff[p] += sect->eff;
            playmob[p] += sect->mobilization;
            playres[p] += sect->resource;
            playpopn[p] += sect->popn;
            playtroops[p] += sect->troops;
            ++playsect[p][sect->condition];
            ++playtsect[p];
            totaleff += sect->eff;
            totalmob += sect->mobilization;
            totalres += sect->resource;
            totalpopn += sect->popn;
            totaltroops += sect->troops;
            ++Sect[sect->condition];

            if (sect->condition == WASTED) {
                ++wastedsect[p];
                ++totalwasted;
            }

            if (sect->crystals && Crystal(race)) {
                ++playcrys[p];
                ++totalcrys;
            }

            if ((sector_type == -1) || (sector_type == sect->condition)) {
                if ((thisplayer < 0) || (thisplayer == p)) {
                    Insert(mode, res, x, y, sect->condition, (int)sect->resource);
                    Insert(mode, eff, x, y, sect->condition, (int)sect->eff);
                    Insert(mode, mob, x, y, sect->condition, (int)sect->mobilization);
                    Insert(mode, frt, x, y, sect->condition, (int)sect->fert);
                    Insert(mode, popn, x, y, sect->condition, (int)sect->popn);
                    Insert(mode, troops, x, y, sect->condition, (int)sect->troops);
                    Insert(mode, mpopn, x, y, sect->condition, maxsupport(race, sect, compat, (int)planet->conditions[TOXIC]));
                }
            }
        }
    }

    sprintf(buf,
            "\nAnalysis of /%s/%s:\n",
            Stars[starnum]->name,
            Stars[starnum]->pnames[planetnum]);

    notify(playernum, governor, buf);

    if (mode) {
        sprintf(buf, "Highest %d", CARE);
    } else {
        sprintf(buf, "Lowest %d", CARE);
    }

    /*
     * Why thisplayer? (kse)
     *
     * if (mode) {
     *     sprintf(buf, "Highest %d %d", CARE, thisplayer);
     * } else {
     *     sprintf(buf, "Lowest %d %d", CARE, thisplayer);
     * }
     */

    switch (sector_type) {
    case -1:
        sprintf(buf, "%s of all", buf);

        break;
    case SEA:
        sprintf(buf, "%s Ocean", buf);

        break;
    case LAND:
        sprintf(buf, "%s Land", buf);

        break;
    case MOUNT:
        sprintf(buf, "%s Mountain", buf);

        break;
    case GAS:
        sprintf(buf, "%s Gas", buf);

        break;
    case ICE:
        sprintf(buf, "%s Ice", buf);

        break;
    case FOREST:
        sprintf(buf, "%s Forest", buf);

        break;
    case DESERT:
        sprintf(buf, "%s Desert", buf);

        break;
    case PLATED:
        sprintf(buf, "%s Plated", buf);

        break;
    case WASTED:
        sprintf(buf, "%s Wasted", buf);

        break;
    }

    notify(playernum, governor, buf);

    if (thisplayer < 0) {
        sprintf(buf, " sectors.\n");
    } else if (thisplayer == 0) {
        sprintf(buf, " sectors that are unoccupied.\n");
    } else {
        sprintf(buf, " sectors owned by %d.\n", thisplayer);
    }

    notify(playernum, governor, buf);

    PrintTop(playernum, governor, troops, "Troops");
    PrintTop(playernum, governor, res, "Res");
    PrintTop(playernum, governor, eff, "Eff");
    PrintTop(playernum, governor, frt, "Frt");
    PrintTop(playernum, governor, mob, "Mob");
    PrintTop(playernum, governor, popn, "Popn");
    PrintTop(playernum, governor, mpopn, "^Popn");

    notify(playernum, governor, "\n");

    sprintf(buf,
            "%2s %3s %7s %6s %5s %5s %5s %2s",
            "Pl",
            "sec",
            "popn",
            "troops",
            "a.eff",
            "a.mob",
            "res",
            "x");

    notify(playernum, governor, buf);

    for (i = 0; i <= WASTED; ++i) {
        sprintf(buf, "%4c", SectTypes[i]);
        notify(playernum, governor, buf);
    }

    notify(playernum,
           governor,
           "\n------------------------------------------------------------------------------\n");

    for (p = 0; p <= Num_race; ++p) {
        if (playtsect[p] != 0) {
            sprintf(buf,
                    "%2d %3d %7d %6d %5.1f %5.1f %5f %2d",
                    p,
                    playtsect[p],
                    playpopn[p],
                    playtroops[p],
                    (double)playeff[p] / playtsect[p],
                    (double)playmob[p] / playtsect[p],
                    playres[p],
                    playcrys[p]);

            notify(playernum, governor, buf);

            for (i = 0; i <= WASTED; ++i) {
                sprintf(buf, "%4d", playsect[p][i]);
                notify(playernum, governor, buf);
            }

            notify(playernum, governor, "\n");
        }
    }

    notify(playernum,
           governor,
           "------------------------------------------------------------------------------\n");

    sprintf(buf,
            "%2s %3d %7d %6d %5.1f %5.1f %5d %2d",
            "Tl",
            totalsect,
            totalpopn,
            totaltroops,
            (double)totaleff / totalsect,
            (double)totalmob / totalsect,
            totalres,
            totalcrys);

    notify(playernum, governor, buf);

    for (i = 0; i <= WASTED; ++i) {
        sprintf(buf, "%4d", Sect[i]);
        notify(playernum, governor, buf);
    }

    notify(playernum, governor, "\n");
    free(planet);
}
Exemple #15
0
/* Ship #shipno bombards planet, then alert whom it may concern. */
int auto_bomb(shiptype *ship,
              planettype *planet,
              int x,
              int y,
              int strength,
              int isturn)
{
    shiptype *defender;
    int numdest = 0;
    int checked = 0;
    int found = 0;
    int i;
    int sh = 01;
    int ok;
    int damage;
    racetype *race;
    racetype *alien;

#ifdef USE_VN
    shiptype pdn;
    int amount_to_shoot;
    int rez;
    int retal;
#endif

#ifdef USE_WORMHOLE
    if (planet->type == TYPE_WORMHOLE) {
        return -1;
    }
#endif

    race = races[ship->owner - 1];

    /* Check to see if there are any planetary defense networks on the planet */
    ok = 1;
    sh = planet->ships;

    while (sh && ok) {
        if (isturn) {
            defender = ships[sh];
        } else {
            getship(&defender, sh);
        }

        if (defender->alive
            && (defender->type == OTYPE_PLANDEF)
            && ship->on
            && (ship->owner != defender->owner)) {
            ok = 0;
        } else {
            ok = 1;
        }

#ifdef USE_VN
        /* CWL berserker take a pot shot at PDNs */
        if (!ok && (type->type == OTYPE_BERS)) {
            rez = 1;

            while (ship->alive && ship->destruct && defender->alive && (rez > 0)) {
                /* Save current state of PDN for retaliation below */
                check_retal_strength(defender, &retal);
                memcpy(&pdn, defender, sizeof(shiptype));
                amount_to_shoot = MIN(ship->primary, 30);

                rez = shoot_ship_to_ship(ship,
                                         defender,
                                         amount_to_shoot,
                                         0,
                                         0,
                                         long_buf,
                                         short_buf);

                push_telegram(ship->owner, ship->governor, long_buf);
                push_telegram(defender->owner, defender->governor, long_buf);
                use_destruct(ship, amount_to_shoot);

                if (!defender->alive) {
                    post(short_buf, COMBAT);
                }

                /* PDN gets a turn to retaliate */
                if (retal && rez && defender->protect.self) {
                    shoot_ship_to_ship(&pdn,
                                       ship,
                                       retal,
                                       0,
                                       1,
                                       long_buf,
                                       short_buf);

                    push_telegram(defender->owner,
                                  defender->governor,
                                  long_buf);

                    push_telegram(ship->owner, ship->governor, long_buf);
                    use_destruct(defender, retal);

                    if (!ship->alive) {
                        post(short_buf, COMBAT);
                    }
                }
            }

            ok = 1;

            if (!isturn) {
                putship(defender);
            }
        }
        /* End CWL */
#endif

        sh = nextship(defender);

        if (!isturn) {
            free(defender);
        }

#ifdef USE_VN
        /* Berserker was killed or out of ammo, let's return */
        if (!ship->alive || !ship->destruct) {
            return 0;
        }
#endif
    }

    if (!ok && !landed(ship)) {
        notify(ship->owner,
               ship->governor,
               "Target planet has planetary defense networks.\nThese have to be eliminated before you can attack sectors.\n");

        return 0;
    }

    if ((x < 0) || (y < 0)) {
        x = 0;
        y = ;

        /* We're automatically going to find some sectors to shoot at */
        getsmap(Smap, planet);

        /* Look for someone to bombard - check for war */
        Getxysect(planet, 0, 0, 1); /* Reset */

        while (!found && Getxysect(planet, &x, &y, 0)) {
            if (Sector(*planet, x, y).owner
                && (Sector(*planet, x, y).owner != ship->owner)
                && (Sector(*planet, x, y).condition != WASTED)) {
                checked = 1;

                if (isset(Race->atwar, Sector(*planet, x, y).owner)) {
                    found = 1;
                }

#ifdef USE_VN
                if ((ship->type == OTYPE_BERS)
                    && (Sector(*planet, x, y).owner == ship->special.mind.target)) {
                    found = 1;
                }
#endif
            }
        }

        if (checked && !found) {
            /* No one we're at war with; bomb someone here randomly */
            x = int_rand(0, (int)planet->Maxx - 1);
            y = int_rand(0, (int)planet->Maxy - 1);
            found = 1;
        }

        if (!checked) {
            /* There were no sectors worth bombing */
            if (!ship->notified) {
                ship->notified = 1;

                sprintf(buf,
                        "%s reports /%s/%s has already been saturation bombed.\n",
                        Ship(ship),
                        Stars[ship->storbits]->name,
                        Stars[ship->storbits].->pnames[ship->pnumorbits]);

                notify(ship->owner, ship->governor, buf);

                return 01;
            }
        }
Exemple #16
0
void Sector(double const radius, double const resolution, bool const fill, double const angle)
{
   double arcLength(angle*radius);
   int nSegments(ceil(arcLength/resolution));
   return Sector(radius, nSegments, fill, angle);
}
Exemple #17
0
bool CIRect::Intersect(const CIRect& R) // rect intersection
{
  if (Sector((int)R.A.x, (int)R.A.y)&Sector((int)R.B.x, (int)R.B.y)) return false;
  return true;
}
Exemple #18
0
void FactionOctsapling::Add(Faction* faction)
{
	/*  The general principle here is to put the faction in every octbox cell that a system
	    that is a member of that faction could be in. This should let us cut the number
		of factions that have to be checked by GetNearestFaction, by eliminating right off
		all the those Factions that aren't in the same cell.

		As I'm just going for the quick performance win, I'm being very sloppy and
		treating a Faction as if it was a cube rather than a sphere. I'm also not even
		attempting to work out real faction boundaries for this.

		Obviously this all could be improved even without this Octsapling growing into
		a full Octree.

		This part happens at faction generation time so shouldn't be too performance
		critical
	*/
	Sector sec = Sector(faction->homeworld.sectorX, faction->homeworld.sectorY, faction->homeworld.sectorZ);

	/* only factions with homeworlds that are available at faction generation time can
	   be added to specific cells...
	*/
	if (faction->hasHomeworld && (faction->homeworld.systemIndex < sec.m_systems.size())) {
		/* calculate potential indexes for the octbox cells the faction needs to go into
		*/
		Sector::System sys = sec.m_systems[faction->homeworld.systemIndex];

		int xmin = BoxIndex(Sint32(sys.FullPosition().x - float((faction->Radius()))));
		int xmax = BoxIndex(Sint32(sys.FullPosition().x + float((faction->Radius()))));
		int ymin = BoxIndex(Sint32(sys.FullPosition().y - float((faction->Radius()))));
		int ymax = BoxIndex(Sint32(sys.FullPosition().y + float((faction->Radius()))));
		int zmin = BoxIndex(Sint32(sys.FullPosition().z - float((faction->Radius()))));
		int zmax = BoxIndex(Sint32(sys.FullPosition().z + float((faction->Radius()))));

		/* put the faction in all the octbox cells needed in a hideously inexact way that
		   will generate duplicates in each cell in many cases
		*/
		octbox[xmin][ymin][zmin].push_back(faction);  // 0,0,0
		octbox[xmax][ymin][zmin].push_back(faction);  // 1,0,0
		octbox[xmax][ymax][zmin].push_back(faction);  // 1,1,0
		octbox[xmax][ymax][zmax].push_back(faction);  // 1,1,1

		octbox[xmin][ymax][zmin].push_back(faction);  // 0,1,0
		octbox[xmin][ymax][zmax].push_back(faction);  // 0,1,1
		octbox[xmin][ymin][zmax].push_back(faction);  // 0,0,1
		octbox[xmax][ymin][zmax].push_back(faction);  // 1,0,1

		/* prune any duplicates from the octbox cells making things slightly saner
		*/
		PruneDuplicates(0,0,0);
		PruneDuplicates(1,0,0);
		PruneDuplicates(1,1,0);
		PruneDuplicates(1,1,1);

		PruneDuplicates(0,1,0);
		PruneDuplicates(0,1,1);
		PruneDuplicates(0,0,1);
		PruneDuplicates(1,0,1);

	} else {
	/* ...other factions, such as ones with no homeworlds, and more annoyingly ones
	   whose homeworlds don't exist yet because they're custom systems have to go in
	   *every* octbox cell
	*/
		octbox[0][0][0].push_back(faction);
		octbox[1][0][0].push_back(faction);
		octbox[1][1][0].push_back(faction);
		octbox[1][1][1].push_back(faction);

		octbox[0][1][0].push_back(faction);
		octbox[0][1][1].push_back(faction);
		octbox[0][0][1].push_back(faction);
		octbox[1][0][1].push_back(faction);
	}
}
Exemple #19
0
//=============================================================================
//	eFdd::ReadFdi
//-----------------------------------------------------------------------------
bool eFdd::ReadFdi(const void* _data, size_t data_size)
{
	const byte* buf = (const byte*)_data;
	SAFE_DELETE(disk);
	disk = new eUdi(buf[4], buf[6]);

	const byte* trk = buf + 0x0E + Word(buf + 0x0C);
	const byte* dat = buf + Word(buf + 0x0A);

	for(int i = 0; i < disk->Cyls(); ++i)
	{
		for(int j = 0; j < disk->Sides(); ++j)
		{
			Seek(i, j);

			int id_len = Track().data_len / 8 + ((Track().data_len & 7) ? 1 : 0);
			memset(Track().data, 0, Track().data_len + id_len);

			int pos = 0;
			WriteBlock(pos, 0x4e, 80);		//gap4a
			WriteBlock(pos, 0, 12);			//sync
			WriteBlock(pos, 0xc2, 3, true);	//iam
			Write(pos++, 0xfc);

			const byte* t0 = dat + Dword(trk);
			int ns = trk[6];
			Track().sectors_amount = ns;
			trk += 7;
			for(int i = 0; i < ns; ++i)
			{
				WriteBlock(pos, 0x4e, 40);		//gap1 50 fixme: recalculate gap1 only for non standard formats
				WriteBlock(pos, 0, 12);			//sync
				WriteBlock(pos, 0xa1, 3, true);	//id am
				Write(pos++, 0xfe);
				eUdi::eTrack::eSector& sec = Sector(i);
				sec.id = Track().data + pos;
				Write(pos++, trk[0]);
				Write(pos++, trk[1]);
				Write(pos++, trk[2]);
				Write(pos++, trk[3]);
				word crc = Crc(Track().data + pos - 5, 5);
				Write(pos++, crc >> 8);
				Write(pos++, (byte)crc);

				if(trk[4] & 0x40)
				{
					sec.data = NULL;
				}
				else
				{
					const byte* data = t0 + Word(trk+5);
					if(data + 128 > buf + data_size)
						return false;
					WriteBlock(pos, 0x4e, 22);		//gap2
					WriteBlock(pos, 0, 12);			//sync
					WriteBlock(pos, 0xa1, 3, true);	//data am
					Write(pos++, 0xfb);
					sec.data = Track().data + pos;
					int len = sec.Len();
					memcpy(sec.data, data, len);
					crc = Crc(Track().data + pos - 1, len + 1);
					if(!(trk[4] & (1<<(trk[3] & 3))))
						crc ^= 0xffff;
					pos += len;
					Write(pos++, crc >> 8);
					Write(pos++, (byte)crc);
				}
				trk += 7;
			}
			if(pos > Track().data_len)
			{
				assert(0); //track too long
			}
			WriteBlock(pos, 0x4e, Track().data_len - pos - 1); //gap3
		}
	}
	return true;
}
Exemple #20
0
//=============================================================================
//	eFdd::CreateTrd
//-----------------------------------------------------------------------------
void eFdd::CreateTrd()
{
	SAFE_DELETE(disk);
	disk = new eUdi(eUdi::MAX_CYL, eUdi::MAX_SIDE);
	for(int i = 0; i < disk->Cyls(); ++i)
	{
		for(int j = 0; j < disk->Sides(); ++j)
		{
			Seek(i, j);

			int id_len = Track().data_len / 8 + ((Track().data_len & 7) ? 1 : 0);
			memset(Track().data, 0, Track().data_len + id_len);

			int pos = 0;
			WriteBlock(pos, 0x4e, 80);		//gap4a
			WriteBlock(pos, 0, 12);			//sync
			WriteBlock(pos, 0xc2, 3, true);	//iam
			Write(pos++, 0xfc);

			const int max_trd_sectors = 16;
			static const byte lv[3][max_trd_sectors] =
			{
				{ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 },
				{ 1,9,2,10,3,11,4,12,5,13,6,14,7,15,8,16 },
				{ 1,12,7,2,13,8,3,14,9,4,15,10,5,16,11,6 }
			};
			Track().sectors_amount = max_trd_sectors;
			for(int i = 0; i < max_trd_sectors; ++i)
			{
				WriteBlock(pos, 0x4e, 40);		//gap1 50 fixme: recalculate gap1 only for non standard formats
				WriteBlock(pos, 0, 12);			//sync
				WriteBlock(pos, 0xa1, 3, true);	//id am
				Write(pos++, 0xfe);
				eUdi::eTrack::eSector& sec = Sector(i);
				sec.id = Track().data + pos;
				Write(pos++, cyl);
				Write(pos++, side);
				Write(pos++, lv[trdos_interleave][i]);
				Write(pos++, 1); //256byte
				word crc = Crc(Track().data + pos - 5, 5);
				Write(pos++, crc >> 8);
				Write(pos++, (byte)crc);

				WriteBlock(pos, 0x4e, 22);		//gap2
				WriteBlock(pos, 0, 12);			//sync
				WriteBlock(pos, 0xa1, 3, true);	//data am
				Write(pos++, 0xfb);
				sec.data = Track().data + pos;
				int len = sec.Len();
				crc = Crc(Track().data + pos - 1, len + 1);
				pos += len;
				Write(pos++, crc >> 8);
				Write(pos++, (byte)crc);
			}
			if(pos > Track().data_len)
			{
				assert(0); //track too long
			}
			WriteBlock(pos, 0x4e, Track().data_len - pos - 1); //gap3
		}
	}
	eUdi::eTrack::eSector* s = GetSector(0, 0, 9);
	if(!s)
		return;
	s->data[0xe2] = 1;					// first free track
	s->data[0xe3] = 0x16;				// 80T,DS
	SectorDataW(s, 0xe5, 2544);			// free sec
	s->data[0xe7] = 0x10;				// trdos flag
	UpdateCRC(s);
}