Here it is. My package for spewing pods from a pod-spewer and docking them to a station that has a pod-spwer. Docking means they get properly docked/consumed by the spewer.
Code:
//
// By Joco. 14-Apr-2005.
//
// package iSpewPods
//
// iSpewPods.pog
//
// Package name ///////////////////////////////////////////////////////////////
package iSpewPods;
// Imports ////////////////////////////////////////////////////////////////////
// these are the packages were going to use
uses Debug, Task, Sim, iCargo, iHabitat, iSim, iFaction, iInventory, iHabitat, iDockport,
iPilotSetup, iAI;
// Exports ////////////////////////////////////////////////////////////////////
// these are the functions that are going to be called from other packages
// n.b. these start with uppercase letters, no underscores
provides SpewPod, DockPod;
// Local functions ////////////////////////////////////////////////////////////
prototype task detach_spewed_pod( hsim pod_sim );
prototype list get_subsims_like(hsim source, int type);
///////////////////////////////////////////////////////////////////////////////
// Detach spewed pods and send them away from the station for pick up
///////////////////////////////////////////////////////////////////////////////
list get_subsims_like(hsim source, int type)
{
// we need to find all the subsims in the source sim that have a type_flags
// equal to 'type'
hsubsim ssim;
list results;
int i;
int subsim_count = Sim.SubsimCount( source );
for(i = 0; i < subsim_count; ++i)
{
ssim = Sim.NthSubsim( source, i );
if( Object.IntProperty( ssim, "type_flags" ) == type )
{
List.AddTail( results, ssim );
}
}
return results;
}
task detach_spewed_pod( hsim pod_sim )
{
hsim dock_parent;
// as the pod spewer is animated we have to wait for the anim to finish before trying
// to do anything more - like undocking it.
Task.Sleep( Task.Current(), 15 ); // is there a better way?
dock_parent = Sim.Parent( pod_sim );
debug
{
Debug.PrintString( "detach_spewed_pod: pod_sims dock parent: " );
Debug.PrintHandle( dock_parent );
Debug.PrintString( "\n" );
}
// ensure the docking lock is off
iSim.SetDockingLock( iSim.Cast(dock_parent), iSim.Cast(pod_sim), false );
// undock from station
iSim.Undock( iSim.Cast(dock_parent), iSim.Cast(pod_sim) );
// Get the sim away from the station
Sim.SetVelocityLocalToSim( pod_sim, 0, 0, -200 );
}
hsim SpewPod(hhabitat station, int cargo_type, string owner_faction, string cargo_faction)
{
hsim pod_sim;
hcargo cargo_defn;
string sim_url = "ini:/sims/ships/utility/cargo_pod";
//sim_url = "ini:/sims/ships/utility/freightpod";
debug Debug.PrintString( "iSpewPods.SpewPod: Version 0.1\n" );
// make sure station has a spewer
if( !iHabitat.HasSpewer( station ) )
{
return none;
}
// is there a free spewer slot?
if( !iHabitat.HasSpewerSlotFree( station ) )
{
return none;
}
cargo_defn = iCargo.Find(cargo_type);
pod_sim = Sim.Create(sim_url, iCargo.Name( cargo_defn ));
if( pod_sim == none)
{
// if failed to create the sim don't go any further
return none;
}
if (iSim.Type(iSim.Cast(pod_sim)) == T_CargoPod)
{
// we have a cargo pod, so set it up correctly
//iSim.SetFaction(iSim.Cast(pod_sim), iFaction.Find(owner_faction));
Object.AddIntProperty(pod_sim,"cargo",cargo_type);
//Object.AddIntProperty(pod,"cargo_faction",iFaction.Allegiance(iFaction.Find(cargo_faction)));
}
// try to spew from station
if( iHabitat.Spew( station, pod_sim) )
{
// install a basic AI in the pod so we can direct it to do things later,
// like dock with things.
iPilotSetup.GenericCargoPod( iShip.Cast(pod_sim) );
Task.Detach( start detach_spewed_pod( pod_sim ) );
return pod_sim;
}
return none;
}
bool DockPod(hsim pod_sim, hhabitat station)
{
int i;
hsubsim spewer_port;
hsubsim pod_sim_port;
set station_modules;
hobject hobj;
list spewer_port_list;
debug Debug.PrintString( "iSpewPods.DockPod: Version 0.1\n" );
// Some sanity checks first
// make sure station has a spewer
if( !iHabitat.HasSpewer( station ) )
{
return false;
}
if( !iHabitat.HasSpewerSlotFree( station ) )
{
return false;
}
// get handle to a spewer docking port
spewer_port_list = get_subsims_like( Sim.Cast(station), 64);
// find the first available port to use
while( !List.IsEmpty( spewer_port_list ) )
{
spewer_port = Subsim.Cast( List.Head( spewer_port_list ) );
List.RemoveHead( spewer_port_list );
// test if this port is available and enabled
if( iDockport.Status( iDockport.Cast(spewer_port) ) == DS_Free)
{
if( !iDockport.IsDisabled( iDockport.Cast(spewer_port) ) )
break;
}
spewer_port = none;
}
debug
{
Debug.PrintString( "spewer_port = " );
Debug.PrintHandle( spewer_port );
Debug.PrintString( "\n" );
}
// get the dockport on the cargo pod
pod_sim_port = Sim.FindSubsimByName( pod_sim, "system_pod_port" );
// make sure we have both docking ports
if((spewer_port == none) || (pod_sim_port == none))
{
debug Debug.PrintString( "iSpewPods.DockPod: failed to find both spewer port and pod port\n");
return false;
}
// give the pods installed AI the docking order.
iAI.GiveDockOrderWithDockport( iDockport.Cast(pod_sim_port), iDockport.Cast(spewer_port) );
return true;
}