Example #1
0
void Body::UpdateFrame()
{
	if (!(GetFlags() & Body::FLAG_CAN_MOVE_FRAME)) return;

	// falling out of frames
	if (!GetFrame()->IsLocalPosInFrame(GetPosition())) {
		printf("%s leaves frame %s\n", GetLabel().c_str(), GetFrame()->GetLabel().c_str());

		Frame *new_frame = GetFrame()->m_parent;
		if (new_frame) { // don't let fall out of root frame
			matrix4x4d m = matrix4x4d::Identity();
			GetFrame()->ApplyLeavingTransform(m);

			vector3d new_pos = m * GetPosition();

			matrix4x4d rot;
			GetRotMatrix(rot);
			SetRotMatrix(m * rot);
			
			m.ClearToRotOnly();
			SetVelocity(GetFrame()->GetVelocity() + m*(GetVelocity() - 
				GetFrame()->GetStasisVelocityAtPosition(GetPosition())));

			SetFrame(new_frame);
			SetPosition(new_pos);

			Pi::luaOnFrameChanged->Queue(this);
			
			return;
		}
	}

	// entering into frames
	for (std::list<Frame*>::iterator j = GetFrame()->m_children.begin(); j != GetFrame()->m_children.end(); ++j) {
		Frame *kid = *j;
		matrix4x4d m;
		Frame::GetFrameTransform(GetFrame(), kid, m);
		vector3d pos = m * GetPosition();
		if (!kid->IsLocalPosInFrame(pos)) continue;
		
		printf("%s enters frame %s\n", GetLabel().c_str(), kid->GetLabel().c_str());

		SetPosition(pos);
		SetFrame(kid);

		matrix4x4d rot;
		GetRotMatrix(rot);
		SetRotMatrix(m * rot);
				
		// get rid of transforms
		m.ClearToRotOnly();
		SetVelocity(m*(GetVelocity() - kid->GetVelocity())
			+ kid->GetStasisVelocityAtPosition(pos));

		Pi::luaOnFrameChanged->Queue(this);

		break;
	}
}
Example #2
0
/*
 * Function: SpawnShipNear
 *
 * Create a ship and place it in space near the given <Body>.
 *
 * > ship = Space.SpawnShip(type, body, min, max, hyperspace)
 *
 * Parameters:
 *
 *   type - the name of the ship
 *
 *   body - the <Body> near which the ship should be spawned
 *
 *   min - minimum distance from the body to place the ship, in Km
 *
 *   max - maximum distance to place the ship
 *
 *   hyperspace - optional table containing hyperspace entry information. If
 *                this is provided the ship will not spawn directly. Instead,
 *                a hyperspace cloud will be created that the ship will exit
 *                from. The table contains two elements, a <SystemPath> for
 *                the system the ship is travelling from, and the due
 *                date/time that the ship should emerge from the cloud.
 *
 * Return:
 *
 *   ship - a <Ship> object for the new ship
 *
 * Example:
 *
 * > -- spawn a ship 10km from the player
 * > local ship = Ship.SpawnNear("viper_police_craft", Game.player, 10, 10)
 *
 * Availability:
 *
 *   alpha 10
 *
 * Status:
 *
 *   experimental
 */
static int l_space_spawn_ship_near(lua_State *l)
{
	if (!Pi::game)
		luaL_error(l, "Game is not started");

	LUA_DEBUG_START(l);

	const char *type = luaL_checkstring(l, 1);
	if (! ShipType::Get(type))
		luaL_error(l, "Unknown ship type '%s'", type);

	Body *nearbody = LuaBody::CheckFromLua(2);
	float min_dist = luaL_checknumber(l, 3);
	float max_dist = luaL_checknumber(l, 4);

	SystemPath *path = NULL;
	double due = -1;
	_unpack_hyperspace_args(l, 5, path, due);

	Ship *ship = new Ship(type);
	assert(ship);

	Body *thing = _maybe_wrap_ship_with_cloud(ship, path, due);

	// XXX protect against spawning inside the body
	Frame * newframe = nearbody->GetFrame();
	const vector3d newPosition = (MathUtil::RandomPointOnSphere(min_dist, max_dist)* 1000.0) + nearbody->GetPosition();
	// If the frame is rotating and the chosen position is too far, use non-rotating parent.
	// Otherwise the ship will be given a massive initial velocity when it's bumped out of the
	// rotating frame in the next update
	if (newframe->IsRotatingFrame() && !newframe->IsLocalPosInFrame(newPosition)) {
		assert(newframe->m_parent);
		newframe = newframe->m_parent;
	}

	thing->SetFrame(newframe);;
	thing->SetPosition(newPosition);
	thing->SetVelocity(vector3d(0,0,0));
	Pi::game->GetSpace()->AddBody(thing);

	LuaShip::PushToLua(ship);

	LUA_DEBUG_END(l, 1);

	return 1;
}