Merge pull request #112 from OoliteProject/customisable-laser-properties
Customisable laser properties
This commit is contained in:
commit
5d07437a55
@ -97,6 +97,23 @@
|
||||
available_to_all = true;
|
||||
}
|
||||
),
|
||||
(
|
||||
3, 0, "Remove Laser",
|
||||
"EQ_WEAPON_NONE",
|
||||
"Remove laser weapon from selected mounting.",
|
||||
{
|
||||
condition_script = "oolite-conditions.js";
|
||||
available_to_all = true;
|
||||
weapon_info = {
|
||||
range = 32000;
|
||||
energy = 0.0;
|
||||
damage = 0.0;
|
||||
recharge_rate = 100.0;
|
||||
shot_temperature = 0.0;
|
||||
threat_assessment = -1.0;
|
||||
};
|
||||
}
|
||||
),
|
||||
(
|
||||
3, 4000, "Pulse Laser",
|
||||
"EQ_WEAPON_PULSE_LASER",
|
||||
@ -104,6 +121,15 @@
|
||||
{
|
||||
condition_script = "oolite-conditions.js";
|
||||
available_to_all = true;
|
||||
weapon_info = {
|
||||
range = 12500;
|
||||
energy = 0.8;
|
||||
damage = 15.0;
|
||||
recharge_rate = 0.5;
|
||||
shot_temperature = 7.0;
|
||||
color = "redColor";
|
||||
threat_assessment = 0.0;
|
||||
};
|
||||
}
|
||||
),
|
||||
(
|
||||
@ -113,6 +139,16 @@
|
||||
{
|
||||
condition_script = "oolite-conditions.js";
|
||||
available_to_all = true;
|
||||
weapon_info = {
|
||||
range = 15000;
|
||||
energy = 0.5;
|
||||
damage = 6.0;
|
||||
recharge_rate = 0.1;
|
||||
shot_temperature = 3.2;
|
||||
color = "yellowColor";
|
||||
threat_assessment = 0.5;
|
||||
};
|
||||
|
||||
}
|
||||
),
|
||||
(
|
||||
@ -122,6 +158,16 @@
|
||||
{
|
||||
condition_script = "oolite-conditions.js";
|
||||
available_to_all = true;
|
||||
weapon_info = {
|
||||
range = 12500;
|
||||
energy = 1.4;
|
||||
damage = 50.0;
|
||||
recharge_rate = 2.5;
|
||||
shot_temperature = 10.0;
|
||||
color = "blueColor";
|
||||
is_mining_laser = 1;
|
||||
threat_assessment = -0.5;
|
||||
};
|
||||
}
|
||||
),
|
||||
(
|
||||
@ -131,6 +177,15 @@
|
||||
{
|
||||
condition_script = "oolite-conditions.js";
|
||||
available_to_all = true;
|
||||
weapon_info = {
|
||||
range = 30000;
|
||||
energy = 1.1;
|
||||
damage = 12.0;
|
||||
recharge_rate = 0.1;
|
||||
shot_temperature = 4.25;
|
||||
color = "magentaColor";
|
||||
threat_assessment = 1.0;
|
||||
};
|
||||
}
|
||||
),
|
||||
/* condition script blocks this one from appearing normally */
|
||||
@ -287,6 +342,16 @@
|
||||
"Captured Thargoid weapon, self-aiming.",
|
||||
{
|
||||
available_to_player = false;
|
||||
weapon_info = {
|
||||
range = 17500;
|
||||
energy = 1.1;
|
||||
damage = 12.5;
|
||||
recharge_rate = 1.0;
|
||||
shot_temperature = 8.0;
|
||||
color = "greenColor";
|
||||
is_turret_laser = true;
|
||||
threat_assessment = 1.0;
|
||||
};
|
||||
}
|
||||
),
|
||||
(
|
||||
@ -318,12 +383,12 @@
|
||||
condition_script = "oolite-conditions.js";
|
||||
}
|
||||
),
|
||||
/* next item was a test item */
|
||||
(
|
||||
2, 2000, "Twin Plasma Cannon",
|
||||
"EQ_WEAPON_TWIN_PLASMA_CANNON",
|
||||
"Basic cannon delivering charged plasma bursts at sublight speed."
|
||||
),
|
||||
/* next item was a test item, no longer supported */
|
||||
// (
|
||||
// 2, 2000, "Twin Plasma Cannon",
|
||||
// "EQ_WEAPON_TWIN_PLASMA_CANNON",
|
||||
// "Basic cannon delivering charged plasma bursts at sublight speed."
|
||||
// ),
|
||||
/* new items */
|
||||
(
|
||||
4, 15000, "External Heat Shielding",
|
||||
|
@ -447,7 +447,6 @@ typedef enum
|
||||
|
||||
GLfloat forward_shield, aft_shield;
|
||||
OOTimeDelta forward_shot_time, aft_shot_time, port_shot_time, starboard_shot_time;
|
||||
GLfloat weapon_energy_use, weapon_reload_time;
|
||||
|
||||
OOWeaponFacing chosen_weapon_facing; // for purchasing weapons
|
||||
|
||||
|
@ -718,10 +718,10 @@ NSComparisonResult marketSorterByMassUnit(id a, id b, void *market);
|
||||
|
||||
[result oo_setBool:[self weaponsOnline] forKey:@"weapons_online"];
|
||||
|
||||
[result oo_setInteger:forward_weapon_type forKey:@"forward_weapon"];
|
||||
[result oo_setInteger:aft_weapon_type forKey:@"aft_weapon"];
|
||||
[result oo_setInteger:port_weapon_type forKey:@"port_weapon"];
|
||||
[result oo_setInteger:starboard_weapon_type forKey:@"starboard_weapon"];
|
||||
[result setObject:[forward_weapon_type identifier] forKey:@"forward_weapon"];
|
||||
[result setObject:[aft_weapon_type identifier] forKey:@"aft_weapon"];
|
||||
[result setObject:[port_weapon_type identifier] forKey:@"port_weapon"];
|
||||
[result setObject:[starboard_weapon_type identifier] forKey:@"starboard_weapon"];
|
||||
[result setObject:[self serializeShipSubEntities] forKey:@"subentities_status"];
|
||||
if (hud != nil && [hud nonlinearScanner])
|
||||
{
|
||||
@ -1248,24 +1248,27 @@ NSComparisonResult marketSorterByMassUnit(id a, id b, void *market);
|
||||
OOWeaponFacingSet available_facings = [shipyard_info oo_unsignedIntForKey:KEY_WEAPON_FACINGS defaultValue:[self weaponFacings]];
|
||||
|
||||
if (available_facings & WEAPON_FACING_FORWARD)
|
||||
forward_weapon_type = [dict oo_intForKey:@"forward_weapon"];
|
||||
forward_weapon_type = OOWeaponTypeFromEquipmentIdentifierLegacy([dict oo_stringForKey:@"forward_weapon"]);
|
||||
else
|
||||
forward_weapon_type = WEAPON_NONE;
|
||||
forward_weapon_type = OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_NONE");
|
||||
|
||||
if (available_facings & WEAPON_FACING_AFT)
|
||||
aft_weapon_type = [dict oo_intForKey:@"aft_weapon"];
|
||||
aft_weapon_type = OOWeaponTypeFromEquipmentIdentifierLegacy([dict oo_stringForKey:@"aft_weapon"]);
|
||||
else
|
||||
aft_weapon_type = WEAPON_NONE;
|
||||
aft_weapon_type = OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_NONE");
|
||||
|
||||
if (available_facings & WEAPON_FACING_PORT)
|
||||
port_weapon_type = [dict oo_intForKey:@"port_weapon"];
|
||||
port_weapon_type = OOWeaponTypeFromEquipmentIdentifierLegacy([dict oo_stringForKey:@"port_weapon"]);
|
||||
else
|
||||
port_weapon_type = WEAPON_NONE;
|
||||
port_weapon_type = OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_NONE");
|
||||
|
||||
if (available_facings & WEAPON_FACING_STARBOARD)
|
||||
starboard_weapon_type = [dict oo_intForKey:@"starboard_weapon"];
|
||||
starboard_weapon_type = OOWeaponTypeFromEquipmentIdentifierLegacy([dict oo_stringForKey:@"starboard_weapon"]);
|
||||
else
|
||||
starboard_weapon_type = WEAPON_NONE;
|
||||
starboard_weapon_type = OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_NONE");
|
||||
|
||||
[self setWeaponDataFromType:forward_weapon_type];
|
||||
|
||||
if (hud != nil && [hud nonlinearScanner])
|
||||
{
|
||||
[hud setScannerZoom: [dict oo_floatForKey:@"ship_scanner_zoom" defaultValue: 1.0]];
|
||||
@ -1769,10 +1772,11 @@ NSComparisonResult marketSorterByMassUnit(id a, id b, void *market);
|
||||
fuel_leak_rate = 0.0f;
|
||||
|
||||
galaxy_number = 0;
|
||||
forward_weapon_type = WEAPON_PULSE_LASER;
|
||||
aft_weapon_type = WEAPON_NONE;
|
||||
port_weapon_type = WEAPON_NONE;
|
||||
starboard_weapon_type = WEAPON_NONE;
|
||||
// will load real weapon data later
|
||||
forward_weapon_type = nil;
|
||||
aft_weapon_type = nil;
|
||||
port_weapon_type = nil;
|
||||
starboard_weapon_type = nil;
|
||||
scannerRange = (float)SCANNER_MAX_RANGE;
|
||||
|
||||
weapons_online = YES;
|
||||
@ -5424,42 +5428,6 @@ NSComparisonResult marketSorterByMassUnit(id a, id b, void *market);
|
||||
|
||||
// Basic stats: weapon_damage & weaponRange (weapon_recharge_rate is not used by the player)
|
||||
[self setWeaponDataFromType:currentWeapon];
|
||||
|
||||
// Advanced stats: all the other stats used by the player!
|
||||
switch (currentWeapon)
|
||||
{
|
||||
case WEAPON_PLASMA_CANNON:
|
||||
weapon_energy_use = 6.0f;
|
||||
weapon_reload_time = 0.25f;
|
||||
break;
|
||||
|
||||
case WEAPON_PULSE_LASER:
|
||||
weapon_energy_use = 0.8f;
|
||||
weapon_reload_time = 0.5f;
|
||||
break;
|
||||
|
||||
case WEAPON_BEAM_LASER:
|
||||
weapon_energy_use = 1.0f;
|
||||
weapon_reload_time = 0.1f;
|
||||
break;
|
||||
|
||||
case WEAPON_MINING_LASER:
|
||||
weapon_energy_use = 1.4f;
|
||||
weapon_reload_time = 2.5f;
|
||||
break;
|
||||
|
||||
case WEAPON_THARGOID_LASER:
|
||||
case WEAPON_MILITARY_LASER:
|
||||
weapon_energy_use = 1.2f;
|
||||
weapon_reload_time = 0.1f;
|
||||
break;
|
||||
|
||||
case WEAPON_NONE:
|
||||
case WEAPON_UNDEFINED:
|
||||
weapon_energy_use = 0.0f;
|
||||
weapon_reload_time = 0.1f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5484,7 +5452,7 @@ NSComparisonResult marketSorterByMassUnit(id a, id b, void *market);
|
||||
|
||||
- (BOOL) fireMainWeapon
|
||||
{
|
||||
int weapon_to_be_fired = [self currentWeapon];
|
||||
OOWeaponType weapon_to_be_fired = [self currentWeapon];
|
||||
|
||||
if (![self weaponsOnline])
|
||||
{
|
||||
@ -5498,7 +5466,7 @@ NSComparisonResult marketSorterByMassUnit(id a, id b, void *market);
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (weapon_to_be_fired == WEAPON_NONE)
|
||||
if (isWeaponNone(weapon_to_be_fired))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
@ -5511,7 +5479,7 @@ NSComparisonResult marketSorterByMassUnit(id a, id b, void *market);
|
||||
return NO;
|
||||
}
|
||||
|
||||
using_mining_laser = (weapon_to_be_fired == WEAPON_MINING_LASER);
|
||||
using_mining_laser = [weapon_to_be_fired isMiningLaser];
|
||||
|
||||
energy -= weapon_energy_use;
|
||||
|
||||
@ -5542,23 +5510,17 @@ NSComparisonResult marketSorterByMassUnit(id a, id b, void *market);
|
||||
}
|
||||
|
||||
BOOL weaponFired = NO;
|
||||
switch (weapon_to_be_fired)
|
||||
if (!isWeaponNone(weapon_to_be_fired))
|
||||
{
|
||||
case WEAPON_PLASMA_CANNON:
|
||||
[self firePlasmaShotAtOffset:10.0 speed:PLAYER_PLASMA_SPEED color:[OOColor greenColor]];
|
||||
weaponFired = YES;
|
||||
break;
|
||||
|
||||
case WEAPON_PULSE_LASER:
|
||||
case WEAPON_BEAM_LASER:
|
||||
case WEAPON_MINING_LASER:
|
||||
case WEAPON_MILITARY_LASER:
|
||||
if (![weapon_to_be_fired isTurretLaser])
|
||||
{
|
||||
[self fireLaserShotInDirection:currentWeaponFacing];
|
||||
weaponFired = YES;
|
||||
break;
|
||||
|
||||
case WEAPON_THARGOID_LASER:
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// nothing: compatible with previous versions
|
||||
}
|
||||
}
|
||||
|
||||
if (weaponFired && cloaking_device_active && cloakPassive)
|
||||
@ -5589,7 +5551,7 @@ NSComparisonResult marketSorterByMassUnit(id a, id b, void *market);
|
||||
case WEAPON_FACING_NONE:
|
||||
break;
|
||||
}
|
||||
return WEAPON_NONE;
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
@ -7325,24 +7287,24 @@ NSComparisonResult marketSorterByMassUnit(id a, id b, void *market);
|
||||
[quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], nil]];
|
||||
}
|
||||
|
||||
if (forward_weapon_type > WEAPON_NONE)
|
||||
if (!isWeaponNone(forward_weapon_type))
|
||||
{
|
||||
desc = [NSString stringWithFormat:DESC(@"equipment-fwd-weapon-@"),[[OOEquipmentType equipmentTypeWithIdentifier:OOEquipmentIdentifierFromWeaponType(forward_weapon_type)] name]];
|
||||
desc = [NSString stringWithFormat:DESC(@"equipment-fwd-weapon-@"),[forward_weapon_type name]];
|
||||
[quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], nil]];
|
||||
}
|
||||
if (aft_weapon_type > WEAPON_NONE)
|
||||
if (!isWeaponNone(aft_weapon_type))
|
||||
{
|
||||
desc = [NSString stringWithFormat:DESC(@"equipment-aft-weapon-@"),[[OOEquipmentType equipmentTypeWithIdentifier:OOEquipmentIdentifierFromWeaponType(aft_weapon_type)] name]];
|
||||
desc = [NSString stringWithFormat:DESC(@"equipment-aft-weapon-@"),[aft_weapon_type name]];
|
||||
[quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], nil]];
|
||||
}
|
||||
if (port_weapon_type > WEAPON_NONE)
|
||||
if (!isWeaponNone(port_weapon_type))
|
||||
{
|
||||
desc = [NSString stringWithFormat:DESC(@"equipment-port-weapon-@"),[[OOEquipmentType equipmentTypeWithIdentifier:OOEquipmentIdentifierFromWeaponType(port_weapon_type)] name]];
|
||||
desc = [NSString stringWithFormat:DESC(@"equipment-port-weapon-@"),[port_weapon_type name]];
|
||||
[quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], nil]];
|
||||
}
|
||||
if (starboard_weapon_type > WEAPON_NONE)
|
||||
if (!isWeaponNone(starboard_weapon_type))
|
||||
{
|
||||
desc = [NSString stringWithFormat:DESC(@"equipment-stb-weapon-@"),[[OOEquipmentType equipmentTypeWithIdentifier:OOEquipmentIdentifierFromWeaponType(starboard_weapon_type)] name]];
|
||||
desc = [NSString stringWithFormat:DESC(@"equipment-stb-weapon-@"),[starboard_weapon_type name]];
|
||||
[quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], nil]];
|
||||
}
|
||||
|
||||
@ -7425,7 +7387,7 @@ NSComparisonResult marketSorterByMassUnit(id a, id b, void *market);
|
||||
|
||||
- (OOEquipmentType *) weaponTypeForFacing:(OOWeaponFacing)facing strict:(BOOL)strict
|
||||
{
|
||||
OOWeaponType weaponType = WEAPON_NONE;
|
||||
OOWeaponType weaponType = nil;
|
||||
|
||||
switch (facing)
|
||||
{
|
||||
@ -7449,7 +7411,7 @@ NSComparisonResult marketSorterByMassUnit(id a, id b, void *market);
|
||||
break;
|
||||
}
|
||||
|
||||
return [OOEquipmentType equipmentTypeWithIdentifier:OOEquipmentIdentifierFromWeaponType(weaponType)];
|
||||
return weaponType;
|
||||
}
|
||||
|
||||
|
||||
@ -8449,25 +8411,25 @@ static NSString *last_outfitting_key=nil;
|
||||
case 1:
|
||||
displayRow = available_facings & WEAPON_FACING_FORWARD;
|
||||
desc = FORWARD_FACING_STRING;
|
||||
weaponMounted = forward_weapon_type > WEAPON_NONE;
|
||||
weaponMounted = !isWeaponNone(forward_weapon_type);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
displayRow = available_facings & WEAPON_FACING_AFT;
|
||||
desc = AFT_FACING_STRING;
|
||||
weaponMounted = aft_weapon_type > WEAPON_NONE;
|
||||
weaponMounted = !isWeaponNone(aft_weapon_type);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
displayRow = available_facings & WEAPON_FACING_PORT;
|
||||
desc = PORT_FACING_STRING;
|
||||
weaponMounted = port_weapon_type > WEAPON_NONE;
|
||||
weaponMounted = !isWeaponNone(port_weapon_type);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
displayRow = available_facings & WEAPON_FACING_STARBOARD;
|
||||
desc = STARBOARD_FACING_STRING;
|
||||
weaponMounted = starboard_weapon_type > WEAPON_NONE;
|
||||
weaponMounted = !isWeaponNone(starboard_weapon_type);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -9281,7 +9243,7 @@ static NSString *last_outfitting_key=nil;
|
||||
}
|
||||
|
||||
OOWeaponType chosen_weapon = OOWeaponTypeFromEquipmentIdentifierStrict(eqKey);
|
||||
OOWeaponType current_weapon = WEAPON_NONE;
|
||||
OOWeaponType current_weapon = nil;
|
||||
|
||||
switch (chosen_weapon_facing)
|
||||
{
|
||||
@ -9312,7 +9274,7 @@ static NSString *last_outfitting_key=nil;
|
||||
credits -= price;
|
||||
|
||||
// Refund current_weapon
|
||||
if (current_weapon != WEAPON_NONE)
|
||||
if (current_weapon != nil)
|
||||
{
|
||||
tradeIn = [UNIVERSE getEquipmentPriceForKey:OOEquipmentIdentifierFromWeaponType(current_weapon)];
|
||||
}
|
||||
@ -9477,7 +9439,7 @@ static NSString *last_outfitting_key=nil;
|
||||
}
|
||||
|
||||
// sets WEAPON_NONE if not recognised
|
||||
int chosen_weapon = OOWeaponTypeFromEquipmentIdentifierStrict(eqKey);
|
||||
OOWeaponType chosen_weapon = OOWeaponTypeFromEquipmentIdentifierStrict(eqKey);
|
||||
|
||||
switch (facing)
|
||||
{
|
||||
@ -10485,8 +10447,13 @@ static NSString *last_outfitting_key=nil;
|
||||
|
||||
- (BOOL) hasPrimaryWeapon:(OOWeaponType)weaponType
|
||||
{
|
||||
if (forward_weapon_type == weaponType || aft_weapon_type == weaponType) return YES;
|
||||
if (port_weapon_type == weaponType || starboard_weapon_type == weaponType) return YES;
|
||||
if ([[forward_weapon_type identifier] isEqualToString:[weaponType identifier]] ||
|
||||
[[aft_weapon_type identifier] isEqualToString:[weaponType identifier]] ||
|
||||
[[port_weapon_type identifier] isEqualToString:[weaponType identifier]] ||
|
||||
[[starboard_weapon_type identifier] isEqualToString:[weaponType identifier]])
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
return [super hasPrimaryWeapon:weaponType];
|
||||
}
|
||||
|
@ -1868,25 +1868,26 @@ static NSMutableDictionary *currentShipyard = nil;
|
||||
int base_facings = [shipDict oo_unsignedIntForKey:KEY_WEAPON_FACINGS defaultValue:15];
|
||||
int available_facings = [ship_info oo_unsignedIntForKey:KEY_WEAPON_FACINGS defaultValue:base_facings];
|
||||
|
||||
// not retained - weapon types are references to the objects in OOEquipmentType's cache
|
||||
if (available_facings & WEAPON_FACING_AFT)
|
||||
aft_weapon_type = OOWeaponTypeFromEquipmentIdentifierSloppy([shipDict oo_stringForKey:@"aft_weapon_type"]);
|
||||
else
|
||||
aft_weapon_type = WEAPON_NONE;
|
||||
aft_weapon_type = OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_NONE");
|
||||
|
||||
if (available_facings & WEAPON_FACING_PORT)
|
||||
port_weapon_type = OOWeaponTypeFromEquipmentIdentifierSloppy([shipDict oo_stringForKey:@"port_weapon_type"]);
|
||||
else
|
||||
port_weapon_type = WEAPON_NONE;
|
||||
port_weapon_type = OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_NONE");
|
||||
|
||||
if (available_facings & WEAPON_FACING_STARBOARD)
|
||||
starboard_weapon_type = OOWeaponTypeFromEquipmentIdentifierSloppy([shipDict oo_stringForKey:@"starboard_weapon_type"]);
|
||||
else
|
||||
starboard_weapon_type = WEAPON_NONE;
|
||||
starboard_weapon_type = OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_NONE");
|
||||
|
||||
if (available_facings & WEAPON_FACING_FORWARD)
|
||||
forward_weapon_type = OOWeaponTypeFromEquipmentIdentifierSloppy([shipDict oo_stringForKey:@"forward_weapon_type"]);
|
||||
else
|
||||
forward_weapon_type = WEAPON_NONE;
|
||||
forward_weapon_type = OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_NONE");
|
||||
|
||||
// new ships start with weapons online
|
||||
weapons_online = 1;
|
||||
|
@ -950,7 +950,7 @@ static NSTimeInterval time_last_frame;
|
||||
|
||||
exceptionContext = @"shoot";
|
||||
// shoot 'a'
|
||||
if ((([gameView isDown:key_fire_lasers])||((mouse_control_on)&&([gameView isDown:gvMouseLeftButton]))||joyButtonState[BUTTON_FIRE])&&(shot_time > weapon_reload_time))
|
||||
if ((([gameView isDown:key_fire_lasers])||((mouse_control_on)&&([gameView isDown:gvMouseLeftButton]))||joyButtonState[BUTTON_FIRE])&&(shot_time > weapon_recharge_rate))
|
||||
{
|
||||
if ([self fireMainWeapon])
|
||||
{
|
||||
@ -2105,18 +2105,18 @@ static NSTimeInterval time_last_frame;
|
||||
if ([self handleGUIUpDownArrowKeys])
|
||||
{
|
||||
NSString *itemText = [gui selectedRowText];
|
||||
OOWeaponType weaponType = WEAPON_UNDEFINED;
|
||||
OOWeaponType weaponType = nil;
|
||||
|
||||
if ([itemText isEqual:FORWARD_FACING_STRING]) weaponType = forward_weapon_type;
|
||||
if ([itemText isEqual:AFT_FACING_STRING]) weaponType = aft_weapon_type;
|
||||
if ([itemText isEqual:PORT_FACING_STRING]) weaponType = port_weapon_type;
|
||||
if ([itemText isEqual:STARBOARD_FACING_STRING]) weaponType = starboard_weapon_type;
|
||||
|
||||
if (weaponType != WEAPON_UNDEFINED)
|
||||
if (weaponType != nil)
|
||||
{
|
||||
BOOL sameAs = OOWeaponTypeFromEquipmentIdentifierSloppy([gui selectedRowKey]) == weaponType;
|
||||
// override showInformation _completely_ with itemText
|
||||
if (weaponType == WEAPON_NONE) itemText = DESC(@"no-weapon-enter-to-install");
|
||||
if ([[weaponType identifier] isEqualToString:@"EQ_WEAPON_NONE"]) itemText = DESC(@"no-weapon-enter-to-install");
|
||||
else
|
||||
{
|
||||
NSString *weaponName = [[OOEquipmentType equipmentTypeWithIdentifier:OOEquipmentIdentifierFromWeaponType(weaponType)] name];
|
||||
|
@ -149,7 +149,7 @@ typedef enum OOBehaviour
|
||||
#undef ENTRY
|
||||
|
||||
|
||||
typedef enum
|
||||
/*typedef enum
|
||||
{
|
||||
WEAPON_NONE = 0U,
|
||||
WEAPON_PLASMA_CANNON = 1,
|
||||
@ -159,7 +159,8 @@ typedef enum
|
||||
WEAPON_MILITARY_LASER = 5,
|
||||
WEAPON_THARGOID_LASER = 10,
|
||||
WEAPON_UNDEFINED
|
||||
} OOWeaponType;
|
||||
} OOWeaponType; */
|
||||
typedef OOEquipmentType* OOWeaponType;
|
||||
|
||||
|
||||
typedef enum
|
||||
@ -220,6 +221,7 @@ typedef enum
|
||||
NSDictionary *dockingInstructions;
|
||||
|
||||
OOColor *laser_color;
|
||||
OOColor *default_laser_color;
|
||||
OOColor *exhaust_emissive_color;
|
||||
OOColor *scanner_display_color1;
|
||||
OOColor *scanner_display_color2;
|
||||
@ -296,7 +298,7 @@ typedef enum
|
||||
GLfloat weaponRange; // range of the weapon (in meters)
|
||||
OOWeaponFacing currentWeaponFacing; // not necessarily the same as view for the player
|
||||
|
||||
GLfloat weapon_temp, weapon_shot_temperature; // active weapon temp, delta-temp
|
||||
GLfloat weapon_energy_use, weapon_temp, weapon_shot_temperature; // active weapon temp, delta-temp
|
||||
GLfloat forward_weapon_temp, aft_weapon_temp, port_weapon_temp, starboard_weapon_temp; // current weapon temperatures
|
||||
|
||||
GLfloat scannerRange; // typically 25600
|
||||
@ -1235,23 +1237,22 @@ NSDictionary *OODefaultShipShaderMacros(void);
|
||||
|
||||
GLfloat getWeaponRangeFromType(OOWeaponType weapon_type);
|
||||
|
||||
// Stuff implemented in OOConstToString.m
|
||||
enum
|
||||
{
|
||||
// Values used for unknown strings.
|
||||
kOOWeaponTypeDefault = WEAPON_NONE
|
||||
};
|
||||
|
||||
// Defined in OOConstToString.m
|
||||
NSString *OOStringFromBehaviour(OOBehaviour behaviour) CONST_FUNC;
|
||||
|
||||
// Weapon strings prefixed with EQ_, used in shipyard.plist.
|
||||
NSString *OOEquipmentIdentifierFromWeaponType(OOWeaponType weapon) CONST_FUNC;
|
||||
OOWeaponType OOWeaponTypeFromEquipmentIdentifierSloppy(NSString *string) PURE_FUNC; // Uses suffix match for backwards compatibility.
|
||||
OOWeaponType OOWeaponTypeFromEquipmentIdentifierStrict(NSString *string) PURE_FUNC;
|
||||
OOWeaponType OOWeaponTypeFromEquipmentIdentifierLegacy(NSString *string);
|
||||
|
||||
|
||||
NSString *OOStringFromWeaponType(OOWeaponType weapon) CONST_FUNC;
|
||||
OOWeaponType OOWeaponTypeFromString(NSString *string) PURE_FUNC;
|
||||
|
||||
BOOL isWeaponNone(OOWeaponType weapon);
|
||||
|
||||
NSString *OODisplayStringFromAlertCondition(OOAlertCondition alertCondition);
|
||||
|
||||
NSString *OOStringFromShipDamageType(OOShipDamageType type) CONST_FUNC;
|
||||
|
||||
|
@ -279,13 +279,13 @@ static ShipEntity *doOctreesCollide(ShipEntity *prime, ShipEntity *other);
|
||||
|
||||
weapon_facings = [shipDict oo_intForKey:@"weapon_facings" defaultValue:VALID_WEAPON_FACINGS] & VALID_WEAPON_FACINGS;
|
||||
if (weapon_facings & WEAPON_FACING_FORWARD)
|
||||
forward_weapon_type = OOWeaponTypeFromString([shipDict oo_stringForKey:@"forward_weapon_type" defaultValue:@"WEAPON_NONE"]);
|
||||
forward_weapon_type = OOWeaponTypeFromString([shipDict oo_stringForKey:@"forward_weapon_type" defaultValue:@"EQ_WEAPON_NONE"]);
|
||||
if (weapon_facings & WEAPON_FACING_AFT)
|
||||
aft_weapon_type = OOWeaponTypeFromString([shipDict oo_stringForKey:@"aft_weapon_type" defaultValue:@"WEAPON_NONE"]);
|
||||
aft_weapon_type = OOWeaponTypeFromString([shipDict oo_stringForKey:@"aft_weapon_type" defaultValue:@"EQ_WEAPON_NONE"]);
|
||||
if (weapon_facings & WEAPON_FACING_PORT)
|
||||
port_weapon_type = OOWeaponTypeFromString([shipDict oo_stringForKey:@"port_weapon_type" defaultValue:@"WEAPON_NONE"]);
|
||||
port_weapon_type = OOWeaponTypeFromString([shipDict oo_stringForKey:@"port_weapon_type" defaultValue:@"EQ_WEAPON_NONE"]);
|
||||
if (weapon_facings & WEAPON_FACING_STARBOARD)
|
||||
starboard_weapon_type = OOWeaponTypeFromString([shipDict oo_stringForKey:@"starboard_weapon_type" defaultValue:@"WEAPON_NONE"]);
|
||||
starboard_weapon_type = OOWeaponTypeFromString([shipDict oo_stringForKey:@"starboard_weapon_type" defaultValue:@"EQ_WEAPON_NONE"]);
|
||||
|
||||
cloaking_device_active = NO;
|
||||
military_jammer_active = NO;
|
||||
@ -374,18 +374,24 @@ static ShipEntity *doOctreesCollide(ShipEntity *prime, ShipEntity *other);
|
||||
float density = [shipDict oo_floatForKey:@"density" defaultValue:1.0f];
|
||||
if (octree) mass = (GLfloat)(density * 20.0 * [octree volume]);
|
||||
|
||||
OOColor *color = [OOColor brightColorWithDescription:[shipDict objectForKey:@"laser_color"]];
|
||||
|
||||
if (color == nil) color = [OOColor redColor];
|
||||
[self setLaserColor:color];
|
||||
DESTROY(default_laser_color);
|
||||
default_laser_color = [[OOColor brightColorWithDescription:[shipDict objectForKey:@"laser_color"]] retain];
|
||||
|
||||
if (default_laser_color == nil)
|
||||
{
|
||||
[self setLaserColor:[OOColor redColor]];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setLaserColor:default_laser_color];
|
||||
}
|
||||
// exhaust emissive color
|
||||
OORGBAComponents defaultExhaustEmissiveColorComponents; // pale blue is exhaust default color
|
||||
defaultExhaustEmissiveColorComponents.r = 0.7f;
|
||||
defaultExhaustEmissiveColorComponents.g = 0.9f;
|
||||
defaultExhaustEmissiveColorComponents.b = 1.0f;
|
||||
defaultExhaustEmissiveColorComponents.a = 0.9f;
|
||||
color = [OOColor brightColorWithDescription:[shipDict objectForKey:@"exhaust_emissive_color"]];
|
||||
OOColor *color = [OOColor brightColorWithDescription:[shipDict objectForKey:@"exhaust_emissive_color"]];
|
||||
if (color == nil) color = [OOColor colorWithRGBAComponents:defaultExhaustEmissiveColorComponents];
|
||||
[self setExhaustEmissiveColor:color];
|
||||
|
||||
@ -393,13 +399,13 @@ static ShipEntity *doOctreesCollide(ShipEntity *prime, ShipEntity *other);
|
||||
[self setUpSubEntities];
|
||||
|
||||
// correctly initialise weaponRange, etc. (must be after subentity setup)
|
||||
if (forward_weapon_type == WEAPON_NONE)
|
||||
if (isWeaponNone(forward_weapon_type))
|
||||
{
|
||||
OOWeaponType weapon_type = WEAPON_NONE;
|
||||
OOWeaponType weapon_type = nil;
|
||||
BOOL hasTurrets = NO;
|
||||
NSEnumerator *subEnum = [self shipSubEntityEnumerator];
|
||||
ShipEntity *se = nil;
|
||||
while (weapon_type == WEAPON_NONE && (se = [subEnum nextObject]))
|
||||
while (isWeaponNone(weapon_type) && (se = [subEnum nextObject]))
|
||||
{
|
||||
weapon_type = se->forward_weapon_type;
|
||||
if (se->behaviour == BEHAVIOUR_TRACK_AS_TURRET)
|
||||
@ -407,11 +413,14 @@ static ShipEntity *doOctreesCollide(ShipEntity *prime, ShipEntity *other);
|
||||
hasTurrets = YES;
|
||||
}
|
||||
}
|
||||
if (weapon_type == WEAPON_NONE && hasTurrets)
|
||||
if (isWeaponNone(weapon_type) && hasTurrets)
|
||||
{ // safety for ships only equipped with turrets
|
||||
weapon_type = WEAPON_PLASMA_CANNON;
|
||||
weaponRange = 10000.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setWeaponDataFromType:weapon_type];
|
||||
}
|
||||
[self setWeaponDataFromType:weapon_type];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -492,11 +501,11 @@ static ShipEntity *doOctreesCollide(ShipEntity *prime, ShipEntity *other);
|
||||
// no weapon_damage? It's a missile: set weapon_damage from shipdata!
|
||||
if (weapon_damage == 0.0)
|
||||
{
|
||||
weapon_damage_override = weapon_damage = [shipDict oo_floatForKey:@"weapon_energy"]; // any damage value for missiles/bombs
|
||||
weapon_damage_override = weapon_damage = [shipDict oo_floatForKey:@"weapon_energy" defaultValue:0]; // any damage value for missiles/bombs
|
||||
}
|
||||
else
|
||||
{
|
||||
weapon_damage_override = OOClamp_0_max_f([shipinfoDictionary oo_floatForKey:@"weapon_energy" defaultValue:weapon_damage],50.0); // front laser damage can be modified, within limits!
|
||||
{
|
||||
weapon_damage_override = 0;
|
||||
}
|
||||
|
||||
scannerRange = [shipDict oo_floatForKey:@"scanner_range" defaultValue:(float)SCANNER_MAX_RANGE];
|
||||
@ -999,6 +1008,7 @@ static ShipEntity *doOctreesCollide(ShipEntity *prime, ShipEntity *other);
|
||||
DESTROY(roleSet);
|
||||
DESTROY(primaryRole);
|
||||
DESTROY(laser_color);
|
||||
DESTROY(default_laser_color);
|
||||
DESTROY(exhaust_emissive_color);
|
||||
DESTROY(scanner_display_color1);
|
||||
DESTROY(scanner_display_color2);
|
||||
@ -2864,7 +2874,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
{
|
||||
// Check for primary weapon
|
||||
OOWeaponType weaponType = OOWeaponTypeFromEquipmentIdentifierStrict(itemKey);
|
||||
if (weaponType != WEAPON_NONE)
|
||||
if (!isWeaponNone(weaponType))
|
||||
{
|
||||
if ([self hasPrimaryWeapon:weaponType]) return YES;
|
||||
}
|
||||
@ -2903,8 +2913,14 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
NSEnumerator *subEntEnum = nil;
|
||||
ShipEntity *subEntity = nil;
|
||||
|
||||
if (forward_weapon_type == weaponType || aft_weapon_type == weaponType || port_weapon_type == weaponType || starboard_weapon_type == weaponType) return YES;
|
||||
|
||||
if ([[forward_weapon_type identifier] isEqualToString:[weaponType identifier]] ||
|
||||
[[aft_weapon_type identifier] isEqualToString:[weaponType identifier]] ||
|
||||
[[port_weapon_type identifier] isEqualToString:[weaponType identifier]] ||
|
||||
[[starboard_weapon_type identifier] isEqualToString:[weaponType identifier]])
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
for (subEntEnum = [self shipSubEntityEnumerator]; (subEntity = [subEntEnum nextObject]); )
|
||||
{
|
||||
if ([subEntity hasPrimaryWeapon:weaponType]) return YES;
|
||||
@ -3010,7 +3026,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
|
||||
- (OOWeaponType) weaponTypeIDForFacing:(OOWeaponFacing)facing strict:(BOOL)strict
|
||||
{
|
||||
OOWeaponType weaponType = WEAPON_NONE;
|
||||
OOWeaponType weaponType = nil;
|
||||
|
||||
if (facing & weapon_facings)
|
||||
{
|
||||
@ -3019,11 +3035,11 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
case WEAPON_FACING_FORWARD:
|
||||
weaponType = forward_weapon_type;
|
||||
// if no forward weapon, and not carrying out a strict check, see if subentities have forward weapons, return the first one found.
|
||||
if (weaponType == WEAPON_NONE && !strict)
|
||||
if (isWeaponNone(weaponType) && !strict)
|
||||
{
|
||||
NSEnumerator *subEntEnum = [self shipSubEntityEnumerator];
|
||||
ShipEntity *subEntity = nil;
|
||||
while (weaponType == WEAPON_NONE && (subEntity = [subEntEnum nextObject]))
|
||||
while (isWeaponNone(weaponType) && (subEntity = [subEntEnum nextObject]))
|
||||
{
|
||||
weaponType = subEntity->forward_weapon_type;
|
||||
}
|
||||
@ -3051,9 +3067,9 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
|
||||
- (OOEquipmentType *) weaponTypeForFacing:(OOWeaponFacing)facing strict:(BOOL)strict
|
||||
{
|
||||
OOWeaponType weaponType = [self weaponTypeIDForFacing:facing strict:strict];
|
||||
|
||||
return [OOEquipmentType equipmentTypeWithIdentifier:OOEquipmentIdentifierFromWeaponType(weaponType)];
|
||||
// OOWeaponType weaponType = [self weaponTypeIDForFacing:facing strict:strict];
|
||||
// return [OOEquipmentType equipmentTypeWithIdentifier:OOEquipmentIdentifierFromWeaponType(weaponType)];
|
||||
return [self weaponTypeIDForFacing:facing strict:strict];
|
||||
}
|
||||
|
||||
|
||||
@ -4244,12 +4260,12 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
GLfloat forward_weapon_real_temp = forward_weapon_temp;
|
||||
|
||||
// if forward weapon is actually on a subent
|
||||
if (forward_weapon_real_type == WEAPON_NONE)
|
||||
if (isWeaponNone(forward_weapon_real_type))
|
||||
{
|
||||
BOOL hasTurrets = NO;
|
||||
NSEnumerator *subEnum = [self shipSubEntityEnumerator];
|
||||
ShipEntity *se = nil;
|
||||
while (forward_weapon_real_type == WEAPON_NONE && (se = [subEnum nextObject]))
|
||||
while (isWeaponNone(forward_weapon_real_type) && (se = [subEnum nextObject]))
|
||||
{
|
||||
forward_weapon_real_type = se->forward_weapon_type;
|
||||
forward_weapon_real_temp = se->forward_weapon_temp;
|
||||
@ -4258,14 +4274,14 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
hasTurrets = YES;
|
||||
}
|
||||
}
|
||||
if (forward_weapon_real_type == WEAPON_NONE && hasTurrets)
|
||||
if (isWeaponNone(forward_weapon_real_type) && hasTurrets)
|
||||
{ // safety for ships only equipped with turrets
|
||||
forward_weapon_real_type = WEAPON_PLASMA_CANNON;
|
||||
forward_weapon_real_type = OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_PULSE_LASER");
|
||||
forward_weapon_real_temp = COMBAT_AI_WEAPON_TEMP_USABLE * 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
if (forward_weapon_real_type == WEAPON_THARGOID_LASER)
|
||||
if ([forward_weapon_real_type isTurretLaser])
|
||||
{
|
||||
behaviour = BEHAVIOUR_ATTACK_FLY_TO_TARGET_TWELVE;
|
||||
}
|
||||
@ -4273,19 +4289,19 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
{
|
||||
BOOL in_good_range = aim_tolerance*range < COMBAT_AI_CONFIDENCE_FACTOR;
|
||||
|
||||
BOOL aft_weapon_ready = (aft_weapon_type != WEAPON_NONE) && (aft_weapon_temp < COMBAT_AI_WEAPON_TEMP_READY) && in_good_range;
|
||||
BOOL forward_weapon_ready = (forward_weapon_real_type != WEAPON_NONE) && (forward_weapon_real_temp < COMBAT_AI_WEAPON_TEMP_READY); // does not require in_good_range
|
||||
BOOL port_weapon_ready = (port_weapon_type != WEAPON_NONE) && (port_weapon_temp < COMBAT_AI_WEAPON_TEMP_READY) && in_good_range;
|
||||
BOOL starboard_weapon_ready = (starboard_weapon_type != WEAPON_NONE) && (starboard_weapon_temp < COMBAT_AI_WEAPON_TEMP_READY) && in_good_range;
|
||||
BOOL aft_weapon_ready = !isWeaponNone(aft_weapon_type) && (aft_weapon_temp < COMBAT_AI_WEAPON_TEMP_READY) && in_good_range;
|
||||
BOOL forward_weapon_ready = !isWeaponNone(forward_weapon_real_type) && (forward_weapon_real_temp < COMBAT_AI_WEAPON_TEMP_READY); // does not require in_good_range
|
||||
BOOL port_weapon_ready = !isWeaponNone(port_weapon_type) && (port_weapon_temp < COMBAT_AI_WEAPON_TEMP_READY) && in_good_range;
|
||||
BOOL starboard_weapon_ready = !isWeaponNone(starboard_weapon_type) && (starboard_weapon_temp < COMBAT_AI_WEAPON_TEMP_READY) && in_good_range;
|
||||
// if no weapons cool enough to be good choices, be less picky
|
||||
BOOL weapons_heating = NO;
|
||||
if (!forward_weapon_ready && !aft_weapon_ready && !port_weapon_ready && !starboard_weapon_ready)
|
||||
{
|
||||
weapons_heating = YES;
|
||||
aft_weapon_ready = (aft_weapon_type != WEAPON_NONE) && (aft_weapon_temp < COMBAT_AI_WEAPON_TEMP_USABLE) && in_good_range;
|
||||
forward_weapon_ready = (forward_weapon_real_type != WEAPON_NONE) && (forward_weapon_real_temp < COMBAT_AI_WEAPON_TEMP_USABLE); // does not require in_good_range
|
||||
port_weapon_ready = (port_weapon_type != WEAPON_NONE) && (port_weapon_temp < COMBAT_AI_WEAPON_TEMP_USABLE) && in_good_range;
|
||||
starboard_weapon_ready = (starboard_weapon_type != WEAPON_NONE) && (starboard_weapon_temp < COMBAT_AI_WEAPON_TEMP_USABLE) && in_good_range;
|
||||
aft_weapon_ready = !isWeaponNone(aft_weapon_type) && (aft_weapon_temp < COMBAT_AI_WEAPON_TEMP_USABLE) && in_good_range;
|
||||
forward_weapon_ready = !isWeaponNone(forward_weapon_real_type) && (forward_weapon_real_temp < COMBAT_AI_WEAPON_TEMP_USABLE); // does not require in_good_range
|
||||
port_weapon_ready = !isWeaponNone(port_weapon_type) && (port_weapon_temp < COMBAT_AI_WEAPON_TEMP_USABLE) && in_good_range;
|
||||
starboard_weapon_ready = !isWeaponNone(starboard_weapon_type) && (starboard_weapon_temp < COMBAT_AI_WEAPON_TEMP_USABLE) && in_good_range;
|
||||
}
|
||||
|
||||
ShipEntity* target = [self primaryTarget];
|
||||
@ -4295,7 +4311,10 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
{ // no usable weapons! Either not fitted or overheated
|
||||
|
||||
// if unarmed
|
||||
if (forward_weapon_real_type == WEAPON_NONE && aft_weapon_type == WEAPON_NONE && port_weapon_type == WEAPON_NONE && starboard_weapon_type == WEAPON_NONE)
|
||||
if (isWeaponNone(forward_weapon_real_type) &&
|
||||
isWeaponNone(aft_weapon_type) &&
|
||||
isWeaponNone(port_weapon_type) &&
|
||||
isWeaponNone(starboard_weapon_type))
|
||||
{
|
||||
behaviour = BEHAVIOUR_ATTACK_FLY_FROM_TARGET;
|
||||
}
|
||||
@ -4382,7 +4401,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
jink = kZeroVector; // almost all behaviours
|
||||
|
||||
// TODO: good pilots use behaviour_attack_sniper sometimes
|
||||
if (getWeaponRangeFromType(forward_weapon_real_type) > getWeaponRangeFromType(WEAPON_PULSE_LASER) && range > getWeaponRangeFromType(WEAPON_PULSE_LASER))
|
||||
if (getWeaponRangeFromType(forward_weapon_real_type) > 12500 && range > 12500)
|
||||
{
|
||||
behaviour = BEHAVIOUR_ATTACK_SNIPER;
|
||||
}
|
||||
@ -4447,7 +4466,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
{
|
||||
if (port_weapon_temp < starboard_weapon_temp)
|
||||
{
|
||||
if (port_weapon_type == WEAPON_NONE)
|
||||
if (isWeaponNone(port_weapon_type))
|
||||
{
|
||||
behaviour = BEHAVIOUR_ATTACK_BROADSIDE_RIGHT;
|
||||
[self setWeaponDataFromType:starboard_weapon_type];
|
||||
@ -4460,7 +4479,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (starboard_weapon_type != WEAPON_NONE)
|
||||
if (isWeaponNone(starboard_weapon_type))
|
||||
{
|
||||
behaviour = BEHAVIOUR_ATTACK_BROADSIDE_RIGHT;
|
||||
[self setWeaponDataFromType:starboard_weapon_type];
|
||||
@ -4556,7 +4575,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
{ // will probably have more luck with the other laser or picking a different attack method
|
||||
if (leftside)
|
||||
{
|
||||
if (starboard_weapon_type != WEAPON_NONE)
|
||||
if (!isWeaponNone(starboard_weapon_type))
|
||||
{
|
||||
behaviour = BEHAVIOUR_ATTACK_BROADSIDE_RIGHT;
|
||||
}
|
||||
@ -4567,7 +4586,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (port_weapon_type != WEAPON_NONE)
|
||||
if (!isWeaponNone(port_weapon_type))
|
||||
{
|
||||
behaviour = BEHAVIOUR_ATTACK_BROADSIDE_LEFT;
|
||||
}
|
||||
@ -4644,7 +4663,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
|
||||
behaviour = BEHAVIOUR_ATTACK_FLY_TO_TARGET_TWELVE;
|
||||
[self behaviour_fly_to_target_six:delta_t];
|
||||
if (port_weapon_type != WEAPON_NONE)
|
||||
if (!isWeaponNone(port_weapon_type))
|
||||
{
|
||||
[self setWeaponDataFromType:port_weapon_type];
|
||||
}
|
||||
@ -4712,7 +4731,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
[self noteLostTargetAndGoIdle];
|
||||
return;
|
||||
}
|
||||
else if (range < getWeaponRangeFromType(WEAPON_PULSE_LASER))
|
||||
else if (range < 15000)
|
||||
{
|
||||
behaviour = BEHAVIOUR_ATTACK_TARGET;
|
||||
}
|
||||
@ -4848,9 +4867,10 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
// target-twelve
|
||||
if (behaviour == BEHAVIOUR_ATTACK_FLY_TO_TARGET_TWELVE)
|
||||
{
|
||||
if (forward_weapon_type == WEAPON_THARGOID_LASER)
|
||||
if ([forward_weapon_type isTurretLaser])
|
||||
{
|
||||
// head for a point near the target, avoiding common Galcop weapon mount locations
|
||||
// head for a point near the target, avoiding common Galcop weapon mount locations
|
||||
// TODO: this should account for weapon ranges
|
||||
GLfloat offset = 1000.0;
|
||||
GLfloat spacing = 2000.0;
|
||||
if (accuracy > 0.0)
|
||||
@ -4878,7 +4898,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
else if(frustration > 0.0) frustration -= delta_t * 0.75;
|
||||
|
||||
double aspect = [self approachAspectToPrimaryTarget];
|
||||
if(forward_weapon_type != WEAPON_THARGOID_LASER && (frustration > 10 || aspect > 0.75))
|
||||
if(![forward_weapon_type isTurretLaser] && (frustration > 10 || aspect > 0.75))
|
||||
{
|
||||
behaviour = BEHAVIOUR_ATTACK_FLY_TO_TARGET;
|
||||
}
|
||||
@ -5061,7 +5081,10 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
// don't do this if the target is fleeing and the front laser is
|
||||
// the only weapon, or if we're too far away to use non-front
|
||||
// lasers effectively
|
||||
if (aspect < 0 || aft_weapon_type != WEAPON_NONE || port_weapon_type != WEAPON_NONE || starboard_weapon_type != WEAPON_NONE)
|
||||
if (aspect < 0 ||
|
||||
!isWeaponNone(aft_weapon_type) ||
|
||||
!isWeaponNone(port_weapon_type) ||
|
||||
!isWeaponNone(starboard_weapon_type))
|
||||
{
|
||||
frustration = 0.0;
|
||||
behaviour = BEHAVIOUR_ATTACK_TARGET;
|
||||
@ -5073,7 +5096,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
// need to dodge sooner if in aft sights
|
||||
if ([target behaviour] != BEHAVIOUR_FLEE_TARGET && [target behaviour] != BEHAVIOUR_FLEE_EVASIVE_ACTION)
|
||||
{
|
||||
if ((aspect > 0.99999 && [target weaponTypeForFacing:WEAPON_FACING_FORWARD strict:NO] != WEAPON_NONE) || (aspect < -0.999 && [target weaponTypeForFacing:WEAPON_FACING_AFT strict:NO] != WEAPON_NONE))
|
||||
if ((aspect > 0.99999 && !isWeaponNone([target weaponTypeForFacing:WEAPON_FACING_FORWARD strict:NO])) || (aspect < -0.999 && !isWeaponNone([target weaponTypeForFacing:WEAPON_FACING_AFT strict:NO])))
|
||||
{
|
||||
frustration = 0.0;
|
||||
behaviour = BEHAVIOUR_EVASIVE_ACTION;
|
||||
@ -5180,14 +5203,14 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
if (range > weaponRange || range > 0.8 * scannerRange || range == 0)
|
||||
{
|
||||
behaviour = BEHAVIOUR_CLOSE_WITH_TARGET;
|
||||
if (forward_weapon_type == WEAPON_THARGOID_LASER)
|
||||
if ([forward_weapon_type isTurretLaser])
|
||||
{
|
||||
behaviour = BEHAVIOUR_ATTACK_FLY_TO_TARGET_TWELVE;
|
||||
}
|
||||
frustration = 0.0;
|
||||
}
|
||||
[self trackPrimaryTarget:delta_t:YES];
|
||||
if (forward_weapon_type == WEAPON_THARGOID_LASER)
|
||||
if ([forward_weapon_type isTurretLaser])
|
||||
{
|
||||
// most Thargoids will only have the forward weapon
|
||||
[self fireMainWeapon:range];
|
||||
@ -5268,7 +5291,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
}
|
||||
|
||||
// thargoids won't normally be fleeing, but if they do, they can still shoot
|
||||
if (forward_weapon_type == WEAPON_THARGOID_LASER)
|
||||
if ([forward_weapon_type isTurretLaser])
|
||||
{
|
||||
[self fireMainWeapon:range];
|
||||
}
|
||||
@ -6943,65 +6966,20 @@ static BOOL IsBehaviourHostile(OOBehaviour behaviour)
|
||||
- (void) setWeaponDataFromType: (OOWeaponType) weapon_type
|
||||
{
|
||||
weaponRange = getWeaponRangeFromType(weapon_type);
|
||||
switch (weapon_type)
|
||||
weapon_energy_use = [weapon_type weaponEnergyUse];
|
||||
weapon_recharge_rate = [weapon_type weaponRechargeRate];
|
||||
weapon_shot_temperature = [weapon_type weaponShotTemperature];
|
||||
weapon_damage = [weapon_type weaponDamage];
|
||||
|
||||
if (default_laser_color == nil)
|
||||
{
|
||||
case WEAPON_PLASMA_CANNON:
|
||||
weapon_damage = 6.0;
|
||||
weapon_recharge_rate = 0.25;
|
||||
weapon_shot_temperature = 8.0f;
|
||||
break;
|
||||
case WEAPON_PULSE_LASER:
|
||||
#ifdef DEBUG_LASER_TYPES
|
||||
[self setLaserColor:[OOColor redColor]];
|
||||
#endif
|
||||
weapon_damage = 15.0;
|
||||
// weapon_recharge_rate = 0.33;
|
||||
weapon_recharge_rate = 0.5;
|
||||
weapon_shot_temperature = 7.0f;
|
||||
break;
|
||||
case WEAPON_BEAM_LASER:
|
||||
#ifdef DEBUG_LASER_TYPES
|
||||
[self setLaserColor:[OOColor yellowColor]];
|
||||
#endif
|
||||
weapon_damage = 15.0;
|
||||
// weapon_recharge_rate = 0.25;
|
||||
weapon_recharge_rate = 0.1;
|
||||
weapon_shot_temperature = 8.0f;
|
||||
break;
|
||||
case WEAPON_MINING_LASER:
|
||||
#ifdef DEBUG_LASER_TYPES
|
||||
[self setLaserColor:[OOColor blueColor]];
|
||||
#endif
|
||||
weapon_damage = 50.0;
|
||||
weapon_recharge_rate = 2.5;
|
||||
weapon_shot_temperature = 10.0f;
|
||||
break;
|
||||
case WEAPON_THARGOID_LASER: // omni directional lasers FRIGHTENING!
|
||||
weapon_damage = 12.5;
|
||||
// changing weapon_recharge_rate to accompany change to onTarget - CIM 20120502
|
||||
// weapon_recharge_rate = 0.5;
|
||||
// old behaviour gave range of 0.7-1.3 between 25 and 100 FPS
|
||||
// so duplicate this range
|
||||
// weapon_recharge_rate = 0.7+(0.6*[self entityPersonality]);
|
||||
weapon_recharge_rate = 0.7+(0.04*(10-accuracy));
|
||||
weapon_shot_temperature = 8.0f;
|
||||
break;
|
||||
case WEAPON_MILITARY_LASER:
|
||||
#ifdef DEBUG_LASER_TYPES
|
||||
[self setLaserColor:[OOColor magentaColor]];
|
||||
#endif
|
||||
weapon_damage = 23.0;
|
||||
// weapon_recharge_rate = 0.20;
|
||||
weapon_recharge_rate = 0.10;
|
||||
weapon_shot_temperature = 8.0f;
|
||||
break;
|
||||
case WEAPON_NONE:
|
||||
case WEAPON_UNDEFINED:
|
||||
weapon_damage = 0.0; // indicating no weapon!
|
||||
weapon_recharge_rate = 0.20; // maximum rate
|
||||
weapon_shot_temperature = 0.0f;
|
||||
break;
|
||||
OOColor *wcol = [weapon_type weaponColor];
|
||||
if (wcol != nil)
|
||||
{
|
||||
[self setLaserColor:wcol];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -9101,14 +9079,14 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
- (GLfloat)laserHeatLevelForward
|
||||
{
|
||||
GLfloat result = forward_weapon_temp / NPC_MAX_WEAPON_TEMP;
|
||||
if (forward_weapon_type == WEAPON_NONE)
|
||||
if (isWeaponNone(forward_weapon_type))
|
||||
{ // must check subents
|
||||
OOWeaponType forward_weapon_real_type = WEAPON_NONE;
|
||||
OOWeaponType forward_weapon_real_type = nil;
|
||||
NSEnumerator *subEnum = [self shipSubEntityEnumerator];
|
||||
ShipEntity *se = nil;
|
||||
while (forward_weapon_real_type == WEAPON_NONE && (se = [subEnum nextObject]))
|
||||
while (isWeaponNone(forward_weapon_real_type) && (se = [subEnum nextObject]))
|
||||
{
|
||||
if (se->forward_weapon_type != WEAPON_NONE)
|
||||
if (!isWeaponNone(se->forward_weapon_type))
|
||||
{
|
||||
forward_weapon_real_type = se->forward_weapon_type;
|
||||
result = se->forward_weapon_temp / NPC_MAX_WEAPON_TEMP;
|
||||
@ -10661,11 +10639,8 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
GLfloat dq = -1.0f;
|
||||
GLfloat d2, radius, astq;
|
||||
Vector rel_pos, urp;
|
||||
if (weapon_type == WEAPON_THARGOID_LASER)
|
||||
if ([weapon_type isTurretLaser])
|
||||
{
|
||||
/* this gives a frame rate dependency. Modified weapon_recharge_time
|
||||
* elsewhere to give a similar effect - CIM 20120502 */
|
||||
// if (randf() < 0.05) return YES; // one in twenty shots on target
|
||||
return YES;
|
||||
}
|
||||
|
||||
@ -10744,8 +10719,9 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
}
|
||||
if (weapon_temp / NPC_MAX_WEAPON_TEMP >= WEAPON_COOLING_CUTOUT) return NO;
|
||||
|
||||
if (energy <= weapon_energy_use) return NO;
|
||||
if ([self shotTime] < weapon_recharge_rate) return NO;
|
||||
if (weapon_type != WEAPON_THARGOID_LASER)
|
||||
if (![weapon_type isTurretLaser])
|
||||
{ // thargoid laser may just pick secondary target in this case
|
||||
if (range > randf() * weaponRange * (accuracy+7.5)) return NO;
|
||||
if (range > weaponRange) return NO;
|
||||
@ -10753,34 +10729,23 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
if (![self onTarget:direction withWeapon:weapon_type]) return NO;
|
||||
|
||||
BOOL fired = NO;
|
||||
switch (weapon_type)
|
||||
if (!isWeaponNone(weapon_type))
|
||||
{
|
||||
case WEAPON_PLASMA_CANNON:
|
||||
[self firePlasmaShotAtOffset:0.0 speed:NPC_PLASMA_SPEED color:[OOColor yellowColor] direction:direction];
|
||||
fired = YES;
|
||||
break;
|
||||
|
||||
case WEAPON_PULSE_LASER:
|
||||
case WEAPON_BEAM_LASER:
|
||||
case WEAPON_MINING_LASER:
|
||||
case WEAPON_MILITARY_LASER:
|
||||
[self fireLaserShotInDirection:direction];
|
||||
fired = YES;
|
||||
break;
|
||||
|
||||
case WEAPON_THARGOID_LASER:
|
||||
if ([weapon_type isTurretLaser])
|
||||
{
|
||||
[self fireDirectLaserShot:range];
|
||||
fired = YES;
|
||||
break;
|
||||
|
||||
case WEAPON_NONE:
|
||||
case WEAPON_UNDEFINED:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
[self fireLaserShotInDirection:direction];
|
||||
fired = YES;
|
||||
}
|
||||
}
|
||||
|
||||
if (fired)
|
||||
{
|
||||
energy -= weapon_energy_use;
|
||||
switch (direction)
|
||||
{
|
||||
case WEAPON_FACING_FORWARD:
|
||||
@ -10831,18 +10796,19 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
currentWeaponFacing = WEAPON_FACING_FORWARD;
|
||||
[self setWeaponDataFromType:forward_weapon_type];
|
||||
|
||||
weapon_damage = weapon_damage_override;
|
||||
// weapon damage override no longer effective
|
||||
// weapon_damage = weapon_damage_override;
|
||||
|
||||
BOOL result = [self fireWeapon:forward_weapon_type direction:WEAPON_FACING_FORWARD range:range];
|
||||
if (forward_weapon_type == WEAPON_NONE)
|
||||
if (isWeaponNone(forward_weapon_type))
|
||||
{
|
||||
// need to check subentities to avoid AI oddities
|
||||
// will already have fired them by now, though
|
||||
NSEnumerator *subEnum = [self shipSubEntityEnumerator];
|
||||
ShipEntity *se = nil;
|
||||
OOWeaponType weapon_type = WEAPON_NONE;
|
||||
OOWeaponType weapon_type = nil;
|
||||
BOOL hasTurrets = NO;
|
||||
while (weapon_type == WEAPON_NONE && (se = [subEnum nextObject]))
|
||||
while (isWeaponNone(weapon_type) && (se = [subEnum nextObject]))
|
||||
{
|
||||
weapon_type = se->forward_weapon_type;
|
||||
weapon_temp = se->forward_weapon_temp;
|
||||
@ -10851,9 +10817,9 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
hasTurrets = YES;
|
||||
}
|
||||
}
|
||||
if (weapon_type == WEAPON_NONE && hasTurrets)
|
||||
if (isWeaponNone(weapon_type) && hasTurrets)
|
||||
{ // no forward weapon but has turrets, so set up range calculations accordingly
|
||||
[self setWeaponDataFromType:WEAPON_PLASMA_CANNON];
|
||||
weaponRange = 10000.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -10988,18 +10954,21 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
{
|
||||
[self setShipHitByLaser:nil];
|
||||
|
||||
if (forward_weapon_type == WEAPON_NONE) return NO;
|
||||
if (isWeaponNone(forward_weapon_type)) return NO;
|
||||
[self setWeaponDataFromType:forward_weapon_type];
|
||||
|
||||
ShipEntity *parent = [self owner];
|
||||
NSAssert([parent isShipWithSubEntityShip:self], @"-fireSubentityLaserShot: called on ship which is not a subentity.");
|
||||
|
||||
|
||||
// subentity lasers still draw power from the main entity
|
||||
if ([parent energy] <= weapon_energy_use) return NO;
|
||||
if ([self shotTime] < weapon_recharge_rate) return NO;
|
||||
if (forward_weapon_temp > WEAPON_COOLING_CUTOUT * NPC_MAX_WEAPON_TEMP) return NO;
|
||||
if (range > weaponRange) return NO;
|
||||
|
||||
|
||||
forward_weapon_temp += weapon_shot_temperature;
|
||||
|
||||
[parent setEnergy:([parent energy] - weapon_energy_use)];
|
||||
|
||||
GLfloat hitAtRange = weaponRange;
|
||||
OOWeaponFacing direction = WEAPON_FACING_FORWARD;
|
||||
ShipEntity *victim = [UNIVERSE firstShipHitByLaserFromShip:self inDirection:direction offset:kZeroVector gettingRangeFound:&hitAtRange];
|
||||
@ -11165,12 +11134,6 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
|
||||
[self resetShotTime];
|
||||
|
||||
// random laser over-heating for AI ships
|
||||
/* if ((!isPlayer)&&((ranrot_rand() & 255) < weapon_damage)&&(![self isMining]))
|
||||
{
|
||||
shot_time -= (randf() * weapon_damage);
|
||||
} */
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@ -13521,7 +13484,7 @@ static BOOL AuthorityPredicate(Entity *entity, void *parameter)
|
||||
|
||||
- (BOOL) isMining
|
||||
{
|
||||
return ((behaviour == BEHAVIOUR_ATTACK_MINING_TARGET)&&(forward_weapon_type == WEAPON_MINING_LASER));
|
||||
return ((behaviour == BEHAVIOUR_ATTACK_MINING_TARGET)&&([forward_weapon_type isMiningLaser]));
|
||||
}
|
||||
|
||||
|
||||
@ -14152,24 +14115,11 @@ BOOL OOUniformBindingPermitted(NSString *propertyName, id bindingTarget)
|
||||
|
||||
GLfloat getWeaponRangeFromType(OOWeaponType weapon_type)
|
||||
{
|
||||
switch (weapon_type)
|
||||
{
|
||||
case WEAPON_PLASMA_CANNON:
|
||||
return 5000.0;
|
||||
case WEAPON_PULSE_LASER:
|
||||
case WEAPON_MINING_LASER:
|
||||
return 12500.0;
|
||||
case WEAPON_BEAM_LASER:
|
||||
return 15000.0;
|
||||
case WEAPON_THARGOID_LASER:
|
||||
return 17500.0;
|
||||
case WEAPON_MILITARY_LASER:
|
||||
return 30000.0;
|
||||
case WEAPON_NONE:
|
||||
case WEAPON_UNDEFINED:
|
||||
return 32000.0;
|
||||
}
|
||||
// never reached
|
||||
return 32000.0;
|
||||
return [weapon_type weaponRange];
|
||||
}
|
||||
|
||||
|
||||
BOOL isWeaponNone(OOWeaponType weapon)
|
||||
{
|
||||
return weapon == nil || [[weapon identifier] isEqualToString:@"EQ_WEAPON_NONE"];
|
||||
}
|
||||
|
@ -254,6 +254,8 @@ OOINLINE void GLColorWithOverallAlpha(const GLfloat *color, GLfloat alpha)
|
||||
|
||||
_compassActive = isCompassToBeDrawn;
|
||||
|
||||
_lastWeaponType = nil;
|
||||
|
||||
NSArray *legends = [hudinfo oo_arrayForKey:LEGENDS_KEY];
|
||||
for (i = 0; i < [legends count]; i++)
|
||||
{
|
||||
@ -886,6 +888,7 @@ OOINLINE void GLColorWithOverallAlpha(const GLfloat *color, GLfloat alpha)
|
||||
- (NSArray *) crosshairDefinitionForWeaponType:(OOWeaponType)weapon
|
||||
{
|
||||
NSString *weaponName = nil;
|
||||
NSString *weaponName2 = nil;
|
||||
static NSDictionary *crosshairDefs = nil;
|
||||
NSArray *result = nil;
|
||||
|
||||
@ -897,7 +900,12 @@ OOINLINE void GLColorWithOverallAlpha(const GLfloat *color, GLfloat alpha)
|
||||
*/
|
||||
|
||||
weaponName = OOStringFromWeaponType(weapon);
|
||||
weaponName2 = [weaponName substringFromIndex:3]; // strip "EQ_"
|
||||
result = [_crosshairOverrides oo_arrayForKey:weaponName];
|
||||
if (result == nil)
|
||||
{
|
||||
result = [_crosshairOverrides oo_arrayForKey:weaponName2];
|
||||
}
|
||||
if (result == nil) result = [_crosshairOverrides oo_arrayForKey:@"OTHER"];
|
||||
if (result == nil)
|
||||
{
|
||||
@ -910,6 +918,10 @@ OOINLINE void GLColorWithOverallAlpha(const GLfloat *color, GLfloat alpha)
|
||||
}
|
||||
|
||||
result = [crosshairDefs oo_arrayForKey:weaponName];
|
||||
if (result == nil)
|
||||
{
|
||||
result = [crosshairDefs oo_arrayForKey:weaponName2];
|
||||
}
|
||||
if (result == nil) result = [crosshairDefs oo_arrayForKey:@"OTHER"];
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ MA );-);, USA.
|
||||
|
||||
#import "Universe.h"
|
||||
#import "PlayerEntity.h"
|
||||
|
||||
#import "OOEquipmentType.h"
|
||||
|
||||
#define CASE(foo) case foo: return @#foo;
|
||||
#define REVERSE_CASE(foo) if ([string isEqualToString:@#foo]) return foo;
|
||||
@ -247,85 +247,71 @@ NSString *JSTypeToString(int /* JSType */ type)
|
||||
|
||||
NSString *OOStringFromWeaponType(OOWeaponType weapon)
|
||||
{
|
||||
switch (weapon)
|
||||
{
|
||||
CASE(WEAPON_NONE);
|
||||
CASE(WEAPON_PLASMA_CANNON);
|
||||
CASE(WEAPON_PULSE_LASER);
|
||||
CASE(WEAPON_BEAM_LASER);
|
||||
CASE(WEAPON_MINING_LASER);
|
||||
CASE(WEAPON_MILITARY_LASER);
|
||||
CASE(WEAPON_THARGOID_LASER);
|
||||
CASE(WEAPON_UNDEFINED);
|
||||
}
|
||||
return @"Unknown weapon";
|
||||
return [weapon identifier];
|
||||
}
|
||||
|
||||
|
||||
OOWeaponType OOWeaponTypeFromString(NSString *string)
|
||||
{
|
||||
REVERSE_CASE(WEAPON_PLASMA_CANNON);
|
||||
REVERSE_CASE(WEAPON_PULSE_LASER);
|
||||
REVERSE_CASE(WEAPON_BEAM_LASER);
|
||||
REVERSE_CASE(WEAPON_MINING_LASER);
|
||||
REVERSE_CASE(WEAPON_MILITARY_LASER);
|
||||
REVERSE_CASE(WEAPON_THARGOID_LASER);
|
||||
|
||||
return kOOWeaponTypeDefault;
|
||||
return OOWeaponTypeFromEquipmentIdentifierSloppy(string);
|
||||
}
|
||||
|
||||
|
||||
NSString *OOEquipmentIdentifierFromWeaponType(OOWeaponType weapon)
|
||||
{
|
||||
#define EQ_CASE(foo) case foo: return @"EQ_"#foo;
|
||||
|
||||
switch (weapon)
|
||||
{
|
||||
// EQ_CASE(WEAPON_PLASMA_CANNON);
|
||||
case WEAPON_PLASMA_CANNON: return @"EQ_WEAPON_TWIN_PLASMA_CANNON";
|
||||
EQ_CASE(WEAPON_PULSE_LASER);
|
||||
EQ_CASE(WEAPON_BEAM_LASER);
|
||||
EQ_CASE(WEAPON_MINING_LASER);
|
||||
EQ_CASE(WEAPON_MILITARY_LASER);
|
||||
EQ_CASE(WEAPON_THARGOID_LASER);
|
||||
|
||||
case WEAPON_NONE:
|
||||
case WEAPON_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
return nil;
|
||||
#undef EQ_CASE
|
||||
return [weapon identifier];
|
||||
}
|
||||
|
||||
|
||||
OOWeaponType OOWeaponTypeFromEquipmentIdentifierSloppy(NSString *string)
|
||||
{
|
||||
#define EQ_REVERSE_CASE(foo) if ([string hasSuffix:@#foo]) return WEAPON_##foo;
|
||||
EQ_REVERSE_CASE(PLASMA_CANNON); // required in playerEntityControls (case GUI_SCREEN_EQUIP_SHIP)
|
||||
EQ_REVERSE_CASE(PULSE_LASER);
|
||||
EQ_REVERSE_CASE(BEAM_LASER);
|
||||
EQ_REVERSE_CASE(MINING_LASER);
|
||||
EQ_REVERSE_CASE(MILITARY_LASER);
|
||||
EQ_REVERSE_CASE(THARGOID_LASER);
|
||||
|
||||
return kOOWeaponTypeDefault;
|
||||
#undef EQ_REVERSE_CASE
|
||||
OOWeaponType w = [OOEquipmentType equipmentTypeWithIdentifier:string];
|
||||
if (w == nil)
|
||||
{
|
||||
if (![string hasPrefix:@"EQ_"])
|
||||
{
|
||||
w = [OOEquipmentType equipmentTypeWithIdentifier:[NSString stringWithFormat:@"EQ_%@",string]];
|
||||
if (w != nil)
|
||||
{
|
||||
return w;
|
||||
}
|
||||
}
|
||||
return [OOEquipmentType equipmentTypeWithIdentifier:@"EQ_WEAPON_NONE"];
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
/* Previous save games will have weapon types stored as ints to the
|
||||
* various weapon types */
|
||||
OOWeaponType OOWeaponTypeFromEquipmentIdentifierLegacy(NSString *string)
|
||||
{
|
||||
if ([string intValue] > 0)
|
||||
{
|
||||
switch ([string intValue])
|
||||
{
|
||||
case 2:
|
||||
return OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_PULSE_LASER");
|
||||
case 3:
|
||||
return OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_BEAM_LASER");
|
||||
case 4:
|
||||
return OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_MINING_LASER");
|
||||
case 5:
|
||||
return OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_MILITARY_LASER");
|
||||
case 10:
|
||||
return OOWeaponTypeFromEquipmentIdentifierSloppy(@"EQ_WEAPON_THARGOID_LASER");
|
||||
default:
|
||||
return OOWeaponTypeFromEquipmentIdentifierSloppy(string);
|
||||
}
|
||||
}
|
||||
return OOWeaponTypeFromEquipmentIdentifierSloppy(string);
|
||||
}
|
||||
|
||||
|
||||
OOWeaponType OOWeaponTypeFromEquipmentIdentifierStrict(NSString *string)
|
||||
{
|
||||
#define EQ_REVERSE_CASE(foo) if ([string isEqualToString:@"EQ_WEAPON_" #foo]) return WEAPON_##foo;
|
||||
// EQ_REVERSE_CASE(PLASMA_CANNON);
|
||||
if ([string isEqual:@"EQ_WEAPON_TWIN_PLASMA_CANNON"]) return WEAPON_PLASMA_CANNON;
|
||||
EQ_REVERSE_CASE(PULSE_LASER);
|
||||
EQ_REVERSE_CASE(BEAM_LASER);
|
||||
EQ_REVERSE_CASE(MINING_LASER);
|
||||
EQ_REVERSE_CASE(MILITARY_LASER);
|
||||
EQ_REVERSE_CASE(THARGOID_LASER);
|
||||
|
||||
return kOOWeaponTypeDefault;
|
||||
#undef EQ_REVERSE_CASE
|
||||
// there is no difference between the two any more
|
||||
return OOWeaponTypeFromEquipmentIdentifierSloppy(string);
|
||||
}
|
||||
|
||||
|
||||
|
@ -66,6 +66,7 @@ SOFTWARE.
|
||||
NSSet *_incompatibleEquipment;
|
||||
NSArray *_conditions;
|
||||
NSDictionary *_scriptInfo;
|
||||
NSDictionary *_weaponInfo;
|
||||
NSString *_script;
|
||||
NSString *_condition_script;
|
||||
|
||||
@ -130,6 +131,16 @@ SOFTWARE.
|
||||
- (NSUInteger) installTime;
|
||||
- (NSUInteger) repairTime;
|
||||
|
||||
- (BOOL) isTurretLaser;
|
||||
- (BOOL) isMiningLaser;
|
||||
- (GLfloat) weaponRange;
|
||||
- (GLfloat) weaponEnergyUse;
|
||||
- (GLfloat) weaponDamage;
|
||||
- (GLfloat) weaponRechargeRate;
|
||||
- (GLfloat) weaponShotTemperature;
|
||||
- (GLfloat) weaponThreatAssessment;
|
||||
- (OOColor *) weaponColor;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -231,6 +231,8 @@ static NSDictionary *sMissilesRegistry = nil;
|
||||
_installTime = [extra oo_unsignedIntForKey:@"installation_time" defaultValue:0];
|
||||
_repairTime = [extra oo_unsignedIntForKey:@"repair_time" defaultValue:0];
|
||||
|
||||
_weaponInfo = [[extra oo_dictionaryForKey:@"weapon_info" defaultValue:[NSDictionary dictionary]] retain];
|
||||
|
||||
_damageProbability = [extra oo_floatForKey:@"damage_probability" defaultValue:(_isMissileOrMine?0.0:1.0)];
|
||||
|
||||
id object = [extra objectForKey:@"requires_equipment"];
|
||||
@ -325,6 +327,7 @@ static NSDictionary *sMissilesRegistry = nil;
|
||||
DESTROY(_incompatibleEquipment);
|
||||
DESTROY(_conditions);
|
||||
DESTROY(_condition_script);
|
||||
DESTROY(_weaponInfo);
|
||||
DESTROY(_scriptInfo);
|
||||
DESTROY(_script);
|
||||
|
||||
@ -582,6 +585,60 @@ static NSDictionary *sMissilesRegistry = nil;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) isTurretLaser
|
||||
{
|
||||
return [_weaponInfo oo_boolForKey:@"is_turret_laser" defaultValue:NO];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) isMiningLaser
|
||||
{
|
||||
return [_weaponInfo oo_boolForKey:@"is_mining_laser" defaultValue:NO];
|
||||
}
|
||||
|
||||
|
||||
- (GLfloat) weaponRange
|
||||
{
|
||||
return [_weaponInfo oo_floatForKey:@"range" defaultValue:12500.0];
|
||||
}
|
||||
|
||||
|
||||
- (GLfloat) weaponEnergyUse
|
||||
{
|
||||
return [_weaponInfo oo_floatForKey:@"energy" defaultValue:0.8];
|
||||
}
|
||||
|
||||
|
||||
- (GLfloat) weaponDamage
|
||||
{
|
||||
return [_weaponInfo oo_floatForKey:@"damage" defaultValue:15.0];
|
||||
}
|
||||
|
||||
|
||||
- (GLfloat) weaponRechargeRate
|
||||
{
|
||||
return [_weaponInfo oo_floatForKey:@"recharge_rate" defaultValue:0.5];
|
||||
}
|
||||
|
||||
|
||||
- (GLfloat) weaponShotTemperature
|
||||
{
|
||||
return [_weaponInfo oo_floatForKey:@"shot_temperature" defaultValue:7.0];
|
||||
}
|
||||
|
||||
|
||||
- (GLfloat) weaponThreatAssessment
|
||||
{
|
||||
return [_weaponInfo oo_floatForKey:@"threat_assessment" defaultValue:1.0];
|
||||
}
|
||||
|
||||
|
||||
- (OOColor *) weaponColor
|
||||
{
|
||||
return [OOColor brightColorWithDescription:[_weaponInfo objectForKey:@"color"]];
|
||||
}
|
||||
|
||||
|
||||
/* This method exists purely to suppress Clang static analyzer warnings that
|
||||
this ivar is unused (but may be used by categories, which it is).
|
||||
FIXME: there must be a feature macro we can use to avoid actually building
|
||||
|
@ -3806,27 +3806,25 @@ static JSBool ShipThreatAssessment(JSContext *context, uintN argc, jsval *vp)
|
||||
|
||||
// check lasers
|
||||
OOWeaponType wt = [thisEnt weaponTypeIDForFacing:WEAPON_FACING_FORWARD strict:NO];
|
||||
if (wt == WEAPON_NONE)
|
||||
assessment += ShipThreatAssessmentWeapon(wt);
|
||||
if (isWeaponNone(wt))
|
||||
{
|
||||
assessment -= 2.5; // cancel base ship danger
|
||||
}
|
||||
else
|
||||
{
|
||||
assessment += ShipThreatAssessmentWeapon(wt);
|
||||
assessment -= 1.5; // further penalty for ships with no forward laser
|
||||
}
|
||||
|
||||
wt = [thisEnt weaponTypeIDForFacing:WEAPON_FACING_AFT strict:NO];
|
||||
if (wt != WEAPON_NONE)
|
||||
if (!isWeaponNone(wt))
|
||||
{
|
||||
assessment += 1 + ShipThreatAssessmentWeapon(wt);
|
||||
}
|
||||
// port and starboard weapons less important
|
||||
wt = [thisEnt weaponTypeIDForFacing:WEAPON_FACING_PORT strict:NO];
|
||||
if (wt != WEAPON_NONE)
|
||||
if (!isWeaponNone(wt))
|
||||
{
|
||||
assessment += 0.2 + ShipThreatAssessmentWeapon(wt)/5.0;
|
||||
}
|
||||
wt = [thisEnt weaponTypeIDForFacing:WEAPON_FACING_STARBOARD strict:NO];
|
||||
if (wt != WEAPON_NONE)
|
||||
if (!isWeaponNone(wt))
|
||||
{
|
||||
assessment += 0.2 + ShipThreatAssessmentWeapon(wt)/5.0;
|
||||
}
|
||||
@ -3891,22 +3889,11 @@ static JSBool ShipThreatAssessment(JSContext *context, uintN argc, jsval *vp)
|
||||
|
||||
static double ShipThreatAssessmentWeapon(OOWeaponType wt)
|
||||
{
|
||||
switch (wt)
|
||||
if (wt == nil)
|
||||
{
|
||||
case WEAPON_NONE:
|
||||
return -1;
|
||||
case WEAPON_PULSE_LASER:
|
||||
return 0;
|
||||
case WEAPON_BEAM_LASER:
|
||||
return 0.5;
|
||||
case WEAPON_MINING_LASER:
|
||||
return -0.5;
|
||||
case WEAPON_MILITARY_LASER:
|
||||
case WEAPON_THARGOID_LASER:
|
||||
return 1.0;
|
||||
default:
|
||||
return 0;
|
||||
return -1.0;
|
||||
}
|
||||
return [wt weaponThreatAssessment];
|
||||
}
|
||||
|
||||
|
||||
|
@ -9107,10 +9107,10 @@ static OOComparisonResult comparePrice(id dict1, id dict2, void *context)
|
||||
|
||||
OOCreditsQuantity scrap_value = 351; // translates to 250 cr.
|
||||
|
||||
OOWeaponType ship_fwd_weapon = [dict oo_unsignedIntForKey:@"forward_weapon"];
|
||||
OOWeaponType ship_aft_weapon = [dict oo_unsignedIntForKey:@"aft_weapon"];
|
||||
OOWeaponType ship_port_weapon = [dict oo_unsignedIntForKey:@"port_weapon"];
|
||||
OOWeaponType ship_starboard_weapon = [dict oo_unsignedIntForKey:@"starboard_weapon"];
|
||||
OOWeaponType ship_fwd_weapon = [OOEquipmentType equipmentTypeWithIdentifier:[dict oo_stringForKey:@"forward_weapon"]];
|
||||
OOWeaponType ship_aft_weapon = [OOEquipmentType equipmentTypeWithIdentifier:[dict oo_stringForKey:@"aft_weapon"]];
|
||||
OOWeaponType ship_port_weapon = [OOEquipmentType equipmentTypeWithIdentifier:[dict oo_stringForKey:@"port_weapon"]];
|
||||
OOWeaponType ship_starboard_weapon = [OOEquipmentType equipmentTypeWithIdentifier:[dict oo_stringForKey:@"starboard_weapon"]];
|
||||
unsigned ship_missiles = [dict oo_unsignedIntForKey:@"missiles"];
|
||||
unsigned ship_max_passengers = [dict oo_unsignedIntForKey:@"max_passengers"];
|
||||
NSMutableArray *ship_extra_equipment = [NSMutableArray arrayWithArray:[[dict oo_dictionaryForKey:@"extra_equipment"] allKeys]];
|
||||
|
Loading…
x
Reference in New Issue
Block a user