Back to Index Page generated: May 8, 2024, 6:16:03 AM

Expansion HardShips

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Ships get 6 side armours, 10 Hard ships with Hard Armour, many new defensive equipments and Drones. Ships get 6 side armours, 10 Hard ships with Hard Armour, many new defensive equipments and Drones.
Identifier oolite.oxp.Norby.HardShips oolite.oxp.Norby.HardShips
Title HardShips HardShips
Category Mechanics Mechanics
Author Norby Norby
Version 0.89 0.89
Tags wip wip
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
  • oolite.oxp.CommonSenseOTB.CustomShields:0.83
  • oolite.oxp.CommonSenseOTB.ShieldEqualizer+Capacitors:1.3
  • oolite.oxp.Thargoid.IronHide:2.00
  • oolite.oxp.Norby.ShipVersion:1.21
  • oolite.oxp.CommonSenseOTB.CustomShields:0.83
  • oolite.oxp.CommonSenseOTB.ShieldEqualizer+Capacitors:1.3
  • oolite.oxp.Thargoid.IronHide:2.00
  • oolite.oxp.Norby.ShipVersion:1.21
  • Conflict Expansions
    Information URL http://wiki.alioth.net/index.php/HardShips n/a
    Download URL https://wiki.alioth.net/img_auth.php/4/45/HardShips_0.89.oxz n/a
    License CC BY-NC-SA 4 CC BY-NC-SA 4
    File Size n/a
    Upload date 1610873287

    Documentation

    Also read http://wiki.alioth.net/index.php/HardShips

    HardShips readme.txt

    HardShips OXP
    
    This OXP contains:
    1. New Hard Ships based on the player ships with the new Hard Armour.
    2. Standard Armour on 6 sides of all ships including NPCs.
    3. Defensive Equipments.
    4. Drones: Laser Drone and Hard Drone.
    
    
    1. Hard Ships
    
    The following ships can be choosed at new game from the start menu:
    Hard Cobra Mark III, Hard Cobra Mark I, Hard Adder and Hard Moray.
    If you choose cheaper ship then more will be left from the starting 100.000 credits to buy equipments and goods.
    
    The Cobra III is seems to be pretty cheap, but it is an old ship: if you installed ShipVersion OXP then you will always see the lowest v1.0. All others get many equipments and you can search for a very high version by call another offer again and again.
    
    If you want to try your next ship then the more costly ships allow a test drive for 20 minutes:
    Hard Anaconda, Hard Asp, Hard Boa, Har-de-Lance and Hard Python.
    
    But what offer the Hard Armour?
    
    It is not a damage holder as the standard melting armours: it is a very hard material which can partially deflect lasers and other attacks before any damage!
    It has a base value of 3 which deducted from all attacks. The large Hard Anaconda has 5 due to can hold higher mass.
    If the power of an attack is less than the base value, then no damage at all, as small bullets will never penetrate thick plates.
    If more, then only the difference deducted from the standard armour of the ship.
    If no armour left then the deflection effect of the Hard Armour still remain, so all energy damages will be reduced also!
    
    It is different from an additional energy bank because the less damage means faster regeneration, so it is equal with if there are more banks and higher recharge values also, and more standard armour with faster armour repair rates, and larger IronHide armour (if installed), and raise all other bonuses and effects of the equipments, and.., and.., and..
    
    If it is not enough for you, then install ShipVersion OXP and see what endurance can come from a trader if supported with some good equipments which multiplied by the Hard Armour. :)
    
    To count the high mass of the Hard Armour these ships get only half thrust so accelerate (and brake!) much slower, but the maximum speed unchanged due to some physical blah about inertialess drives (or to do not unbalance the game, who knows?).
    
    To visualize the Hard Armour these ships got orange tiled textures from Gimp (Terra pattern, Granite to pirates, Pool Bottom to police).
    Please use it if you make your own Hard Armoured ships: set hardarmour=10 in script_info, set density=2, halve the thrust, make orange tiled textures and done. A good question is why not reduce the acceleration (named thrust) more on the ships with thicker armour. I can say some technical blah again but better if imagine that the given Hard Armours matched to the ship size: larger armour set on ships with larger mass already. Additional decrease needed only if a ship get (somehow) larger Hard Armour than the default.
    
    The spread of the armour usage inspired the weapon makers to invent Armour Piercing Lasers and Missiles.
    The best against Hard Armour is the Armour Piercing weapons (coming soon as secondary weapons):
    
    -Hammer Laser is an advanced Mining Laser with double power (technically two tube fire together) which not reduced by Hard Armour and a bit faster (1.5x) recharge. But the range is the original 12.5km only and reduced by Hard Shield until there are enough shield to catch the whole damage.
    
    -Sniper Laser is developed as a twin Military Laser to get Armour Piercing ability and 30km effective range, but usable in pulse mode only and can not pierce shield.
    
    -All type of Railguns in the Railgun OXP has Armour Piercing ability, as all other collision (scrape) type damage also.
    
    
    2. Armour sides to all ships
    
    The standard armour of the ships divided into 6 side: Fore, Aft, Port, Starboard, Top, Bottom.
    There are two "inner" side also: IronHide armour and Core hull.
    
    After taken enough (maxEnergy/2) damage either outer side to destroy it, the next hits from the damaged side counted to Core hull hit.
    Taking equal amount with maxEnergy of Core hull hit cause internal damage or if it happen in short time then more likely Fuel Leak.
    The chance of the Leak is higher if the ship is low in energy.
    
    Armour Repair Bots can fix 1 points of armour in every seconds, and works on all side at one time but use up 1t Alloy for each 100 damage points.
    Buy Alloys before undock otherwise the Bots can fix only as little as 100 points from the Alloy which already in the hand of the Bots.
    NPCs always start to fly with 1-5t alloys and if damaged (or died) then can leave some alloy, but you also if at least one side of your ship lost all armour (leaked).
    If you scoop it the Repair Bot can put back some armour.
    
    Core repairs do not use Alloys due to it is hull and not Armour (but need more time to fix the larger amount).
    The main difference is that hull can not prevent energy loss if get hit but the armour can.
    
    Technically the Core hull is another counter of the energy damage but repaired much slower than the energy recharged.
    If you get many hit in short time then the energy will be low also when the Core hull run out so it can cause Fuel Leak.
    But if there was enough pause between hits to recharge many energy (but not enough to repair the hull) then get internal damage.
    The Fuel Leak will be sealed if repaired the 25% of the hull, then continues until fully repaired, but can be leaked again if run out next time.
    
    The maximum armour of small ships under 30t (Adder, Mamba, Sidewinder and below) is 100 regardless of maxEnergy.
    The standard armour damages will be fixed in any dock for free.
    
    No Core Armour which can defend from all directions because the sides founded to make more reality.
    But if you want, install IronHide OXP because the usage of the IronHide Armours is supported and additive.
    Placed inside of the side armours to get damage after the in-flight repairable part is depleleted only.
    
    To compensate NPCs if IronHide OXP present (which is player-only), the HardShips OXP will award extra armour to NPCs.
    It will be an one-time armour without in-flight repair as the player version.
    
    NPC ships with larger random entityPersonality value will get more IronHide Armour:
    -30% get as many as the normal IronHide Armour (200 points, if ShipVersion OXP present then v5-v7),
    -20% get Military IronHide Armour (400 points, v8-v9),
    -1% get 1.5x of the Military IronHide Armour (600 points, v10).
    To tell the truth, the IronHide support is made to create some really hard enemy. :)
    For example you can see Vipers with not only the basic 180 energy points but with 490 armour and 384 shield points, which is 6x more.
    
    In addition there are harder ones in Granite suit for NPC hunters and pirates.
    
    
    3. Defensive Equipments
    
    Additional Armour Equipments
    
    The Front and Aft side can hold an extra layer standard armour which is repairable in dock only (and for a fee), so give an one-time defense only.
    Other sides can not hold additions, it would be too much extra mass to any ship.
    
    If an Additional Armour Equipment damaged then the defense still remain in this fly but need repair when docked to use again.
    The repair team can not restore the armour value of a damaged equipment, furthermore wipes the remaining armour value after landing to prevent accidents in dock, but the equipment remain in damaged status to can buy repair.
    If you do not pay the repair then you will undock without working additional defense.
    
    A surprise can happen due to the game mechanics: a frontal hit can damage the Additional Aft Armour also as any other equipments.
    But it is rare enough to accept as an unlucky hit which managed to go through the whole ship.
    
     Cost: 2*5000.0 Cr.
     Techlevel: 5
    
    
    Additional Core Hull Equipment
    
    Doubles the damage amount before start to get internal damage or Fuel Leak.
    Repaired in-flight automatically as the normal part of the Core hull due to it is not an armour.
    If the equipment is damaged then repairable in dock only, but the added hull remains as an one-time defense.
    
    You can fix all of the Additional equipments in one step when docked in all system, but you can buy in tech level 5 or above.
    The showed price is enough to fix a single damaged equipment, if all three damaged then will deduct three times more.
    
     Cost: 5000.0 Cr.
     Techlevel: 5
    
    
    Dummy Equipments
    
    Many metal fragments placed between equipments to take out damage with high odds, but take cargo space also.
    There are different packages: 1t, 5t, 10t, 50t and 100t with 10, 50, 100, 500 and 1000 times higher odds to damage before others.
    You can buy all of them if you have 166t cargo space and use together because the size of the fragments are different and can put the small ones into the remaining spaces of the large ones.
    But never found these in the buyable ships by default, so you must get it by hand after bought a new ship.
    (Technically not possible, a bug in Oolite v1.77 cause sometime disappearing eqipments with cargo space reqirement in shipyard.plist.)
    Fortunately you can buy worthless metals in all systems. :)
    
     Cost: 10.0 Cr./1 t
     Techlevel: 1
    
    
    Engine Repair Bot
    
    Can fix damaged Injectors, Q-charger and Broken Engines in a minute to help survive and run from a bad situation.
    Need 1t Machinery for each fix.
    Can not fit into ships under 30t mass.
    
     Cost: 1000.0 Cr.
     Techlevel: 5
    
    
    Equipment Box
    
    This armoured box can defend all equipments. This will be damaged first, the equipments later only.
    Does not require cargo space but you can place into the ship a single Equipment Box only.
    More specific boxes available also which placed inside this box to save the most important equipments which can help in retreat.
    Other equipments can not be boxed separatedly due to not enough space in the ships, these guarded by the general Equipment Box only.
    All damaged boxes repaired automatically in a minute but need 100kg alloys to fix a damage.
    Can not fit any of the boxes into ships under 30t.
    
     Cost: 100.0 Cr.
     Techlevel: 1
    
    
    Electronics Box
    
    Defend your Docking Computers, E.C.M. System, Multi-Targeting System, Scanner Targeting Enhancement and Target System Memory Expansion until penetrated.
    
     Cost: 200.0 Cr.
     Techlevel: 1
    
    
    Injector Box
    
    Armoured box around Witchdrive Fuel Injectors to take over the first damage.
    A must-have due to Injectors is the best escape tool in a hot situation and can be fatal if suddenly damaged.
    You can retreat instantly when this box damaged before losing your ability to run.
    Protect your Engine Repair Bot, Q-Charger from Q-Charger OXP and your engines also if Breakable Engines OXP is installed.
    
     Cost: 200.0 Cr.
     Techlevel: 1
    
    
    Life Box
    
    Put your Escape Pod and Passenger Berths into a protecting box.
    Protect your HUD and IFF scanner due to these are in your cockpit also if Breakable_HUD_IFF_Scanner OXP is installed.
    
     Cost: 200.0 Cr.
     Techlevel: 1
    
    
    Shield Box
    
    Defend Shield Boosters, Shield Capacitors and Military Shield Enhancement, but not Hard Shields which placed outside of the hull.
    Protect your normal shields also if Breakable Shield Generators OXP is installed.
    
     Cost: 200.0 Cr.
     Techlevel: 1
    
    
    Emergency Energy Generator
    
    Refill all energy banks from Radioactives and Platinum as catalyst but once only due to need repair after used.
    Need 1t Radioactives and 1kg Platinum for each bank, beware: storing radioactives are illegal in some systems.
    Triggered when the last energy bank is remaining only.
    The speedy recharge can cause internal damage to the ship (in cargo, equipment or service level).
    
     Cost: 10000.0 Cr.
     Techlevel: 5
    
    
    Emergency Shield Generator
    
    Need an Emergency Energy Generator which can recharge shields also with this equipment.
    Can not refill Shield Capacitors.
    
     Cost: 10000.0 Cr.
     Techlevel: 12
    
    
    High-Tech Catalyst
    
    EEG can use Fuel with Gold catalyst if no more Radioactives or Platinum on board.
    Need clean status because these tools are regulated, drain 0.1ly fuel and 1kg Gold to refill one energy bank.
    Can take the first damage from an emergency refill so Emergency Energy Generator can trigger another times.
    
     Cost: 10000.0 Cr.
     Techlevel: 12
    
    
    Renewable Energy Generator
    
    Generate two banks of energy when the last bank is touched and will renew in any dock for free.
    Need unclean status to buy due to use old unsafe technology which cause many internal damages to the ship when break down.
    
     Cost: 5000.0 Cr.
     Techlevel: 3
    
    
    Hard Nose
    
    The front of the ship can hold an additional Hard Armour layer which increase the deflected amount of any damage which hit the front side by 1 points in addition to the base Hard Armour.
    Other sides can not hold similar addition.
    Can put on non-HardShips, and can be damaged (base Hard Armour can not).
    
     Cost: 5000.0 Cr.
     Techlevel: 5
    
    
    Very Hard Nose
    
    Doubled Hard Nose can deflect additional 2 points in any ship, but can buy at tech level 12 planets or above only and a bit costly.
    
    Can not use in addition to the normal Hard Nose, if you buy the better then the normal will be sold and refunded.
    You can downgrade also if you need money.
    
    Your equipments still can get damaged from a hit which not caused armour damage if no shield by short circuit and shock, and the Armour Piercing weapons still can strike through these very hard front armours.
    
    If you use ShipVersion OXP then you must go around the best NPCs after the shield is out because you can not scratch the front also. The Detectors equipment can help to check the caused damage if installed.
    
     Cost: 10000.0 Cr.
     Techlevel: 12
    
    
    Hard Shield Equipments
    
    Similar with the Hard Armour but hardening the shield by placing more shield emitters denser, but the cost growth also lineal.
    Every hit reduced with the level of the Hard Shield Equipment.
    Exists from level 1 to 10, the best sold only at techlevel 14 planets or above and costs 10.000 credits.
    Can found only in systems where the tech level is 4 level more than the level of the Hard Shield, but all is repairable from tech level 5.
    Can use only one at a time, if you buy another then the old will be sold and you will get full refund from it.
    This means also if you need some money then you can downgrade it and get back the difference to buy another important things.
    It is not additive with the Hard Armour, can not protect the hull of the ship after the shield is depleted.
    
    The (incoming) Shield-Sapper weapons also very affected by Hard Shield: can reduce the 5x depleting ability to 5-HSLevel/6.
    If you are not mathematician, then here is a table:
    HSLevel  	0	2	4	6	8	10
    Depleting	5	4.667	4.333	4	3.667	3.333
    
    The 1x damage of the Sapper and the range is similar with a dual predecessor Beam Laser: 30 energy points and 15km, need 5x energy per shot and usable in pulse mode only, but it is more effective against shield than the Beam laser in beam mode and not only for 3 seconds due to never overheated.
    The dual mode means one shot and 150 points (2*5*15) gone from a soft shield.
    The 256 points of a full Boosted (but not Military) normal shield can be Sapped in 1 second: the first instant hit more than halving it then the next after a second clearing out.
    A Military shield with Hard Shield 8 (default on v8 NPCs if ShipVersion OXP present) need at least 6 second (if all shot hit), but against armour and hull or a shield with Anti-Sapper equipment is working as a dual Pulse Laser only.
    
     Cost: 1000.0 Cr./level
     Techlevel: 5-14
    
    
    Anti-Sapper Shield Equipment
    
    Please use the full name in nice talk, do not say the short acronym as pirates does.
    Requires Hard Shield 10, and can not reduce the normal hits, but totally negate the Shield-Sapper effect.
    Cost as much as a mid-class ship itself, and your vehicle will be look as a hedgehog from the exceptionally densely placed emitters.
    The many parts cause that can be damaged with 10x more probability than other equipments.
    Can found only in systems with tech level 14 or above but can repair from tech level 5.
    The repair is cheap due to usually a small piece damaged only in the same time.
    But if you install the Realistic Damage OXP then can be totally destroyed which maybe cost more to worth, so in in this case buy only after you are earned really much money.
    
     Cost: 20000.0 Cr.
     Techlevel: 14
    
    
    Big Shield Capacitors
    
    Extend the Shield Capacitors (if any) to 4 times of the original size (256).
    Available at tech level 14 planets (as normal capacitors), and need installed ShieldEqualizer+Capacitors OXP.
    Cost many credits, but you get in one equipment not only the forward but the aft extension also.
    At least v3.1 needed from the Numeric HUD to show the big values of the capacitors (older show max. 99).
    
     Cost: 10000.0 Cr
     Techlevel: 14
    
    
    There are some hidden equipments in this OXP, please do not ask or publish it in the forum if you found one, think on others who want to find it in the game. If you are unsure to something is a bug or feature then ask the author in email (norbylite@gmail.com) or in private message (Norby).
    
    
    
    Ship size restrictions
    
    Ships with less than 30t mass can not get any equipments from this OXP due to the small inner space:
    Adder (11t), Gecko (23t), Mamba (27t), Sidewinder (25t) and Viper (23t).
    But can get standard and Hard Armour.
    
    Ships under 130t can not get Big Shield Capacitors, Very Hard Nose and Military IronHide Armour:
    Asp (59t), Cobra I (47t), Constrictor (33t), Fer-de-Lance (51t), Krait (80t), Moray (40t), Viper Interceptor (43t) and the previous small ships.
    
    Large ships can get anything (be wise): Anaconda, Boa, Boa Mk2, Cobra III and Python.
    The ship size is more important if ShipVersion OXP is installed.
    
    
    4. Drones
    
    Fast and agile tiny remote controlled ships, designed to reach as little hull size as possible to minimalize the aimable area.
    No Life Support so can fight in automatic mode only, but large ships like Cobra III can hold and launch drones if needed.
    Can not hold Injectors, Shield Boosters or any other extras, and no Hyperdrive so must call back before jump.
    
    Laser Drones hold a Pulse Laser and 2 energy banks with very slow recharge rate (1) but fast (500).
    Hard Drones equipped with Hard Amour, better recharge (2) and a Mini Turret also, but slower and less agile.
    
    
    
    
    Dependencies:
    Oolite v1.77 or later.
    
    Instructions:
    In Oolite v1.79 or later do not unzip the .oxz file, just move into the AddOns folder of your Oolite installation.
    
    In Oolite v1.77 make a HardShips.oxp subfolder in your AddOns folder and unzip the .oxz file into the newly created subfolder.
    
    If you use a custom replacement shipset (from Griff, Smivs or others) and you want to see the custom ship designs as hard ships also instead of the ships in this oxp then rename the shipdata.plistforcustomshipsets to shipdata.plist in the Config folder.
    
    Conflicts:
    -CustomShields OXP included Fuel Leak support also, turn it off if you do not want double chance to leaking.
    -Start Choices OXP was the source of the new game screen. To insert new menu items HardShips OXP included all ships from the Start Choices 1.3 and disabled the original script, but if a new Start Choices will arrive then it will not shown until somebody port the changes into the HardShips OXP.
    
    Recommended OXPs:
    -CustomShields OXP to put shields into NPC ships, Hard Shields is player-only without this.
    -Detectors OXP to show important ship data including facing armour value in the target box.
    -Griff's replacement shipset supported with hard and granite textures.
    -IronHide OXP to get extra armour, NPCs will get also if HardShips present.
    -Numeric HUD v3.11 to show Shield Capacitor values.
    -Realistic Damage OXP to fear for your ASS (oh sorry I said).
    -ShieldEqualizer+Capacitors OXP if you want to use Big Shield Capacitors.
    -ShipVersion OXP to maintain balance with awarded equipments from HardShips OXP to NPCs.
    
    License:
    This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License version 4.0
    If you are re-using any piece of this OXP, please let me know by sending an e-mail to norbylite@gmail.com .
    
    Thanks to the community for:
    * Feedbacks by Oolite Forum members.
    * Main program by the core programmer team.
    * Programming instructions by all Wiki writers.
    * Recommended OXPs by its authors.
    * Start menu from Start Choices OXP by Mika Spara.
    
    Changelog:
    2016.10.20. v0.89 Fix Hard Boa Mk2 to allow fitting Military Shields, thanks to javirodriguez.
    2015.03.10. v0.88 Hard Armor made less hard, following reduced laser power in Oolite 1.81.
                      Allow selection of extra ships in Start Choices OXP.
                      Send less emails with Email System OXP.
    2014.11.09. v0.87 Fixed the discharge of Big Shield Capacitor 2, thanks to V12.
                      Small fix in start menu for Oolite v1.79.
    2013.11.21. v0.86 Small fix in texture of hardballturret.
    2013.11.18. v0.85 Granite player ships in shipdata.plistforgriffgranite.
    2013.11.16. v0.84 New textures for Griff ships.
    2013.10.19. v0.83 Equipment boxes repaired from alloys in a minute.
                       Engine Repair Bot added.
    2013.10.19. v0.82 Made compatible with Renegade Pirates OXP.
    2013.10.14. v0.81 Added an alternative shipdata.plist for custom shipsets.
    2013.10.13. v0.8  Granite hunters and Energy Generator equipments added.
    2013.06.12. v0.7  Drones added.
    2013.06.09. v0.6  More equipments added.
    2013.05.05. v0.5  Some equipments added.
    2013.04.08. v0.2  Second test version.
    2013.03.31. v0.1  First test files.
    

    Equipment

    Name Visible Cost [deci-credits] Tech-Level
    Additional Aft Armour yes 50000 5+
    Refund Additional Aft Armour yes 0 5+
    Repair Armours, Core Hull, Hard Nose and Energy Gen. yes 10000 1+
    Additional Core Hull yes 50000 5+
    Refund Additional Core Hull yes 0 5+
    Additional Front Armour yes 50000 5+
    Refund Additional Front Armour yes 0 5+
    Anti-Sapper Shield yes 200000 14+
    Refund Anti-Sapper Shield yes 0 14+
    Big Shield Capacitors yes 100000 4+
    Big Shield Capacitors 2 yes 200000 5+
    Refund Big Shield Capacitors 2 yes 0 5+
    Station Shield Capacitors yes 1000000 100+
    Refund Big Shield Capacitors yes 0 4+
    1t Dummy yes 100 1+
    10t Dummy yes 1000 1+
    100t Dummy yes 10000 1+
    Refund 100t Dummy yes 0 1+
    Refund 10t Dummy yes 0 1+
    Refund 1t Dummy yes 0 1+
    5t Dummy yes 500 1+
    50t Dummy yes 5000 1+
    Refund 50t Dummy yes 0 1+
    Refund 5t Dummy yes 0 1+
    Emergency Energy Generator yes 100000 5+
    Refund Emergency Energy Generator yes 0 5+
    Electronics Box yes 2000 1+
    Equipment Box yes 1000 1+
    Refund Equipment Box yes 0 1+
    Repair Boxes and Dummy Eqs in one step yes 200 1+
    Engine Repair Bot yes 10000 5+
    Emergency Shield Generator yes 100000 12+
    Refund Emergency Shield Generator yes 0 12+
    Hard Armour yes 0 100+
    Hard Armour V yes 0 100+
    Hard Armour X yes 0 100+
    Hard Nose yes 50000 5+
    Refund Hard Nose yes 0 5+
    Hard Shield I yes 10000 5+
    Hard Shield X yes 100000 14+
    Refund Hard Shield I yes 0 5+
    Hard Shield II yes 20000 6+
    Hard Shield III yes 30000 7+
    Hard Shield IV yes 40000 8+
    Hard Shield V yes 50000 9+
    Hard Shield VI yes 60000 10+
    Hard Shield VII yes 70000 11+
    Hard Shield VIII yes 80000 12+
    Hard Shield IX yes 90000 13+
    Repair Hard Shield yes 5000 2+
    High-Tech Catalyst yes 100000 12+
    Refund High-Tech Catalyst yes 0 12+
    Injector Box yes 2000 1+
    Life Box yes 2000 1+
    Renewable Energy Generator yes 50000 3+
    Refund Renewable Energy Generator yes 0 3+
    Sapper Nullifier yes 300000 15+
    Shield Box yes 2000 1+
    Very Hard Nose yes 100000 12+
    Very Very Hard Nose yes 1000000 15+

    Ships

    Name
    constrictor-player
    drones
    gecko-player
    Hard Adder
    Hard Anaconda
    Hard Asp
    Hard Boa
    Hard Boa Mk2
    Hard Cobra Mk III
    Hard Cobra Mk I
    Hard Moray
    Hard Python
    hardadder-player
    hardanaconda-player
    Anaconda X
    Granite Anaconda X
    Granite Asp
    hardasp-player
    Police Asp
    Granite Boa
    hardboa-player
    Granite Boa Mk2
    hardboa2-player
    Granite Cobra Mk III
    hardcobra3-player
    hardcobramk1-player
    Hard Drone
    Har-de-Lance
    Granite Fer-de-Lance
    hardelance-player
    Hard Pod
    Granite Moray
    hardmoray-player
    Granite Python
    hardpython-player
    HardShip
    Mini Blue Turret
    Mini Red Turret
    Mini Turret
    Strong Blue Turret
    Strong Red Turret
    Strong Turret
    Hard Turret
    krait-player
    Laser Drone
    mamba-player
    piratedrone
    Granite Drone
    Police Drone
    Hard Drone
    shuttle-player
    sidewinder-player
    tharglet-player
    thargoid-player
    transporter-player
    viper-interceptor-player
    viper-player
    worm-player

    Models

    This expansion declares no models.

    Scripts

    Path
    Scripts/armourrepair.js
    "use strict";
    this.name        = "armourrepair";
    this.author      = "Norby";
    this.copyright   = "2013 Norbert Nagy";
    this.licence     = "CC BY-NC-SA 3.0";
    this.description = "Repair Additional Armour and Core Hull Equipments if damaged.";
    this.version     = "1.0";
    
    this.allowAwardEquipment = function(eqKey, ship, context)
    {
    	if(eqKey==="EQ_ADDITIONAL_ARMOUR_REPAIR" && ship === player.ship && context === "purchase"
    		&& ( player.ship.equipmentStatus("EQ_ADDITIONAL_FRONT_ARMOUR") === "EQUIPMENT_DAMAGED"
    		|| player.ship.equipmentStatus("EQ_ADDITIONAL_AFT_ARMOUR") === "EQUIPMENT_DAMAGED"
    		|| player.ship.equipmentStatus("EQ_ADDITIONAL_CORE_HULL") === "EQUIPMENT_DAMAGED"
    		|| player.ship.equipmentStatus("EQ_HARDNOSE") === "EQUIPMENT_DAMAGED"
    		|| player.ship.equipmentStatus("EQ_VERYHARDNOSE") === "EQUIPMENT_DAMAGED"
    		|| player.ship.equipmentStatus("EQ_VERYVERYHARDNOSE") === "EQUIPMENT_DAMAGED"
    		|| player.ship.equipmentStatus("EQ_EEG") === "EQUIPMENT_DAMAGED"
    		|| player.ship.equipmentStatus("EQ_ESG") === "EQUIPMENT_DAMAGED"
    		|| player.ship.equipmentStatus("EQ_HTCAT") === "EQUIPMENT_DAMAGED" && player.bounty == 0
    		|| player.ship.equipmentStatus("EQ_REG") === "EQUIPMENT_DAMAGED" && player.bounty > 0 ) )
    		return true;
    	else return false;
    }
    
    Scripts/eqboxrepair.js
    "use strict";
    this.name        = "eqboxrepair";
    this.author      = "Norby";
    this.copyright   = "2013 Norbert Nagy";
    this.licence     = "CC BY-NC-SA 3.0";
    this.description = "Repair Additional Armour equipments if damaged.";
    this.version     = "1.0";
    
    this.allowAwardEquipment = function(eqKey, ship, context)
    {
    	if(eqKey==="EQ_EQUIPMENT_BOX_REPAIR" && ship === player.ship && context === "purchase"
    		&& player.ship.equipmentStatus("EQ_EQUIPMENT_BOX") === "EQUIPMENT_DAMAGED" )
    		return true;
    	else return false;
    }
    
    Scripts/hardarmour.js
    "use strict";
    this.name        = "hardarmour";
    this.author      = "Norby";
    this.copyright   = "2013 Norbert Nagy";
    this.licence     = "CC BY-NC-SA 3.0";
    this.description = "Ship script to call a function to give back the energy loss which is prevented by armour";
    this.version     = "1.0";
    
    this.shipTakingDamage = function(amount, whom, type) {
    //	if(whom.isPlayer) player.consoleMessage(Math.floor(amount)+" --> "+this.ship.name);//debug
    	worldScripts["hardships"].$HardShips_TakingDamage(this.ship, amount, whom, type);
    }
    
    this.shipDied = function(whom, why) {
    	var a = worldScripts["hardships"].$HardShips_Alloys[ worldScripts["hardships"].$HardShips_Ships.indexOf(this.ship) ];
    	var min = worldScripts["hardships"].$HardShips_ArmourMinToSpawnAlloy;
    	if( a > min ) this.ship.spawnOne("alloy");
    	if( a > 2 * min ) this.ship.spawnOne("alloy");
    }
    
    Scripts/hardescape-capsule-player.js
    "use strict";
    this.name        = "hardescape-capsule-player";
    this.author      = "Norby";
    this.copyright   = "2013 Norbert Nagy";
    this.licence     = "CC BY-NC-SA 3.0";
    this.description = "Set the shields to 0";
    this.version     = "1.0";
    
    this.shipSpawned = function() {
    	if(this.ship.isPlayer)  {
    		this.$EscapeCapsulePlayerFCB = addFrameCallback(function (delta)
    			{
    				if(player.ship.forwardShield > 0 || player.ship.aftShield > 0) {
    					player.ship.forwardShield = 0; //no shield on escape capsule
    					player.ship.aftShield = 0;
    				}
    			});
    	}
    }
    
    Scripts/hardmenu.js
    "use strict";
    this.name        = "hardmenu";
    this.author      = "Norby";
    this.copyright   = "2013 Norbert Nagy";
    this.licence     = "CC BY-NC-SA 3.0";
    this.description = "Hard Ships with armours and defensive equipments";
    
    //customizable properties
    this.$HardMenu_StartCredits = 100000; //Buy your first ship from this, the rest will be your starting money
    this.$HardMenu_StartFuel = 0; //set to 7 if you want to start with full tank
    this.$HardMenu_TestDriveTime = 20; //minutes
    
    //internal properties, should not touch
    this.$HardMenu_TestDriveTimer = null;
    this.$HardMenu_TestDriveTimerEnd = null;
    this.$HardMenu_TestDriveTimerEnd2 = null;
    this.$HardMenu_Name = [ "hardcobra3-player",
    	"hardcobramk1-player",
    	"hardadder-player",
    	"hardmoray-player",
    	"hardanaconda-player",
    	"hardasp-player",
    	"hardboa-player",
    	"hardboa2-player",
    	"hardelance-player",
    	"hardpython-player",
    	"gecko-player",//90k
    	"krait-player",//80k
    	"mamba-player",//85k
    	"sidewinder-player",//75k
    	"shuttle-player",//guess:20k
    	"transporter-player",//guess:40k
    	"worm-player",//guess:30k
    	"viper-player",//520k
    	"viper-interceptor-player",//620k
    	"constrictor-player",//10M
    	"thargoid-player",//guess:10M
    	"tharglet-player"];//guess:200k
    this.$HardMenu_LastMainMenuItem = 0;
    this.$HardMenu_serviceLevel = 95;
    
    this.startUp = function() {
    	if( worldScripts["start_choices"] ) delete worldScripts["start_choices"].guiScreenChanged;
    }
    
    this.guiScreenChanged = function(to, from) {
    	if( missionVariables.oolite_tutorial ) return;
    	//start in HardCobra v1.0 if press F1 before choose any ship
    	if( !worldScripts["rocketmenu"] && ( from == "GUI_SCREEN_INTRO2" || from == "GUI_SCREEN_NEWGAME")
    		&& to == "GUI_SCREEN_STATUS") {
    //		log(this.name, oolite.compareVersion("1.79")+" "+player.ship.dataKey);//debug
    		if( 0 < oolite.compareVersion("1.79") //if version is less than 1.79
     			//or the ship in hardships-menu.oolite-save loaded by scenario.plist
    			|| player.ship.dataKey == "hardcobra3-player" ) { //to allow starting in hauler, etc.
    			this.$HardMenu_ReplacePlayerShip2(this.$HardMenu_Name[0], 0); 
    			this.$HardMenu_NewGameScreen();
    		}
    	}
    	delete this.guiScreenChanged;
    }
    
    this.shipWillExitWitchspace = function() {//place some HardShip into the system
    	if(this.ship === player.ship && !system.isInterstellarSpace) {
    		//setup the ambush, less probable in safe governments
    		if (Math.random() > system.government / 7 ) {//government:0-7 Anarchy-Corporate State
    			//more pirate with techlevel and unsafety
    			var tech = Math.random() * system.techLevel / 5;//same bonus to pirates and police
    			var num = Math.ceil(tech + ( 7 - system.government) / 2);//number of pirate ships, 1-7
    			var rnum = 1 + Math.floor(Math.random() * (num - 1));//about the half is hardpirate
    			var radius = 10000 + Math.random() * 30000;
    			system.addShips("hardpirate", rnum, player.ship.position, radius);
    			if(num > rnum) system.addShips("pirate", num - rnum, player.ship.position, radius);
    			if ( system.government > 0 ) {//no police in Anarchy
    				//more police with techlevel and safety
    				num = Math.ceil(tech + system.government / 3);///number of police ships, 1-5 
    				rnum = Math.floor(1 + Math.random() * (num - 1));//about the half is hardpolice
    				radius = 1000 + Math.random() * 29000; //closer to the player
    				if(rnum > 0) system.addShips("hardpolice", rnum, player.ship.position, radius);
    				if(num > rnum) system.addShips("police", num - rnum, player.ship.position, radius);
    			}
    		}
    		this.$HardMenu_AddHardShipsToTheSystem();
    	}
    }
    
    this.shipWillLaunchFromStation = function() {
    	player.ship.hudHidden = false;
    	this.$HardMenu_AddHardShipsToTheSystem();
    	//Test Drive
    	if(!this.$HardMenu_TestDriveTimer && missionVariables.HardShips_LoanAtStart
    		&& missionVariables.HardShips_LoanAtStart<0) {
    		missionVariables.HardShips_TestDriveTime = this.$HardMenu_TestDriveTime;//minutes
    		this.$HardMenu_TestDriveTimer = new Timer(this, this.$HardMenu_TestDrive, 0, 60);
    	}
    }
    
    this.$HardMenu_AddHardShipsToTheSystem = function() {
    	if( system.isInterstellarSpace ) return;
    	system.addShips("policedrone", 1, system.mainStation.position, 20000);//demo
    	system.addShips("policeharddrone", 1, system.mainStation.position, 20000);//demo
    	//setup a hardShip combat somewhere between the witchpoint and the planet
    	var pos = player.ship.position;
    	var place = Math.random() * 0.9; //here will be the ships
    	var ships = system.addShipsToRoute("hardtrader", 1, place, "wp");
    	//player.consoleMessage("addShips "+ships);
    	//player.consoleMessage(pos.x+" "+pos.y+" "+pos.z);	
    	if(ships) if(ships[0]) if(ships[0].position) pos = ships[0].position;
    	//player.consoleMessage("pos "+pos);
    	system.addShips("hardhunter", 1, Vector3D(pos.x, pos.y, pos.z), 10000);
    	system.addShips("hardpirate", 3, pos);
    	if ( system.government > 0 ) system.addShips("hardpolice", 1, pos); //no police in Anarchy		
    	//add sun guards
    	system.addShipsToRoute("hardpirate", 2, 0.9, "ws");
    	system.addShipsToRoute("hardpirate", 2, 0.9, "ps");
    	//add solo ships
    	system.addShipsToRoute("hardtrader", 1, Math.random(), "wp");
    	system.addShipsToRoute("hardtrader", 1, Math.random(), "ps");
    	system.addShipsToRoute("hardhunter", 1, Math.random(), "ws");
    	system.addShipsToRoute("hardpirate", 1, Math.random(), "wp");
    	system.addShipsToRoute("hardpirate", 1, Math.random(), "ps");
    	system.addShipsToRoute("hardpirate", 1, Math.random(), "ws");
    	if ( system.government > 0 ) //no police in Anarchy
    		system.addShipsToRoute("hardpolice", 1, Math.random(), "wp");
    }
    
    this.$HardMenu_TestDrive = function() {
    	var t = missionVariables.HardShips_TestDriveTime;
    	if(t > 0) {
    		if(t == this.$HardMenu_TestDriveTime || t < 6)
    			player.commsMessage(t+" minutes left from your test drive.",10);
    		missionVariables.HardShips_TestDriveTime--;
    	} else {//time out
    		missionVariables.HardShips_TestDriveTime = 0;
    		missionVariables.HardShips_LoanAtStart = 0;
    		//player.ship.launch();
    		player.consoleMessage("Thank you for the testing! Your game will be over in 10 seconds.",5);
    		if(this.$HardMenu_TestDriveTimer) {
    			this.$HardMenu_TestDriveTimer.stop();
    			delete this.$HardMenu_TestDriveTimer;
    		}
    		this.$HardMenu_TestDriveTimerEnd = new Timer(this, this.$HardMenu_TestDriveEnd, 5, 0);
    	}
    }
    
    this.$HardMenu_TestDriveEnd = function() {
    	player.consoleMessage("You can begin new game and select a ship.",5);
    	if(this.$HardMenu_TestDriveTimerEnd) {
    		this.$HardMenu_TestDriveTimerEnd.stop();
    		delete this.$HardMenu_TestDriveTimerEnd;
    	}
    	this.$HardMenu_TestDriveTimerEnd = new Timer(this, this.$HardMenu_TestDriveEnd2, 5, 0);
    }
    
    this.$HardMenu_TestDriveEnd2 = function() {
    	if(this.$HardMenu_TestDriveTimerEnd) {
    		this.$HardMenu_TestDriveTimerEnd.stop();
    		delete this.$HardMenu_testDriveTimerEnd;
    	}
    	player.ship.launch();//needed to explode
    	player.ship.explode();//Game Over
    }
    
    this.$HardMenu_ShipConfirmed = function(shipid) {
    	player.ship.hudHidden = false;
    	player.ship.fuel = this.$HardMenu_StartFuel;
    	if(shipid == 5) {//HardRacer start with a missile to test
    		player.ship.awardEquipment("EQ_MISSILE");
    	}
    	if(missionVariables.HardShips_LoanAtStart && missionVariables.HardShips_LoanAtStart<0 
    	  || player.ship.dataKey == "hardescape-capsule-player")
    		player.ship.fuel = 7;//test ship or ecape pod, needed to Injectors
    	var credits = this.$HardMenu_StartCredits - player.ship.price; //less than 0 if test drive
    	missionVariables.HardShips_LoanAtStart = credits;//trigger the test drive timer if negative
    	player.credits = credits; //the game set it to 0 if negative
    }
    
    this.$HardMenu_ReplacePlayerShip = function(shipname) {
    	this.$HardMenu_ReplacePlayerShip2(shipname, Math.floor(Math.random()*32767) ); //must give correct number to make other entityPersonalyit than 0
    }
    
    this.$HardMenu_ReplacePlayerShip2 = function(shipname, pers) {
    //	player.consoleMessage(player.ship.name);//debug
    	player.replaceShip(shipname, pers);
    	player.replaceShip(shipname, pers);//bugfix for eqs with conditions scripts: need double replace to work!
    	if(worldScripts["shipversion"]) {
    		var shipVersion = worldScripts["shipversion"].$ShipVersion_Int(player.ship);
    		if(player.ship.equipmentStatus("EQ_SHIP_VERSION_"+shipVersion) === "EQUIPMENT_UNAVAILABLE")
    			player.ship.awardEquipment("EQ_SHIP_VERSION_"+shipVersion);
    	}
    	if(worldScripts["hardships"]) {
    		if( player.ship.scriptInfo ) {
    			var h = parseInt(player.ship.scriptInfo.hardarmour); //award Hard Armour equipment to show version
    			if( h > 0 && player.ship.equipmentStatus("EQ_HARDARMOUR_III") == "EQUIPMENT_UNAVAILABLE"
    				&& player.ship.equipmentStatus("EQ_HARDARMOUR_V") == "EQUIPMENT_UNAVAILABLE"
    				&& player.ship.equipmentStatus("EQ_HARDARMOUR_X") == "EQUIPMENT_UNAVAILABLE" ) {
    				var v = "III";
    				if( h >= 10 ) v = "X";
    				else if( h >= 5 ) v = "V";
    				player.ship.awardEquipment("EQ_HARDARMOUR_"+v);
    			}
    		}
    	}
    //	player.consoleMessage(player.ship.name);//debug
    }
    
    this.$HardMenu_GetPlayerShipData = function() { //called from shipversion.js of Ship Version OXP also
    	//detailed ship info old version, new can be found in rocketmenu.js of the RocketShips OXP
    	player.ship.hudHidden = true;
    	var equip="";
    	var s=""; 
    	s=player.ship.forwardWeapon;
    	if( s!=null ) equip+="Forward "+s.name;
    	s=player.ship.aftWeapon;
    	if( s!=null ) equip+=", Aft "+s.name;
    	s=player.ship.portWeapon;
    	if( s!=null ) equip+="\nPort "+s.name;
    	s=player.ship.starboardWeapon;
    	if( s!=null ) equip+=", Starboard "+s.name;
    	if(equip.length > 0) equip+="\n";
    	else equip+="No Laser\n";
    	var eqs = "";
    	var n = "";
    	var eq = player.ship.equipment;
    	var i=-1;
    	while(eq[++i]) {
    		n = eq[i].name;
    //		eqs += n + ", "; if( n.length == 0 && !skipped ) { //debug
    		if( n.length > 0 ) eqs += n + ", ";
    		else {	//skip noname eqs awarded by NumericHUD to avoid timeLimit error
    			//bugfix for timeLimit caused by many noname eqs from NumericHUD on slow computer:
    			//[script.javaScript.timeLimit] OperationCallback (OOJSEngineTimeManagement.m:221):
    			//***** ERROR: Script "hardmenu" ran for 1.07 seconds and has been terminated.
    			for( var j = i + 10; j < eq.length; j+=10 ) {
    				if( eq[j].name.length != 0 ) {
    					i = j - 10; //end of skip
    					j = eq.length;
    				}
    			}
    			while( i < eq.length && eq[i].name.length == 0 ) i++;
    			i--;
    		}
    	}
    	eqs = eqs.substr(0, eqs.length - 2); //cut last comma
    	if( eqs.length > 0 ) equip+=eqs+"\n\n";
    	else equip+="\n";//empty line before desc if no eqs
    	var desc = "";
    	var sh = player.ship.maxForwardShield;
    	if( player.ship.dataKey.indexOf("escape-capsule-player") > -1 ) sh = 0;
    	else if( worldScripts["shieldequalizercapacitors"] ) {
    		if( player.ship.equipmentStatus("E//internal properties, should not touchQ_BIGSHCAP") == "EQUIPMENT_OK"
    			&& player.ship.equipmentStatus("EQ_FORWARD_SHIELD_CAPACITOR") == "EQUIPMENT_OK" )
    			sh = sh + "+256";
    		else if( player.ship.equipmentStatus("EQ_FORWARD_SHIELD_CAPACITOR") == "EQUIPMENT_OK" )
    			sh = sh + "+64";
    	}
    	if( player.ship.scriptInfo && player.ship.scriptInfo.buydesc )//show ship description if any
    		desc="\""+player.ship.scriptInfo.buydesc+"\"\n\n";
    	var psd = "";//player.ship.displayName+
    	var hd = "";
    	if(!player.ship.hasHyperspaceMotor ) hd = "   No Hyperdrive";
    	psd += "Speed: "+(player.ship.maxSpeed)+" mLS  Thrust: "+player.ship.maxThrust+
    		"  Pitch: "+Math.round(player.ship.maxPitch*100)/100+
    		"  Roll: "+Math.round(player.ship.maxRoll*100)/100+
    		"  Yaw: "+Math.round(player.ship.maxYaw*100)/100+hd+
    //		"  Version: "+this.$shipVersion(player.ship)+
    //		"  Service "+player.ship.serviceLevel+
    		"\nCargo Space: "+player.ship.cargoSpaceCapacity;
    	if( player.ship.scriptInfo && player.ship.scriptInfo.cargoext && parseInt(player.ship.scriptInfo.cargoext) > 0 )
    		psd += "+"+parseInt(player.ship.scriptInfo.cargoext);
    	var r = "";
    	if( player.ship.scriptInfo && player.ship.scriptInfo.recharge && parseInt(player.ship.scriptInfo.recharge) > 0 )
    		r = "  Recharge: "+parseInt(player.ship.scriptInfo.recharge);
    	var sp = "";
    	var sph = Math.round(player.ship.collisionRadius*player.ship.collisionRadius*Math.PI);
    	if( sph < 1000000 ) sp = sph;
    	else sp = Math.round(sph/100000)/10+"k";//show large sphere in km^2
    	psd += "t  Mass: "+Math.max(Math.round(player.ship.mass/1000), 1)+ //min.1t
    		"t  Size: "+Math.round(player.ship.boundingBox.x)+"*"+
    		Math.round(player.ship.boundingBox.y)+"*"+Math.round(player.ship.boundingBox.z)+
    		"m Radius: "+Math.round(player.ship.collisionRadius)+"m Sphere: "+sp+
    		"m^2\nEnergy: "+player.ship.maxEnergy+r+"  Shield: "+sh+"  Max.Missile: "+player.ship.missileCapacity;
    	if( player.ship.scriptInfo && player.ship.scriptInfo.hardarmour && parseInt(player.ship.scriptInfo.hardarmour) > 0 )
    		psd += "\nHard Armour deflect "+parseInt(player.ship.scriptInfo.hardarmour)+" points from any damage";
    	psd += "\n"+equip+desc+"Price: "+formatCredits(player.ship.price, false, true);
    	return(psd);
    }
    
    this.$HardMenu_NewGameScreen = function() {
    	player.ship.hudHidden = true;
    	player.ship.removeEquipment("EQ_FUEL_INJECTION");
    	player.ship.removeEquipment("EQ_FUEL_SCOOPS");
    	player.ship.removeEquipment("EQ_WEAPON_MINING_LASER");
    	var options = {
                    "_0" : "HardShips",
    		"_1" : "Classic: Cobra Mk III",
    		"_2" : "Fast-track: Cobra Mk III with extra equipment",
    		"_3" : "Medium: Cobra Mk I",
    		"_4" : "Hard: Adder",
    		"_5" : "Harder: Adder Broke",
    		"_6" : "Hardest: Escaped Broke",
    		"_7" : "Hauler: Beaten-up Python",
    		"_8" : "Exotic Ships"
    	};
    	mission.runScreen({
    		title: "New Game Selection" ,
    		message: "Greetings Commander. You are about to start your new career of space flight, combat and trading starting from the space station orbiting the planet Lave. Before embarking you will need to select a starting ship.\n\n"+
    			"HardShips covered by orange Hard Armour to partially deflect laser and other attacks at a cost of the lower acceleration and brake.\n\n"+
    			"Costly HardShips are available for a test drive only: you will set back here in "+this.$HardMenu_TestDriveTime+" minutes. There are more choices below if you want the Classic start or some harder situations.\n\nAfter having made your choice, go to options and choose your name by saving the game.",
    		choices: options,
    		initialChoicesKey: "_"+this.$HardMenu_LastMainMenuItem,
    		model: "[hard-cobra3]",
    		spinModel: true,
    		background: "start_choices_bg.png"
    	},		
    	function (choice)
    	{
                    if (choice === "_0") this.$HardMenu_Choice(0);
                    else if (choice === "_1") this.$HardMenu_Choice(1);
                    else if (choice === "_2") this.$HardMenu_Choice(2);
                    else if (choice === "_3") this.$HardMenu_Choice(3);
    		else if (choice === "_4") this.$HardMenu_Choice(4);
    		else if (choice === "_5") this.$HardMenu_Choice(5);
    		else if (choice === "_6") this.$HardMenu_Choice(6);
    		else if (choice === "_7") this.$HardMenu_Choice(7);
    		else if (choice === "_8") this.$HardMenu_Choice(8);
    	});		
    }
    
    this.$HardMenu_Choice = function(select) {
    	this.$HardMenu_LastMainMenuItem = select;
    	player.ship.hudHidden = true;
            var shipnum = 0;
    	switch(select) {
                    case 0:
    			this.$HardMenu_NewGameScreen2(0);
    			break;
    		case 1: //classic start
    			this.$HardMenu_ReplacePlayerShip2("cobra3-player", 0); //always get ShipVersion 1.0
    			while (player.ship.missiles.length < 3)
    				player.ship.awardEquipment("EQ_MISSILE");
    			player.credits = 100;
    			player.ship.fuel = 100;
    			var dname=player.ship.displayName;
    			if( worldScripts["shipversion"] ) dname = worldScripts["shipversion"].$ShipVersion_PlayerShipName();
    			var options = {
    				"1_NO" : "Go Back",
    				"2_YES" : "Confirm Choice"
    			};
    			mission.runScreen({
    				title: "Classic Start" ,
    				message: "Ship: "+dname+"\nSpeed: 0.35 lm\nCargo Space: 20 t\nBase Equipment: Pulse Laser, 3 Missiles\n\Fuel: 7.0 ly\nCredits: "+formatCredits(100, true, true)+
    					"\n\n\"The most successful medium-size ship ever built and a versatile fighter/trader ship.\"",
    				choices: options,
    				model: "[cobra3-player]",
    				background: "start_choices_bg.png"
    			},
    			function (choice) {
    				if (choice === "1_NO") this.$HardMenu_NewGameScreen();
    			});
    			break;
    		case 2: //easy start
    			this.$HardMenu_ReplacePlayerShip2("cobra3-player", 0); //always get ShipVersion 1.0
    			player.credits = 100;
    			player.ship.fuel = 100;
    			while (player.ship.missiles.length < 3)
    				player.ship.awardEquipment("EQ_MISSILE");
    			player.ship.awardEquipment("EQ_FUEL_INJECTION");
    			player.ship.awardEquipment("EQ_FUEL_SCOOPS");
    			player.ship.aftWeapon = "EQ_WEAPON_MINING_LASER";
    			var dname=player.ship.displayName;
    			if( worldScripts["shipversion"] ) dname = worldScripts["shipversion"].$ShipVersion_PlayerShipName();
    			var options = {
    				"1_NO" : "Go Back",
    				"2_YES" : "Confirm Choice"
    			};
    			mission.runScreen({
    				title: "Fast-track Start" ,
    				message: "Ship: "+dname+"\nSpeed: 0.35 lm\nCargo Space: 20 t\nBase Equipment: Pulse Laser, Mining Laser, 3 Missiles,  Fuel Scoops, Witchspace Fuel Injectors\n\Fuel: 7.0 ly\nCredits: "+formatCredits(100, true, true)+"\n\n* Bounty Hunter: Collect bounties for pirate/fugitive craft destoyed. Capture/rescue escape pods for rewards.\n* Carrier Service: Deliver goods for some-one else and get paid. You can do parcel deliveries right from the start, but for carrier contracts you'll need a ship with larger cargo bays. Find contracts from the interfaces screen.\n* Miner: Blast the asteroids with your mining laser, scoop the fragments and sell the minerals. Aim for the sun to find asteroids.\n* Passenger Service: Carry passengers for profit. You'll need a passenger berth installed to do passenger contracts. Find contracts from the interfaces screen.\n* Trader: Buy low-priced commodities on one world and sell at a higher price on another.",
    				choices: options,
    				model: "[cobra3-player]",
    				background: "start_choices_bg.png"
    			},		
    			function (choice) {
    				if (choice === "1_NO") this.$HardMenu_NewGameScreen();
    			});					
    			break;
    		case 3: //medium start
    			this.$HardMenu_ReplacePlayerShip2("cobramk1-player", 0); //always get ShipVersion 1.0
    			player.credits = 100;
    			player.ship.fuel = 100;
    			var dname=player.ship.displayName;
    			if( worldScripts["shipversion"] ) dname = worldScripts["shipversion"].$ShipVersion_PlayerShipName();
    			var options = {
    				"1_NO" : "Go Back",
    				"2_YES" : "Confirm Choice"
    			};
    			mission.runScreen({
    				title: "Medium Start" ,
    				message: "Ship: "+dname+"\nSpeed: 0.26 lm\nCargo Space: 10 t\nBase Equipment: Pulse Laser, 1 Missile\n\Fuel: 7.0 ly\nCash: "+formatCredits(100, true, true)+
    					"\n\n\"The first truly effective solo fighter/trader ship, but now superceded by the Mk III.\"",
    				choices: options,
    				model: "[cobramk1-player]",
    				background: "start_choices_bg.png"
    			},
    			function (choice) {
    				if (choice === "1_NO") this.$HardMenu_NewGameScreen();
    			});
    			break;
    		case 4: //hard start
    			this.$HardMenu_ReplacePlayerShip2("adder-player", 0); //always get ShipVersion 1.0
    			player.credits = 100;
    			player.ship.fuel = 100;
    			var dname=player.ship.displayName;
    			if( worldScripts["shipversion"] ) dname = worldScripts["shipversion"].$ShipVersion_PlayerShipName();
    			var options = {
    				"1_NO" : "Go Back",
    				"2_YES" : "Confirm Choice"
    			};
    			mission.runScreen({
    				title: "Hard Start" ,
    				message: "Ship: "+dname+"\nSpeed: 0.24 lm\nCargo Space: 2+3 t\nBase Equipment: Pulse Laser, 1 Missile, External Heat Shielding\n\Fuel: 7.0 ly\nCash: "+formatCredits(100, true, true)+
    				"\n\n\"An agile and compact ship favored by couriers, customizers and professional racers.\"",
    				choices: options,
    				model: "[adder-player]",
    				background: "start_choices_bg.png"
    			},
    			function (choice) {
    				if (choice === "1_NO") this.$HardMenu_NewGameScreen();
    			});
    			break;
    		case 5: //harder start
    			this.$HardMenu_ReplacePlayerShip2("adder-player", 0); //always get ShipVersion 1.0
    			var dname=player.ship.displayName;
    			if( worldScripts["shipversion"] ) dname = worldScripts["shipversion"].$ShipVersion_PlayerShipName();
    			player.credits = 0;
    			player.ship.fuel = 0;
    			player.ship.removeEquipment("EQ_HEAT_SHIELD");
    			player.ship.removeEquipment("EQ_MISSILE");
    			var options = {
    				"1_NO" : "Go Back",
    				"2_YES" : "Confirm Choice"
    			};
    			mission.runScreen({
    				title: "Harder Start" ,
    				message: "Ship: "+dname+"\nSpeed: 0.24 lm\nCargo Space: 2+3 t\nBase Equipment: Pulse Laser\n\Fuel: 0.0 ly\nCash: "+formatCredits(0, true, true)+
    					"\n\n\"An agile and compact ship favored by couriers, customizers and professional racers, although you must find a way to earn credits for fuel, equipment and upgrades.\"",
    				choices: options,
    				model: "[adder-player]",
    				background: "start_choices_bg.png"
    			},		
    			function (choice) {
    				if (choice === "1_NO") {
    					player.credits = 100;
    					player.ship.fuel = 100;
    					player.ship.awardEquipment("EQ_MISSILE");
    					player.ship.awardEquipment("EQ_HEAT_SHIELD");
    					this.$HardMenu_NewGameScreen();
    				}
    			});
    			break;
    		case 6: //hardest
    			player.replaceShip("hardescape-capsule-player", 0);
    			player.credits = 0;
    			player.ship.fuel = 0;
    			player.ship.removeEquipment("EQ_HEAT_SHIELD");
    			player.ship.removeEquipment("EQ_MISSILE");
    			var dname=player.ship.displayName;
    			var options = {
    				"1_NO" : "Go Back",
    				"2_YES" : "Confirm Choice"
    			};
    			mission.runScreen({
    				title: "Hard Pod",
    				message: this.$HardMenu_GetPlayerShipData(0),
    				choices: options,
    				model: "[hardescape-capsule-player]",
    				background: "start_choices_bg.png"
    			},
    			function (choice) {
    				if (choice === "1_NO") {
    					player.credits = 100;
    					player.ship.fuel = 100;
    					player.ship.awardEquipment("EQ_MISSILE");
    					player.ship.awardEquipment("EQ_HEAT_SHIELD");
    					this.$HardMenu_NewGameScreen();
    				}
    				player.ship.hudHidden = false;
                                    player.ship.fuel = 7;
    			});
    			break;
    		case 7: //hauler start
    			player.replaceShip("python-player", 0);
    			this.$HardMenu_serviceLevel = player.ship.serviceLevel;
    			player.ship.serviceLevel = 75;
    			var options = {
    				"1_YES" : "Confirm Choice",
    				"2_NO" : "Go Back"
    			};
    			mission.runScreen({
    				title: "Harder Start" ,
    				message: "Ship: Python\nSpeed: 0.20 lm\nCargo Space: 100 t\nBase Equipment: Pulse Laser\n\Fuel: 7.0 ly\nCash: "+formatCredits(100, true, true)+"\n\n\"An ageing design that’s still popular with commanders needing a simple robust freighter. She's in a bad shape though, be ready for malfunctions until you can afford a maintenance overhaul.\"",
    				choices: options,
    				model: "[python-player]",
    				background: "start_choices_bg.png"
    			},		
    			function (choice) {
    				if (choice === "2_NO") {
    					player.ship.serviceLevel = this.$HardMenu_serviceLevel;
    					this.$HardMenu_NewGameScreen();
    				}
    			});	
    			break;
                    case 8:
    			this.$HardMenu_NewGameScreen2(10);
    			break;
    	}
    }
    
    this.$HardMenu_NewGameScreen2 = function(lastship) {
    	player.ship.hudHidden = true;
    	if( lastship < 0 ) lastship = 0;
    	missionVariables.targetAutolock = null;//bugfix for ships equipped with Autolock in shipyard.plist
    	if( lastship == 0 ) this.$HardMenu_ReplacePlayerShip2(this.$HardMenu_Name[lastship], 0); //Cobra III always get ShipVersion 1.0
    	else this.$HardMenu_ReplacePlayerShip(this.$HardMenu_Name[lastship]);
    	if(player.ship.equipmentStatus("EQ_HEAT_SHIELD") != "EQUIPMENT_UNAVAILABLE")
    		player.ship.removeEquipment("EQ_HEAT_SHIELD");
    	while(player.ship.equipmentStatus("EQ_MISSILE") != "EQUIPMENT_UNAVAILABLE")
    		player.ship.removeEquipment("EQ_MISSILE");
    	var shipname = $HardMenu_Name[lastship];
    	var dname=player.ship.displayName;
    //	log("hardmenu",shipname+" "+dname);
    	if( worldScripts["shipversion"] ) dname = worldScripts["shipversion"].$ShipVersion_PlayerShipName();	
    	if( lastship < 10 ) {
    		var options = {
    			"_" : "Confirm Choice",
    			"_0" : "Hard Cobra Mk III",
    			"_1" : "Hard Cobra Mk I",
    			"_2" : "Hard Adder",
    			"_3" : "Hard Moray",
    			"_4" : "Test: Hard Anaconda",
    			"_5" : "Test: Hard Asp",
    			"_6" : "Test: Hard Boa",
    			"_7" : "Test: Hard Boa Mk2",
    			"_8" : "Test: Har-de-Lance",
    			"_9" : "Test: Hard Python",
    			"X" : "Go Back"
    		};		
    //player.consoleMessage(this.$HardMenu_Name[lastship]+"["+player.ship.dataKey.substr(0,player.ship.dataKey.length-7)+"-model]");
    		mission.runScreen({
    			title: dname,
    			message: this.$HardMenu_GetPlayerShipData(lastship),
    			choices: options,
    			initialChoicesKey: "_"+(lastship),
    			model: "["+player.ship.dataKey+"]",//.substr(0,player.ship.dataKey.length-7)+"]",
    			background: "start_choices_bg.png"
    		},
    		function (choice)
    		{
    			player.ship.hudHidden = true;
    			if (choice == "_0") this.$HardMenu_NewGameScreen2(0);
    			else if (choice == "_1") this.$HardMenu_NewGameScreen2(1);
    			else if (choice == "_2") this.$HardMenu_NewGameScreen2(2);
    			else if (choice == "_3") this.$HardMenu_NewGameScreen2(3);
    			else if (choice == "_4") this.$HardMenu_NewGameScreen2(4);
    			else if (choice == "_5") this.$HardMenu_NewGameScreen2(5);
    			else if (choice == "_6") this.$HardMenu_NewGameScreen2(6);
    			else if (choice == "_7") this.$HardMenu_NewGameScreen2(7);
    			else if (choice == "_8") this.$HardMenu_NewGameScreen2(8);
    			else if (choice == "_9") this.$HardMenu_NewGameScreen2(9);
    			else if (choice == "X") this.$HardMenu_NewGameScreen();
    			this.$HardMenu_ShipConfirmed(lastship);
    		});
    	} else {
    		var options = {
    			"_A" : "Confirm Choice",
    			"_B" : "Gecko",
    			"_C" : "Krait",
    			"_D" : "Mamba",
    			"_E" : "Sidewinder",
    			"_F" : "Shuttle",
    			"_G" : "Transporter",
    			"_H" : "Worm",
    			"_I" : "Test: Viper",
    			"_J" : "Test: Viper Interceptor",
    			"_K" : "Test: Constrictor",
    			"_L" : "Test: Thargoid",
    			"_M" : "Test: Tharglet",
    			"X" : "Go Back"
    		};		
    //player.consoleMessage(this.$HardMenu_Name[lastship]+"["+player.ship.dataKey.substr(0,player.ship.dataKey.length-7)+"-model]");
    		var init="B";
    		switch(lastship) {
                    	case 10: init="B"; break;
                    	case 11: init="C"; break;
    			case 12: init="D"; break;
                    	case 13: init="E"; break;
                    	case 14: init="F"; break;
                    	case 15: init="G"; break;
                    	case 16: init="H"; break;
                    	case 17: init="I"; break;
                    	case 18: init="J"; break;
                    	case 19: init="K"; break;
                    	case 20: init="L"; break;
                    	case 21: init="M"; break;
    		}
    		mission.runScreen({
    			title: dname,
    			message: this.$HardMenu_GetPlayerShipData(lastship),
    			choices: options,
    			initialChoicesKey: "_"+init,
    			model: "["+player.ship.dataKey+"]",//.substr(0,player.ship.dataKey.length-7)+"]",
    			background: "start_choices_bg.png"
    		},
    		function (choice)
    		{
    			player.ship.hudHidden = true;
    			if (choice == "_B") this.$HardMenu_NewGameScreen2(10);
    			else if (choice == "_C") this.$HardMenu_NewGameScreen2(11);
    			else if (choice == "_D") this.$HardMenu_NewGameScreen2(12);
    			else if (choice == "_E") this.$HardMenu_NewGameScreen2(13);
    			else if (choice == "_F") this.$HardMenu_NewGameScreen2(14);
    			else if (choice == "_G") this.$HardMenu_NewGameScreen2(15);
    			else if (choice == "_H") this.$HardMenu_NewGameScreen2(16);
    			else if (choice == "_I") this.$HardMenu_NewGameScreen2(17);
    			else if (choice == "_J") this.$HardMenu_NewGameScreen2(18);
    			else if (choice == "_K") this.$HardMenu_NewGameScreen2(19);
    			else if (choice == "_L") this.$HardMenu_NewGameScreen2(20);
    			else if (choice == "_M") this.$HardMenu_NewGameScreen2(21);
    			else if (choice == "X") this.$HardMenu_NewGameScreen();
    			this.$HardMenu_ShipConfirmed(lastship);
    		});		
    	}
    }
    
    Scripts/hardnose.js
    "use strict";
    this.name        = "hardnose";
    this.author      = "Norby";
    this.copyright   = "2013 Norbert Nagy";
    this.licence     = "CC BY-NC-SA 3.0";
    this.description = "Hard Nose check to fit in the Max with the base Hard Armour.";
    this.version     = "1.0";
    
    this.allowAwardEquipment = function(eqKey, ship, context)
    {
    	if( ship.mass < 30000 ) return false; //small ship can not get nose
    	if( eqKey==="EQ_HARDNOSE" && (!ship.scriptInfo || !ship.scriptInfo.hardarmour) )
    		return true; //can get nose a ship without Hard Armour also
    	if( eqKey==="EQ_HARDNOSE" && ship.scriptInfo && ship.scriptInfo.hardarmour //awardable only if fit in Max
    		&& parseInt(ship.scriptInfo.hardarmour) + 5 <= worldScripts["hardships"].$HardShips_MaxHardArmour )
    		return true;
    
    	if( ship.mass < 130000 ) return false; //only a large ship can get the following things
    	if( (eqKey==="EQ_VERYHARDNOSE" || eqKey==="EQ_VERYVERYHARDNOSE")
    		&& (!ship.scriptInfo || !ship.scriptInfo.hardarmour) )
    		return true; //can get nose a ship without Hard Armour also
    	if( eqKey==="EQ_VERYHARDNOSE" && ship.scriptInfo && ship.scriptInfo.hardarmour
    		&& parseInt(ship.scriptInfo.hardarmour) + 10 <= worldScripts["hardships"].$HardShips_MaxHardArmour )
    		return true;
    	if( eqKey==="EQ_VERYVERYHARDNOSE" && ship.scriptInfo && ship.scriptInfo.hardarmour
    		&& parseInt(ship.scriptInfo.hardarmour) + 15 <= worldScripts["hardships"].$HardShips_MaxHardArmour )
    		return true;
    	return false;
    }
    
    Scripts/hardships.js
    "use strict";
    this.name        = "hardships";
    this.author      = "Norby";
    this.copyright   = "2013 Norbert Nagy";
    this.licence     = "CC BY-NC-SA 3.0";
    this.description = "Armour on 6 side and Fuel Leak if the damage break the Core.";
    this.version     = "0.88";
    
    //customizable properties
    this.$HardShips_AlloyStart = 100; //How many damage can be repaired without using alloys from cargo
    this.$HardShips_ArmourDivider = 2; //Armour = maxEnergy / ArmourDivider
    this.$HardShips_ArmourFixableWith1tAlloy = 100;//How many damage can be repaired using up 1t Alloy
    this.$HardShips_ArmourMinToSpawnAlloy = 120; //leave more than the fixable amount with 1t Alloy for some waste
    this.$HardShips_FuelLeakRate = 0.1; //ly/second
    this.$HardShips_MaxHardArmour = 35; //reduce to 20 if you do not want ships with harder noses than the Military Laser can damage
    
    //internal properties, should not touch
    this.$HardShips_Alloys = [];//partial metal left from an 1t alloy in ships to fix later damages
    this.$HardShips_AMax = [[0, 0, 0, 0, 0, 0, 0, 0]]; //maximum armour values of the ship given by $HardShips_AllSideFixed()
    this.$HardShips_Armour = [[0, 0, 0, 0, 0, 0, 0, 0]]; //6 side plus Core hull plus IronHide armour, the -1. side is allocated to choose random side around facing corner from 0 to 5 but the direction is determine which 3 is possible and the odds also
    this.$HardShips_Damaged = [[false, false, false, false, false, false, false, false]]; //from depleted until full restored
    this.$HardShips_Debug = false; //Show extra messages to help developing if uncomment the related lines
    this.$HardShips_OrigShieldCapMax = 64; //must be equal with the value coded in shieldequalizercapacitors.js
    this.$HardShips_Ships = [player.ship]; //this array will contain all spawned ships, the 0. is the player
    this.$HardShips_ShipsBigSC = 0; //Big Shield Capacitor existence check on NPCs in timed BigSC setup
    this.$HardShips_Side = ["Fore", "Aft", "Port", "Starboard", "Top", "Bottom", "Core", "IronHide"]; //name of the side
    this.$HardShips_Timer = null; //timed repairs
    this.$HardShips_TimerB = null; //timer for Big Shield Capacitor setup to surely do after ShipVersion award and customshields setup
    
    //world script events
    this.startUp = function() {
    	this.$HardShips_Timer = new Timer(this, this.$HardShips_Timed, 0, 1);//in every 1 second
    	this.$HardShips_AllSideFixed(player.ship, 0);//initialize player data
    	this.$HardShips_Alloys[0] = this.$HardShips_AlloyStart;
    	if( worldScripts["IronHide Armour Script"] &&
    		worldScripts["IronHide Armour Script"].shipTakingDamage ) { //do not get back the double of the lost energy
    		delete worldScripts["IronHide Armour Script"].shipTakingDamage;
    	}
    }
    
    this.equipmentDamaged = function(equipment) {
    	//Hard Armour eq can not be damaged, it is a player-only to display the version.
    	var e="EQ_HARDARMOUR_III"; if(equipment === e) player.ship.setEquipmentStatus(e,"EQUIPMENT_OK");
    	e="EQ_HARDARMOUR_V"; if(equipment === e) player.ship.setEquipmentStatus(e,"EQUIPMENT_OK");
    	e="EQ_HARDARMOUR_X"; if(equipment === e) player.ship.setEquipmentStatus(e,"EQUIPMENT_OK");
    	var s = worldScripts["shieldequalizercapacitors"];
    	if( s && ( equipment == "EQ_BIGSHCAP" || equipment == "EQ_BIGSHCAP2" || equipment == "EQ_BIGSHCAP3" ) ) {
    		this.$HardShips_SetupPlayerBigShCap(); //reduce the max value and discharge additional power if any
    		s.secforwardshieldcapacitor = Math.min( s.secforwardshieldcapacitormax, s.secforwardshieldcapacitor );
    		s.secaftshieldcapacitor = Math.min( s.secaftshieldcapacitormax, s.secaftshieldcapacitor );
    	} 
    	if( player.ship.equipmentStatus("EQ_ELECTRONICS_BOX") == "EQUIPMENT_OK" &&
    		( equipment == "EQ_ECM" || equipment == "EQ_SCANNER_SHOW_MISSILE_TARGET"
    			|| equipment == "EQ_TARGET_MEMORY" || equipment == "EQ_MULTI_TARGET"
    			|| equipment == "EQ_DOCK_COMP" ) ) {
    		player.ship.setEquipmentStatus("EQ_ELECTRONICS_BOX","EQUIPMENT_DAMAGED"); //help only once
    		player.ship.setEquipmentStatus(equipment,"EQUIPMENT_OK");
    	}
    	if( player.ship.equipmentStatus("EQ_INJECTOR_BOX") == "EQUIPMENT_OK" &&
    		( ( equipment == "EQ_FUEL_INJECTION"
    			&& ( !worldScripts["towbar"] || worldScripts["towbar"].$TowbarInjectors != 1 ) )
    			|| equipment == "EQ_ERB"
    			|| equipment == "EQ_Q-CHARGER"
    			|| equipment.indexOf("EQ_BREAKABLE_ENGINE") > -1 ) ) {
    		player.ship.setEquipmentStatus("EQ_INJECTOR_BOX","EQUIPMENT_DAMAGED"); //help only once
    		player.ship.setEquipmentStatus(equipment,"EQUIPMENT_OK");
    	} else if( player.ship.equipmentStatus("EQ_ERB") == "EQUIPMENT_OK" &&
    		( equipment == "EQ_BREAKABLE_ENGINE_SMALL"
    		|| equipment == "EQ_BREAKABLE_ENGINE_MEDIUM"
    		|| equipment == "EQ_BREAKABLE_ENGINE_LARGE"
    		|| equipment == "EQ_BREAKABLE_ENGINE_MONSTER"
    		|| equipment == "EQ_FUEL_INJECTION"
    		|| equipment == "EQ_Q-CHARGER" ) ) {
    			if( player.ship.manifest.machinery > 0 )
    				player.consoleMessage("Engine repair started", 10);
    			else player.consoleMessage("Engine repair need Machinery", 10);
    		}
    
    	
    	if( player.ship.equipmentStatus("EQ_LIFE_BOX") == "EQUIPMENT_OK" &&
    		( equipment == "EQ_ESCAPE_POD" || equipment == "EQ_PASSENGER_BERTH"
    			||  equipment == "EQ_BREAKABLE_HUD_IFF_SCANNER" ) ) {
    		player.ship.setEquipmentStatus("EQ_LIFE_BOX","EQUIPMENT_DAMAGED"); //help only once
    		player.ship.setEquipmentStatus(equipment,"EQUIPMENT_OK");
    	}
    	if( player.ship.equipmentStatus("EQ_SHIELD_BOX") == "EQUIPMENT_OK" &&
    		( equipment == "EQ_SHIELD_BOOSTER" || equipment == "EQ_NAVAL_SHIELD_BOOSTER"
    			|| equipment.indexOf("SHIELD_CAPACITOR") > -1
    			|| equipment.indexOf("EQ_BIGSHCAP") > -1
    			|| equipment.indexOf("EQ_BREAKABLE_SHIELD") > -1 ) ) {
    		player.ship.setEquipmentStatus("EQ_SHIELD_BOX","EQUIPMENT_DAMAGED"); //help only once
    		player.ship.setEquipmentStatus(equipment,"EQUIPMENT_OK");
    	}
    }
    
    this.equipmentDestroyed = function(equipment) { //Hard Armour can not be destroyed
    	var e="EQ_HARDARMOUR_III"; if(equipment === e) player.ship.awardEquipment(e);
    	e="EQ_HARDARMOUR_V"; if(equipment === e) player.ship.awardEquipment(e);
    	e="EQ_HARDARMOUR_X"; if(equipment === e) player.ship.awardEquipment(e);
    }
    
    this.guiScreenWillChange = function(to, from) {
    	if(to === "GUI_SCREEN_STATUS") {//fix a bug when the player got new ship without shipSpawned
    //		if( this.$HardShips_Debug ) player.consoleMessage(player.ship.name);
    		if( player.ship.scriptInfo ) {
    			var h = parseInt(player.ship.scriptInfo.hardarmour); //award Hard Armour equipment to show version
    			if( h > 0 && player.ship.equipmentStatus("EQ_HARDARMOUR_III") == "EQUIPMENT_UNAVAILABLE"
    				&& player.ship.equipmentStatus("EQ_HARDARMOUR_V") == "EQUIPMENT_UNAVAILABLE"
    				&& player.ship.equipmentStatus("EQ_HARDARMOUR_X") == "EQUIPMENT_UNAVAILABLE" ) {
    				var v = "III";
    				if( h >= 10 ) v = "X";
    				else if( h >= 5 ) v = "V";
    				player.ship.awardEquipment("EQ_HARDARMOUR_"+v);
    			}
    		}
    	}
    }
    
    this.playerBoughtEquipment = function(equipmentKey) {
    	if( equipmentKey.substr(-7,7) == "_REFUND" ) { //any eq which end with _refund means full refund the eq named before
    		player.ship.removeEquipment( equipmentKey ); //remove the "bought" refund eq
    		var eq = equipmentKey.substr( 0, equipmentKey.length-7 );//the real eq
    		if( player.ship.equipmentStatus( eq ) == "EQUIPMENT_OK" ) this.$HardShips_RefundEQ( eq );
    		else if( player.ship.equipmentStatus( eq ) == "EQUIPMENT_DAMAGED" ) //need check to avoid message at refund
    			player.consoleMessage("Need repair first"); //do not get full price back for a damaged eq
    		return;
    	}
    	var repeq = "EQ_ADDITIONAL_ARMOUR_REPAIR"; //Front, Aft Add. Armour, Core, Nose and Energy Generator repairs in one step
    	if( equipmentKey == repeq ) {
    		var price = EquipmentInfo.infoForKey( repeq ).price / 10;
    		player.ship.removeEquipment( repeq );
    		var firstfix = true; //first fix do not need additional money, deducted by the game
    		firstfix = this.$HardShips_FixEQ("EQ_ADDITIONAL_FRONT_ARMOUR", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_ADDITIONAL_AFT_ARMOUR", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_ADDITIONAL_CORE_HULL", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_HARDNOSE", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_VERYHARDNOSE", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_VERYVERYHARDNOSE", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_EEG", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_ESG", price, firstfix);
    		if( player.bounty == 0 ) firstfix = this.$HardShips_FixEQ("EQ_HTCAT", price, firstfix);
    		if( player.bounty > 0 ) firstfix = this.$HardShips_FixEQ("EQ_REG", price, firstfix);
    	}
    	repeq = "EQ_EQUIPMENT_BOX_REPAIR";
    	if( equipmentKey == repeq ) {
    		var price = EquipmentInfo.infoForKey( repeq ).price / 10;
    		player.ship.removeEquipment( repeq );
    		var firstfix = true; //first fix do not need additional money, deducted by the game
    		firstfix = this.$HardShips_FixEQ("EQ_EQUIPMENT_BOX", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_ELECTRONICS_BOX", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_LIFE_BOX", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_INJECTOR_BOX", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_SHIELD_BOX", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_DUMMY100", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_DUMMY50", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_DUMMY10", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_DUMMY5", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_DUMMY1", price, firstfix);
    	}
    	repeq = "EQ_HARDSHIELD_REPAIR"; //Hard Shield and Anti-Sapper Shield repairs in one step
    	if( equipmentKey == repeq ) {
    		var price = EquipmentInfo.infoForKey( repeq ).price / 10;
    		player.ship.removeEquipment( repeq );
    		var firstfix = true; //first fix do not need additional money, deducted by the game
    		firstfix = this.$HardShips_FixEQ("EQ_HARDSHIELD_1", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_HARDSHIELD_2", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_HARDSHIELD_3", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_HARDSHIELD_4", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_HARDSHIELD_5", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_HARDSHIELD_6", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_HARDSHIELD_7", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_HARDSHIELD_8", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_HARDSHIELD_9", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_HARDSHIELD_10", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_BIGSHCAP", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_BIGSHCAP2", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_BIGSHCAP3", price, firstfix);
    		firstfix = this.$HardShips_FixEQ("EQ_SAPPERNULLIFIER", price, firstfix); //for sure only
    		firstfix = this.$HardShips_FixEQ("EQ_ANTISAPPER", price, firstfix);
    	}
    	if( equipmentKey === "EQ_HARDNOSE" ) { //downgrade
    		if( player.ship.equipmentStatus( "EQ_VERYHARDNOSE" ) == "EQUIPMENT_DAMAGED" ||
    			player.ship.equipmentStatus( "EQ_VERYVERYHARDNOSE" ) == "EQUIPMENT_DAMAGED" ) {
    			player.consoleMessage("Nose need repair first"); //do not get full price back for a damaged eq
    			player.ship.removeEquipment( equipmentKey );
    			player.credits += EquipmentInfo.infoForKey( equipmentKey ).price / 10;
    		} else {
    			this.$HardShips_RefundEQ("EQ_VERYHARDNOSE");
    			this.$HardShips_RefundEQ("EQ_VERYVERYHARDNOSE");
    		}
    	}
    	if( equipmentKey === "EQ_VERYHARDNOSE" ) { //upgrade or downgrade
    		if( player.ship.equipmentStatus( "EQ_HARDNOSE" ) == "EQUIPMENT_DAMAGED" ||
    			player.ship.equipmentStatus( "EQ_VERYVERYHARDNOSE" ) == "EQUIPMENT_DAMAGED" ) {
    			player.consoleMessage("Nose need repair first"); //do not get full price back for a damaged eq
    			player.ship.removeEquipment( equipmentKey );
    			player.credits += EquipmentInfo.infoForKey( equipmentKey ).price / 10;
    		} else {
    			this.$HardShips_RefundEQ("EQ_HARDNOSE");
    			this.$HardShips_RefundEQ("EQ_VERYVERYHARDNOSE");
    		}
    	}
    	if( equipmentKey === "EQ_VERYVERYHARDNOSE" ) { //upgrade
    		if( player.ship.equipmentStatus( "EQ_HARDNOSE" ) == "EQUIPMENT_DAMAGED" ||
    			player.ship.equipmentStatus( "EQ_VERYHARDNOSE" ) == "EQUIPMENT_DAMAGED" ) {
    			player.consoleMessage("Nose need repair first"); //do not get full price back for a damaged eq
    			player.ship.removeEquipment( equipmentKey );
    			player.credits += EquipmentInfo.infoForKey( equipmentKey ).price / 10;
    		} else {
    			this.$HardShips_RefundEQ("EQ_HARDNOSE");
    			this.$HardShips_RefundEQ("EQ_VERYHARDNOSE");
    		}
    	}
    	var i = 1;
    	while( i < 11 && equipmentKey != "EQ_HARDSHIELD_" + i ) i++;
    	if( i < 11 ) for( var j = 1; j < 11; j++) {//found, refund old HS
    		if( j != i ) {
    			var ok = true; //only if no damaged HardShield
    			for( var k = 1; k < 11; k++) {
    				if( player.ship.equipmentStatus( "EQ_HARDSHIELD_" + i ) == "EQUIPMENT_DAMAGED"  ) {
    					player.consoleMessage("Hard Shield need repair first"); //do not get full refund
    					player.ship.removeEquipment( equipmentKey );
    					player.credits += EquipmentInfo.infoForKey( equipmentKey ).price * 0.1;
    					ok = false; //flag to fail
    				}
    			}
    			if( ok ) this.$HardShips_RefundEQ( "EQ_HARDSHIELD_" + j );  //upgrade or downgrade
    		}
    	}
    }
    
    this.playerBoughtNewShip = function() {
    	this.$HardShips_AllSideFixed(player.ship, 0);//initialize player data
    	this.$HardShips_Alloys[0] = this.$HardShips_AlloyStart;
    }
    
    this.shipAttackedOther = function(other) { //player hits other
    	this.$HardShips_EEG(other); //check Emergency Energy Generator
    	if( !other || !other.isValid || other.isDerelict ) return; //exit if the target is died or escaped meantime
    	if( !other.isPlayer && other.energy <= 23 ) { //the next Military Laser hit can destroy the target
    		other.fireMissile();//last resort
    		if( other.equipmentStatus("EQ_ESCAPE_POD") === "EQUIPMENT_OK"
    			&& other.abandonShip()) {//eject to save life but only if has Escape Pod
    			var dn = other.displayName;
    			if( worldScripts["detectors"] && other.script )
    				dn = other.script.$Detectors_Origname;//short name with version
    			player.consoleMessage(dn+" ejected to save life.");
    		}
    	}
    	this.$HardShips_CanLeaveAlloy(other); //can escape some cargo
    }
    
    this.shipBeingAttacked = function(other) { //player get hit from other
    //	if( !other || !other.isValid || other.isDerelict ) return; //exit if the target is died or escaped meantime
    	this.$HardShips_CanLeaveAlloy( player.ship );
    	this.$HardShips_EEG(player.ship); //check Emergency Energy Generator
    }
    
    
    this.shipDockedWithStation = this.shipWillLaunchFromStation = function() {
    //	player.ship.setEquipmentStatus("EQ_FUEL_INJECTION", "EQUIPMENT_DAMAGED");//debug
    //	player.ship.setEquipmentStatus("EQ_FUEL_INJECTION", "EQUIPMENT_DAMAGED");//debug
    	if( player.ship.docked ) {
    		if( player.ship.equipmentStatus("EQ_REG") == "EQUIPMENT_DAMAGED" )
    			player.ship.setEquipmentStatus("EQ_REG", "EQUIPMENT_OK"); //renew for free
    		this.$HardShips_AllSideFixed(player.ship, 0);//initialize player data
    		this.$HardShips_Alloys[0] = this.$HardShips_AlloyStart;
    	}
    }
    
    this.shipSpawned = function(ship) {
    	if( !ship || ship.isPlayer || !ship.isPiloted || ship.isThargoid || ship.isStation) return; //do not fix cargo, etc.
    	var shipno = this.$HardShips_Ships.length;
    	this.$HardShips_AllSideFixed(ship, shipno);
    	this.$HardShips_Alloys[shipno] = 100*(1+Math.min(ship.cargoSpaceCapacity, Math.random()*7)); //as like NPC carry 1-8t alloy
    //	if( this.$HardShips_Debug ) player.consoleMessage(shipno+". "+ship.name + " armoured");//debug
    
     	//award Standard Armour to all ships but do not overwite ship scripts
    	if( !ship.script ) ship.setScript("hardarmour.js"); //for sure, usually has oolite-default-ship-script, but if not then must set script to make usable the NPC Fuel Leak timer also
    	else if( !ship.script.shipTakingDamage ) {//set callback function into ship script to get damage amount
    		ship.script.shipTakingDamage = worldScripts["hardships"].$HardShips_ShipTakingDamage;
    //		if( this.$HardShips_Debug ) player.consoleMessage(ship.name + " armour handled");
    	} else {
    		ship.script.$HardShips_oldShipTakingDamage = ship.script.shipTakingDamage; //save the original function
    		
    		var std = function(amount, whom, type) {
    //			player.consoleMessage("HSTD "+Math.round(amount)+" "+whom.name+" "+type);//debug
    			amount = worldScripts["hardships"].$HardShips_ArmourDamage(this.ship, amount, whom); //damage armour first
    			if(ship.script.$HardShips_oldShipTakingDamage)
    //				ship.script.$HardShips_oldShipTakingDamage.apply(this, arguments); //call the original function
    				ship.script.$HardShips_oldShipTakingDamage(amount, whom, type); //call the original function
    			if(this.ship.script.$HardShips_oldShipTakingDamage)
    				this.ship.script.$HardShips_oldShipTakingDamage(amount, whom, type); //call the original function
    		}
    		ship.script.shipTakingDamage = std;
    		var s = ship.script.shipTakingDamage.toString();
    		if( ship.script.shipTakingDamage.toString() != s ) { //for sure, if ever will be changed to read-only
    			player.consoleMessage(ship.name + " script can NOT changed!");//debug
    			log("hardships.js armour handler addition failed", "***"+ship.script.shipTakingDamage.toString());
    		}
    //		else log("hardships.js armour handler added", "***"+ship.script.shipTakingDamage.toString());//debug
    	}
    	if( ship.dataKey == "hardanacondax" || ship.dataKey == "hardanacondax-pirate" ) { //extras for the kings of the enemies
    		ship.awardEquipment("EQ_BIGSHCAP");
    		ship.awardEquipment("EQ_BIGSHCAP2"); //ShipVersion will not award these to make more rare so awarded here only
    		ship.awardEquipment("EQ_SAPPERNULLIFIER");
    		ship.awardEquipment("EQ_VERYVERYHARDNOSE");
    	}
    	this.$HardShips_TimerB = new Timer(this, this.$HardShips_TimedB, 2, 0);//after the end of other shipSpawneds setup BigShCap
    }
    
    //this.shipTakingDamage = function(amount, whom, type) { //not working here for NPC ships due to it is a worldscript and must be in ship script
    //	worldScripts["hardships"].$HardShips_ArmourDamage(this.ship, amount, whom);
    //}
    
    this.shipWillEnterWitchspace = function(cause)
    {
    //	if( this.$HardShips_Debug )
    //		player.consoleMessage("Deleted "+this.$HardShips_Ships.length+" ship, doing "+cause+".", 10);
    	delete this.$HardShips_Ships;
    	this.$HardShips_Ships = [ player.ship ]; //start a new array in the new system
    	this.$HardShips_ShipsBigSC = 0;
    }
    
    
    //HardShips methods
    this.$HardShips_AftShieldFacing = function(ship, whom) { //determine which shield of the ship facing to the attacker
    	if( whom && whom.isValid && whom.vectorForward.angleTo(whom.position.subtract(ship.position)) <= 1.57) return(true);
    //player.consoleMessage("Front hit");
    	return(false);
    }
    
    this.$HardShips_AllSideFixed = function(ship, shipno) {
    	this.$HardShips_SetupPlayerBigShCap();
    	this.$HardShips_Ships[shipno] = ship;//save the new ship, increase the array
    	var ar = this.$HardShips_ArmourMax(ship);
    	var frontar = ar;
    	if( ship.equipmentStatus("EQ_ADDITIONAL_FRONT_ARMOUR") === "EQUIPMENT_OK" ) frontar = 2 * frontar;
    	var aftar = ar;
    	if( ship.equipmentStatus("EQ_ADDITIONAL_AFT_ARMOUR") === "EQUIPMENT_OK" ) aftar = 2 * aftar;
    	var corear = ship.maxEnergy;
    	if( ship.equipmentStatus("EQ_ADDITIONAL_CORE_HULL") === "EQUIPMENT_OK" ) corear = 2 * corear;
    	var ih = 0;
    	if( worldScripts["IronHide Armour Script"] ) {
    		if( ship.isPlayer ) { //copy player's IronHide armour
    			if(player.ship.equipmentStatus("EQ_IRONHIDE") == "EQUIPMENT_OK" )
    				ih = EquipmentInfo.infoForKey("EQ_IRONHIDE").scriptInfo.ironHideStrength //200
    					* missionVariables.ironHide_percentage * 0.01; //can be damaged after a fly
    			if(player.ship.equipmentStatus("EQ_IRONHIDE_MIL") == "EQUIPMENT_OK" )
    				ih = EquipmentInfo.infoForKey("EQ_IRONHIDE_MIL").scriptInfo.ironHideStrength //400
    					* missionVariables.ironHide_percentage * 0.01; //can be damaged after a fly
    		} else if ( ship.mass >= 30000 ) {
    			//compensate the large NPCs with IronHide armour, do the same math as with ShipVersion OXP
    			var v = null;
    			if( ship.scriptInfo ) { //support regardless from shipversion OXP is present
    				var sv = parseInt( ship.scriptInfo.shipversion );
    				if( sv ) {
    					if( sv <= 1 ) v = 10;
    					if( sv >= 10 ) v = 100;
    					if( sv > 1 && sv < 10 ) v = 10 * sv;
    				}
    			}
    			if( !v ) v = Math.floor( ship.entityPersonality / 328 ) + 1; //
    			if( v >= 100 && ship.mass >= 130000) ih = 600; //v10.0 get uber-armour
    			else if( v >= 80 && ship.mass >= 130000 ) //from ShipVersion 8.0
    				ih = EquipmentInfo.infoForKey("EQ_IRONHIDE_MIL").scriptInfo.ironHideStrength; //400
    			else if( v >= 50 ) //from ShipVersion 5.0
    				ih = EquipmentInfo.infoForKey("EQ_IRONHIDE").scriptInfo.ironHideStrength; //200
    		}
    	}
    	this.$HardShips_AMax[shipno] = this.$HardShips_Armour[shipno] = [frontar, aftar, ar, ar, ar, ar, corear, ih];
    	this.$HardShips_Damaged[shipno] = [false, false, false, false, false, false, false, false]; 
    }
    
    
    this.$HardShips_ArmourPiercingDamage = function(ship, amount, whom) { //callable from other OXPs to do Armour Piercing damage
    	return( this.$HardShips_ArmourDamage2( ship, amount, whom, true ) );
    }
    
    this.$HardShips_ArmourDamage = function(ship, amount, whom) { //callable from other OXPs to normal damage
    	return( this.$HardShips_ArmourDamage2( ship, amount, whom, false ) ); //no Armour Piercing
    }
    
    this.$HardShips_ArmourDamage2 = function(ship, amount, whom, ap) { //callable from other OXPs to either AP or normal damage
    	if( !ship || !ship.isValid ) return;
    	var side = -1;
    	if( ship && ship.isValid && whom && whom.isValid )
    		side = worldScripts["hardships"].$HardShips_WhichSideHit( ship, whom ); //which side damaged
    	if( !side || side == -1 ) side = 0; //if side not known then assume front hit as most attacked side
    	return( worldScripts["hardships"].$HardShips_ArmourDamageSide( ship, amount, whom, side, ap ) );
    }
    
    this.$HardShips_ArmourPiercingDamageSide = function(ship, amount, whom, side) { //callable from other OXPs to do Armour Piercing damage to a specific side
    	return( this.$HardShips_ArmourDamageSide2( ship, amount, whom, side, true ) );
    }
    
    this.$HardShips_ArmourDamageSide = function(ship, amount, whom, side) { //callable from other OXPs to normal damage to a side
    	return( this.$HardShips_ArmourDamageSide2( ship, amount, whom, side, false ) );
    }
    
    this.$HardShips_ArmourDamageSide2 = function(ship, amount, whom, side, ap) {//called from RocketShips OXPs after WhichSideHit called once to check armour size and now do damage on the previously randomly choosed side around facing corner
    	if( !ship || !ship.isValid ) return(amount);
    	var ws = worldScripts["hardships"];
    	if( player.ship.target == ship && ws.$HardShips_Debug )
    		player.consoleMessage("AD "+Math.round(amount)+" "+ship.name+" "+side+" "+ap);//debug
    	if( amount == 0 ) { //HardShield support, get back some if no shield penetrating damage only to do not add to HardArmour
    		var hardsh = ws.$HardShips_GetHardShieldLevel( ship );
    		if(hardsh > 0 && whom && whom.isValid ) { //get shield back only if attacker is valid
    			if(ship.isPlayer) {
    				if(ws.$HardShips_AftShieldFacing(ship, whom)) ship.aftShield += hardsh;
    				else ship.forwardShield += hardsh;
    			} else if(worldScripts["customshields"]) { //check if CustomShields installed
    				if(ws.$HardShips_AftShieldFacing(ship, whom)) ship.script.customshieldsaftshieldlevel += hardsh;
    				else ship.script.customshieldsforwardshieldlevel += hardsh;
    			}
    		}
    	}
    	if( amount <= 0 ) return(0); //amount=0 if shield damage only
    	var j = ws.$HardShips_Ships.indexOf( ship ); //where is the damaged ship in the Ships array?
    	if( j < 0 ) return(amount);//not found, the whole damage remain
    	var ha = ws.$HardShips_GetHardArmourValue( ship, side );
    	if( !ap && ha > 0 ) { //Hard Armour if not Armour Piercing
    		var d = Math.max( 0, Math.min( ha, amount - 1 ) ); //get back the prevented energy damage
    		 	//but leave at least one point damage
    		if( ship.energy > 5 ) ship.energy += d; //bugfix: hardly explode without if
    		amount -= d; //do less armour damage
    	}
    	if( amount <= 0 ) return(0);
    	
    //if( player.ship.target == ship || this.$HardShips_Debug ) player.consoleMessage(j+". "+ship.name+" "+Math.round(amount)+" "+side+" "+Math.round(ws.$HardShips_Armour[j][side]));
    	//additional armours give more starting values than max, if drop to or below max then set to damaged
    	if( side == 0 && ship.equipmentStatus("EQ_ADDITIONAL_FRONT_ARMOUR") === "EQUIPMENT_OK"
    		&& ws.$HardShips_Armour[j][0] - amount <= ws.$HardShips_ArmourMaxShipNo(j) )
    		ship.setEquipmentStatus("EQ_ADDITIONAL_FRONT_ARMOUR", "EQUIPMENT_DAMAGED");
    	if( side == 1 && ship.equipmentStatus("EQ_ADDITIONAL_AFT_ARMOUR") === "EQUIPMENT_OK"
    		&& ws.$HardShips_Armour[j][1] - amount <= ws.$HardShips_ArmourMaxShipNo(j) )
    		ship.setEquipmentStatus("EQ_ADDITIONAL_AFT_ARMOUR", "EQUIPMENT_DAMAGED");
    
    	var prevented = Math.max( 0, Math.min( ws.$HardShips_Armour[j][side], amount - 1 ) ); //min 1 damage
    //	if( this.$HardShips_Debug )
    //		player.consoleMessage(j+". "+ship.name+" "+Math.round(prevented)+" "+Math.round(ws.$HardShips_Armour[j][side]));
    	if( ship.energy > 5 ) ship.energy += prevented; //give back the prevented energy loss
    	ws.$HardShips_Armour[j][side] -= prevented; //side damage
    	if( ws.$HardShips_Armour[j][side] <= 0 ) {//too much cumulated damage
    		if( ws.$HardShips_Damaged[j][side] === false ) {
    			ws.$HardShips_Damaged[j][side] = true;
    //			if(ws.$HardShips_ArmourMaxShipNo(j) >= ws.$HardShips_ArmourMinToSpawnAlloy
    //				&& ws.$HardShips_Ships[j].mass > 30 ) //too light ship to produce a full alloy
    //				ship.spawnOne("alloy"); //fragmented from the ship - removed when CanLeaveAlloy coded
    			if(j == 0) player.consoleMessage(ws.$HardShips_Side[side]+" armour leaked");
    		}
    	} else if( j == 0 )//player ship
    		player.consoleMessage(ws.$HardShips_Side[side]+" hit, "
    			+Math.ceil(ws.$HardShips_Armour[j][side])+" left ("
    			+Math.floor((ws.$HardShips_Armour[j][side]/(ws.$HardShips_ArmourMaxShipNo(j)))*100)+"%)");
    	var ramount = amount - prevented; //remaining amount
    	if( ramount > 1 ) { //if there are remaining damage over the min. 1 then Core damage
    		ramount = ws.$HardShips_CoreDamage(ship, j, ramount - 1 );
    		//ramount means how many damage penertated both shield and armour and do energy loss
    		if( this.$HardShips_Debug )
    			if( j == 0 ) player.consoleMessage(ramount+" energy lost");
    	}
    //	if( player.ship.target == ship || this.$HardShips_Debug ) player.consoleMessage(j+". "+ship.name+" "+Math.round(amount)+"-"+Math.round(prevented)+":"+Math.round(ramount));//debug
    	return( ramount );
    }
    
    this.$HardShips_ArmourFacing = function(ship, whom) { //how many armour of ship facing whom (called from Detectors OXP)
    	var side = worldScripts["hardships"].$HardShips_WhichSide(ship, whom);//which side facing to whom
    	return( worldScripts["hardships"].$HardShips_ArmourOnSide(ship, side) );
    }
    
    this.$HardShips_ArmourMax = function(ship) {
    	if( ship.mass < 30)
    		return(Math.min(100, ship.maxEnergy / worldScripts["hardships"].$HardShips_ArmourDivider)); //small ship max. 100
    	return(ship.maxEnergy / worldScripts["hardships"].$HardShips_ArmourDivider); //the start Armour value for each side
    }
    
    this.$HardShips_ArmourMaxShipNo = function(shipno) {
    	return( worldScripts["hardships"].$HardShips_ArmourMax( worldScripts["hardships"].$HardShips_Ships[shipno] ) );
    }
    
    this.$HardShips_ArmourOnSide = function(ship, side) { //how many armour left on this side of the ship
    	var ar = 0;
    	var ws = worldScripts["hardships"];
    	var j = ws.$HardShips_Ships.indexOf(ship);
    	if( j > -1 && ws.$HardShips_Armour[j] ) { //found
    		ar = ws.$HardShips_Armour[j][side]; //armour facing
    		if( ws.$HardShips_Armour[j][7] ) //IronHide armour
    			ar += parseInt(ws.$HardShips_Armour[j][7]); //is additive
    	}
    	return( ar );
    }
    
    this.$HardShips_ArmourMaxOnSide = function(ship, side) { //how many armour was originally on this side of the ship
    	var ar = 0;
    	var ws = worldScripts["hardships"];
    	var j = ws.$HardShips_Ships.indexOf(ship);
    	if( j > -1 && ws.$HardShips_AMax[j] ) { //found
    		ar = ws.$HardShips_AMax[j][side]; //armour facing
    		if( ws.$HardShips_AMax[j][7] ) //IronHide armour
    			ar += parseInt(ws.$HardShips_AMax[j][7]); //is additive
    	}
    	return( ar );
    }
    
    this.$HardShips_CanLeaveAlloy = function( ship ) {
    	var lowenergy = ship.maxEnergy * 0.5; //below this can leave alloy the player and NPCs also
    	var odds = 10; //below this t alloy reduced odds to leave, same to player and NPCs
    	var ws = worldScripts["hardships"];
    	if( ship.isPlayer ) {
    		if( ship.energy <= lowenergy && ship.manifest.alloys > odds * Math.random()
    			&& ws.$HardShips_Armour[0][7] == 0 && //IronHide armour 0
    			( ws.$HardShips_Damaged[0][0]
    			|| ws.$HardShips_Damaged[0][1]
    			|| ws.$HardShips_Damaged[0][2]
    			|| ws.$HardShips_Damaged[0][3]
    			|| ws.$HardShips_Damaged[0][4]
    			|| ws.$HardShips_Damaged[0][5] ) ) {
    			ship.manifest.alloys--;
    			ship.spawnOne("alloy");
    			player.consoleMessage("RepairBot: Oh, we leaved 1t Alloy!");
    		}
    	} else {  //NPC
    		var i = ws.$HardShips_Ships.indexOf(ship);
    		var a = ws.$HardShips_Alloys[ i ];
    		var min = ws.$HardShips_ArmourMinToSpawnAlloy;
    		if( a > min * ( 1 + odds * Math.random() ) && ship.energy <= lowenergy
    			&& ws.$HardShips_Armour[i][7] == 0 && //IronHide armour 0
    			( ws.$HardShips_Damaged[i][0]
    			|| ws.$HardShips_Damaged[i][1]
    			|| ws.$HardShips_Damaged[i][2]
    			|| ws.$HardShips_Damaged[i][3]
    			|| ws.$HardShips_Damaged[i][4]
    			|| ws.$HardShips_Damaged[i][5] ) ) {
    			ws.$HardShips_Alloys[ i ] -= min;
    			ship.spawnOne("alloy");
    		}
    	}
    }
    
    this.$HardShips_CoreDamage = function(ship, shipno, ramount) {
    	//remaining damage amount after shield and normal armour cause first IronHide armour loss then Core damage
    	var ihdamage = 0;
    	var ws = worldScripts["hardships"];
    	if( ws.$HardShips_Armour[shipno][7] > 0 ) { //simulated IronHide armour damage
    		ihdamage = Math.min( ws.$HardShips_Armour[shipno][7], ramount );
    		ws.$HardShips_Armour[shipno][7] -= ihdamage; //reduce the simulated IronHide armour variable
    		ramount -= ihdamage; //either the armour or the remaining amount will be 0
    		if( ship.energy > 5 ) ship.energy += ihdamage; //give back the prevented energy loss
    		if( shipno === 0 ) missionVariables.ironHide_percentage -= //reduce the original IronHide armour also
    			Math.floor(100 * (ihdamage / missionVariables.ironHide_strength));
    		if( shipno === 0 && ws.$HardShips_Armour[shipno][7] <= 0 ) {//player lost IronHide armour
    			if(player.ship.equipmentStatus("EQ_IRONHIDE") == "EQUIPMENT_OK" ) 
    				player.ship.removeEquipment("EQ_IRONHIDE");
    			if(player.ship.equipmentStatus("EQ_IRONHIDE_MIL") == "EQUIPMENT_OK" ) 
    				player.ship.removeEquipment("EQ_IRONHIDE_MIL");
    			missionVariables.ironHide_percentage = 0;
           			missionVariables.ironHide_milFlag = 0;
    			player.consoleMessage("IronHide armour has been destroyed!", 6);
    			mission.setInstructionsKey(null, "IronHide Armour Script"); //copyed from the IronHide script.js
    		}
    	}
    	var coredamage = ramount; //remaining after ironhide armour cause
    //	if( ship.equipmentStatus("EQ_ADDITIONAL_CORE_HULL") === "EQUIPMENT_OK" //repairable over max due to it is hull not armour
    //		&& ws.$HardShips_Armour[shipno][6] - coredamage <= ship.maxEnergy ) 
    //		ship.setEquipmentStatus("EQ_ADDITIONAL_CORE_HULL", "EQUIPMENT_DAMAGED");
    	ws.$HardShips_Armour[6] -= coredamage; //Core can hold negative values to store real fixable amount
    	//do not give back energy due to Core is hull and not armour, can not prevent energy loss if hit
    	if( ws.$HardShips_Armour[6] <= 0 ) { //Core hull damaged to 0
    		if( ws.$HardShips_Damaged[6] === false ) {
    			ws.$HardShips_Damaged[6] = true;
    			var ship = ws.$HardShips_Ships[shipno];
    			if( ship.fuel > 0 && Math.random() > ship.energy/ship.maxEnergy ) { //Fuel Leak
    				// 25% odds to Fuel Leak at 3/4 energy, 50% at 1/2, 75% at 1/4.
    				if( shipno === 0 && player.ship.fuelLeakRate == 0) {//player ship with no Leak
    					player.ship.fuelLeakRate = 10 * ws.$HardShips_FuelLeakRate; //leaked
    					player.commsMessage("Core damaged, fuel leaking!",10);
    				} else {
    					if( ship.script && !ship.script.$HardShips_TimerNFL ) //NPC Fuel Leak timer
    						ship.script.$HardShips_TimerNFL = new Timer(ship,
    							ws.$HardShips_TimedNFL, 0, 1);
    					else ship.fuel = 0;//NPCs without script sustain very fast fuel leak but this should not happen due to the awarded hardarmour.js
    //todo: spawn scoopable Fuel cloud if CustomShields installed
    //				if(worldScripts["customshields"]) {
    //var sparksfuelleaks = ship.spawnOne("customshieldssparksfuelleaks");
    //sparksfuelleaks.position = ship.position.add([0, -30, 0]);//30m down
    //sparksfuelleaks.orientation = (0, 0, -1, 0);
    //sparksfuelleaks.target = ship;
    				}
    			} else { //no fuel or successful roll
    				if(ship.takeInternalDamage()) //cause cargo, equipment or service level damage
    					if( shipno === 0 ) player.consoleMessage("Core hit caused internal damage.");
    			}
    		}
    	}
    //	if( shipno > 0 && ship.script && !ship.script.$HardShips_TimerNFL) //debug: all hit after shield cause fuel leak
    //		ship.script.$HardShips_TimerNFL = new Timer(ship, ws.$HardShips_TimedNFL, 0, 1);
    	return(ramount - ihdamage); //Core damage is not deducted from amount as it is not armour
    }
    
    this.$HardShips_DamageEQ = function(ship, eq) {  //set to damaged and equipment box can not catch the damage
    	if( ship && ship.equipmentStatus(eq) == "EQUIPMENT_OK") {
    		var boxok = false;
    		if( ship.equipmentStatus("EQ_EQUIPMENT_BOX") == "EQUIPMENT_OK" ) {
    			ship.setEquipmentStatus("EQ_EQUIPMENT_BOX", "EQUIPMENT_DAMAGED"); //disable temporary
    			boxok = true;
    		}
    		ship.setEquipmentStatus(eq, "EQUIPMENT_DAMAGED");
    		if( boxok ) ship.setEquipmentStatus("EQ_EQUIPMENT_BOX", "EQUIPMENT_OK"); //restore if disabled
    	}
    }
    
    this.$HardShips_EEG = function(ship) { //Emergency Energy Generator handler
    	if( !ship || !ship.isValid || ship.energy > 64 ) return; //trigger when the last bank is touched
    	var npc = true;
    	if( ship == player.ship ) npc = false;
    //	if( this.$HardShips_Debug ) log("hardships", ship.displayName+" EQ_REG "+ship.equipmentStatus("EQ_REG"));
    	if( ship.equipmentStatus("EQ_REG")=="EQUIPMENT_OK" ) { //Renewable Energy Generator
    		if( Math.random() > 0.1 ) { //90% to work well
    			ship.energy += 128;
    			this.$HardShips_DamageEQ(ship, "EQ_REG"); //one shot but will renew in dock
    			if( !npc ) player.consoleMessage("Renewable Energy Generator triggered", 5);
    //			if( this.$HardShips_Debug ) log("hardships", ship.displayName+" EQ_REG triggered");
    		} else { //10% to break down
    			ship.removeEquipment( "EQ_REG" );
    //			if( this.$HardShips_Debug ) log("hardships", ship.displayName+" EQ_REG break down");
    			if( !npc ) {
    				player.consoleMessage("Renewable Energy Generator break down, cause internal damages!", 10);
    				ship.takeInternalDamage(); //only player ship has takeInternalDamage method
    				ship.takeInternalDamage();
    				ship.takeInternalDamage();
    			}
    		}
    	}
    	if( ship.energy < 64 && ship.equipmentStatus("EQ_EEG")=="EQUIPMENT_OK" ) { //skip EEG if REG is triggered
    		var htc = false;
    		if( ship.equipmentStatus("EQ_HTCAT")=="EQUIPMENT_OK" ) htc = true; //High-Tech Catalyst
    		if( ( (npc || ship.manifest.radioactives >= 1)
    			|| htc && ship.fuel >= 0.1 && (npc || ship.manifest.gold >= 1) )
    			&& (npc || ship.manifest.platinum >= 1 )) {
    			var ebank = 0;
    			var fue = 0;
    			if( npc ) {
    				ebank = 1 + 50 * Math.random(); //NPCs has resources to trigger EEG
    				if( htc ) ebank += ship.fuel * 10;
    			} else {
    				if( htc ) ebank = Math.min(ship.manifest.gold, ship.fuel * 10); //max.regen.ebanks
    				fue = ebank;
    				ebank += Math.min(ship.manifest.radioactives, ship.manifest.platinum);
    			}
    				
    			
    			if( htc ) this.$HardShips_DamageEQ(ship, "EQ_HTCAT"); //one more shot
    			else this.$HardShips_DamageEQ(ship, "EQ_EEG"); //one shot
    
    			if( !npc ) { //only player ship has takeInternalDamage method
    				var g = "";
    				if( htc && fue > 0 ) g += " using fuel";
    				if( ship.takeInternalDamage() ) g += ", internal damage taken";
    				player.consoleMessage("Emergency Energy Generator triggered"+g, 10);
    			}
    			
    			var need = ship.maxEnergy - ship.energy;
    			var adde = Math.min(ebank * 64, need);
    			ship.energy += adde;
    			ebank -= adde / 64;
    			if( ship.equipmentStatus("EQ_ESG")=="EQUIPMENT_OK" && ebank > 0 ) {
    				if( npc ) {
    					var wsc = false;
    					if( worldScripts["customshields"] ) wsc = true; //check if CustomShields installed
    					if( wsc ) need = ship.script.customshieldsmaxforwardshieldlevel -
    						ship.script.customshieldsforwardshieldlevel;
    					else need = 0;
    				} else need = ship.maxForwardShield - ship.forwardShield;
    				var addfs = Math.min(ebank * 64, need);
    				if( npc ) {
    					if( wsc ) ship.script.customshieldsforwardshieldlevel += addfs;
    				} else ship.forwardShield += addfs;
    				ebank -= addfs / 64;
    				adde += addfs;
    				if( ebank > 0 ) {
    					if( npc ) {
    						if( wsc ) need = ship.script.customshieldsmaxaftshieldlevel -
    							ship.script.customshieldsaftshieldlevel;
    						else need = 0;
    					} else need = ship.maxAftShield - ship.aftShield;
    					var addas = Math.min(ebank * 64, need);
    					if( npc ) {
    						if( wsc ) ship.script.customshieldsaftshieldlevel += addas;
    					} else ship.aftShield += addas;
    					ebank -= addas / 64;
    					adde += addas;
    				}
    			}
    			if( npc ) {
    				if( htc ) {
    					var f = Math.ceil( adde / 64 ) / 10;
    					if( ship.fuel <= f ) ship.fuel = 0;
    					else ship.fuel -= f;
    				}
    			} else {
    				var fu = Math.min(fue, adde / 64);
    				if( htc ) {
    					ship.fuel -= Math.ceil( adde / 64 ) / 10;
    					ship.manifest.gold -= Math.ceil( fu );
    				}
    				adde -= fu * 64;
    				if( adde > 0 ) {
    					ship.manifest.radioactives -= Math.ceil( adde / 64 );
    					ship.manifest.platinum -= Math.ceil( adde / 64 );
    				}
    			}
    		} else {
    			if( !npc ) {
    				var g = "";
    				if( htc ) g = " or Fuel and Gold";
    				player.consoleMessage("Emergency Energy Generator can not triggered,"+
    					" need more Radioactives and Platinum"+g, 10);
    			}
    		}
    	}
    }
    
    this.$HardShips_FixEQ = function(eq, price, firstfix) {
    	if(player.ship.equipmentStatus(eq) === "EQUIPMENT_DAMAGED") {
    		if(!firstfix) {
    			if( player.credits < pr ) {
    				player.consoleMessage("Not enough money to fix "+EquipmentInfo.infoForKey(eq).name);
    				return(firstfix); //exit before fixing
    			} else player.credits -= price; //deduct additional price to pay non-first fixing
    		}
    		player.ship.setEquipmentStatus(eq, "EQUIPMENT_OK"); //do fixing
    		clock.addSeconds("3600"); //fixing time per equipment
    		firstfix = false; //next need additional money
    	}
    	return(firstfix);
    }
    
    this.$HardShips_GetHardArmourValue = function( ship, side ) {
    	if( !ship ) return( 0 );
    	var ha = 0;
    	if( ship.scriptInfo && parseInt(ship.scriptInfo.hardarmour) > 0 )
    		ha = Math.max( 0, Math.min( parseInt(ship.scriptInfo.hardarmour), 10 ) ); //from 0 to 10
    	if( side == 0 ) {
    		if( ship.equipmentStatus("EQ_VERYVERYHARDNOSE") == "EQUIPMENT_OK" ) ha += 3; //undamaged VVHard Nose
    		else if( ship.equipmentStatus("EQ_VERYHARDNOSE") == "EQUIPMENT_OK" ) ha += 2; //undamaged VHard Nose
    		else if( ship.equipmentStatus("EQ_HARDNOSE") == "EQUIPMENT_OK" ) ha += 1; //undamaged Hard Nose
    	}
    	return( Math.min( ha, this.$HardShips_MaxHardArmour ) ); //the sum can not be more than MaxHardArmour
    }
    
    this.$HardShips_GetHardShieldLevel = function( ship ) {
    	var hardsh = 0;
    	for( var i = 10; i > 0; i-- ) { //check HardShield equipment
    		if( ship.equipmentStatus("EQ_HARDSHIELD_"+i) == "EQUIPMENT_OK" ) {
    			hardsh = i / 2; //highest match, lower HardShields unnecessary
    			i = 0; //amount halved to match the lower laser powers from Oolite 1.81
    //			if( this.$HardShips_Debug ) player.consoleMessage(ship.name+" HardShield "+hardsh);
    		}
    	}
    	return( hardsh );
    }
    
    this.$HardShips_GetSapperMultiplier = function( ship ) {
    	if( ship.equipmentStatus("EQ_SAPPERNULLIFIER") == "EQUIPMENT_OK" ) return( 0 ); //Equipment of the Kings
    	if( ship.equipmentStatus("EQ_EQ_ANTISAPPER") == "EQUIPMENT_OK" ) return( 1 );
    	return( 5 - worldScripts["hardships"].$HardShips_GetHardShieldLevel( ship ) / 3 );
    //HSLevel  	0	1	2	3	4	5	6	7	8	9	10
    //Depleting	5	4.667	4.333	4	3.667	3.333	3	2.667	2.333	2	1.667
    }
    
    this.$HardShips_GetShieldCap = function( ship ) {
    	if( !worldScripts["shieldequalizercapacitors"] ) return( 0 );
    	var m = this.$HardShips_OrigShieldCapMax;
    	var b = 0;
    	if( player.ship.equipmentStatus("EQ_BIGSHCAP") == "EQUIPMENT_OK" ) b++;
    	if( player.ship.equipmentStatus("EQ_BIGSHCAP2") == "EQUIPMENT_OK" ) b++;
    	if( b > 0 ) m = b * 256;
    	if( player.ship.equipmentStatus("EQ_BIGSHCAP3") == "EQUIPMENT_OK" ) m = 960; //for bases only
    	return( m );
    }
    
    this.$HardShips_RefundEQ = function( eq ) {
    	if( player.ship.equipment.indexOf( eq ) ) {
    		if( player.ship.equipmentStatus( eq ) == "EQUIPMENT_DAMAGED" )
    			player.consoleMessage("Need repair first"); //do not get back full price for a damaged eq
    		else if( player.ship.equipmentStatus( eq ) == "EQUIPMENT_OK" ) {
    			player.ship.removeEquipment( eq );
    			clock.addSeconds ("3600");
    			var refund = EquipmentInfo.infoForKey( eq ).price * 0.1;
    			player.credits += refund;
    			player.consoleMessage("Refunded "+refund+" credits for "+EquipmentInfo.infoForKey( eq ).name);
    			return( refund );
    		}
    	}
    	return( 0 );
    }
    
    this.$HardShips_ShipTakingDamage = function(amount, whom, type) { //used to add shipTakingDamage() to ship script
    //	if(whom.isPlayer) player.consoleMessage(Math.floor(amount)+" --> "+this.ship.name);//debug
    	worldScripts["hardships"].$HardShips_TakingDamage(this.ship, amount, whom, type);
    }
    
    this.$HardShips_TakingDamage = function(ship, amount, whom, type) { //used to add shipTakingDamage() to ship script
    //	if(whom.isPlayer) player.consoleMessage(Math.floor(amount)+" --> "+ship.name);//debug
    	if(type == "scrape damage" ) {//Railgun support
    		//if(player.ship.target == whom) player.consoleMessage(Math.floor(amount)+" "+type+" --> "+ship.name);//debug2
    		worldScripts["hardships"].$HardShips_ArmourPiercingDamage(ship, amount, whom);
    	}
    	else worldScripts["hardships"].$HardShips_ArmourDamage(ship, amount, whom);
    }
    
    this.$HardShips_Timed = function() {//repair run in every 1 sec
    	var hslen = this.$HardShips_Ships.length;
    	for( var j = 0; j < hslen; j++) {
    		var amax = this.$HardShips_AMax[j];
    		var armour = this.$HardShips_Armour[j];
    		var ship = this.$HardShips_Ships[j];
    		
    //		if( this.$HardShips_Debug )
    //		if( j==0 ) log("HardShips", ship.isInSpace+" "+ship.isPiloted+" "+this.$HardShips_Alloys[j]);
    		if( ship && ship.isValid && ship.isInSpace && ship.isPiloted ) {//equipment repairs
    			var r = Math.random();
    			if( r < 0.02 //engine repair need 50sec in average
    				&& ship.equipmentStatus("EQ_ERB") == "EQUIPMENT_OK" ) { //and working engine repair bot
    				var eq = "EQ_BREAKABLE_ENGINE_SMALL"; if( ship.equipmentStatus(eq) != "EQUIPMENT_DAMAGED" ) {
    				eq = "EQ_BREAKABLE_ENGINE_MEDIUM"; if( ship.equipmentStatus(eq) != "EQUIPMENT_DAMAGED" ) {
    				eq = "EQ_BREAKABLE_ENGINE_LARGE"; if( ship.equipmentStatus(eq) != "EQUIPMENT_DAMAGED" ) {
    				eq = "EQ_BREAKABLE_ENGINE_MONSTER"; if( ship.equipmentStatus(eq) != "EQUIPMENT_DAMAGED" ) {
    				eq = "EQ_FUEL_INJECTION"; if( ship.equipmentStatus(eq) != "EQUIPMENT_DAMAGED" ) {
    				eq = "EQ_Q-CHARGER"; if( ship.equipmentStatus(eq) != "EQUIPMENT_DAMAGED" ) eq = null;
    				}}}}}
    //				if(ship.isPlayer) log("HardShips", ship.equipmentStatus("EQ_ERB")+" "+eq);//debug
    				if( eq ) {
    					if( ship.isPlayer && player.ship.manifest.machinery < 1 ) {
    						player.consoleMessage("Need Machinery to fix "
    							+EquipmentInfo.infoForKey(eq).name, 10);
    					} else  {
    						ship.setEquipmentStatus(eq, "EQUIPMENT_OK");
    						if( ship.isPlayer ) {
    							player.ship.manifest.machinery--;
    							player.consoleMessage(EquipmentInfo.infoForKey(eq).name+" fixed.", 10);
    						}
    					}
    				}
    			}
    			if( r > 0.98 && this.$HardShips_Alloys[j] > 0 ) { //box repair need alloys
    				var eq = "EQ_INJECTOR_BOX"; if( ship.equipmentStatus(eq) != "EQUIPMENT_DAMAGED" ) {
    				eq = "EQ_LIFE_BOX"; if( ship.equipmentStatus(eq) != "EQUIPMENT_DAMAGED" ) {
    				eq = "EQ_SHIELD_BOX"; if( ship.equipmentStatus(eq) != "EQUIPMENT_DAMAGED" ) {
    				eq = "EQ_ELECTRONICS_BOX"; if( ship.equipmentStatus(eq) != "EQUIPMENT_DAMAGED" ) {
    				eq = "EQ_EQUIPMENT_BOX"; if( ship.equipmentStatus(eq) != "EQUIPMENT_DAMAGED" ) eq = null;
    				}}}}
    				if( eq ) {
    					ship.setEquipmentStatus(eq, "EQUIPMENT_OK");
    					this.$HardShips_Alloys[j] -= 10; //one box fix need 100kg alloy
    					if( ship.isPlayer )
    						player.consoleMessage(EquipmentInfo.infoForKey(eq).name+" fixed.", 5);
    				}
    			}
    		}
    	
    		if( ship && ship.isInSpace && ship.isPiloted && armour )//no timed repairs in dock
    		//restoring armour damages
    		for(var i=0; i < 7; i++) //sides and Core
    		if( armour[i] < amax[i] ) {
    			var damaged = this.$HardShips_Damaged[j];
    			//Additional Core Hull is repairable in-flight due to it is not armour
    //			|| i == 6 && ship.equipmentStatus("EQ_ADDITIONAL_CORE_HULL") === "EQUIPMENT_OK"
    //			&& armour[i] < 2 * this.$HardShips_ArmourMaxShipNo(j) ) {
    //			if(!damaged[6] || i === 6) {//Core damage means restore Core only - old idea, removed
    
    			//fix the armour
    			if( i != 6 && this.$HardShips_Alloys[j] < 1) { //check if alloys left in cargo
    				if( j != 0 ) return; //NPC no alloys left, no fix
    				if( player.ship.manifest.alloys > 0) {//player ship
    					player.ship.manifest.alloys--;// -1t
    					this.$HardShips_Alloys[j] = this.$HardShips_ArmourFixableWith1tAlloy;
    					player.consoleMessage("1t Alloy used to fixing, "+player.ship.manifest.alloys+"t left.", 	5);
    				} else {//if out of alloys first time then send a message
    					if(this.$HardShips_Alloys[j] > -this.$HardShips_ArmourFixableWith1tAlloy) {
    						player.commsMessage("Out of Alloys. Scoop some or go to Dock.", 5);
    						this.$HardShips_Alloys[j] = -this.$HardShips_ArmourFixableWith1tAlloy; //flag to no more message
    					}
    					return;//no alloys left, no fix
    				}
    			}
    			armour[i]++; //restore 1 points of armour per second
    			if( i != 6 ) this.$HardShips_Alloys[j]--; //Core repair do not need alloy, it is hull and not armour
    			if( j == 0 && i != 6 && damaged[i]) { //player ship armour
    				var x = Math.floor(amax[i]-armour[i]) / 10;
    				if( x === Math.floor(x) && x > 0) //divisible means x*10 seconds left
    					 player.consoleMessage(this.$HardShips_Side[i]+
    						" armour will be fixed in "+x+"0 seconds.", 10);
    			}
    
    //			}
    			if( damaged[i] || j == 0 && i == 6) { //player core fixed later than set to undamaged
    				if( armour[i] >= amax[i] ) {//damage reached 0
    					damaged[i] = false;//restored
    					if( j === 0 ) {//player ship
    						var name = "armour";
    						if( i === 6 ) name = "hull"; //Core
    						player.commsMessage(this.$HardShips_Side[i]+" "+name+" fixed.");
    					}
    				}
    				if( i == 6 ) {//Core
    //					if(worldScripts["customshields"]) { //if CustomShields OXP installed
    //						//stop the leak somehow
    //					} else {
    					if( armour[i] >= amax[i] / 4) {
    						if( j == 0 ) {
    							//not only if Rate>0 to inform regardless from out of fuel
    							player.ship.fuelLeakRate = 0;
    							player.commsMessage("Fuel leak sealed.");
    						} else if( ship.script.$HardShips_TimerNFL ) { //NPC Fuel Leak
    							ship.script.$HardShips_TimerNFL.stop();
    							delete ship.script.$HardShips_TimerNFL; //sealed
    						}
    						damaged[i] == false;//after sealed make leakable again
    					}
    				}
    			}
    		}
    	}
    }
    
    this.$HardShips_TimedB = function() { //NPC with Big Shield Capacitor setup
    	if( !worldScripts["shieldequalizercapacitors"] || !worldScripts["customshields"] ) return;
    	while( this.$HardShips_ShipsBigSC < this.$HardShips_Ships.length ) { //all spawned ships after last check
    		var ship = this.$HardShips_Ships[ this.$HardShips_ShipsBigSC++ ];
    		var m = this.$HardShips_GetShieldCap( ship ) - this.$HardShips_OrigShieldCapMax;
    		if( ship.script ) {
    			ship.script.customshieldsmaxforwardshieldlevel += m;
    			ship.script.customshieldsmaxaftshieldlevel += m;
    		}
    	}
    }
    
    this.$HardShips_TimedNFL = function() {//NPC Fuel Leak run in every sec
    	if( !this.ship || !this.ship.isValid || this.ship.isPlayer ) return;
    	this.ship.fuel -= Math.max( 0.1, worldScripts["hardships"].$HardShips_FuelLeakRate ); //min. 0.1ly/second needed
    	if( player.ship.target == this.ship || this.$HardShips_Debug ) {
    		var n = this.ship.name;
    		if( this.ship.script && this.ship.script.$Detectors_Origname )
    			n = this.ship.script.$Detectors_Origname;
    		var r = "";
    //		if(this.$HardShips_Debug)
    			r = ", remain: "+Math.round(this.ship.fuel*10)/10;
    		player.consoleMessage( n + " fuel leak" + r );
    	}
    	if( this.ship.fuel < 0.1 && this.ship.script && this.ship.script.$HardShips_TimerNFL ) {
    		this.ship.script.$HardShips_TimerNFL.stop();
    		delete this.ship.script.$HardShips_TimerNFL; //ended
    	}
    }
    
    this.$HardShips_WhichSide = function(ship, whom) { //which side of ship facing to whom
    	return worldScripts["hardships"].$HardShips_FindWhichSide(ship, whom, false);
    }
    
    this.$HardShips_WhichSideHit = function(ship, whom) { //which side of ship hit by whom using angle based randomness
    	return worldScripts["hardships"].$HardShips_FindWhichSide(ship, whom, true);
    //	var side = worldScripts["hardships"].$HardShips_FindWhichSide(ship, whom, true);//debug
    //	if( this.$HardShips_Debug ) if(whom.isPlayer) player.consoleMessage(ship.name+" "+this.$HardShips_Side[this.$HardShips_FindWhichSide(ship, whom, false)]+" side "+this.$HardShips_Side[side]+" hit");
    }
    
    this.$HardShips_FindWhichSide = function(ship, whom, hit) { //which side of ship facing to whom or hit by whom
    	var side = -1;
    	var v = ship.position.subtract(whom.position);  //cube face comparsions
    	var f = ship.vectorForward.angleTo(v);
    	var r = ship.vectorRight.angleTo(v);
    	var u = ship.vectorUp.angleTo(v);
    //	if( this.$HardShips_Debug )  player.consoleMessage(f+" "+r+" "+u);
    	var pi = Math.PI; //3.1416...
    	var pi2 = pi / 2;   //1.5708...
    	var fw = true;
    	if( f <= pi2 ) fw = false; //small f
    	if( fw ) f = pi - f; //make comparable, either fwd or aft
    	var ri = true;
    	if( r <= pi2 ) ri = false; //small r
    	if( ri ) r = pi - r; //make comparable, either right or left
    	var up = true;
    	if( u <= pi2 ) up = false; //small u
    	if( up ) u = pi - u; //make comparable, either up or down
    	if( hit ) { //requested to hit side
    		//randomize which side get damaged around facing corner using the angle of the whom position
    		var min = 0.175;//do not randomize if in the center 10 degree cone of the best side (0.175=pi/180*10)
    		if( f < min ) f = 0;
    		else f = Math.random() * f / pi2; //as high odds to front or aft as low the f angle
    		if( r < min ) r = 0;
    		else r = Math.random() * r / pi2; //as high odds to right or left as low the r angle
    		if( u < min ) u = 0;
    		else u = Math.random() * u / pi2; //as high odds to top or bottom as low the u angle
    	} //if requested facing side then f, r and u remain unchanged
    	//side compares, new method using "make comparable" lines to find the smallest angle
    	if( f <= r && f <= u ) { //Front or Aft
    		if( fw ) side = 0; //Front
    		else side = 1; //Aft
    	} else if( r <= f && r <= u ) { //Right or left
    		if( ri ) side = 2; //Right
    		else  side = 3; //Left
    	} else if( u <= r && u <= f ) { //Top or Bottom
    		if( up ) side = 4; //Top
    		else  side = 5; //Bottom
    	}
    	return(side);
    }
    	//old side compares without "make comparable" lines, leaved here to demonstrate complexity
    //	if( fw && ( ri && f >= r || !ri && f >= pi - r ) && ( up && f >= u || !up && f >= pi - u ) ) side = 0; //Front
    //	else if( !fw && ( !ri && f <= r || ri && f <= pi - r ) && ( !up && f <= u || up && f <= pi - u ) ) side = 1; //Aft
    //	else if( ri && ( fw && r >= f || !fw && r >= pi - f ) && ( up && r >= u || !up && r >= pi - u ) ) side = 2; //Right
    //	else if( !ri && ( !fw && r <= f || fw && r <= pi - f ) && ( !up && r <= u || up && r <= pi - u ) ) side = 3; //Left
    //	else if( up && ( ri && u >= r || !ri && pi - u <= r ) && ( fw && u >= f || !fw && pi - u <= f ) ) side = 4; //Top
    //	else if( !up && ( !ri && u <= r || ri && u <= pi - r ) && ( !fw && u <= f || fw && u <= pi - f ) ) side = 5; //Bottom
    
    this.$HardShips_SetupPlayerBigShCap = function() {
    	if( !worldScripts["shieldequalizercapacitors"] ) return;
    	if( !worldScripts["shieldequalizercapacitors"].secforwardshieldcapacitormax ) { //update the original script if too old
    		worldScripts["shieldequalizercapacitors"].secforwardshieldcapacitormax = this.$HardShips_OrigShieldCapMax;
    		worldScripts["shieldequalizercapacitors"].secaftshieldcapacitormax = this.$HardShips_OrigShieldCapMax;
    		worldScripts["shieldequalizercapacitors"].forwardshieldcapacitor = function()
       {
       if(player.ship.equipmentStatus("EQ_FORWARD_SHIELD_CAPACITOR") == "EQUIPMENT_OK")
          {
          if(player.ship.forwardShield == player.ship.maxForwardShield)// shield full so charge capacitor
             {
             this.secforwardshieldcapacitor = (this.secforwardshieldcapacitor + (player.ship.forwardShieldRechargeRate * 0.5));
    		 if(this.secforwardshieldcapacitor <= this.secforwardshieldcapacitormax - 1.5)
    		    {
    			if(this.togglemessages == "ON")
    			   {
    			   this.fscpause += 1.0;
    			   if(this.fscpause > 3.0)
    			      {
    			      this.fscpause = 1.0;
    			      }
                   if(this.fscpause == 2.0)
    			      {
    				  player.consoleMessage("Forward Shield Capacitor ===> CHARGING...",1.5);
    				  }
    			   }			
    			if(this.togglesoundfx2 == "ON")
                   {
    			   if(!this.mySound3.isPlaying)
    			      {
                      this.mySound3.play();
    				  }
                   }
    			}   			
             if((this.secforwardshieldcapacitor <= this.secforwardshieldcapacitormax) && 
    		 (this.secforwardshieldcapacitor > this.secforwardshieldcapacitormax - 1.5))
                {
    			if(this.togglemessages == "ON")
    			   {
                   player.consoleMessage("Forward Shield Capacitor ===> FULLY CHARGED",6);
    			   }
    			this.secforwardshieldcapacitor = this.secforwardshieldcapacitormax; // v1.1 fix
    			if(this.mySound3.isPlaying)
                   {
                   this.mySound3.stop();
                   }
    			if(this.togglesoundfx2 == "ON")
                   {
    			   this.mySound5.play();
    			   }
                }			
             if(this.secforwardshieldcapacitor > this.secforwardshieldcapacitormax)
                {
                this.secforwardshieldcapacitor = this.secforwardshieldcapacitormax;
                }
             return;
             }
          if(player.ship.forwardShield < 10 ||
    	      player.ship.forwardShield < (player.ship.maxForwardShield - (this.secforwardshieldcapacitor + (player.ship.forwardShieldRechargeRate * 0.5))))
             {
    		 if(this.mySound3.isPlaying)
                {
                this.mySound3.stop();
                }
    	 var s = this.secforwardshieldcapacitor;
             if(s > 0.0)// shield below capacitor level so discharge capacitor
                {
    	    var c = 0;
    	    var r = player.ship.maxForwardShield - player.ship.forwardShield;
                if( s > r ) { //some energy left in capacitor
    		s = player.ship.maxForwardShield - player.ship.forwardShield;
    		c = this.secforwardshieldcapacitor - s;
    	    }
                player.ship.forwardShield += s;
                this.secforwardshieldcapacitor = c;
    			if(this.togglemessages == "ON")
    			   {
                   player.consoleMessage("Forward Shield Capacitor DISCHARGED!!!",6);
    			   }
    			if(this.togglesoundfx1 == "ON")
                   {
    			   this.mySound1.play();
    			   }
                }
             return;
             }
          }
    	if(this.mySound3.isPlaying)
          {
          this.mySound3.stop();
          }
       return;
       }
    
    		worldScripts["shieldequalizercapacitors"].aftshieldcapacitor = function()
       {
       if(player.ship.equipmentStatus("EQ_AFT_SHIELD_CAPACITOR") == "EQUIPMENT_OK")
          {
          if(player.ship.aftShield == player.ship.maxAftShield)// shield full so charge capacitor
             {
             this.secaftshieldcapacitor = (this.secaftshieldcapacitor + (player.ship.aftShieldRechargeRate * 0.5));
    		 if(this.secaftshieldcapacitor <= this.secaftshieldcapacitormax - 1.5)
    		    {
    			if(this.togglemessages == "ON")
    			   {
    			   this.ascpause += 1.0;
    			   if(this.ascpause > 3.0)
    			      {
    			      this.ascpause = 1.0;
    			      }
                   if(this.ascpause == 2.0)
    			      {
    				  player.consoleMessage("Aft Shield Capacitor ===> CHARGING...",1.5);
    				  }
    			   }			
    			if(this.togglesoundfx2 == "ON")
                   {
    			   if(!this.mySound4.isPlaying)
    			      {
                      this.mySound4.play();
    				  }
                   }
    			} 
    		 if((this.secaftshieldcapacitor <= this.secaftshieldcapacitormax) 
    			 && (this.secaftshieldcapacitor > this.secaftshieldcapacitormax - 1.5))
                {
    			if(this.togglemessages == "ON")
    			   {
                   player.consoleMessage("Aft Shield Capacitor ===> FULLY CHARGED",6);
    			   }
    			this.secaftshieldcapacitor = this.secaftshieldcapacitormax;// v1.1 fix
    			if(this.mySound4.isPlaying)
                   {
                   this.mySound4.stop();
                   }
                if(this.togglesoundfx2 == "ON")
                   {
    			   this.mySound5.play();
    			   }
                }
             if(this.secaftshieldcapacitor > this.secaftshieldcapacitormax)
                {
                this.secaftshieldcapacitor = this.secaftshieldcapacitormax;
                }
             return;
             }
          if(player.ship.aftShield < 10 ||
    	      player.ship.aftShield < (player.ship.maxAftShield - (this.secaftshieldcapacitor + (player.ship.aftShieldRechargeRate * 0.5))))
             {
    		 if(this.mySound4.isPlaying)
                {
                this.mySound4.stop();
                }
    	 var s = this.secaftshieldcapacitor;
             if(s > 0.0)// shield below capacitor level so discharge capacitor
                {
    	    var c = 0;
    	    var r = player.ship.maxAftShield - player.ship.aftShield;
                if( s > r ) { //some energy left in capacitor
    		s = player.ship.maxAftShield - player.ship.aftShield;
    		c = this.secaftshieldcapacitor - s;
    	    }
                player.ship.aftShield += s;
                this.secaftshieldcapacitor = c;
    			if(this.togglemessages == "ON")
    			   {
                   player.consoleMessage("Aft Shield Capacitor DISCHARGED!!!",6);
    			   }
    			if(this.togglesoundfx1 == "ON")
                   {
    			   this.mySound1.play();
    			   }
                }
             return;
             }
           }
        if(this.mySound4.isPlaying)
           {
           this.mySound4.stop();
           }
       return;
       }
    	}
    
    	var m = this.$HardShips_GetShieldCap( player.ship );
    	worldScripts["shieldequalizercapacitors"].secforwardshieldcapacitormax = m;
    	worldScripts["shieldequalizercapacitors"].secaftshieldcapacitormax = m;
    }
    Scripts/hardturret.js
    "use strict";
    this.name        = "hardturret";
    this.author      = "Norby";
    this.copyright   = "2013 Norbert Nagy";
    this.description = "Reduce damages, place turret inside of the shields and send message if a turret gone.";
    this.licence     = "CC BY-NC-SA 3.0";
    this.version     = "1.0";
    
    this.$Hardturret_HitTimer = null;
    
    //this.shipBeingAttacked = function(whom) {
    this.shipTakingDamage = function(amount, whom, type) {
    	if(amount<=0) return;//player shield can take the whole damage
    //if(this.ship.isPlayer) {var a=Math.round(amount); var e=Math.round(this.ship.energy);}//debug
    	if(this.ship.scriptInfo.hardarmour > 0) { //Hard Armour support
    		var d = Math.min(this.ship.scriptInfo.hardarmour, amount);
    		if(this.ship.energy > 5) this.ship.energy += d; //Hardly explode without if
    		amount -= d;
    	}
    //if(this.ship.isPlayer) player.commsMessage(a+" "+Math.round(amount)+" "+e+" "+Math.round(this.ship.energy));//debug
    	if(amount<=0) return;//extra check after armor
    	var energydamage = amount;
    	var owner = this.ship.owner;
    	if(owner.isValid && !this.ship.scriptInfo.noturretshield
    		&& !owner.scriptInfo.noturretshield) {//can disable turret shield in shipdata.plist
    		var angle = 3.14;//unknown attacker assumed in front
    		if(whom && whom.isValid)
    			angle = owner.vectorForward.angleTo(owner.position.subtract(whom.position));
    		if(owner.isPlayer) {
    			if(angle > 1.57) {//forward
    				if(energydamage > owner.forwardShield) { //hit the shield first
    					this.ship.energy += owner.forwardShield;
    					energydamage -= owner.forwardShield;
    					owner.forwardShield = 0;
    				} else {
    					if(owner.isPlayer) var d = Math.round(this.ship.energy);//debug
    					this.ship.energy += energydamage;
    					if(this.ship.isPlayer) player.console(this.ship.name+" "+d+" "+Math.round(this.ship.energy)
    						+" "+Math.round(amount));//debug
    					owner.forwardShield -= energydamage;
    					energydamage = 0;
    				}
    			} else { //aft
    				if(energydamage > owner.aftShield) {
    					this.ship.energy += owner.aftShield;
    					energydamage -= owner.aftShield;
    					owner.aftShield = 0;
    				} else {
    					this.ship.energy += energydamage;
    					owner.aftShield -= energydamage;
    					energydamage = 0;
    				}
    			}
    		} else if(worldScripts["customshields"]) { //NPC, check if CustomShields installed
    			if(angle < 1.57) {
    				if(energydamage > owner.script.customshieldsaftshieldlevel) {
    					this.ship.energy += owner.script.customshieldsaftshieldlevel;
    					energydamage -= owner.script.customshieldsaftshieldlevel;
    					owner.script.customshieldsaftshieldlevel = 0;
    				} else {
    					this.ship.energy += energydamage;
    					owner.script.customshieldsaftshieldlevel -= energydamage;
    					energydamage = 0;
    				}
    			} else {
    				if(energydamage > owner.script.customshieldsforwardshieldlevel) {
    					this.ship.energy += owner.script.customshieldsforwardshieldlevel;
    					energydamage -= owner.script.customshieldsforwardshieldlevel;
    					owner.script.customshieldsforwardshieldlevel = 0;
    				} else {
    					this.ship.energy += energydamage;
    					owner.script.customshieldsforwardshieldlevel -= energydamage;
    					energydamage = 0;
    				}
    			}
    		}
    	}
    	if(energydamage > 0 && owner.isPlayer) {
    		if(!this.$Hardturret_HitTimer)  { 
    			//delayed show the energy of the turret after hit to avoid too many messages
    			this.$Hardturret_HitTimer = new Timer(this, this.$Hardturret_Hit, 1);
    		}
    	}
    }
    
    this.$Hardturret_Pos = function() {
    	var pos = "";
    	if(this.ship.name === "Main Turret") pos+="Main ";//Main Turret always placed in Front
    	else if(this.ship.position.z>2)  pos+="Fore ";
    	if(this.ship.position.z<-2)  pos+="Aft ";
    	if(this.ship.position.x>2)  pos+="Port ";
    	if(this.ship.position.x<-2)  pos+="Starboard ";
    	if(this.ship.position.y>2)  pos+="Up ";
    	if(this.ship.position.y<-2)  pos+="Down ";
    	return(pos);
    }
    
    this.$Hardturret_Hit = function() {
    	player.consoleMessage(this.$Hardturret_Pos()+"Turret "+Math.ceil(this.ship.energy)+" armor left.");
    	if(this.$Hardturret_HitTimer) {
    		this.$Hardturret_HitTimer.stop();
    		delete this.$Hardturret_HitTimer;
    	}
    }
    
    this.shipDied = function () {
    	if(this.ship.owner === player.ship) //switch(this.ship.primaryRole)
    	{
    //		case "ballturret":
    //		case "ball_turret":
    //		{
    			player.commsMessage(this.$Hardturret_Pos()+"Turret gone.");
    //			break;
    //		}
    //		default: break
    	}
    };
    
    Scripts/largeonly.js
    "use strict";
    this.name        = "largeonly";
    this.author      = "Norby";
    this.copyright   = "2013 Norbert Nagy";
    this.licence     = "CC BY-NC-SA 3.0";
    this.description = "This equipment is usable only for ships over 130t like the Cobra III or Rocket Miner.";
    this.version     = "1.0";
    
    this.allowAwardEquipment = function(eqKey, ship, context)
    {
    //	player.consoleMessage( eqKey+" "+ship+" "+context );//debug
    	if( ship.mass >= 130000 ) return true;
    	else return false;
    }
    
    Scripts/notforsmall.js
    "use strict";
    this.name        = "notforsmall";
    this.author      = "Norby";
    this.copyright   = "2013 Norbert Nagy";
    this.licence     = "CC BY-NC-SA 3.0";
    this.description = "This equipment can not fit into small ships like the Rocket Fighter.";
    this.version     = "1.0";
    
    this.allowAwardEquipment = function(eqKey, ship, context)
    {
    //bugfix for eqs with conditions scripts: need double replaceShip() to work!
    //player.replaceShip(shipname, pers); player.replaceShip(shipname, pers);
    //call twice! the first always got false for allow without run this script.
    //Proof: if you uncomment the following line, only the 2nd call will write into the log.
    //log("notforsmall", eqKey+" "+ship.name+" "+ship.mass+" "+context );
    
    	if( ship.mass >= 30000 ) return true;
    	else return false;
    }
    
    Scripts/shieldrepair.js
    "use strict";
    this.name        = "shieldrepair";
    this.author      = "Norby";
    this.copyright   = "2013 Norbert Nagy";
    this.licence     = "CC BY-NC-SA 3.0";
    this.description = "Repair Hard Shield and Anti-Sapper Shield Equipments if damaged only.";
    this.version     = "1.0";
    
    this.allowAwardEquipment = function(eqKey, ship, context)
    {
    	if( eqKey==="EQ_HARDSHIELD_REPAIR" //Repair Hard Shield and Anti-Sapper Shield Equipments if damaged only
    			&& ( player.ship.equipmentStatus("EQ_HARDSHIELD_1") === "EQUIPMENT_DAMAGED"
    			|| player.ship.equipmentStatus("EQ_HARDSHIELD_2") === "EQUIPMENT_DAMAGED"
    			|| player.ship.equipmentStatus("EQ_HARDSHIELD_3") === "EQUIPMENT_DAMAGED"
    			|| player.ship.equipmentStatus("EQ_HARDSHIELD_4") === "EQUIPMENT_DAMAGED"
    			|| player.ship.equipmentStatus("EQ_HARDSHIELD_5") === "EQUIPMENT_DAMAGED"
    			|| player.ship.equipmentStatus("EQ_HARDSHIELD_6") === "EQUIPMENT_DAMAGED"
    			|| player.ship.equipmentStatus("EQ_HARDSHIELD_7") === "EQUIPMENT_DAMAGED"
    			|| player.ship.equipmentStatus("EQ_HARDSHIELD_8") === "EQUIPMENT_DAMAGED"
    			|| player.ship.equipmentStatus("EQ_HARDSHIELD_9") === "EQUIPMENT_DAMAGED"
    			|| player.ship.equipmentStatus("EQ_HARDSHIELD_10") === "EQUIPMENT_DAMAGED"
    			|| player.ship.equipmentStatus("EQ_BIGSHCAP") === "EQUIPMENT_DAMAGED"
    			|| player.ship.equipmentStatus("EQ_SAPPERNULLIFIER") === "EQUIPMENT_DAMAGED" //for sure only
    			|| player.ship.equipmentStatus("EQ_ANTISAPPER") === "EQUIPMENT_DAMAGED" ) )
    			return true;
    	return false;
    }