JS properties and methods for docking (issue #35)

ship.dockingInstructions;
ship.requestDockingInstructions(); from targeted else nearest station, returns instructions, sets flight parameters to instructions
ship.recallDockingInstructions(); returns instructions, resets flight parameters to instructions
This commit is contained in:
cim 2013-07-07 10:58:53 +01:00
parent 4e0797139f
commit b3681c2cdc
6 changed files with 134 additions and 86 deletions

View File

@ -1043,6 +1043,7 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
- (void) landOnPlanet:(OOPlanetEntity *)planet;
- (void) abortDocking;
- (NSDictionary *) dockingInstructions;
- (void) broadcastThargoidDestroyed;

View File

@ -12352,6 +12352,13 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
}
- (NSDictionary *) dockingInstructions
{
OOLog(@"docking.debug",@"%@",dockingInstructions);
return dockingInstructions;
}
- (void) broadcastThargoidDestroyed
{
[[UNIVERSE findShipsMatchingPredicate:HasRolePredicate

View File

@ -67,4 +67,8 @@ MA 02110-1301, USA.
- (void) broadcastDistressMessage;
- (void) requestDockingCoordinates;
- (void) recallDockingInstructions;
@end

View File

@ -111,8 +111,6 @@
- (void) checkForFullHold;
- (void) requestDockingCoordinates;
- (void) getWitchspaceEntryCoordinates;
- (void) setDestinationFromCoordinates;
@ -222,7 +220,6 @@
- (void) setTargetToRandomStation;
- (void) setTargetToLastStation;
- (void) recallDockingInstructions;
- (void) addFuel:(NSString *) fuel_number;
@ -475,6 +472,89 @@
}
- (void) requestDockingCoordinates
{
/*- requests coordinates from the target station
if the target station can't be found
then use the nearest it can find (which may be a rock hermit) -*/
StationEntity *station = nil;
Entity *targStation = nil;
NSString *message = nil;
double distanceToStation2 = 0.0;
targStation = [self targetStation];
if ([targStation isStation])
{
station = (StationEntity*)targStation;
}
else
{
station = [UNIVERSE nearestShipMatchingPredicate:IsStationPredicate
parameter:nil
relativeToEntity:self];
}
distanceToStation2 = distance2([station position], [self position]);
// Player check for being inside the aegis already exists in PlayerEntityControls. We just
// check here that distance to station is less than 2.5 times scanner range to avoid problems with
// NPC ships getting stuck with a dockingAI while just outside the aegis - Nikos 20090630, as proposed by Eric
// On very busy systems (> 50 docking ships) docking ships can be sent to a hold position outside the range,
// so also test for presence of dockingInstructions. - Eric 20091130
if (station != nil && (distanceToStation2 < SCANNER_MAX_RANGE2 * 6.25 || dockingInstructions != nil))
{
// remember the instructions
[dockingInstructions release];
dockingInstructions = [[station dockingInstructionsForShip:self] retain];
if (dockingInstructions != nil)
{
[self recallDockingInstructions];
message = [dockingInstructions objectForKey:@"ai_message"];
if (message != nil) [shipAI message:message];
message = [dockingInstructions objectForKey:@"comms_message"];
if (message != nil) [station sendExpandedMessage:message toShip:self];
}
OOLog(@"docking.debug",@"%@",dockingInstructions);
}
else
{
DESTROY(dockingInstructions);
}
if (dockingInstructions == nil)
{
[shipAI message:@"NO_STATION_FOUND"];
}
}
- (void) recallDockingInstructions
{
if (dockingInstructions != nil)
{
destination = [dockingInstructions oo_vectorForKey:@"destination"];
desired_speed = fmin([dockingInstructions oo_floatForKey:@"speed"], maxFlightSpeed);
desired_range = [dockingInstructions oo_floatForKey:@"range"];
if ([dockingInstructions objectForKey:@"station"])
{
StationEntity *targetStation = [[dockingInstructions objectForKey:@"station"] weakRefUnderlyingObject];
if (targetStation != nil)
{
[self addTarget:targetStation];
[self setTargetStation:targetStation];
}
else
{
[self removeTarget:[self primaryTarget]];
}
}
docking_match_rotation = [dockingInstructions oo_boolForKey:@"match_rotation"];
}
}
- (void) scanForNearestIncomingMissile
{
BinaryOperationPredicateParameter param =
@ -2403,88 +2483,6 @@
}
- (void) requestDockingCoordinates
{
/*- requests coordinates from the target station
if the target station can't be found
then use the nearest it can find (which may be a rock hermit) -*/
StationEntity *station = nil;
Entity *targStation = nil;
NSString *message = nil;
double distanceToStation2 = 0.0;
targStation = [self targetStation];
if ([targStation isStation])
{
station = (StationEntity*)targStation;
}
else
{
station = [UNIVERSE nearestShipMatchingPredicate:IsStationPredicate
parameter:nil
relativeToEntity:self];
}
distanceToStation2 = distance2([station position], [self position]);
// Player check for being inside the aegis already exists in PlayerEntityControls. We just
// check here that distance to station is less than 2.5 times scanner range to avoid problems with
// NPC ships getting stuck with a dockingAI while just outside the aegis - Nikos 20090630, as proposed by Eric
// On very busy systems (> 50 docking ships) docking ships can be sent to a hold position outside the range,
// so also test for presence of dockingInstructions. - Eric 20091130
if (station != nil && (distanceToStation2 < SCANNER_MAX_RANGE2 * 6.25 || dockingInstructions != nil))
{
// remember the instructions
[dockingInstructions release];
dockingInstructions = [[station dockingInstructionsForShip:self] retain];
if (dockingInstructions != nil)
{
[self recallDockingInstructions];
message = [dockingInstructions objectForKey:@"ai_message"];
if (message != nil) [shipAI message:message];
message = [dockingInstructions objectForKey:@"comms_message"];
if (message != nil) [station sendExpandedMessage:message toShip:self];
}
}
else
{
DESTROY(dockingInstructions);
}
if (dockingInstructions == nil)
{
[shipAI message:@"NO_STATION_FOUND"];
}
}
- (void) recallDockingInstructions
{
if (dockingInstructions != nil)
{
destination = [dockingInstructions oo_vectorForKey:@"destination"];
desired_speed = fmin([dockingInstructions oo_floatForKey:@"speed"], maxFlightSpeed);
desired_range = [dockingInstructions oo_floatForKey:@"range"];
if ([dockingInstructions objectForKey:@"station"])
{
StationEntity *targetStation = [[dockingInstructions objectForKey:@"station"] weakRefUnderlyingObject];
if (targetStation != nil)
{
[self addTarget:targetStation];
[self setTargetStation:targetStation];
}
else
{
[self removeTarget:[self primaryTarget]];
}
}
docking_match_rotation = [dockingInstructions oo_boolForKey:@"match_rotation"];
}
}
- (void) addFuel:(NSString*) fuel_number
{

View File

@ -465,7 +465,6 @@ NSDictionary *OOMakeDockingInstructions(StationEntity *station, Vector coords, f
[acc oo_setFloat:speed forKey:@"speed"];
[acc oo_setFloat:range forKey:@"range"];
[acc setObject:[[station weakRetain] autorelease] forKey:@"station"];
[acc oo_setInteger:[station universalID] forKey:@"station_id"]; // TODO: remove
[acc oo_setBool:match_rotation forKey:@"match_rotation"];
if (ai_message)
{

View File

@ -115,6 +115,9 @@ static JSBool ShipPerformScriptedAttackAI(JSContext *context, uintN argc, jsval
static JSBool ShipPerformStop(JSContext *context, uintN argc, jsval *vp);
static JSBool ShipPerformTumble(JSContext *context, uintN argc, jsval *vp);
static JSBool ShipRequestDockingInstructions(JSContext *context, uintN argc, jsval *vp);
static JSBool ShipRecallDockingInstructions(JSContext *context, uintN argc, jsval *vp);
static BOOL RemoveOrExplodeShip(JSContext *context, uintN argc, jsval *vp, BOOL explode);
static JSBool ShipSetMaterialsInternal(JSContext *context, uintN argc, jsval *vp, ShipEntity *thisEnt, BOOL fromShaders);
@ -168,6 +171,7 @@ enum
kShip_desiredSpeed, // AI desired flight speed, double, read/write
kShip_destination, // flight destination, Vector, read/write
kShip_displayName, // name displayed on screen, string, read/write
kShip_dockingInstructions, // name displayed on screen, string, read/write
kShip_energyRechargeRate, // energy recharge rate, float, read-only
kShip_entityPersonality, // per-ship random number, int, read-only
kShip_equipment, // the ship's equipment, array of EquipmentInfo, read only
@ -290,6 +294,7 @@ static JSPropertySpec sShipProperties[] =
{ "desiredSpeed", kShip_desiredSpeed, OOJS_PROP_READWRITE_CB },
{ "destination", kShip_destination, OOJS_PROP_READWRITE_CB },
{ "displayName", kShip_displayName, OOJS_PROP_READWRITE_CB },
{ "dockingInstructions", kShip_dockingInstructions, OOJS_PROP_READONLY_CB },
{ "energyRechargeRate", kShip_energyRechargeRate, OOJS_PROP_READONLY_CB },
{ "entityPersonality", kShip_entityPersonality, OOJS_PROP_READONLY_CB },
{ "equipment", kShip_equipment, OOJS_PROP_READONLY_CB },
@ -433,6 +438,8 @@ static JSFunctionSpec sShipMethods[] =
{ "remove", ShipRemove, 0 },
{ "removeEquipment", ShipRemoveEquipment, 1 },
{ "requestHelpFromGroup", ShipRequestHelpFromGroup, 1},
{ "requestDockingInstructions", ShipRequestDockingInstructions, 0},
{ "recallDockingInstructions", ShipRecallDockingInstructions, 0},
{ "restoreSubEntities", ShipRestoreSubEntities, 0 },
{ "__runLegacyScriptActions", ShipRunLegacyScriptActions, 2 }, // Deliberately not documented
{ "selectNewMissile", ShipSelectNewMissile, 0 },
@ -884,6 +891,10 @@ static JSBool ShipGetProperty(JSContext *context, JSObject *this, jsid propID, j
result = [entity contractListForScripting];
break;
case kShip_dockingInstructions:
result = [entity dockingInstructions];
break;
case kShip_scannerDisplayColor1:
result = [[entity scannerDisplayColor1] normalizedArray];
break;
@ -3004,6 +3015,34 @@ static JSBool ShipPerformTumble(JSContext *context, uintN argc, jsval *vp)
}
static JSBool ShipRequestDockingInstructions(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
ShipEntity *thisEnt = nil;
GET_THIS_SHIP(thisEnt);
[thisEnt requestDockingCoordinates];
OOJS_RETURN_OBJECT([thisEnt dockingInstructions]);
OOJS_PROFILE_EXIT
}
static JSBool ShipRecallDockingInstructions(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
ShipEntity *thisEnt = nil;
GET_THIS_SHIP(thisEnt);
[thisEnt recallDockingInstructions];
OOJS_RETURN_OBJECT([thisEnt dockingInstructions]);
OOJS_PROFILE_EXIT
}
static JSBool ShipBroadcastDistressMessage(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER