Пример #1
0
void do_ap(shiptype *ship)
{
    racetype *Race;

    /* if landed on planet, change conditions to be like race */
    if (landed(ship) && ship->on) {
        int j,d,a;
        planettype *p;
        p = planets[ship->storbits][ship->pnumorbits];
        Race = races[ship->owner-1];
        if (ship->fuel >= 3.0) {
            use_fuel(ship, 3.0);
            for (j=RTEMP+1; j<=OTHER; j++) {
                d = round_rand(ap_planet_factor(p)*crew_factor(ship)*
                               (double)(Race->conditions[j]-p->conditions[j]));
                if(d)
                    p->conditions[j] += d;
            }
        } else if (!ship->notified) {
            ship->notified = 1;
            ship->on = 0;
            msg_OOF(ship);
        }
    }
}
Пример #2
0
void FlyAI::init()
{
    Q_ASSERT(m_fsm == nullptr);

    m_fsm = new QStateMachine();

    m_thinkingState = new QState(m_fsm);
    m_flyingState = new QState(m_fsm);
    m_landingState = new QState(m_fsm);
    m_fallingState = new QState(m_fsm);
    m_deadState = new QFinalState(m_fsm);

    m_thinkingState->addTransition(this, SIGNAL(thinkTimeout()), m_flyingState);
    m_thinkingState->addTransition(this, SIGNAL(maxAgeReached()), m_deadState);
    QObject::connect(m_thinkingState, SIGNAL(entered()), this, SLOT(onThinkingEnter()));

    m_flyingState->addTransition(this, SIGNAL(almostArrived()), m_landingState);
    m_flyingState->addTransition(this, SIGNAL(maxAgeReached()), m_fallingState);
    m_flyingState->addTransition(this, SIGNAL(maxFlyingDistanceReached()), m_fallingState);
    QObject::connect(m_flyingState, SIGNAL(entered()), this, SLOT(onFlyingEnter()));

    m_landingState->addTransition(this, SIGNAL(maxAgeReached()), m_fallingState);
    m_landingState->addTransition(this, SIGNAL(maxFlyingDistanceReached()), m_fallingState);
    m_landingState->addTransition(this, SIGNAL(thinkTimeout()), m_flyingState);
    m_landingState->addTransition(this, SIGNAL(landed()), m_thinkingState);
    QObject::connect(m_landingState, SIGNAL(entered()), this, SLOT(onLandingEnter()));

    m_fallingState->addTransition(this, SIGNAL(stopped()), m_deadState);
    QObject::connect(m_fallingState, SIGNAL(entered()), this, SLOT(onFallingEnter()));

    QObject::connect(m_deadState, SIGNAL(entered()), this, SLOT(onDeadEnter()));

    QSignalTransition *trans = new QSignalTransition(this, SIGNAL(advanceSignal()));
    m_thinkingState->addTransition(trans);
    QObject::connect(trans, SIGNAL(triggered()), this, SLOT(advanceThinking()));

    QSignalTransition *transFlying = new QSignalTransition(this, SIGNAL(advanceSignal()));
    m_flyingState->addTransition(transFlying);
    QObject::connect(transFlying, SIGNAL(triggered()), this, SLOT(advanceFlying()));

    QSignalTransition *transLanding = new QSignalTransition(this, SIGNAL(advanceSignal()));
    m_landingState->addTransition(transLanding);
    QObject::connect(transLanding, SIGNAL(triggered()), this, SLOT(advanceLanding()));

    QSignalTransition *transFalling = new QSignalTransition(this, SIGNAL(advanceSignal()));
    m_fallingState->addTransition(transFalling);
    QObject::connect(transFalling, SIGNAL(triggered()), this, SLOT(advanceFalling()));

    m_fsm->setInitialState(m_thinkingState);
    m_fsm->start();
    qDebug() << "fly fsm started";
}
Пример #3
0
void FlyAI::advanceLanding()
{
    double dt = m_dt;
    m_flyingDuration += dt;

    double s = m_flyingDuration * m_state.m_vel;
    double dx = (m_targetSpotPart.x() - m_takeOffPt.x());
    double dy = (m_targetSpotPart.y() - m_takeOffPt.y());
    double c = sqrt(dx * dx + dy * dy);
    double maxS = c;

    if (s >= maxS)
    {
        m_state.m_transPos = m_targetSpotPart;
        m_state.m_pos = m_targetSpot;

        if (!m_gameDataProvider->isLandingPointFree(m_targetSpotPart))
        {
            changeRoute();
            return;
        }

        //qDebug() << "landing: " << m_state.m_transPos;
        emit landed();
        m_movesHolder->addMove(m_flyingDuration, m_state.m_vel);
        return;
    }

    double cosA = dx / c;
    double sinA = dy / c;

    m_state.m_transPos = m_takeOffPt + QPointF(s * cosA, s * sinA);

    //qDebug() << "landing: " << m_state.m_transPos;

    m_state.m_age += dt;
    if (m_state.m_age > m_maxAge)
    {
        emit maxAgeReached();
        return;
    }

    if (!m_gameDataProvider->isLandingPointFree(m_targetSpotPart))
    {
        changeRoute();
    }
}
Пример #4
0
void do_canister(shiptype *ship)
{
    if (ship->whatorbits == LEVEL_PLAN && !landed(ship)) {
        if (++ship->special.timer.count < DISSIPATE) {
            if ( Stinfo[ship->storbits][ship->pnumorbits].temp_add < -90 )
                Stinfo[ship->storbits][ship->pnumorbits].temp_add = -100;
            else
                Stinfo[ship->storbits][ship->pnumorbits].temp_add -= 10;
        } else {	/* timer expired; destroy canister */
            reg int j=0;
            kill_ship((int)(ship->owner), ship);
            sprintf(telegram_buf, "Canister of dust previously covering %s has dissipated.\n",
                    prin_ship_orbits(ship));
            for (j=1; j<=Num_races; j++)
                if (planets[ship->storbits][ship->pnumorbits]->info[j-1].numsectsowned)
                    push_telegram(j, (int)Stars[ship->storbits]->governor[j-1],
                                  telegram_buf);
        }
    }
}
Пример #5
0
void doabm(shiptype *ship)
{
    int sh2;
    int numdest, caliber;
    planettype *p;

    if(!ship->alive || !ship->owner) return;
    if(!ship->on || !ship->retaliate || !ship->destruct) return;

    if(landed(ship)) {
        p=planets[ship->storbits][ship->pnumorbits];
        caliber = current_caliber(ship);
        /* check to see if missiles/mines are present */
        sh2 = p->ships;
        while(sh2 && ship->destruct) {
            if(ships[sh2]->alive &&
                    ((ships[sh2]->type==STYPE_MISSILE) ||
                     (ships[sh2]->type==STYPE_MINE)) &&
                    (ships[sh2]->owner != ship->owner) &&
                    !(isset(races[ship->owner-1]->allied, ships[sh2]->owner) &&
                      isset(races[ships[sh2]->owner-1]->allied, ship->owner))) {
                /* added last two tests to prevent mutually allied missiles
                getting shot up. */
                /* attack the missile/mine */
                numdest = retal_strength(ship);
                numdest = MIN(numdest, ship->destruct);
                numdest = MIN(numdest, ship->retaliate);
                ship->destruct -= numdest;
                (void)shoot_ship_to_ship(ship, ships[sh2], numdest, 0, 0,
                                         long_buf, short_buf);
                push_telegram((int)(ship->owner), (int)ship->governor, long_buf);
                push_telegram((int)(ships[sh2]->owner),
                              (int)ships[sh2]->governor, long_buf);
                post(short_buf, COMBAT);
            }
            sh2 = ships[sh2]->nextship;
        }
    }
}
Пример #6
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;
            }
        }
void BlockLocalPositionEstimator::update()
{
	// wait for a sensor update, check for exit condition every 100 ms
	int ret = px4_poll(_polls, 3, 100);

	if (ret < 0) {
		return;
	}

	uint64_t newTimeStamp = hrt_absolute_time();
	float dt = (newTimeStamp - _timeStamp) / 1.0e6f;
	_timeStamp = newTimeStamp;

	// set dt for all child blocks
	setDt(dt);

	// auto-detect connected rangefinders while not armed
	bool armedState = _sub_armed.get().armed;

	if (!armedState && (_sub_lidar == nullptr || _sub_sonar == nullptr)) {
		// detect distance sensors
		for (int i = 0; i < N_DIST_SUBS; i++) {
			uORB::Subscription<distance_sensor_s> *s = _dist_subs[i];

			if (s == _sub_lidar || s == _sub_sonar) { continue; }

			if (s->updated()) {
				s->update();

				if (s->get().timestamp == 0) { continue; }

				if (s->get().type == distance_sensor_s::MAV_DISTANCE_SENSOR_LASER &&
				    s->get().orientation == distance_sensor_s::ROTATION_DOWNWARD_FACING &&
				    _sub_lidar == nullptr) {
					_sub_lidar = s;
					mavlink_and_console_log_info(&mavlink_log_pub, "%sDownward-facing Lidar detected with ID %i", msg_label, i);

				} else if (s->get().type == distance_sensor_s::MAV_DISTANCE_SENSOR_ULTRASOUND &&
					   s->get().orientation == distance_sensor_s::ROTATION_DOWNWARD_FACING &&
					   _sub_sonar == nullptr) {
					_sub_sonar = s;
					mavlink_and_console_log_info(&mavlink_log_pub, "%sDownward-facing Sonar detected with ID %i", msg_label, i);
				}
			}
		}
	}

	// reset pos, vel, and terrain on arming

	// XXX this will be re-enabled for indoor use cases using a
	// selection param, but is really not helping outdoors
	// right now.

	// if (!_lastArmedState && armedState) {

	//      // we just armed, we are at origin on the ground
	//      _x(X_x) = 0;
	//      _x(X_y) = 0;
	//      // reset Z or not? _x(X_z) = 0;

	//      // we aren't moving, all velocities are zero
	//      _x(X_vx) = 0;
	//      _x(X_vy) = 0;
	//      _x(X_vz) = 0;

	//      // assume we are on the ground, so terrain alt is local alt
	//      _x(X_tz) = _x(X_z);

	//      // reset lowpass filter as well
	//      _xLowPass.setState(_x);
	//      _aglLowPass.setState(0);
	// }

	_lastArmedState = armedState;

	// see which updates are available
	bool paramsUpdated = _sub_param_update.updated();
	_baroUpdated = false;

	if ((_fusion.get() & FUSE_BARO) && _sub_sensor.updated()) {
		int32_t baro_timestamp_relative = _sub_sensor.get().baro_timestamp_relative;

		if (baro_timestamp_relative != _sub_sensor.get().RELATIVE_TIMESTAMP_INVALID) {
			uint64_t baro_timestamp = _sub_sensor.get().timestamp +	\
						  _sub_sensor.get().baro_timestamp_relative;

			if (baro_timestamp != _timeStampLastBaro) {
				_baroUpdated = true;
				_timeStampLastBaro = baro_timestamp;
			}
		}
	}

	_flowUpdated = (_fusion.get() & FUSE_FLOW) && _sub_flow.updated();
	_gpsUpdated = (_fusion.get() & FUSE_GPS) && _sub_gps.updated();
	_visionUpdated = (_fusion.get() & FUSE_VIS_POS) && _sub_vision_pos.updated();
	_mocapUpdated = _sub_mocap.updated();
	_lidarUpdated = (_sub_lidar != nullptr) && _sub_lidar->updated();
	_sonarUpdated = (_sub_sonar != nullptr) && _sub_sonar->updated();
	_landUpdated = landed() && ((_timeStamp - _time_last_land) > 1.0e6f / LAND_RATE);// throttle rate
	bool targetPositionUpdated = _sub_landing_target_pose.updated();

	// get new data
	updateSubscriptions();

	// update parameters
	if (paramsUpdated) {
		updateParams();
		updateSSParams();
	}

	// is xy valid?
	bool vxy_stddev_ok = false;

	if (math::max(_P(X_vx, X_vx), _P(X_vy, X_vy)) < _vxy_pub_thresh.get() * _vxy_pub_thresh.get()) {
		vxy_stddev_ok = true;
	}

	if (_estimatorInitialized & EST_XY) {
		// if valid and gps has timed out, set to not valid
		if (!vxy_stddev_ok && (_sensorTimeout & SENSOR_GPS)) {
			_estimatorInitialized &= ~EST_XY;
		}

	} else {
		if (vxy_stddev_ok) {
			if (!(_sensorTimeout & SENSOR_GPS)
			    || !(_sensorTimeout & SENSOR_FLOW)
			    || !(_sensorTimeout & SENSOR_VISION)
			    || !(_sensorTimeout & SENSOR_MOCAP)
			    || !(_sensorTimeout & SENSOR_LAND)
			    || !(_sensorTimeout & SENSOR_LAND_TARGET)
			   ) {
				_estimatorInitialized |= EST_XY;
			}
		}
	}

	// is z valid?
	bool z_stddev_ok = sqrtf(_P(X_z, X_z)) < _z_pub_thresh.get();

	if (_estimatorInitialized & EST_Z) {
		// if valid and baro has timed out, set to not valid
		if (!z_stddev_ok && (_sensorTimeout & SENSOR_BARO)) {
			_estimatorInitialized &= ~EST_Z;
		}

	} else {
		if (z_stddev_ok) {
			_estimatorInitialized |= EST_Z;
		}
	}

	// is terrain valid?
	bool tz_stddev_ok = sqrtf(_P(X_tz, X_tz)) < _z_pub_thresh.get();

	if (_estimatorInitialized & EST_TZ) {
		if (!tz_stddev_ok) {
			_estimatorInitialized &= ~EST_TZ;
		}

	} else {
		if (tz_stddev_ok) {
			_estimatorInitialized |= EST_TZ;
		}
	}

	// check timeouts
	checkTimeouts();

	// if we have no lat, lon initialize projection to LPE_LAT, LPE_LON parameters
	if (!_map_ref.init_done && (_estimatorInitialized & EST_XY) && _fake_origin.get()) {
		map_projection_init(&_map_ref,
				    _init_origin_lat.get(),
				    _init_origin_lon.get());

		// set timestamp when origin was set to current time
		_time_origin = _timeStamp;

		mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] global origin init (parameter) : lat %6.2f lon %6.2f alt %5.1f m",
					     double(_init_origin_lat.get()), double(_init_origin_lon.get()), double(_altOrigin));
	}

	// reinitialize x if necessary
	bool reinit_x = false;

	for (int i = 0; i < n_x; i++) {
		// should we do a reinit
		// of sensors here?
		// don't want it to take too long
		if (!PX4_ISFINITE(_x(i))) {
			reinit_x = true;
			mavlink_and_console_log_info(&mavlink_log_pub, "%sreinit x, x(%d) not finite", msg_label, i);
			break;
		}
	}

	if (reinit_x) {
		for (int i = 0; i < n_x; i++) {
			_x(i) = 0;
		}

		mavlink_and_console_log_info(&mavlink_log_pub, "%sreinit x", msg_label);
	}

	// force P symmetry and reinitialize P if necessary
	bool reinit_P = false;

	for (int i = 0; i < n_x; i++) {
		for (int j = 0; j <= i; j++) {
			if (!PX4_ISFINITE(_P(i, j))) {
				mavlink_and_console_log_info(&mavlink_log_pub,
							     "%sreinit P (%d, %d) not finite", msg_label, i, j);
				reinit_P = true;
			}

			if (i == j) {
				// make sure diagonal elements are positive
				if (_P(i, i) <= 0) {
					mavlink_and_console_log_info(&mavlink_log_pub,
								     "%sreinit P (%d, %d) negative", msg_label, i, j);
					reinit_P = true;
				}

			} else {
				// copy elememnt from upper triangle to force
				// symmetry
				_P(j, i) = _P(i, j);
			}

			if (reinit_P) { break; }
		}

		if (reinit_P) { break; }
	}

	if (reinit_P) {
		initP();
	}

	// do prediction
	predict();

	// sensor corrections/ initializations
	if (_gpsUpdated) {
		if (_sensorTimeout & SENSOR_GPS) {
			gpsInit();

		} else {
			gpsCorrect();
		}
	}

	if (_baroUpdated) {
		if (_sensorTimeout & SENSOR_BARO) {
			baroInit();

		} else {
			baroCorrect();
		}
	}

	if (_lidarUpdated) {
		if (_sensorTimeout & SENSOR_LIDAR) {
			lidarInit();

		} else {
			lidarCorrect();
		}
	}

	if (_sonarUpdated) {
		if (_sensorTimeout & SENSOR_SONAR) {
			sonarInit();

		} else {
			sonarCorrect();
		}
	}

	if (_flowUpdated) {
		if (_sensorTimeout & SENSOR_FLOW) {
			flowInit();

		} else {
			flowCorrect();
		}
	}

	if (_visionUpdated) {
		if (_sensorTimeout & SENSOR_VISION) {
			visionInit();

		} else {
			visionCorrect();
		}
	}

	if (_mocapUpdated) {
		if (_sensorTimeout & SENSOR_MOCAP) {
			mocapInit();

		} else {
			mocapCorrect();
		}
	}

	if (_landUpdated) {
		if (_sensorTimeout & SENSOR_LAND) {
			landInit();

		} else {
			landCorrect();
		}
	}

	if (targetPositionUpdated) {
		if (_sensorTimeout & SENSOR_LAND_TARGET) {
			landingTargetInit();

		} else {
			landingTargetCorrect();
		}
	}

	if (_altOriginInitialized) {
		// update all publications if possible
		publishLocalPos();
		publishEstimatorStatus();
		_pub_innov.get().timestamp = _timeStamp;
		_pub_innov.update();

		if ((_estimatorInitialized & EST_XY) && (_map_ref.init_done || _fake_origin.get())) {
			publishGlobalPos();
		}
	}

	// propagate delayed state, no matter what
	// if state is frozen, delayed state still
	// needs to be propagated with frozen state
	float dt_hist = 1.0e-6f * (_timeStamp - _time_last_hist);

	if (_time_last_hist == 0 ||
	    (dt_hist > HIST_STEP)) {
		_tDelay.update(Scalar<uint64_t>(_timeStamp));
		_xDelay.update(_x);
		_time_last_hist = _timeStamp;
	}
}
Пример #8
0
void scrap(int playernum, int governor, int apcount)
{
    planettype *planet;
    sectortype *sect;
    shiptype *s;
    shiptype *s2;
    int shipno;
    int nextshipno;
    int scrapval = 0;
    int destval = 0;
    int crewval = 0;
    int max_crew = 0;
    int xtalval = 0;
    int troopval = 0;
    int max_resource = 0;
    int max_mil = 0;
    int max_fuel = 0;
    int max_destruct = 0;
    int cost = 0;
    double fuelval = 0.0;
    racetype *race;

    if (argn < 2) {
        notify(playernum, governor, "Scrap what?\n");

        return;
    }

    nextshipno = start_shiplist(playernum, governor, args[1]);
    race = races[playernum - 1];

    if (race->Guest) {
        notify(playernum, governor, "Guest races cannot scrap ships\n");

        return;
    }

    shipno = do_shiplist(&s, &nextshipno);

    while (shipno) {
        if (in_list(playernum, args[1], s, &nextshipno)) {
#ifdef USE_VN
            if ((s->type == OTYPE_VN) || (s->type == OTYPE_BERS)) {
                notify(playernum, governor, "VNs will not scrap themselves.\n");
                free(s);
                shipno = do_shiplist(&s, &nextshipno);

                continue;
            }
#endif

            if (s->max_crew && !s->popn) {
                notify(playernum,
                       governor,
                       "Can't scrap that ship - no crew.\n");

                free(s);
                shipno = do_shiplist(&s, &nextshipno);

                continue;
            }

            if (s->whatorbits == LEVEL_UNIV) {
                /*
                 * Used to not allow scrapping at the UNIV level for
                 * anything. However, I'm going to permit pods. This is so pod
                 * races can clean up their messes. I'm not going to charge APs
                 * at the UNIV scope either. -mfw
                 */
                if (s->type) {
                    apcount = 0;
                } else {
                    notify(playernum,
                           governor,
                           "Can't scrap at the ship's scope.\n");

                    free(s);
                    shipno = do_shiplist(&s, &nextshipno);

                    continue;
                }
            } else if (!enufAP(playernum, governor, Stars[s->storbits]->AP[playernum - 1], apcount)) {
                notify(playernum, governor, "Not enough APs to scrap.\n");
                free(s);
                shipno = do_shiplist(&s, &nextshipno);

                continue;
            }

            /* HUTm (kse) wc's can't be scrapped inside of ship anymore */
            if (inship(s) && (s->type == OTYPE_TOXIC)) {
                sprintf(buf,
                        "Can't scrap waste canisters inside of other ship.\n");

                notify(playernum, governor, buf);
                free(s);
                shipno = do_shiplist(&s, &nextshipno);

                continue;
            }

            /* Ships that have other ships in the hangar can't scrap *mfw */
            if (s->ships) {
                sprintf(buf,
                        "There are other ships in the hangar; scrap those first.\n");

                notify(playernum, governor, buf);
                free(s);
                shipno = do_shiplist(&s, &nextshipno);

                continue;
            }

            if ((s->whatorbits == LEVEL_PLAN) && (s->type == OTYPE_TOXIC)) {
                sprintf(buf,
                        "WARNING: This releases %d toxin points back into the atmosphere!!!\n",
                        s->special.waste.toxic);

                notify(playernum, governor, buf);
            }

            if (!s->docked) {
                sprintf(buf,
                        "%s is not landed or docked.\nNo resources can be reclaimed.\n",
                        Ship(s));

                notify(playernum, governor, buf);
            }

            if (s->whatorbits == LEVEL_PLAN) {
                /* wc's release poison */
                getplanet(&planet, (int)s->storbits, (int)s->pnumorbits);

                if (landed(s)) {
                    if (!getsector(&sect, planet, (int)s->land_x, (int)s->land_y)) {
                        notify(playernum,
                               governor,
                               "Error in sector database, notify deity.\n");

                        free(s);

                        return;
                    }
                }
            }

            if (docked(s) || inship(s)) {
                if (!getship(&s2, (int)s->destshipno)) {
                    free(s);
                    shipno = do_shiplist(&s, &nextshipno);

                    continue;
                }

                if ((!s2->docked || (s2->destshipno != s->number))
                    && (!s->whatorbits == LEVEL_SHIP)) {
                    sprintf(buf, "Warning, other ship not docked...\n");
                    notify(playernum, governor, buf);
                    free(s);
                    free(s2);
                    shipno = do_shiplist(&s, &nextshipno);

                    continue;
                }
            }

            if (s->type == OTYPE_FACTORY) {
                cost = (2 * s->build_code * s->on) + Shipdata[s->type][ABIL_COST];
            } else {
                cost = s->build_cost;
            }

            scrapval = (cost / 2) + s->resource;

            if (s->docked) {
                sprintf(buf, "%s: original cost: %ld\n", Ship(s), cost);
                notify(playernum, governor, buf);

                sprintf(buf,
                        "         scrap value%s: %d rp's.\n",
                        s->resource ? "(with stockpile) " : "",
                        scrapval);

                notify(playernum, governor, buf);

                /* New code by Kharush. check for STYPE_DHUTTLE added. */
                /* I've removed it, Dhuttle was silly -mfw */

                if (s2->type == OTYPE_FACTORY) {
                    max_resource = Shipdata[s2->type][ABIL_CARGO];
                    max_fuel = Shipdata[s2->type][ABIL_FUELCAP];
                    max_destruct = Shipdata[s2->type][DESTCAP];
                } else {
                    max_resource = s2->max_resource;
                    max_fuel = s2->max_fuel;
                    max_destruct = s2->max_destruct;
                }

                if ((s->whatdest == LEVEL_SHIP)
                    && ((s2->resource + scrapval) > max_resource)
                    && (s2->type != STYPE_SHUTTLE)) {
                    scrapval = max_resource - s2->resource;
                    sprintf(buf,
                            "(There is only room for %d resources.)\n",
                            scrapval);

                    notify(playernum, governor, buf);
                }

                if (s->fuel) {
                    sprintf(buf, "Fuel recover: %.0f.\n", s->fuel);
                    notify(playernum, governor, buf);
                    fuelval = s->fuel;

                    if ((s->whatdest == LEVEL_SHIP)
                        && ((s2->fuel + fuelval) > max_fuel)) {
                        fuelval = max_fuel - s2->fuel;
                        sprintf(buf,
                                "(There is only room for %.2f fuel.)\n",
                                fuelval);

                        notify(playernum, governor, buf);
                    }
                } else {
                    fuelval = 0.0;
                }

                if (s->destruct) {
                    sprintf(buf, "Armament recovery: %d.\n", s->destruct);
                    notify(playernum, governor, buf);
                    destval = s->destruct;

                    if ((s->whatdest == LEVEL_SHIP)
                        && ((s2->destruct + destval) > max_destruct)) {
                        destval = max_destruct - s2->destruct;
                        sprintf(buf,
                                "(There is only room for %d destruct.)\n",
                                destval);

                        notify(playernum, governor, buf);
                    }
                } else {
                    destval = 0;
                }

                if (s->popn + s->troops) {
                    if ((s->whatdest == LEVEL_PLAN)
                        && (sect->owner > 0)
                        && (sect->owner != playernum)) {
                        sprintf(buf,
                                "You don't own this sector; no crew can be recovered.\n");

                        notify(playernum, governor, buf);
                    } else {
                        troopval = s->troops;

                        if (s2->type == OTYPE_FACTORY) {
                            max_mil = Shipdata[s2->type][ABIL_MAXCREW] - s->popn;
                        } else {
                            max_mil = s2->max_crew - s2->popn;
                        }

                        if ((s->whatdest == LEVEL_SHIP)
                            && ((s2->troops + troopval) > max_mil)) {
                            troopval = max_mil - s2->troops;
                            sprintf(buf,
                                    "(There is only room for %d troops.)\n",
                                    troopval);

                            notify(playernum, governor, buf);
                        }

                        crewval = s->popn;

                        if (s2->type == OTYPE_FACTORY) {
                            max_crew = Shipdata[s2->type][ABIL_MAXCREW] - s2->troops;
                        } else {
                            max_crew = s2->max_crew - s2->troops;
                        }

                        if ((s->whatdest == LEVEL_SHIP)
                            && ((s2->popn + crewval) > max_crew)) {
                            crewval = max_crew - s2->popn;
                            sprintf(buf,
                                    "(There is only room for %d crew.)\n",
                                    crewval);

                            notify(playernum, governor, buf);
                        }

                        sprintf(buf,
                                "Population/Troops recover: %d/%d.\n",
                                crewval,
                                troopval);

                        notify(playernum, governor, buf);
                    }
                } else {
                    crewval = 0;
                    troopval = 0;
                }

                if (s->crystals + s->mounted) {
                    if ((s->whatdest == LEVEL_PLAN)
                        && (sect->owner > 0)
                        && (sect->owner != playernum)) {
                        sprintf(buf,
                                "You don't own this sector; no crystals can be recovered.\n");

                        notify(playernum, governor, buf);
                    } else {
                        xtalval = s->crystals + s->mounted;

                        if ((s->whatdest == LEVEL_SHIP)
                            && ((s2->crystals + xtalval) > 127)) {
                            xtalval = 127 - s2->crystals;
                            sprintf(buf,
                                    "(There is only room for %d crystals.)\n",
                                    xtalval);

                            notify(playernum, governor, buf);
                        }

                        sprintf(buf, "Crystal recover: %d.\n", xtalval);
                        notify(playernum, governor, buf);
                    }
                } else {
                    xtalval = 0;
                }
            }

            /* More adjustments needed here for hangar. Maarten */
            if (s->whatorbits == LEVEL_SHIP) {
                s2->hangar -= (unsigned short)s->size;
            }

            if (s->whatorbits == LEVEL_UNIV) {
                deductAPs(playernum, governor, apcount, 0, 1);
            } else {
                deductAPs(playernum, governor, apcount, (int)s->storbits, 0);
            }

            if (docked(s) || inship(s)) {
                s2->crystals += xtalval;
                rcv_fuel(s2, (double)fuelval);
                rcv_destruct(s2, destval);
                rcv_resource(s2, scrapval);
                rcv_troops(s2, troopval, race->mass);
                rcv_popn(s2, crewval, race->mass);

                /*
                 * Check for docking status in case scrapped ship is
                 * landed. Maarten
                 */
                if (s->whatorbits != LEVEL_SHIP) {
                    s2->docked = 0; /* Undock the surviving ship */
                    s2->whatdest = LEVEL_UNIV;
                    s2->destshipno = 0;
                }

                putship(s2);
                free(s2);
            }

            if (s->whatorbits == LEVEL_PLAN) {
                free(planet); /* this has already been allocated */
                getplanet(&planet, (int)s->storbits, (int)s->pnumorbits);

                if (landed(s) || inship(s)) {
                    /*
                     * If colonizing the sector, set sector owner and give a
                     * message it's also nice to check if there is anyone to
                     * colonize
                     */
                    if ((sect->owner == 0)
                        && ((troopval > 0) || (crewval > 0))) {
                        sect->owner = playernum;
                        ++planet->info[playernum - 1].numsectsowned;
                        sprintf(buf,
                                "Sector %d,%d Colonized.\n",
                                s->land_x,
                                s->land_y);

                        notify(playernum, governor, buf);
                    }

                    /* Increase sector's crew and troop count */
                    sect->troops += troopval;
                    sect->popn += crewval;

                    /*
                     * Increase planet's crew, troop, res, tec. count for this
                     * player
                     */
                    planet->info[playernum - 1].popn += crewval;
                    planet->info[playernum - 1].troops += troopval;

                    /*
                     * New code by Kharush. Scrapping does not anymore overflow
                     * stockpiles.
                     */
                    if ((planet->info[playernum - 1].resource + scrapval) <= USHRT_MAX) {
                        planet->info[playernum - 1].resource += scrapval;
                    } else {
                        planet->info[playernum - 1].resource = USHRT_MAX;
                        sprintf(buf,
                                "Planet has room for only %d resources.\n",
                                USHRT_MAX - planet->info[playernum - 1].resource);

                        notify(playernum, governor, buf);
                    }

                    if ((playernum->info[playernum - 1].fuel + fuelval) <= USHRT_MAX) {
                        planet->info[playernum - 1].fuel += fuelval;
                    } else {
                        planet->info[playernum - 1].fuel = USHRT_MAX;
                        sprintf(buf,
                                "Planet has room for only %d fuel.\n",
                                USHRT_MAX - planet->info[playernum - 1].fuel);

                        notify(playernum, governor, buf);
                    }

                    if ((planet->info[playernum - 1].destruct + destval) <= USHRT_MAX) {
                        planet->info[playernum - 1].destruct += destval;
                    } else {
                        planet->info[playernum - 1].destruct = USHRT_MAX;
                        sprintf(buf,
                                "Planet has room for only %d destruct.\n",
                                USHRT_MAX - planet->info[playernum - 1].destruct);

                        notify(playernum, governor, buf);
                    }

                    /*
                     * Old code
                     *
                     * planet->info[playernum - 1].resource += scrapval;
                     * planet->info[playernum - 1].destruct += destval;
                     * planet->info[playernum - 1].fuel += (int)fuelval;
                     */

                    plant->popn += crewval;
                    planet->info[playernum - 1].crystals += (int)xtalval;
                    putsector(sect, planet, (int)s->land_x, (int)s->land_y);
                    free(sect);
                }

                putplanet(planet, (int)s->storbits, (int)s->pnumorbits);
            }

            kill_ship(playernum, s);
            putship(s);
            free(s);

            if (landed(s)) {
                sprintf(buf, "\nScrapped.\n");
            } else {
                sprintf(buf, "\nDestroyed.\n");
            }

            notify(playernum, governor, buf);
        } else {
            free(s);
        }

        shipno = do_shiplist(&s, &nextshipno);
    }
}
Пример #9
0
void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
    int i,n;

    dBodyID b1,b2;

    // only collide things with the ground
    int g1 = (o1 == ground );
    int g2 = (o2 == ground );
    if (!(g1 ^ g2))
    {
        //printf ("Ground colliding..\n");

        //return;
    }


    b1 = dGeomGetBody(o1);
    b2 = dGeomGetBody(o2);
    if (b1 && b2 && dAreConnected (b1,b2)) return;

    if (b1 && isAction(b1) && b2 && (isType(b2,WALRUS) || (isType(b2,MANTA))) && isMineFire(gVehicle(b2),(Gunshot*)gVehicle(b1)) ) return;
    if (b2 && isAction(b2) && b1 && (isType(b1,WALRUS) || (isType(b1,MANTA))) && isMineFire(gVehicle(b1),(Gunshot*)gVehicle(b2)) ) return;

    int val[]={CARRIER,WALRUS,MANTA};

    if (o1 && isRay(o1) && b2 && isType(b2,val,3) && rayHit(gVehicle(b2),(LaserRay*)gVehicle(o1))) {return;}
    if (o2 && isRay(o2) && b1 && isType(b1,val,3) && rayHit(gVehicle(b1),(LaserRay*)gVehicle(o2))) {return;}

    const int N = 10;
    dContact contact[N];
    n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
    if (n > 0) {
        for (i=0; i<n; i++) {

            Vehicle *v1=NULL,*v2=NULL;
            Structure *s1=NULL, *s2=NULL;
            gVehicle(v1,v2,dGeomGetBody(contact[i].geom.g1), dGeomGetBody(contact[i].geom.g2),s1,s2,contact[i].geom.g1,contact[i].geom.g2);


            // Bullets
            if ((isAction(v1) && isWalrus(v2) && isMineFire(v2,(Gunshot*)v1))
                ||
               (isAction(v2) && isWalrus(v1) && isMineFire(v1,(Gunshot*)v2)))
            {
                // Water buyoncy reaction
                contact[i].surface.mode = dContactSlip1 | dContactSlip2 |
                dContactSoftERP | dContactSoftCFM | dContactApprox1;

                contact[i].surface.mu = 0.0f;
                contact[i].surface.slip1 = 1.0f;
                contact[i].surface.slip2 = 1.0f;
                contact[i].surface.soft_erp = 1.0f;   // 0 in both will force the surface to be tight.
                contact[i].surface.soft_cfm = 1.0f;
            } else
            if ( isAction(v1) || isAction(v2))
            {
                contact[i].surface.mode = dContactSlip1 | dContactSlip2 |
                dContactSoftERP | dContactSoftCFM | dContactApprox1;
                contact[i].surface.mu = 0;
                contact[i].surface.slip1 = 0.1f;
                contact[i].surface.slip2 = 0.1f;

                if (isAction(v1) && isCarrier(v2) && hit(v2,(Gunshot*)v1)) {}
                if (isAction(v2) && isCarrier(v1) && hit(v1,(Gunshot*)v2)) {}
                if (isAction(v1) && isManta(v2) && hit(v2,(Gunshot*)v1)) {}
                if (isAction(v2) && isManta(v1) && hit(v1,(Gunshot*)v2)) {}
                if (isAction(v1) && isWalrus(v2) && hit(v2,(Gunshot*)v1)) {}
                if (isAction(v2) && isWalrus(v1) && hit(v1,(Gunshot*)v2)) {}
                if (isAction(v1) && s2 && hit(s2)) {}
                if (isAction(v2) && s1 && hit(s1)) {}
            } else
            if ( ( isManta(v1) && isCarrier(v2) && releasecontrol(v1) ) ||
                 ( isManta(v2) && isCarrier(v1) && releasecontrol(v2) ) )
                {
                // Manta landing on Carrier
                contact[i].surface.mode = dContactBounce |
                dContactApprox1;

                contact[i].surface.mu = dInfinity;
                contact[i].surface.slip1 = 0.0f;
                contact[i].surface.slip2 = 0.0f;
                contact[i].surface.bounce = 0.2f;
            } else
            if  (isRunway(s1) || isRunway(s2))
            {
                // Manta landing on Runways.
                contact[i].surface.mode = dContactBounce |
                dContactApprox1;


                contact[i].surface.mu = 0.99f;
                contact[i].surface.slip1 = 0.9f;
                contact[i].surface.slip2 = 0.9f;
                contact[i].surface.bounce = 0.2f;

                if ( isRunway(s1) && isManta(v2) && landed(v2, s1->island)) {}
                if ( isRunway(s2) && isManta(v1) && landed(v1, s2->island)) {}

            } else
            if (isIsland(contact[i].geom.g1) || isIsland(contact[i].geom.g2))
            {
                 // Island reaction
                 contact[i].surface.mode = dContactBounce |
                 dContactApprox1;

                 contact[i].surface.mu = 0;
                 contact[i].surface.bounce = 0.2f;
                 contact[i].surface.slip1 = 0.1f;
                 contact[i].surface.slip2 = 0.1f;

                 contact[i].surface.soft_erp = 0;   // 0 in both will force the surface to be tight.
                 contact[i].surface.soft_cfm = 0;


                 // Carrier stranded and Walrus arrived on island.
                 if (isIsland(contact[i].geom.g1) && isCarrier(v2) && stranded(v2,getIsland(contact[i].geom.g1))) {}
                 if (isIsland(contact[i].geom.g2) && isCarrier(v1) && stranded(v1,getIsland(contact[i].geom.g2))) {}
                 if (isIsland(contact[i].geom.g1) && isWalrus(v2)  && arrived(v2,getIsland(contact[i].geom.g1))) {}
                 if (isIsland(contact[i].geom.g2) && isWalrus(v1)  && arrived(v1,getIsland(contact[i].geom.g2))) {}


            } else
            if (ground == contact[i].geom.g1 || ground == contact[i].geom.g2 ) {

                 // Water buyoncy reaction
                 contact[i].surface.mode = dContactSlip1 | dContactSlip2 |
                 dContactSoftERP | dContactSoftCFM | dContactApprox1;

                 contact[i].surface.mu = 0.0f;
                 contact[i].surface.slip1 = 0.1f;
                 contact[i].surface.slip2 = 0.1f;
                 contact[i].surface.soft_erp = .5f;   // 0 in both will force the surface to be tight.
                 contact[i].surface.soft_cfm = .3f;

                 // Walrus reaching shore.
                 if (ground == contact[i].geom.g1 && isWalrus(v2) && departed(v2)) {}
                 if (ground == contact[i].geom.g2 && isWalrus(v1) && departed(v1)) {}

                 if (ground == contact[i].geom.g1 && v2 && isManta(v2) && groundcollisions(v2)) {}
                 if (ground == contact[i].geom.g2 && v1 && isManta(v1) && groundcollisions(v1)) {}

            } else {
                /**
                // Water buyoncy reaction
                contact[i].surface.mode = dContactSlip1 | dContactSlip2 |
                dContactSoftERP | dContactSoftCFM | dContactApprox1;

                contact[i].surface.mu = 0.0f;
                contact[i].surface.slip1 = 0.1f;
                contact[i].surface.slip2 = 0.1f;
                contact[i].surface.soft_erp = .5f;   // 0 in both will force the surface to be tight.
                contact[i].surface.soft_cfm = .3f;
                **/
                if (v1 && isManta(v1) && groundcollisions(v1)) {}
                if (v2 && isManta(v2) && groundcollisions(v2)) {}
            }

            dJointID c = dJointCreateContact (world,contactgroup,&contact[i]);
            dJointAttach (c,
                          dGeomGetBody(contact[i].geom.g1),
                          dGeomGetBody(contact[i].geom.g2));
        }
    }
}
Пример #10
0
void orbit(playernum, int governor, int apcount)
{
    int sh;
    int i;
    int iq;
    planettype *p;
    shiptype *s;
    placetype where;
    orbitinfo oi;

    oi.DontDispStars = 0;
    oi.DontDispShips = oi.DontDispStars;
    oi.DontDispPlanets = oi.DontDispShips;
    oi.DontDispNum = -1;

    /* Find options, set flags accordingly */
    if (optn) {
        if (opts['s']) {
            oi.DontDispShips = 1;
        }

        if (opts['S']) {
            oi.Dontdispstars = 1;
        }

        if (opts['p']) {
            oi.DontDispPlanets = 1;
        }

        if (opts['d']) {
            or.DontDispNum = opts['d'];

            if (oi.DontDispNum) {
                /* Make a '1' into a '0' */
                --oi.DontDispNum;
            } else {
                sprintf(buf, "Bad number %d.\n", oi.DontDispNum);
                notify(playernum, governor, buf);
                oi.DontDispNum = -1;
            }
        }
    }

    if (argn == 1) {
        where = Getplace(playernum, governor, ":", 0);

        if (Dir[playernum - 1][governor].level == LEVEL_UNIV) {
            i = 1;
        } else {
            i = 0;
        }

        oi.Lastx = Dir[playernum - 1][governor].lastx[i];
        oi.Lasty = Dir[playernum - 1][governor].lasty[i];
        oi.Zoom = Dir[playernum - 1][governor].zoom[i];
    } else {
        where = Getplace(playernum, governor, args[argn - 1], 0);
        oi.Lasty = 0.0;
        oi.Lastx = oi.Lasty;
        oi.Zoom = 1.0;
    }

    if (where.err) {
        notify(playernum, governor, "Orbit: Error in args.\n");

        return;
    }

    /* Display CSP orbit instead, if the client can understand it */
    if (client_can_understand(playernum, governor, CSP_ORBIT_OUTPUT_INTRO)) {
        csp_orbit(playernum, governor, &oi);

        return;
    }

    /* Orbit type of map */
    notify(playernum, governor, "#");
    race = races[playernum - 1];

    switch (where.level) {
    case LEVEL_UNIV:
        for (i = 0; i < Sdata.numstars; ++i) {
            if (oi.DontdispNum != i) {
                DispStar(playernum,
                         governor,
                         LEVEL_UNIV,
                         Stars[i],
                         (int)race->God,
                         buf,
                         &oi);

                notify(playernum, governor, buf);
            }
        }

        if (!oi.DontDispShips) {
            sh = Sdata.ships;

            while (sh) {
                getship(&s, sh);

                if (oi.DontDispNum != sh) {
                    DispShip(playernum,
                             governor,
                             &where,
                             s,
                             NULL,
                             (int)race->God,
                             buf,
                             &oi);

                    notify(playernum, governor, buf);
                }

                sh = nextship(s);
                free(s);
            }
        }

        break;
    case LEVEL_STAR:
        DispStar(playernum,
                 governor,
                 LEVEL_STAR,
                 Stars[where.snum],
                 (int)race->God,
                 buf,
                 &oi);

        notify(playernum, governor, buf);

        for (i = 0; i < Stars[where.snum]->numplanets; ++i) {
            if (oi.DontDispNum != i) {
                getplanet(&p, (int)where.snum, i);

                DispPlanet(playernum,
                           governor,
                           LEVEL_STAR,
                           p,
                           Stars[where.snum]->pnames[i],
                           race,
                           buf,
                           &oi);

                notify(playernum, governor, buf);
                free(p);
            }
        }

        /*
         * Check to see if you have ships orbiting the star, if so you can see
         * enemy ships
         */
        iq = 0;

        if (race->God) {
            iq = 1;
        } else {
            sh = Stars[where.snum]->ships;

            while (sh && !iq) {
                getship(&s, sh);

                if ((s->owner == playernum)
                    && ((s->type == OTYPE_PROBE) || s->popn)) {
                    /* You are there to sight, need a crew */
                    iq = 1;
                }

                sh = nextship(s);
                free(s);
            }
        }

        if (!oi.DontDispShips) {
            sh = Stars[where].snum->ships;

            while (sh) {
                getship(&s, sh);

                if ((oi.DontDispNum != sh)
                    && ((s->owner == playernum) || (s->type == STYPE_MINEF))) {
                    if ((s->owner == playernum) || (iq == 1)) {
                        DispShip(playernum,
                                 governor,
                                 &where,
                                 s,
                                 NULL,
                                 (int)race->God,
                                 buf,
                                 &oi);

                        notify(playernum, governor, buf);
                    }
                }

                sh = nextship(s);
                free(s);
            }
        }

        break;
    case LEVEL_PLAN:
        getplanet(&p, (int)where.snum, (int)where.pnum);

        DispPlanet(playernum,
                   governor,
                   LEVEL_PLAN,
                   p,
                   Stars[where.snum]->pnames[where.pnum],
                   race,
                   buf,
                   &oi);

        notify(playernum, governor, buf);

        /*
         * Check to see if you have ships landed or orbiting the planet, if so
         * you can see orbiting enemy ships
         */
        iq = 0;
        sh = p->ships;

        while (sh && !iq) {
            getship(&s, sh);

            if ((s->owner == playernum)
                && ((s->type == OTYPE_PROBE) || s->popn)) {
                /* You are there to sight, need a crew */
                iq = 1;
            }

            sh = nextship(s);
            free(s);
        }

        /* End check */
        if (!oi.DontDispShips) {
            sh = p->ships;

            while (sh) {
                getship(&s, sh);

                if (oi.DontDispNum != sh) {
                    if (!landed(s)) {
                        if ((s->owner == playernum) || (iq == 1)) {
                            DispShip(playernum,
                                     governor,
                                     &where,
                                     s,
                                     p,
                                     (int)race->God,
                                     buf,
                                     &oi);

                            notify(playernum, governor, buf);
                        }
                    }
                }

                sh = nextship(s);
                free(s);
            }
        }

        free(p);

        break;
    default:
        notify(playernum, governor, "Bad scope.\n");

        return;
    }

    notify(playernum, governor, "\n");
}
Пример #11
0
void orbit(int Playernum, int Governor, int APcount)
{
register int sh,i,iq;
int DontDispNum= -1, flag;
planettype *p;
shiptype *s;
placetype where;
int DontDispPlanets, DontDispShips, DontDispStars;
char output[100000];

DontDispPlanets = DontDispShips = DontDispStars = 0;

/* find options, set flags accordingly */
for (flag=1; flag<=argn-1; flag++)
    if (*args[flag]=='-') {
	for (i=1; args[flag][i]!='\0'; i++)
	    switch (args[flag][i]) {
	      case 's': DontDispShips = 1;
		break;
	      case 'S': DontDispStars = 1;
		break;
	      case 'p': DontDispPlanets = 1;
		break;
	      default:
		if (sscanf(args[flag]+1,"%d",&DontDispNum)!=1) {
		    sprintf(buf, "Bad number %s.\n", args[flag]+1);
		    notify(Playernum, Governor, buf);
		    DontDispNum = -1;
		}
		if (DontDispNum)
		    DontDispNum--;	/* make a '1' into a '0' */
		break;
	    }
    }

if (argn==1) {
    where = Getplace(Playernum, Governor, ":", 0);
    i = (Dir[Playernum-1][Governor].level==LEVEL_UNIV); 
    Lastx = Dir[Playernum-1][Governor].lastx[i];
    Lasty = Dir[Playernum-1][Governor].lasty[i];
    Zoom = Dir[Playernum-1][Governor].zoom[i];
} else {
    where = Getplace(Playernum, Governor, args[argn-1], 0);
    Lastx = Lasty = 0.0;
    Zoom = 1.1;
}

if (where.err) {
    notify(Playernum, Governor, "orbit: error in args.\n");
    return;
}

/* orbit type of map */
sprintf(output, "#");

Race = races[Playernum-1];

switch (where.level) {
  case LEVEL_UNIV:
    for (i=0; i<Sdata.numstars; i++)
	if (DontDispNum!=i) {
	    DispStar(Playernum, Governor, LEVEL_UNIV, Stars[i], DontDispStars,
		     (int)Race->God, buf);
	    strcat(output, buf);
	}
    if (!DontDispShips) {
	sh = Sdata.ships;
	while (sh) {
	    (void)getship(&s, sh);
	    if (DontDispNum != sh) {
		DispShip(Playernum, Governor, &where, s, NULL,
			 (int)Race->God, buf);
		strcat(output, buf);
	    }
	    sh = s->nextship;
	    free(s);
	}
    }
    break;
  case LEVEL_STAR:
    DispStar(Playernum, Governor, LEVEL_STAR, Stars[where.snum],
	     DontDispStars, (int)Race->God, buf);
    strcat(output, buf);

    for (i=0; i<Stars[where.snum]->numplanets; i++)
	if (DontDispNum!=i) {
	    getplanet(&p,(int)where.snum,i);
	    DispPlanet(Playernum, Governor, LEVEL_STAR, p,
		       Stars[where.snum]->pnames[i],DontDispPlanets, Race, buf);
	    strcat(output, buf);
	    free(p);
	}
    /* check to see if you have ships at orbiting the star, if so you can
       see enemy ships */
    iq = 0;
    if(Race->God) iq = 1;
    else {
	sh = Stars[where.snum]->ships;
	while (sh && !iq) {
	    (void)getship(&s, sh);
	    if(s->owner == Playernum && Sight(s))
		iq = 1; /* you are there to sight, need a crew */
	    sh = s->nextship;
	    free(s);
	}
    }
    if (!DontDispShips) {
	sh = Stars[where.snum]->ships;
	while (sh) {
	    (void)getship(&s, sh);
	    if (DontDispNum != sh &&
		!(s->owner != Playernum && s->type == STYPE_MINE) ) {
		if((s->owner == Playernum) || (iq == 1)) {
		    DispShip(Playernum, Governor, &where, s, NULL,
			     (int)Race->God, buf);
		    strcat(output, buf);
		}
	    }
	    sh = s->nextship;
	    free(s);
	}
    }
    break;
  case LEVEL_PLAN:
    getplanet(&p,(int)where.snum,(int)where.pnum);
    DispPlanet(Playernum, Governor, LEVEL_PLAN, p,
	       Stars[where.snum]->pnames[where.pnum],
	       DontDispPlanets, Race, buf);
    strcat(output, buf);

/* check to see if you have ships at landed or
   orbiting the planet, if so you can see orbiting enemy ships */
    iq = 0;
    sh = p->ships;
    while (sh && !iq) {
	(void)getship(&s, sh);
	if(s->owner == Playernum && Sight(s))
	    iq = 1; /* you are there to sight, need a crew */
	sh = s->nextship;
	free(s);
    }
/* end check */
    if (!DontDispShips) {
	sh = p->ships;
	while (sh) {
	    (void)getship(&s, sh);
	    if (DontDispNum != sh) {
	     	if(!landed(s)) {
		    if((s->owner == Playernum) || (iq ==1)) {
			DispShip(Playernum, Governor, &where, s, p,
				 (int)Race->God, buf);
			strcat(output, buf);
		    }
		}
	    }
	    sh = s->nextship;
	    free(s);
	}
    }
    free(p);
    break;
  default:
    notify(Playernum, Governor,"Bad scope.\n");
    return;	 
}
strcat(output, "\n");
notify(Playernum, Governor, output);
}
Пример #12
0
void domine(int shipno, int detonate)
{
    int sh,sh2,i;
    shiptype *s, *ship;
    planettype *planet;
    racetype *r;

    (void)getship(&ship, shipno);

    if(ship->type!=STYPE_MINE || !ship->alive || !ship->owner) {
        free(ship);
        return;
    }
    /* check around and see if we should explode. */
    if (ship->on || detonate) {
        int rad=0;
        double xd,yd,range;

        switch(ship->whatorbits) {
        case LEVEL_STAR:
            sh = Stars[ship->storbits]->ships;
            break;
        case LEVEL_PLAN:
            getplanet(&planet, (int)ship->storbits, (int)ship->pnumorbits);
            sh=planet->ships;
            free(planet);
            break;
        default:
            free(ship);
            return;
        }
        sh2 = sh;
        /* traverse the list, look for ships that
        are closer than the trigger radius... */
        rad = 0;
        if(!detonate) {
            r = races[ship->owner-1];
            while (sh && !rad) {
                (void)getship(&s, sh);
                xd = s->xpos - ship->xpos;
                yd = s->ypos - ship->ypos;
                range = sqrt(xd*xd + yd*yd);
                if( !isset(r->allied, s->owner) && (s->owner != ship->owner) &&
                        ( (int)range <= ship->special.trigger.radius) )
                    rad = 1;
                else
                    sh = s->nextship;
                free(s);
            }
        } else
            rad = 1;

        if (rad) {
            sprintf(buf, "%s detonated at %s\n",
                    Ship(ship), prin_ship_orbits(ship));
            post(buf, COMBAT);
            notify_star((int)ship->owner, (int)ship->governor, 0,
                        (int)ship->storbits, buf);
            sh = sh2 ;
            while (sh) {
                (void)getship(&s, sh);
                if (sh != shipno && s->alive &&
                        (s->type != OTYPE_CANIST) && (s->type!=OTYPE_GREEN)) {
                    rad = shoot_ship_to_ship(ship, s, (int)(ship->destruct), 0, 0,
                                             long_buf, short_buf);
                    if(rad>0) {
                        post(short_buf, COMBAT);
                        warn((int)s->owner, (int)s->governor, long_buf);
                        putship(s);
                    }
                }
                sh = s->nextship;
                free(s);
            }

            /* if the mine is in orbit around a planet, nuke the planet too! */
            if(ship->whatorbits==LEVEL_PLAN) {
                /* pick a random sector to nuke */
                reg int x,y,numdest;
                getplanet(&planet, (int)ship->storbits, (int)ship->pnumorbits);
                if(landed(ship)) {
                    x = ship->land_x;
                    y = ship->land_y;
                } else {
                    x=int_rand(0, (int)planet->Maxx-1);
                    y=int_rand(0, (int)planet->Maxy-1);
                }
                numdest=shoot_ship_to_planet(ship, planet,
                                             (int)(ship->destruct), x, y, 1, 0, LIGHT,
                                             long_buf, short_buf);
                putplanet(planet, (int)ship->storbits, (int)ship->pnumorbits);

                sprintf(telegram_buf, "%s", buf);
                if(numdest>0) {
                    sprintf(buf, " - %d sectors destroyed.",numdest);
                    strcat(telegram_buf, buf);
                }
                strcat(telegram_buf, "\n");
                for(i=1; i<=Num_races; i++)
                    if(Nuked[i-1])
                        warn(i, (int)Stars[ship->storbits]->governor[i-1],
                             telegram_buf);
                notify((int)(ship->owner), (int)ship->governor, telegram_buf);
                free(planet);
            }
            kill_ship((int)(ship->owner), ship);
        }
        putship(ship);
    }
    free(ship);
}