// ################################
// ##           Protokol na srv  ##
// ##                            ##
// ################################

#include <sstream>

#include "prot_srv.h"

#ifdef _DEBUG
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif
#endif

// --------------------------------

void write_scientific_tree(protocolWriter& w, scientificTree* sc)
{
    w.writeValue(TOKENS_SCIENCE_ENTITY_SHIPS,                                   (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_SHIPS));                             
    w.writeValue(TOKENS_SCIENCE_ENTITY_BASES,                                   (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_BASES));                              
    w.writeValue(TOKENS_SCIENCE_ENTITY_ENERGETIC_ACCUMULATOR,                   (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_ENERGETIC_ACCUMULATOR));  
    w.writeValue(TOKENS_SCIENCE_ENTITY_NAVIGATION_COMPUTER,                     (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_NAVIGATION_COMPUTER));  
    w.writeValue(TOKENS_SCIENCE_ENTITY_QUARK_GLUON_CORE,                        (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_QUARK_GLUON_CORE));  
    w.writeValue(TOKENS_SCIENCE_ENTITY_SUBSPACE_BEACON,                         (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_SUBSPACE_BEACON));  
    w.writeValue(TOKENS_SCIENCE_ENTITY_INERTIAL_DAMPERS,                        (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_INERTIAL_DAMPERS));  
    w.writeValue(TOKENS_SCIENCE_ENTITY_IMPULS_JET_ENGINE,                       (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_IMPULS_JET_ENGINE));  
    w.writeValue(TOKENS_SCIENCE_ENTITY_MECHANICAL_DAMPERS,                      (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_MECHANICAL_DAMPERS));  
    w.writeValue(TOKENS_SCIENCE_ENTITY_DEFLECTOR_SHIELDS,                       (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_DEFLECTOR_SHIELDS));  
    w.writeValue(TOKENS_SCIENCE_ENTITY_WEAPON_ENERGY_CIRCUIT,                   (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_WEAPON_ENERGY_CIRCUIT)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_DRONE_MISSILE_LAUNCHER,                  (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_DRONE_MISSILE_LAUNCHER)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_DRONE_MISSILES,                          (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_DRONE_MISSILES)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_LASER_GUN,                               (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_LASER_GUN)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_TRANSPORT_BEAM_GENERATOR,                (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_TRANSPORT_BEAM_GENERATOR)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_MAGNETICAL_COLLECTORS_OF_PLASMA,         (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_MAGNETICAL_COLLECTORS_OF_PLASMA)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_SUBMERSIBLE_FILTRATION_TANK,             (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_SUBMERSIBLE_FILTRATION_TANK)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_SUBMARINE_MINING_MACHINE,                (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_SUBMARINE_MINING_MACHINE)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_UNDERGROUND_DRILLING_MACHINE,            (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_UNDERGROUND_DRILLING_MACHINE)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_PROBE,                                   (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_PROBE)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_HIGH_RESOLUTION_SENSORS,                 (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_HIGH_RESOLUTION_SENSORS)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_LONG_RANGE_SENSORS,                      (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_LONG_RANGE_SENSORS)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_CLOAKING_DEVICE,                         (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_CLOAKING_DEVICE)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_ANDROIDS,                                (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_ANDROIDS)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_SCIENTIFIC_LAB,                          (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_SCIENTIFIC_LAB)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_LIFE_SUPPORT,                            (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_LIFE_SUPPORT)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_MAINFRAME,                               (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_MAINFRAME)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_HANGAR,                                  (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_HANGAR)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_MAGNETICAL_FILTER,                       (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_MAGNETICAL_FILTER)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_DEUTERIUM_DECOMPOSER,                    (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_DEUTERIUM_DECOMPOSER)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_ZIRCONIUM_REACTOR,                       (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_ZIRCONIUM_REACTOR)); 
    w.writeValue(TOKENS_SCIENCE_ENTITY_ILMENITE_FURNACE,                        (unsigned long long)sc->getPureLeafTokens(SCIENCE_ENTITY_ILMENITE_FURNACE)); 

    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_SCIENCE,                         (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_SCIENCE));

    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_DRIVE,                           (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_DRIVE));
    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_PLATFORM,                        (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_PLATFORM));
    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_MODULES,                         (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_MODULES));
    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_PRODUCTION,                      (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_PRODUCTION));

    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_SUBSPACE_DRIVE,                  (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_SUBSPACE_DRIVE));
    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_IMPULS_DRIVE,                    (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_IMPULS_DRIVE));
    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_CONSTRUCTION,                    (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_CONSTRUCTION));
    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_EQUIPMENT,                       (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_EQUIPMENT));
    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_ENERGETIC_RING,                  (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_ENERGETIC_RING));
    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_RECOGNITION_DEVICES,             (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_RECOGNITION_DEVICES));
    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_FACTORIES,                       (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_FACTORIES));
    w.writeValue(TOKENS_SCIENCE_SUPREME_ENTITY_QUARRYING_MACHINES,              (unsigned long long)sc->getPureInnerTokens(SCIENCE_SUPREME_ENTITY_QUARRYING_MACHINES));

    w.writeValue(SPEC_PTS_QUARK_GLUON_CORE_SPEED,                               (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_QUARK_GLUON_CORE, INDEX_QUARK_GLUON_CORE_SPEED));
    w.writeValue(SPEC_PTS_QUARK_GLUON_CORE_CONSUMPTION,                         (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_QUARK_GLUON_CORE, INDEX_QUARK_GLUON_CORE_CONSUMPTION));

    w.writeValue(SPEC_PTS_NAVIGATION_COMPUTER_SPEED,                            (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_NAVIGATION_COMPUTER, INDEX_NAVIGATION_COMPUTER_SPEED));

    w.writeValue(SPEC_PTS_SUBSPACE_BEACON_SPEED,                                (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_SUBSPACE_BEACON, INDEX_SUBSPACE_BEACON_SPEED));

    w.writeValue(SPEC_PTS_INERTIAL_DAMPERS_SPEED,                               (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_INERTIAL_DAMPERS, INDEX_INERTIAL_DAMPERS_SPEED));

    w.writeValue(SPEC_PTS_IMPULS_ENGINE_FORCE,                                  (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_IMPULS_JET_ENGINE, INDEX_IMPULS_ENGINE_FORCE));
    w.writeValue(SPEC_PTS_IMPULS_ENGINE_CONSUMPTION,                            (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_IMPULS_JET_ENGINE, INDEX_IMPULS_ENGINE_CONSUMPTION));

    w.writeValue(SPEC_PTS_MECHANICAL_DAMPERS_ACCELERATION,                      (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_MECHANICAL_DAMPERS, INDEX_MECHANICAL_DAMPERS_ACCELERATION));

    w.writeValue(SPEC_PTS_DRONE_MISSILES_DAMAGE,                                (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_DRONE_MISSILES, INDEX_DRONE_MISSILES_DAMAGE));
    w.writeValue(SPEC_PTS_DRONE_MISSILES_PRECISION,                             (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_DRONE_MISSILES, INDEX_DRONE_MISSILES_PRECISION));
    w.writeValue(SPEC_PTS_DRONE_MISSILES_RANGE,                                 (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_DRONE_MISSILES, INDEX_DRONE_MISSILES_RANGE));

    w.writeValue(SPEC_PTS_DRONE_MISSILE_LAUNCHER_ACCUMULATOR,                   (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_DRONE_MISSILE_LAUNCHER, INDEX_DRONE_MISSILE_LAUNCHER_ACCUMULATOR));
    w.writeValue(SPEC_PTS_DRONE_MISSILE_LAUNCHER_CHARGING,                      (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_DRONE_MISSILE_LAUNCHER, INDEX_DRONE_MISSILE_LAUNCHER_CHARGING));

    w.writeValue(SPEC_PTS_SHIPS_LEVEL,                                          (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_SHIPS, INDEX_SHIPS_LEVEL));

    w.writeValue(SPEC_PTS_BASES_LEVEL,                                          (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_BASES, INDEX_BASES_LEVEL));

    w.writeValue(SPEC_PTS_HANGARS_LEVEL,                                        (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_HANGAR, INDEX_HANGARS_LEVEL));

    w.writeValue(SPEC_PTS_ANDROIDS_LEVEL,                                       (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_ANDROIDS, INDEX_ANDROIDS_LEVEL));
    w.writeValue(SPEC_PTS_ANDROIDS_CONSUMPTION,                                 (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_ANDROIDS, INDEX_ANDROIDS_CONSUMPTION));

    w.writeValue(SPEC_PTS_ENERGETIC_ACCUMULATOR_ACCUMULATOR,                    (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_ENERGETIC_ACCUMULATOR, INDEX_ENERGETIC_ACCUMULATOR_ACCUMULATOR));
    w.writeValue(SPEC_PTS_ENERGETIC_ACCUMULATOR_CHARGING,                       (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_ENERGETIC_ACCUMULATOR, INDEX_ENERGETIC_ACCUMULATOR_CHARGING));

    w.writeValue(SPEC_PTS_MAINFRAME_BIO_NODES,                                  (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_MAINFRAME, INDEX_MAINFRAME_BIO_NODES));
    w.writeValue(SPEC_PTS_MAINFRAME_PREDICTION,                                 (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_MAINFRAME, INDEX_MAINFRAME_PREDICTION));
    w.writeValue(SPEC_PTS_MAINFRAME_TIME_REUSABILITY,                           (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_MAINFRAME, INDEX_MAINFRAME_TIME_REUSABILITY));
    w.writeValue(SPEC_PTS_MAINFRAME_CONSUMPTION,                                (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_MAINFRAME, INDEX_MAINFRAME_CONSUMPTION));

    w.writeValue(SPEC_PTS_SCIENTIFIC_LABS_LEVEL,                                (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_SCIENTIFIC_LAB, INDEX_SCIENTIFIC_LABS_LEVEL));

    w.writeValue(SPEC_PTS_LIFE_SUPPORT_CAPACITY,                                (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_LIFE_SUPPORT, INDEX_LIFE_SUPPORT_CAPACITY));
    w.writeValue(SPEC_PTS_LIFE_SUPPORT_CONSUMPTION,                             (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_LIFE_SUPPORT, INDEX_LIFE_SUPPORT_CONSUMPTION));

    w.writeValue(SPEC_PTS_WEAPON_ENERGY_CIRCUIT_CHARGING,                       (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_WEAPON_ENERGY_CIRCUIT, INDEX_WEAPON_ENERGY_CIRCUIT_CHARGING));

    w.writeValue(SPEC_PTS_TRANSPORT_BEAM_GENERATOR_ACCUMULATOR,                 (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_TRANSPORT_BEAM_GENERATOR, INDEX_TRANSPORT_BEAM_GENERATOR_ACCUMULATOR));
    w.writeValue(SPEC_PTS_TRANSPORT_BEAM_GENERATOR_CHARGING,                    (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_TRANSPORT_BEAM_GENERATOR, INDEX_TRANSPORT_BEAM_GENERATOR_CHARGING));
    w.writeValue(SPEC_PTS_TRANSPORT_BEAM_GENERATOR_FORCIBILITY,                 (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_TRANSPORT_BEAM_GENERATOR, INDEX_TRANSPORT_BEAM_GENERATOR_FORCIBILITY));
    w.writeValue(SPEC_PTS_TRANSPORT_BEAM_GENERATOR_PRECISION,                   (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_TRANSPORT_BEAM_GENERATOR, INDEX_TRANSPORT_BEAM_GENERATOR_PRECISION));
    w.writeValue(SPEC_PTS_TRANSPORT_BEAM_GENERATOR_RANGE,                       (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_TRANSPORT_BEAM_GENERATOR, INDEX_TRANSPORT_BEAM_GENERATOR_RANGE));

    w.writeValue(SPEC_PTS_LASER_GUN_ACCUMULATOR,                                (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_LASER_GUN, INDEX_LASER_GUN_ACCUMULATOR));
    w.writeValue(SPEC_PTS_LASER_GUN_CHARGING,                                   (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_LASER_GUN, INDEX_LASER_GUN_CHARGING));
    w.writeValue(SPEC_PTS_LASER_GUN_FORCIBILITY,                                (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_LASER_GUN, INDEX_LASER_GUN_FORCIBILITY));
    w.writeValue(SPEC_PTS_LASER_GUN_PRECISION,                                  (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_LASER_GUN, INDEX_LASER_GUN_PRECISION));
    w.writeValue(SPEC_PTS_LASER_GUN_RANGE,                                      (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_LASER_GUN, INDEX_LASER_GUN_RANGE));

    w.writeValue(SPEC_PTS_DEFLECTOR_SHIELDS_GENERATOR_SOLIDITY,                 (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_DEFLECTOR_SHIELDS, INDEX_DEFLECTOR_SHIELDS_GENERATOR_SOLIDITY));
    w.writeValue(SPEC_PTS_DEFLECTOR_SHIELDS_GENERATOR_ACCUMULATOR,              (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_DEFLECTOR_SHIELDS, INDEX_DEFLECTOR_SHIELDS_GENERATOR_ACCUMULATOR));
    w.writeValue(SPEC_PTS_DEFLECTOR_SHIELDS_GENERATOR_CHARGING,                 (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_DEFLECTOR_SHIELDS, INDEX_DEFLECTOR_SHIELDS_GENERATOR_CHARGING));

    w.writeValue(SPEC_PTS_HIGH_RESOLUTION_SENSORS_LEVEL,                        (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_HIGH_RESOLUTION_SENSORS, INDEX_HIGH_RESOLUTION_SENSORS_LEVEL));
    w.writeValue(SPEC_PTS_HIGH_RESOLUTION_SENSORS_RANGE,                        (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_HIGH_RESOLUTION_SENSORS, INDEX_HIGH_RESOLUTION_SENSORS_RANGE));
    w.writeValue(SPEC_PTS_HIGH_RESOLUTION_SENSORS_CONSUMPTION,                  (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_HIGH_RESOLUTION_SENSORS, INDEX_HIGH_RESOLUTION_SENSORS_CONSUMPTION));

    w.writeValue(SPEC_PTS_LONG_RANGE_SENSORS_LEVEL,                             (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_LONG_RANGE_SENSORS, INDEX_LONG_RANGE_SENSORS_LEVEL));
    w.writeValue(SPEC_PTS_LONG_RANGE_SENSORS_RANGE,                             (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_LONG_RANGE_SENSORS, INDEX_LONG_RANGE_SENSORS_RANGE));
    w.writeValue(SPEC_PTS_LONG_RANGE_SENSORS_CONSUMPTION,                       (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_LONG_RANGE_SENSORS, INDEX_LONG_RANGE_SENSORS_CONSUMPTION));

    w.writeValue(SPEC_PTS_CLOAKING_DEVICE_LEVEL,                                (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_CLOAKING_DEVICE, INDEX_CLOAKING_DEVICE_LEVEL));
    w.writeValue(SPEC_PTS_CLOAKING_DEVICE_CONSUMPTION,                          (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_CLOAKING_DEVICE, INDEX_CLOAKING_DEVICE_CONSUMPTION));

    w.writeValue(SPEC_PTS_PROBE_DEVICE_LEVEL,                                   (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_PROBE, INDEX_PROBE_DEVICE_LEVEL));

    w.writeValue(SPEC_PTS_MAGNETICAL_FILTER_PRODUCTION,                         (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_MAGNETICAL_FILTER, INDEX_MAGNETICAL_FILTER_PRODUCTION));

    w.writeValue(SPEC_PTS_DEUTERIUM_DECOMPOSER_PRODUCTION,                      (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_DEUTERIUM_DECOMPOSER, INDEX_DEUTERIUM_DECOMPOSER_PRODUCTION));
    w.writeValue(SPEC_PTS_DEUTERIUM_DECOMPOSER_METAMORPHOSIS,                   (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_DEUTERIUM_DECOMPOSER, INDEX_DEUTERIUM_DECOMPOSER_METAMORPHOSIS));

    w.writeValue(SPEC_PTS_ZIRCONIUM_REACTOR_PRODUCTION,                         (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_ZIRCONIUM_REACTOR, INDEX_ZIRCONIUM_REACTOR_PRODUCTION));
    w.writeValue(SPEC_PTS_ZIRCONIUM_REACTOR_METAMORPHOSIS,                      (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_ZIRCONIUM_REACTOR, INDEX_ZIRCONIUM_REACTOR_METAMORPHOSIS));

    w.writeValue(SPEC_PTS_ILMENITE_FURNACE_PRODUCTION,                          (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_ILMENITE_FURNACE, INDEX_ILMENITE_FURNACE_PRODUCTION));
    w.writeValue(SPEC_PTS_ILMENITE_FURNACE_METAMORPHOSIS,                       (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_ILMENITE_FURNACE, INDEX_ILMENITE_FURNACE_METAMORPHOSIS));

    w.writeValue(SPEC_PTS_MAGNETICAL_COLLECTORS_OF_PLASMA_WINDING_SPEED,        (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_MAGNETICAL_COLLECTORS_OF_PLASMA, INDEX_MAGNETICAL_COLLECTORS_OF_PLASMA_WINDING_SPEED));

    w.writeValue(SPEC_PTS_SUBMERSIBLE_FILTRATION_TANK_WINDING_SPEED,            (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_SUBMERSIBLE_FILTRATION_TANK, INDEX_SUBMERSIBLE_FILTRATION_TANK_WINDING_SPEED));
    w.writeValue(SPEC_PTS_SUBMERSIBLE_FILTRATION_TANK_RANGE,                    (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_SUBMERSIBLE_FILTRATION_TANK, INDEX_SUBMERSIBLE_FILTRATION_TANK_RANGE));

    w.writeValue(SPEC_PTS_SUBMARINE_MINING_MACHINE_WINDING_SPEED,               (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_SUBMARINE_MINING_MACHINE, INDEX_SUBMARINE_MINING_MACHINE_WINDING_SPEED));
    w.writeValue(SPEC_PTS_SUBMARINE_MINING_MACHINE_RANGE,                       (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_SUBMARINE_MINING_MACHINE, INDEX_SUBMARINE_MINING_MACHINE_RANGE));
    
    w.writeValue(SPEC_PTS_UNDERGROUND_DRILLING_MACHINE_WINDING_SPEED,           (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_UNDERGROUND_DRILLING_MACHINE, INDEX_UNDERGROUND_DRILLING_MACHINE_WINDING_SPEED));
    w.writeValue(SPEC_PTS_UNDERGROUND_DRILLING_MACHINE_RANGE,                   (unsigned long long)sc->getSpecLeafTokens(SCIENCE_ENTITY_UNDERGROUND_DRILLING_MACHINE, INDEX_UNDERGROUND_DRILLING_MACHINE_RANGE));

    w.writeValue(SCLEVEL_QUARK_GLUON_CORE_SPEED,                               sc->getRealScienceLevel(SCIENCE_ENTITY_QUARK_GLUON_CORE, INDEX_QUARK_GLUON_CORE_SPEED));
    w.writeValue(SCLEVEL_QUARK_GLUON_CORE_CONSUMPTION,                         sc->getRealScienceLevel(SCIENCE_ENTITY_QUARK_GLUON_CORE, INDEX_QUARK_GLUON_CORE_CONSUMPTION));

    w.writeValue(SCLEVEL_NAVIGATION_COMPUTER_SPEED,                            sc->getRealScienceLevel(SCIENCE_ENTITY_NAVIGATION_COMPUTER, INDEX_NAVIGATION_COMPUTER_SPEED));

    w.writeValue(SCLEVEL_SUBSPACE_BEACON_SPEED,                                sc->getRealScienceLevel(SCIENCE_ENTITY_SUBSPACE_BEACON, INDEX_SUBSPACE_BEACON_SPEED));

    w.writeValue(SCLEVEL_INERTIAL_DAMPERS_SPEED,                               sc->getRealScienceLevel(SCIENCE_ENTITY_INERTIAL_DAMPERS, INDEX_INERTIAL_DAMPERS_SPEED));

    w.writeValue(SCLEVEL_IMPULS_ENGINE_FORCE,                                  sc->getRealScienceLevel(SCIENCE_ENTITY_IMPULS_JET_ENGINE, INDEX_IMPULS_ENGINE_FORCE));
    w.writeValue(SCLEVEL_IMPULS_ENGINE_CONSUMPTION,                            sc->getRealScienceLevel(SCIENCE_ENTITY_IMPULS_JET_ENGINE, INDEX_IMPULS_ENGINE_CONSUMPTION));

    w.writeValue(SCLEVEL_MECHANICAL_DAMPERS_ACCELERATION,                      sc->getRealScienceLevel(SCIENCE_ENTITY_MECHANICAL_DAMPERS, INDEX_MECHANICAL_DAMPERS_ACCELERATION));

    w.writeValue(SCLEVEL_DRONE_MISSILES_DAMAGE,                                sc->getRealScienceLevel(SCIENCE_ENTITY_DRONE_MISSILES, INDEX_DRONE_MISSILES_DAMAGE));
    w.writeValue(SCLEVEL_DRONE_MISSILES_PRECISION,                             sc->getRealScienceLevel(SCIENCE_ENTITY_DRONE_MISSILES, INDEX_DRONE_MISSILES_PRECISION));
    w.writeValue(SCLEVEL_DRONE_MISSILES_RANGE,                                 sc->getRealScienceLevel(SCIENCE_ENTITY_DRONE_MISSILES, INDEX_DRONE_MISSILES_RANGE));

    w.writeValue(SCLEVEL_DRONE_MISSILE_LAUNCHER_ACCUMULATOR,                   sc->getRealScienceLevel(SCIENCE_ENTITY_DRONE_MISSILE_LAUNCHER, INDEX_DRONE_MISSILE_LAUNCHER_ACCUMULATOR));
    w.writeValue(SCLEVEL_DRONE_MISSILE_LAUNCHER_CHARGING,                      sc->getRealScienceLevel(SCIENCE_ENTITY_DRONE_MISSILE_LAUNCHER, INDEX_DRONE_MISSILE_LAUNCHER_CHARGING));

    w.writeValue(SCLEVEL_SHIPS_LEVEL,                                          sc->getRealScienceLevel(SCIENCE_ENTITY_SHIPS, INDEX_SHIPS_LEVEL));

    w.writeValue(SCLEVEL_BASES_LEVEL,                                          sc->getRealScienceLevel(SCIENCE_ENTITY_BASES, INDEX_BASES_LEVEL));

    w.writeValue(SCLEVEL_HANGARS_LEVEL,                                        sc->getRealScienceLevel(SCIENCE_ENTITY_HANGAR, INDEX_HANGARS_LEVEL));

    w.writeValue(SCLEVEL_ANDROIDS_LEVEL,                                       sc->getRealScienceLevel(SCIENCE_ENTITY_ANDROIDS, INDEX_ANDROIDS_LEVEL));
    w.writeValue(SCLEVEL_ANDROIDS_CONSUMPTION,                                 sc->getRealScienceLevel(SCIENCE_ENTITY_ANDROIDS, INDEX_ANDROIDS_CONSUMPTION));

    w.writeValue(SCLEVEL_ENERGETIC_ACCUMULATOR_ACCUMULATOR,                    sc->getRealScienceLevel(SCIENCE_ENTITY_ENERGETIC_ACCUMULATOR, INDEX_ENERGETIC_ACCUMULATOR_ACCUMULATOR));
    w.writeValue(SCLEVEL_ENERGETIC_ACCUMULATOR_CHARGING,                       sc->getRealScienceLevel(SCIENCE_ENTITY_ENERGETIC_ACCUMULATOR, INDEX_ENERGETIC_ACCUMULATOR_CHARGING));

    w.writeValue(SCLEVEL_MAINFRAME_BIO_NODES,                                  sc->getRealScienceLevel(SCIENCE_ENTITY_MAINFRAME, INDEX_MAINFRAME_BIO_NODES));
    w.writeValue(SCLEVEL_MAINFRAME_PREDICTION,                                 sc->getRealScienceLevel(SCIENCE_ENTITY_MAINFRAME, INDEX_MAINFRAME_PREDICTION));
    w.writeValue(SCLEVEL_MAINFRAME_TIME_REUSABILITY,                           sc->getRealScienceLevel(SCIENCE_ENTITY_MAINFRAME, INDEX_MAINFRAME_TIME_REUSABILITY));
    w.writeValue(SCLEVEL_MAINFRAME_CONSUMPTION,                                sc->getRealScienceLevel(SCIENCE_ENTITY_MAINFRAME, INDEX_MAINFRAME_CONSUMPTION));

    w.writeValue(SCLEVEL_SCIENTIFIC_LABS_LEVEL,                                sc->getRealScienceLevel(SCIENCE_ENTITY_SCIENTIFIC_LAB, INDEX_SCIENTIFIC_LABS_LEVEL));

    w.writeValue(SCLEVEL_LIFE_SUPPORT_CAPACITY,                                sc->getRealScienceLevel(SCIENCE_ENTITY_LIFE_SUPPORT, INDEX_LIFE_SUPPORT_CAPACITY));
    w.writeValue(SCLEVEL_LIFE_SUPPORT_CONSUMPTION,                             sc->getRealScienceLevel(SCIENCE_ENTITY_LIFE_SUPPORT, INDEX_LIFE_SUPPORT_CONSUMPTION));

    w.writeValue(SCLEVEL_WEAPON_ENERGY_CIRCUIT_CHARGING,                       sc->getRealScienceLevel(SCIENCE_ENTITY_WEAPON_ENERGY_CIRCUIT, INDEX_WEAPON_ENERGY_CIRCUIT_CHARGING));

    w.writeValue(SCLEVEL_TRANSPORT_BEAM_GENERATOR_ACCUMULATOR,                 sc->getRealScienceLevel(SCIENCE_ENTITY_TRANSPORT_BEAM_GENERATOR, INDEX_TRANSPORT_BEAM_GENERATOR_ACCUMULATOR));
    w.writeValue(SCLEVEL_TRANSPORT_BEAM_GENERATOR_CHARGING,                    sc->getRealScienceLevel(SCIENCE_ENTITY_TRANSPORT_BEAM_GENERATOR, INDEX_TRANSPORT_BEAM_GENERATOR_CHARGING));
    w.writeValue(SCLEVEL_TRANSPORT_BEAM_GENERATOR_FORCIBILITY,                 sc->getRealScienceLevel(SCIENCE_ENTITY_TRANSPORT_BEAM_GENERATOR, INDEX_TRANSPORT_BEAM_GENERATOR_FORCIBILITY));
    w.writeValue(SCLEVEL_TRANSPORT_BEAM_GENERATOR_PRECISION,                   sc->getRealScienceLevel(SCIENCE_ENTITY_TRANSPORT_BEAM_GENERATOR, INDEX_TRANSPORT_BEAM_GENERATOR_PRECISION));
    w.writeValue(SCLEVEL_TRANSPORT_BEAM_GENERATOR_RANGE,                       sc->getRealScienceLevel(SCIENCE_ENTITY_TRANSPORT_BEAM_GENERATOR, INDEX_TRANSPORT_BEAM_GENERATOR_RANGE));

    w.writeValue(SCLEVEL_LASER_GUN_ACCUMULATOR,                                sc->getRealScienceLevel(SCIENCE_ENTITY_LASER_GUN, INDEX_LASER_GUN_ACCUMULATOR));
    w.writeValue(SCLEVEL_LASER_GUN_CHARGING,                                   sc->getRealScienceLevel(SCIENCE_ENTITY_LASER_GUN, INDEX_LASER_GUN_CHARGING));
    w.writeValue(SCLEVEL_LASER_GUN_FORCIBILITY,                                sc->getRealScienceLevel(SCIENCE_ENTITY_LASER_GUN, INDEX_LASER_GUN_FORCIBILITY));
    w.writeValue(SCLEVEL_LASER_GUN_PRECISION,                                  sc->getRealScienceLevel(SCIENCE_ENTITY_LASER_GUN, INDEX_LASER_GUN_PRECISION));
    w.writeValue(SCLEVEL_LASER_GUN_RANGE,                                      sc->getRealScienceLevel(SCIENCE_ENTITY_LASER_GUN, INDEX_LASER_GUN_RANGE));

    w.writeValue(SCLEVEL_DEFLECTOR_SHIELDS_GENERATOR_SOLIDITY,                 sc->getRealScienceLevel(SCIENCE_ENTITY_DEFLECTOR_SHIELDS, INDEX_DEFLECTOR_SHIELDS_GENERATOR_SOLIDITY));
    w.writeValue(SCLEVEL_DEFLECTOR_SHIELDS_GENERATOR_ACCUMULATOR,              sc->getRealScienceLevel(SCIENCE_ENTITY_DEFLECTOR_SHIELDS, INDEX_DEFLECTOR_SHIELDS_GENERATOR_ACCUMULATOR));
    w.writeValue(SCLEVEL_DEFLECTOR_SHIELDS_GENERATOR_CHARGING,                 sc->getRealScienceLevel(SCIENCE_ENTITY_DEFLECTOR_SHIELDS, INDEX_DEFLECTOR_SHIELDS_GENERATOR_CHARGING));

    w.writeValue(SCLEVEL_HIGH_RESOLUTION_SENSORS_LEVEL,                        sc->getRealScienceLevel(SCIENCE_ENTITY_HIGH_RESOLUTION_SENSORS, INDEX_HIGH_RESOLUTION_SENSORS_LEVEL));
    w.writeValue(SCLEVEL_HIGH_RESOLUTION_SENSORS_RANGE,                        sc->getRealScienceLevel(SCIENCE_ENTITY_HIGH_RESOLUTION_SENSORS, INDEX_HIGH_RESOLUTION_SENSORS_RANGE));
    w.writeValue(SCLEVEL_HIGH_RESOLUTION_SENSORS_CONSUMPTION,                  sc->getRealScienceLevel(SCIENCE_ENTITY_HIGH_RESOLUTION_SENSORS, INDEX_HIGH_RESOLUTION_SENSORS_CONSUMPTION));

    w.writeValue(SCLEVEL_LONG_RANGE_SENSORS_LEVEL,                             sc->getRealScienceLevel(SCIENCE_ENTITY_LONG_RANGE_SENSORS, INDEX_LONG_RANGE_SENSORS_LEVEL));
    w.writeValue(SCLEVEL_LONG_RANGE_SENSORS_RANGE,                             sc->getRealScienceLevel(SCIENCE_ENTITY_LONG_RANGE_SENSORS, INDEX_LONG_RANGE_SENSORS_RANGE));
    w.writeValue(SCLEVEL_LONG_RANGE_SENSORS_CONSUMPTION,                       sc->getRealScienceLevel(SCIENCE_ENTITY_LONG_RANGE_SENSORS, INDEX_LONG_RANGE_SENSORS_CONSUMPTION));

    w.writeValue(SCLEVEL_CLOAKING_DEVICE_LEVEL,                                sc->getRealScienceLevel(SCIENCE_ENTITY_CLOAKING_DEVICE, INDEX_CLOAKING_DEVICE_LEVEL));
    w.writeValue(SCLEVEL_CLOAKING_DEVICE_CONSUMPTION,                          sc->getRealScienceLevel(SCIENCE_ENTITY_CLOAKING_DEVICE, INDEX_CLOAKING_DEVICE_CONSUMPTION));

    w.writeValue(SCLEVEL_PROBE_DEVICE_LEVEL,                                   sc->getRealScienceLevel(SCIENCE_ENTITY_PROBE, INDEX_PROBE_DEVICE_LEVEL));

    w.writeValue(SCLEVEL_MAGNETICAL_FILTER_PRODUCTION,                         sc->getRealScienceLevel(SCIENCE_ENTITY_MAGNETICAL_FILTER, INDEX_MAGNETICAL_FILTER_PRODUCTION));

    w.writeValue(SCLEVEL_DEUTERIUM_DECOMPOSER_PRODUCTION,                      sc->getRealScienceLevel(SCIENCE_ENTITY_DEUTERIUM_DECOMPOSER, INDEX_DEUTERIUM_DECOMPOSER_PRODUCTION));
    w.writeValue(SCLEVEL_DEUTERIUM_DECOMPOSER_METAMORPHOSIS,                   sc->getRealScienceLevel(SCIENCE_ENTITY_DEUTERIUM_DECOMPOSER, INDEX_DEUTERIUM_DECOMPOSER_METAMORPHOSIS));

    w.writeValue(SCLEVEL_ZIRCONIUM_REACTOR_PRODUCTION,                         sc->getRealScienceLevel(SCIENCE_ENTITY_ZIRCONIUM_REACTOR, INDEX_ZIRCONIUM_REACTOR_PRODUCTION));
    w.writeValue(SCLEVEL_ZIRCONIUM_REACTOR_METAMORPHOSIS,                      sc->getRealScienceLevel(SCIENCE_ENTITY_ZIRCONIUM_REACTOR, INDEX_ZIRCONIUM_REACTOR_METAMORPHOSIS));

    w.writeValue(SCLEVEL_ILMENITE_FURNACE_PRODUCTION,                          sc->getRealScienceLevel(SCIENCE_ENTITY_ILMENITE_FURNACE, INDEX_ILMENITE_FURNACE_PRODUCTION));
    w.writeValue(SCLEVEL_ILMENITE_FURNACE_METAMORPHOSIS,                       sc->getRealScienceLevel(SCIENCE_ENTITY_ILMENITE_FURNACE, INDEX_ILMENITE_FURNACE_METAMORPHOSIS));

    w.writeValue(SCLEVEL_MAGNETICAL_COLLECTORS_OF_PLASMA_WINDING_SPEED,        sc->getRealScienceLevel(SCIENCE_ENTITY_MAGNETICAL_COLLECTORS_OF_PLASMA, INDEX_MAGNETICAL_COLLECTORS_OF_PLASMA_WINDING_SPEED));

    w.writeValue(SCLEVEL_SUBMERSIBLE_FILTRATION_TANK_WINDING_SPEED,            sc->getRealScienceLevel(SCIENCE_ENTITY_SUBMERSIBLE_FILTRATION_TANK, INDEX_SUBMERSIBLE_FILTRATION_TANK_WINDING_SPEED));
    w.writeValue(SCLEVEL_SUBMERSIBLE_FILTRATION_TANK_RANGE,                    sc->getRealScienceLevel(SCIENCE_ENTITY_SUBMERSIBLE_FILTRATION_TANK, INDEX_SUBMERSIBLE_FILTRATION_TANK_RANGE));

    w.writeValue(SCLEVEL_SUBMARINE_MINING_MACHINE_WINDING_SPEED,               sc->getRealScienceLevel(SCIENCE_ENTITY_SUBMARINE_MINING_MACHINE, INDEX_SUBMARINE_MINING_MACHINE_WINDING_SPEED));
    w.writeValue(SCLEVEL_SUBMARINE_MINING_MACHINE_RANGE,                       sc->getRealScienceLevel(SCIENCE_ENTITY_SUBMARINE_MINING_MACHINE, INDEX_SUBMARINE_MINING_MACHINE_RANGE));
    
    w.writeValue(SCLEVEL_UNDERGROUND_DRILLING_MACHINE_WINDING_SPEED,           sc->getRealScienceLevel(SCIENCE_ENTITY_UNDERGROUND_DRILLING_MACHINE, INDEX_UNDERGROUND_DRILLING_MACHINE_WINDING_SPEED));
    w.writeValue(SCLEVEL_UNDERGROUND_DRILLING_MACHINE_RANGE,                   sc->getRealScienceLevel(SCIENCE_ENTITY_UNDERGROUND_DRILLING_MACHINE, INDEX_UNDERGROUND_DRILLING_MACHINE_RANGE));

    w.writeValue(REQUEST_MAX_SCIENCE_PTS,                                      (unsigned long long)sc->totalTokens());
}

// --------------------------------

char* answerWriter :: science(scientificTree* scTree)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SCIENCE);
    write_scientific_tree(w, scTree);
    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: science_change(scientificTree* scTree)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SCIENCE_CHANGE);
    write_scientific_tree(w, scTree);
    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: science_ie(void)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SCIENCE);
    w.writeValue(REQUEST_SCIENCE_ANSWER_FAIL_REASON, REQUEST_SCIENCE_ANSWER_IE);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------
char* answerWriter :: science_change_ie(void)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SCIENCE_CHANGE);
    w.writeValue(REQUEST_SCIENCE_ANSWER_FAIL_REASON, REQUEST_SCIENCE_ANSWER_IE);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_central_information(fortressClass* shp)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIP_CENTRAL_INFORMATION);
    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_SHIPID, shp->getID());

    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_SINTEGRITY_ACT,         shp->actualStructuralIntegrity());
    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_SINTEGRITY_MAX,         shp->totalStructuralIntegrity());
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_SINTEGRITY_GRADIENT,    shp->actualStructuralIntegrityGradient());
    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_MAN,                    shp->getManoeuvrability());
    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_WIDTH,                  shp->getWidth());
    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_LENGTH,                 shp->getLength());
    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_HEIGHT,                 shp->getHeight());
    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_WEIGHT,                 shp->getWeight());

    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_ACT_QGPLAZMA,           shp->quarkGluonPlasmaInMg(true));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_GRAD_QGPLAZMA,          shp->quarkGluonPlasmaGradient());
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_FREE_CAPACITY_QGPLAZMA, shp->freeSpaceForQuarkGluonPlasmaInMiligrams(0, 1));
	// Quark gluonova plasma nema objem

    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_ACT_ULREA,              shp->ulreiCount(true));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_GRAD_ULREA,             shp->ulreaGradient());
	// Ulrea nema objem, ma nekonecnou volnou kapacitu

    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_ACT_HWATER,             shp->heavyWaterInKg(true));
    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_FREE_CAPACITY_HWATER,   shp->freeSpaceForHeavyWaterInKilograms(0, 0, 1));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_GRAD_HWATER,            shp->heavyWaterGradient());
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_SIZE_HWATER,            shp->heavyWaterSize(true));

    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_ACT_DEUT,               shp->deuteriumInKg(true));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_FREE_CAPACITY_DEUT,     shp->freeSpaceForDeuteriumInKilograms(0, 0, 1));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_GRAD_DEUT,              shp->deuteriumGradient());
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_SIZE_DEUT,              shp->deuteriumSize(true));

	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_ACT_ZCRYSTAL,           shp->zirconiumCrystalInKg(true));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_FREE_CAPACITY_ZCRYSTAL, shp->freeSpaceForZirconiumCrystalsInKilograms(0, 0, 1));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_GRAD_ZCRYSTAL,          shp->zirconiumCrystalGradient());
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_SIZE_ZCRYSTAL,          shp->zirconiumCrystalSize(true));

    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_ACT_ENERGY,			 shp->energyInTJ(true));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_FREE_CAPACITY_ENERGY,   shp->freeSpaceForEnergyInTeraJoules(0, 1));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_GRAD_ENERGY,			 shp->energyGradient());
	// Energie nema objem

	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_ACT_ILMENITE,           shp->ilmeniteInKg(true));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_FREE_CAPACITY_ILMENITE, shp->freeSpaceForIlmeniteInKilograms(0, 0, 1));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_GRAD_ILMENITE,          shp->ilmeniteGradient());
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_SIZE_ILMENITE,          shp->ilmeniteSize(true));

	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_ACT_TITANIUM,           shp->titaniumInKg(true));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_FREE_CAPACITY_TITANIUM, shp->freeSpaceForTitaniumInKilograms(0, 0, 1));
    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_GRAD_TITANIUM,          shp->titaniumGradient());
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_SIZE_TITANIUM,          shp->titaniumSize(true));

	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_WEIGHT_WITH_CARGO,          shp->fortressTotalWeightWithPayload(0, 1));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_LOADING_WEIGHT_LIMIT,       shp->loadingWeightLimit());
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_LOADING_CAPACITY_LIMIT,     shp->loadingCapacityLimit());
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_ACTUAL_TOTAL_CARGO_WEIGHT,  shp->actualTotalCargoWeight(0, 0, 1));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_FREE_WEIGHT,                shp->freeWeight(0, 0, 1));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_CARGO_SIZE,                 shp->actualSizeOfCargoInWarehouse());
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_FREE_CAPACITY,              shp->freeCapacity());

	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_FREE_RES_WEIGHT, shp->freeWeight(1, 1, 0));
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_FREE_RES_CAPACITY, shp->commonRawMaterialCapacityLimit());
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_HEAVY_WATER_DENSITY, (unsigned long) HEAVY_WATER_DENSITY);
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_DEUTERIUM_DENSITY, (unsigned long) DEUTERIUM_DENSITY);
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_ZIRCONIUM_CRYSTAL_DENSITY, (unsigned long) ZIRCONIUM_CRYSTAL_DENSITY);
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_ILMENITE_DENSITY, (unsigned long) ILMENITE_DENSITY);
	w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_TITANIUM_DENSITY, (unsigned long) TITANIUM_DENSITY);

	shp->stopReadingForClient();

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_central_information_FAIL(const unsigned long shipid, const std :: string& reason)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIP_CENTRAL_INFORMATION);
    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_ANSWER_FAIL, reason);
    w.writeValue(REQUEST_SHIP_CENTRAL_INFORMATION_SHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_shields_information(fortressClass* shp)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_SHIELDS_INFORMATION);
    w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_FORTRESSID , shp->getID());

    w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_ANSWER_ENERGY         , shp->deflectorShields.getEnergy(shp));
    w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_ANSWER_ACCUMULATOR    , shp->deflectorShields.deflectorShieldsGenerator()->actualAccumulator());
    w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_ANSWER_SOLIDITY       , shp->deflectorShields.deflectorShieldsGenerator()->actualSolidity());
    w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_ANSWER_CHARGING       , shp->deflectorShields.deflectorShieldsGenerator()->actualCharging());
    w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_ANSWER_LEAK           , shp->deflectorShields.deflectorShieldsGenerator()->actualLeak());
    w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_ANSWER_TARGET_ENERGY  , shp->deflectorShields.deflectorShieldsEnergyState.targetEnergy);
    w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_ANSWER_CONSUMPTION    , shp->deflectorShields.getActualEnergyConsumption());
    w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_ANSWER_STATUS         , shp->deflectorShields.deflectorShieldsGenerator()->getStatus());
	w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_ANSWER_AVAILABLE      , shp->deflectorShields.avalDeflectorShieldsGenerator());
	w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_ANSWER_GRADIENT       ,  shp->deflectorShields.getGradient());

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_shields_information_FAIL(const unsigned long fortressid, const std :: string& reason)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_SHIELDS_INFORMATION);
    w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_ANSWER_FAIL, reason);
    w.writeValue(REQUEST_FORTRESS_SHIELDS_INFORMATION_FORTRESSID, fortressid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ships(const std :: list<shipClass*>& ships)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIPS);

    w.writeValue(REQUEST_SHIPS_ANSWER_COUNT, (unsigned long)ships.size());

    int i = 1;
    for (std :: list<shipClass*> :: const_iterator iter = ships.begin();
        iter != ships.end(); iter++)
    {
        std :: stringstream ssID;
        std :: stringstream ssNAME;
        std :: stringstream ssCLASS;

        ssID << REQUEST_SHIPS_ANSWER_SHIPID << i;
        w.writeValue(ssID.str(), (*iter)->getID());

        ssNAME << REQUEST_SHIPS_ANSWER_SHIPNAME << i;
        w.writeValue(ssNAME.str(), (*iter)->getFortressName());

        ssCLASS << REQUEST_SHIPS_ANSWER_SHIPCLASS << i;
        w.writeValue(ssCLASS.str(), (*iter)->getFortressClassID());

        i++;
    }

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: bases(const std :: list<baseClass*>& bases)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_BASES);

    w.writeValue(REQUEST_BASES_ANSWER_COUNT, (unsigned long)bases.size());

    int i = 1;
    for (std :: list<baseClass*> :: const_iterator iter = bases.begin();
        iter != bases.end(); iter++)
    {
        std :: stringstream ssID;
        std :: stringstream ssNAME;
        std :: stringstream ssCLASS;

        ssID << REQUEST_BASES_ANSWER_BASEID << i;
        w.writeValue(ssID.str(), (*iter)->getID());

        ssNAME << REQUEST_BASES_ANSWER_BASENAME << i;
        w.writeValue(ssNAME.str(), (*iter)->getFortressName());

        ssCLASS << REQUEST_BASES_ANSWER_BASECLASS << i;
        w.writeValue(ssCLASS.str(), (*iter)->getFortressClassID());

        spaceFortressObject* fobj   = actx->cacheSpaceObjectList.getItem<spaceFortressObject>((*iter)->getFortressSpaceObjectHolderId());
        if (fobj != NULL)
        {
            spacePlanetObject*   pl     = actx->cacheSpaceObjectList.getItem<spacePlanetObject>(fobj->getParentSpaceObject());
            if (pl != NULL)
            {
                std :: stringstream ssTEXTURE;
                ssTEXTURE << REQUEST_BASES_ANSWER_BASETEXTURE << i;
                w.writeValue(ssTEXTURE.str(), pl->getTexture());
            }
            else
            {
                errLogicalError("Cannot find planet %u for base %u !",
                    (unsigned long long)fobj->getParentSpaceObject(),
                    (unsigned long long)(*iter)->getID());
            }
        }
        else
        {
            errLogicalError("Cannot find space object holder %u for base %u !",
                (unsigned long long)(*iter)->getFortressSpaceObjectHolderId(),
                (unsigned long long)(*iter)->getID());
        }

        i++;
    }

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_subspace_drive_information(const unsigned long shipid, const subspace_drive_status& sds)
{
	protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION);

		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_SHIPID, shipid );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_NAVIGATION_COMPUTER_MAX_SPEED, sds.navigation_computer_max_speed );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_NAVIGATION_COMPUTER_STATUS, sds.navigation_computer_status );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_NAVIGATION_COMPUTER_AVAILABLE, sds.navigation_computer_available );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_INTERTIAL_DAMPERS_MAX_SPEED, sds.inertial_dampers_max_speed );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_INTERTIAL_DAMPERS_STATUS, sds.inertial_dampers_status );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_INTERTIAL_DAMPERS_AVAILABLE, sds.inertial_dampers_available );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_SUBSPACE_BEACON_MAX_SPEED, sds.subspace_beacon_max_speed );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_SUBSPACE_BEACON_STATUS, sds.subspace_beacon_status );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_SUBSPACE_BEACON_AVAILABLE, sds.subspace_beacon_available );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_QUARK_GLUON_CORE_MAX_SPEED, sds.quark_gluon_core_max_speed );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_QUARK_GLUON_CORE_CONSUMPTION, sds.quark_gluon_core_consumption );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_QUARK_GLUON_CORE_STATUS, sds.quark_gluon_core_status );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_QUARK_GLUON_CORE_AVAILABLE, sds.quark_gluon_core_available );

		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_CONSUMPTION, sds.actualConsumption );
		w.writeValue( REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_SPEED_TOC, sds.actualSpeedToC );

	w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_subspace_drive_information_FAIL(const unsigned long shipid, const std :: string& reason)
{
	protocolWriter w;

		w.beginMessage(MT_ANSWER, REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION);
		w.writeValue(REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_ANSWER_FAIL, reason);
		w.writeValue(REQUEST_SHIP_SUBSPACE_DRIVE_INFORMATION_SHIPID, shipid);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_impulse_drive_information(const unsigned long shipid, const impulse_drive_status& sds)
{
	protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION);

		w.writeValue( REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION_SHIPID, shipid );
		w.writeValue( REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION_ANSWER_ACTUAL_JET_FORCE, sds.actualJetForce );
		w.writeValue( REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION_ANSWER_ACTUAL_CONSUMPTION, sds.actualConsumption );
		w.writeValue( REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION_ANSWER_MECHANICAL_DAMPERS_MAX_ACCELERATION, sds.mechanical_dampers_max_acceleration );
		w.writeValue( REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION_ANSWER_MECHANICAL_DAMPERS_STATUS, sds.mechanical_dampers_status );
		w.writeValue( REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION_ANSWER_MECHANICAL_DAMPERS_AVAILABLE, sds.mechanical_dampers_available );
		w.writeValue( REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION_ANSWER_IMPULSE_JET_ENGINE_ACTUAL_FORCE, sds.impulse_jet_engine_actual_force );
		w.writeValue( REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION_ANSWER_IMPULSE_JET_ENGINE_ACTUAL_CONSUMPTION, sds.impulse_jet_engine_actual_consumption );
		w.writeValue( REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION_ANSWER_IMPULSE_JET_ENGINE_STATUS, sds.impulse_jet_engine_status );
		w.writeValue( REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION_ANSWER_IMPULSE_JET_ENGINE_AVAILABLE, sds.impulse_jet_engine_available );
		

	w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_impulse_drive_information_FAIL(const unsigned long shipid, const std :: string& reason)
{
	protocolWriter w;

		w.beginMessage(MT_ANSWER, REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION);
		w.writeValue(REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION_ANSWER_FAIL, reason);
		w.writeValue(REQUEST_SHIP_IMPULSE_DRIVE_INFORMATION_SHIPID, shipid);

    w.endMessage(false);
    return w.copyMessage();

}

// --------------------------------

static void write_laser_gun(protocolWriter& w, int index, const laser_gun_status & laser_gun)
{
    std :: stringstream ss;

	ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_LASER_GUN_ENERGY << index;
    w.writeValue(ss.str(), laser_gun.energy);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_LASER_GUN_TARGET_ENERGY << index;
	w.writeValue(ss.str(), laser_gun.targetEnergy);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_LASER_GUN_ACTUAL_ACCUMULATOR << index;
	w.writeValue(ss.str(), laser_gun.actualAccumulator);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_LASER_GUN_ACTUAL_RANGE << index;
	w.writeValue(ss.str(), laser_gun.actualRange);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_LASER_GUN_ACTUAL_PRECISION << index;
	w.writeValue(ss.str(), laser_gun.actualPrecision);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_LASER_GUN_ACTUAL_FORCIBILITY << index;
	w.writeValue(ss.str(), laser_gun.actualForcibility);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_LASER_GUN_STATUS << index;
	w.writeValue(ss.str(), laser_gun.status);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_LASER_GUN_INDEX << index;
	w.writeValue(ss.str(), laser_gun.index);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_LASER_GUN_ID << index;
	w.writeValue(ss.str(), laser_gun.id);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_LASER_GUN_GRADIENT << index;
	w.writeValue(ss.str(), laser_gun.gradient);
    ss.str("");
}

// --------------------------------

static void write_drone_missile_launcher(protocolWriter& w, int index, const drone_missile_launcher_status & drone_missile_launcher)
{
    std :: stringstream ss;

	ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_DRONE_LAUNCHER_ENERGY << index;
    w.writeValue(ss.str(), drone_missile_launcher.energy);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_DRONE_LAUNCHER_TARGET_ENERGY << index;
	w.writeValue(ss.str(), drone_missile_launcher.targetEnergy);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_DRONE_LAUNCHER_ACTUAL_ACCUMULATOR << index;
	w.writeValue(ss.str(), drone_missile_launcher.actualAccumulator);
    ss.str("");

	ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_DRONE_LAUNCHER_STATUS << index;
	w.writeValue(ss.str(), drone_missile_launcher.status);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_DRONE_LAUNCHER_INDEX << index;
	w.writeValue(ss.str(), drone_missile_launcher.index);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_DRONE_LAUNCHER_ID << index;
	w.writeValue(ss.str(), drone_missile_launcher.id);
    ss.str("");

    ss << REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_DRONE_LAUNCHER_GRADIENT << index;
	w.writeValue(ss.str(), drone_missile_launcher.gradient);
    ss.str("");
}

// --------------------------------

char* answerWriter :: fortress_weapons_information(const unsigned long fortressid, const weapons_status& sds)
{
    protocolWriter w;
		w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_WEAPONS_INFORMATION);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_FORTRESSID, fortressid);

		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_ENERGY_CIRTUIT_CHARGING, sds.weapon_energy_circuit_charging);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_ENERGY_CIRTUIT_CLIENT_CHARGING, sds.weapon_energy_circuit_client_charging);
		
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_ENERGY_CIRCUIT_STATUS, sds.weapon_energy_circuit_status);

		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_DISTANCE_TO_THE_WEAPONS_TARGET, sds.weapon_distance_to_the_weapons_target);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_TOTAL_CHARGING, sds.weapon_total_charging);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_ACTUAL_ENERGY_CONSUMPTION, sds.weapon_actual_energy_consumption);

		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_DRONE_MISSILES_ACTUAL_LAUNCH, sds.drone_missiles_actual_launch);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_DRONE_MISSILES_ACTUAL_RANGE, sds.drone_missiles_actual_range);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_DRONE_MISSILES_ACTUAL_PRECISION, sds.drone_missiles_actual_precision);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_DRONE_MISSILES_ACTUAL_DAMAGE, sds.drone_missiles_actual_damage);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_DRONE_MISSILES_COUNT, sds.drone_missiles_count);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_DRONE_MISSILES_WORKING, sds.drone_missiles_working);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_WEAPON_DRONE_MISSILES_DAMAGED, sds.drone_missiles_damaged);

		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_LASER_GUN_COUNT, (unsigned long) sds.laser_guns.size());
		
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_AVAL_WEAPON_ENERGY_CIRCUIT, sds.avalWeaponEnergyCircuit);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_AVAL_LASER_GUNS, sds.avalLaserGuns);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_AVAL_DRONE_MISSILE_LAUNCHERS, sds.avalDroneMissileLaunchers);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_AVAL_DRONE_MISSILES, sds.avalDroneMissiles);

		int index = 1;
		for (std::list<laser_gun_status>::const_iterator it = sds.laser_guns.begin(); it != sds.laser_guns.end(); ++it) {
			write_laser_gun(w, index, (*it));
			index++;
		}

		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_DRONE_LAUNCHER_COUNT, (unsigned long) sds.drone_missile_launchers.size());

		index = 1;
		for (std::list<drone_missile_launcher_status>::const_iterator it = sds.drone_missile_launchers.begin(); it != sds.drone_missile_launchers.end(); ++it) {
			write_drone_missile_launcher(w, index, (*it));
			index++;
		}

		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_MAX_LASER_GUNS, sds.max_laser_guns);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_MAX_DRONE_MISSILE_LAUNCHERS, sds.max_drone_missile_launchers);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_weapons_information_FAIL(const unsigned long fortressid, const std :: string& reason)
{
	protocolWriter w;

		w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_WEAPONS_INFORMATION);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_ANSWER_FAIL, reason);
		w.writeValue(REQUEST_FORTRESS_WEAPONS_INFORMATION_FORTRESSID, fortressid);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

#define DT_BUFSIZE 64
char* answerWriter :: chat(unsigned long sender, unsigned long recipient, 
                  const std :: string& message, dv_time:: datetime dt)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_CHAT);
    w.writeValue(REQUEST_CHAT_ANSWER_SENDER, sender);
    w.writeValue(REQUEST_CHAT_ANSWER_RECIPIENT, recipient);
    w.writeValue(REQUEST_CHAT_ANSWER_MESSAGE, message);

    int y, m, d, h, min, sec, msec;
    dv_time:: decodeDateTime(dt, y, m, d, h, min, sec, msec);
    std :: stringstream ss;
    ss << y << ":" << m << ":" << d << ":" << h << ":" << min << ":" << sec << ":" << msec;
    w.writeValue(REQUEST_CHAT_ANSWER_TIMEFLAG, ss.str());
    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: buddy(const std :: list<std :: pair<unsigned long, std :: string>>& buddies)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_BUDDY);

    w.writeValue(REQUEST_BUDDY_ANSWER_COUNT, (unsigned long)buddies.size());

    int i = 1;
    for (std :: list<std :: pair<unsigned long, std :: string>> :: const_iterator iter = buddies.begin();
        iter != buddies.end(); iter++)
    {
        std :: stringstream ssID;
        std :: stringstream ssNAME;

        ssID << REQUEST_BUDDY_ANSWER_IDPREFIX << i;
        w.writeValue(ssID.str(), iter->first);

        ssNAME << REQUEST_BUDDY_ANSWER_NAMEPREFIX << i;
        w.writeValue(ssNAME.str(), iter->second);

        i++;
    }

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: planets_nonexisting(unsigned long areaid)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_PLANETS);
    w.writeValue(REQUEST_PLANETS_BAD_ANSWER_TYPE, REQUEST_PLANETS_BAD_ANSWER_NOT_EXISTS);
    w.writeValue(REQUEST_PLANETS_BAD_ANSWER_BADAREAID, areaid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: planets_notstar(unsigned long areaid)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_PLANETS);
    w.writeValue(REQUEST_PLANETS_BAD_ANSWER_TYPE, REQUEST_PLANETS_BAD_ANSWER_NOT_STAR);
    w.writeValue(REQUEST_PLANETS_BAD_ANSWER_BADAREAID, areaid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: planets_ie(unsigned long areaid)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_PLANETS);
    w.writeValue(REQUEST_PLANETS_BAD_ANSWER_TYPE, REQUEST_PLANETS_BAD_ANSWER_IE);
    w.writeValue(REQUEST_PLANETS_BAD_ANSWER_BADAREAID, areaid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: shipsinarea_notexisting(unsigned long shipid)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIPSINAREA);
    w.writeValue(REQUEST_SHIPSINAREA_ANSWER_FAIL, REQUEST_SHIPSINAREA_ANSWER_NOTEXIST);
    w.writeValue(REQUEST_SHIPSINAREA_ANSWER_OWNSHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: shipsinarea_notown(unsigned long shipid)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIPSINAREA);
    w.writeValue(REQUEST_SHIPSINAREA_ANSWER_FAIL, REQUEST_SHIPSINAREA_ANSWER_NOTOWN);
    w.writeValue(REQUEST_SHIPSINAREA_ANSWER_OWNSHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: shipsinarea_inwarp(unsigned long shipid)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIPSINAREA);
    w.writeValue(REQUEST_SHIPSINAREA_ANSWER_FAIL, REQUEST_SHIPSINAREA_ANSWER_WARP);
    w.writeValue(REQUEST_SHIPSINAREA_ANSWER_OWNSHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: shipsinarea_ie(unsigned long shipid)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIPSINAREA);
    w.writeValue(REQUEST_SHIPSINAREA_ANSWER_FAIL, REQUEST_SHIPSINAREA_ANSWER_IE);
    w.writeValue(REQUEST_SHIPSINAREA_ANSWER_OWNSHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_ship_not_exists(unsigned long shipid, const std :: string& request)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, request);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_FAIL, REQUEST_NAVIGATION_ANSWER_NOT_EXISTS);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_SHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_ship_not_owned(unsigned long shipid, const std :: string& request)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, request);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_FAIL, REQUEST_NAVIGATION_ANSWER_NOT_OWNED);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_SHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_ship_not_controllable(unsigned long shipid, const std :: string& request)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, request);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_FAIL, REQUEST_NAVIGATION_ANSWER_NOT_CONTROLLABLE);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_SHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_ship_in_warp(unsigned long shipid, const std :: string& request)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, request);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_FAIL, REQUEST_NAVIGATION_ANSWER_IN_WARP);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_SHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_ship_not_in_warp(unsigned long shipid, const std :: string& request)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, request);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_FAIL, REQUEST_NAVIGATION_ANSWER_NOT_IN_WARP);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_SHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_ship_docked_in_base(unsigned long shipid, const std :: string& request)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, request);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_FAIL, REQUEST_NAVIGATION_ANSWER_IN_BASE);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_SHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_OK(const std :: string& request, unsigned long shipid)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, request);
    w.writeValue(REQUEST_NAVIGATION_SHIPID, shipid);
    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_FAIL(const std :: string& request, unsigned long shipid)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, request);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_SHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_ship_target_not_exits(unsigned long shipid, const std :: string& request)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, request);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_FAIL, REQUEST_NAVIGATION_ANSWER_BAD_TARGET2);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_SHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_ship_target_not_in_normal_space(unsigned long shipid, const std :: string& request)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, request);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_FAIL, REQUEST_NAVIGATION_ANSWER_BAD_TARGET1);
    w.writeValue(REQUEST_NAVIGATION_ANSWER_SHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_dock_down(unsigned long shipId, unsigned long baseId, dockingResult result)
{
    protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_NAVIGATION_DOCK_DOWN);
	w.writeValue(REQUEST_NAVIGATION_DOCK_DOWN_ANSWER_SHIP_ID, shipId);
    w.writeValue(REQUEST_NAVIGATION_DOCK_DOWN_ANSWER_BASE_ID, baseId);
	w.writeValue(REQUEST_NAVIGATION_DOCK_DOWN_ANSWER_DOCKING_RESULT, (unsigned long) result);
    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_unbound(unsigned long shipId, dockingResult result)
{
    protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_NAVIGATION_UNBOUND);
	w.writeValue(REQUEST_NAVIGATION_UNBOUND_ANSWER_SHIP_ID, shipId);
	w.writeValue(REQUEST_NAVIGATION_UNBOUND_ANSWER_DOCKING_RESULT, (unsigned long) result);
    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_journey_details_FAIL(const unsigned long shipid, const std :: string& reason)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIP_JOURNEY_DETAILS);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_FAIL, reason);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_SHIPID, shipid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_journey_details_STANDARD(const unsigned long shipid, const dist_t positionx,
    const dist_t positiony, const char* state, const char* target, unsigned long long speed,
    unsigned long long acceleration, bool isDockedInBase, dockingResult docking)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIP_JOURNEY_DETAILS);    
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_SHIPID, shipid);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_POSX, (signed long long)positionx);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_POSY, (signed long long)positiony);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_TARGET, target);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_STATE, state);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_SPEED, speed);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_ACCELERATION, acceleration);
	w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_DOCKED_IN_BASE, isDockedInBase);
	w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_DOCKING_RESULT, (unsigned long) docking);
    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_journey_details_PURSUIT(const unsigned long shipid, const char* state, const char* target,
    unsigned long targetShip, dist_t estimation_distance, const dv_time:: datetime estimation_time, 
    const dist_t positionx, const dist_t positiony, unsigned long long speed,
    unsigned long long acceleration, dockingResult docking)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIP_JOURNEY_DETAILS);    
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_SHIPID, shipid);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_TARGET, target);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_STATE, state);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_TARGETSHIP, targetShip);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_ESTDIST, (signed long long)estimation_distance);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_POSX, (signed long long)positionx);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_POSY, (signed long long)positiony);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_SPEED, speed);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_ACCELERATION, acceleration);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_ESTTIME, dv_time :: secondsBetween(0, estimation_time));
	w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_DOCKING_RESULT, (unsigned long) docking);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_journey_details_MOVE_TO_POS(const unsigned long shipid, const char* state, const char* target,
        const dist_t dposx, const dist_t dposy, const dist_t estimation_distance, 
        const dv_time:: datetime estimation_time, const dist_t positionx, const dist_t positiony, unsigned long long speed,
    unsigned long long acceleration, dockingResult docking)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIP_JOURNEY_DETAILS);    
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_SHIPID, shipid);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_TARGET, target);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_STATE, state);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_DPOSX, (signed long long)dposx);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_DPOSY, (signed long long)dposy);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_ESTDIST, (unsigned long long)estimation_distance);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_POSX, (signed long long)positionx);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_POSY, (signed long long)positiony);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_SPEED, speed);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_ACCELERATION, acceleration);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_ESTTIME, dv_time :: secondsBetween(0, estimation_time));
	w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_DOCKING_RESULT, (unsigned long) docking);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_journey_details_MOVE_TO_SPACE_OBJECT(const unsigned long shipid, const char* state, const char* target,
    unsigned long targetSpaceObject, const std :: string& spObjName, dist_t estimation_distance, 
    const dv_time:: datetime estimation_time, const dist_t positionx, const dist_t positiony, unsigned long long speed,
    unsigned long long acceleration, dockingResult docking)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIP_JOURNEY_DETAILS);    
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_SHIPID, shipid);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_TARGET, target);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_STATE, state);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_TARGETSPACEOJBECT, targetSpaceObject);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_TARGETNAME, spObjName);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_ESTDIST, (unsigned long long)estimation_distance);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_POSX, (signed long long)positionx);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_POSY, (signed long long)positiony);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_SPEED, speed);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_ACCELERATION, acceleration);
    w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_ESTTIME, dv_time :: secondsBetween(0, estimation_time));
	w.writeValue(REQUEST_SHIP_JOURNEY_ANSWER_DOCKING_RESULT, (unsigned long) docking);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

void write_energy_state(protocolWriter& w, const char* devName, const answerDeviceEnergyState& des)
{
    std :: stringstream ss;

    ss << devName << REQUEST_DEVICE_ENERGY_STATE_ANSWER_ES_PRIORITY;
    w.writeValue(ss.str(), (unsigned long)des.priority);
    ss.str(std :: string(""));

    ss << devName << REQUEST_DEVICE_ENERGY_STATE_ANSWER_ES_RATIO;
    w.writeValue(ss.str(), (unsigned long)des.ratio);
    ss.str(std :: string(""));

    ss << devName << REQUEST_DEVICE_ENERGY_STATE_ANSWER_ES_MAX_POWER_DRAIN;
    w.writeValue(ss.str(), des.maxPowerDrain);
    ss.str(std :: string(""));

    ss << devName << REQUEST_DEVICE_ENERGY_STATE_ANSWER_ES_SHUT_DOWN_ON_EL;
    w.writeValue(ss.str(), (unsigned long)(des.shutDownOnEnergyLack ? 1 : 0));
    ss.str(std :: string(""));

    ss << devName << REQUEST_DEVICE_ENERGY_STATE_ANSWER_ES_CONSUMPTION;
    w.writeValue(ss.str(), des.consumption);
    ss.str(std :: string(""));

    ss << devName << REQUEST_DEVICE_ENERGY_STATE_ANSWER_ES_MAX_MAX_POWER_DRAIN;
	w.writeValue(ss.str(), des.maxMaxPowerDrain);
    ss.str(std :: string(""));
}

// --------------------------------

char* answerWriter :: device_energy_state(const unsigned long ship, const answerDeviceEnergy& de)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_DEVICE_ENERGY_STATE);

    w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_FORTRESSID, ship);

    write_energy_state(w, REQUEST_DEVICE_ENERGY_STATE_ANSWER_SHIELDS,       de.SHIELDS);
    write_energy_state(w, REQUEST_DEVICE_ENERGY_STATE_ANSWER_WEAPONS,       de.WEAPONS);
    write_energy_state(w, REQUEST_DEVICE_ENERGY_STATE_ANSWER_TRANSPORT,     de.TRANSPORT);
    write_energy_state(w, REQUEST_DEVICE_ENERGY_STATE_ANSWER_HR_SENSORS,    de.HR_SENSORS);
    write_energy_state(w, REQUEST_DEVICE_ENERGY_STATE_ANSWER_LR_SENSORS,    de.LR_SENSORS);
    write_energy_state(w, REQUEST_DEVICE_ENERGY_STATE_ANSWER_MASKING,       de.MASKING);
    write_energy_state(w, REQUEST_DEVICE_ENERGY_STATE_ANSWER_ANDROIDS,      de.ANDROIDS);
    write_energy_state(w, REQUEST_DEVICE_ENERGY_STATE_ANSWER_MAINFRAME,     de.MAINFRAME);
    write_energy_state(w, REQUEST_DEVICE_ENERGY_STATE_ANSWER_LIFE_SUPPORT,  de.LIFE_SUPPORT);

    w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_ACC_CURR_ENERGY,        de.ACC_CURR_ENERGY);
    w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_CURR_ENERGY,            de.CURR_ENERGY);
    w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_ACC_MAX_ENERGY,         de.ACC_MAX_ENERGY);
    w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_MAX_ENERGY,             de.MAX_ENERGY);
    w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_MIN_ENERGY_PRIORITY,    de.MIN_ENERGY_PRIORITY);
    w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_MAX_ENERGY_PRIORITY,    de.MAX_ENERGY_PRIORITY);
    w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_MIN_MAX_ENERGY,         de.MIN_MAX_ENERGY);
    w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_MIN_RATIO,              de.MIN_RATIO);
    w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_MAX_RATIO,              de.MAX_RATIO);

	w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_ACCUMULATOR_GRADIENT,         de.accumulatorGradient);
	w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_TOTAL_ENERGY_GRADIENT,        de.totalEnergyGradient);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: device_energy_state_error(const unsigned long ship, const char* reason)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_DEVICE_ENERGY_STATE);
    w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_FORTRESSID, ship);
    w.writeValue(REQUEST_DEVICE_ENERGY_STATE_ANSWER_FAIL_REASON, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: change_device_energy_state_error(const unsigned long ship, const char* reason)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_CHANGE_DEVICE_ENERGY_STATE);
    w.writeValue(REQUEST_CHANGE_DEVICE_ENERGY_STATE_ANSWER_FORTRESSID, ship);
    w.writeValue(REQUEST_CHANGE_DEVICE_ENERGY_STATE_ANSWER_FAIL_REASON, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_weapons_set(const unsigned long fortressid, const weapons_status& sds)
{
	return fortress_weapons_information(fortressid, sds);
}

// --------------------------------

char* answerWriter :: fortress_weapons_set_FAIL(const unsigned long fortressid, const std :: string& reason)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_CHANGE_DEVICE_ENERGY_STATE);
    w.writeValue(REQUEST_CHANGE_DEVICE_ENERGY_STATE_ANSWER_FORTRESSID, fortressid);
    w.writeValue(REQUEST_CHANGE_DEVICE_ENERGY_STATE_ANSWER_FAIL_REASON, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_mainframe_information(const unsigned long fortressid, const mainframe_status& sds)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_MAINFRAME_INFORMATION);
	w.writeValue(REQUEST_FORTRESS_MAINFRAME_INFORMATION_FORTRESSID, fortressid);
	w.writeValue(REQUEST_FORTRESS_MAINFRAME_INFORMATION_ACTUAL_BIONODES, sds.actualBioNodes);
	w.writeValue(REQUEST_FORTRESS_MAINFRAME_INFORMATION_ACTUAL_PREDICTION, sds.actualPrediction);
	w.writeValue(REQUEST_FORTRESS_MAINFRAME_INFORMATION_ACTUAL_TIME_REUSABILITY, sds.actualTimeReusability);
	w.writeValue(REQUEST_FORTRESS_MAINFRAME_INFORMATION_ACTUAL_CONSUMPTION, sds.actualConsumption);
	w.writeValue(REQUEST_FORTRESS_MAINFRAME_INFORMATION_STATUS, sds.status);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------
char* answerWriter :: fortress_mainframe_information_FAIL(const unsigned long fortressid, const std :: string& reason)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_MAINFRAME_INFORMATION);
    w.writeValue(REQUEST_FORTRESS_MAINFRAME_INFORMATION_FORTRESSID, fortressid);
    w.writeValue(REQUEST_FORTRESS_MAINFRAME_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_crew_information(const unsigned long fortressid, const crew_status& sds)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_CREW_INFORMATION);

	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_FORTRESSID, fortressid);

	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_ABLE_CREW_CAPITAN, sds.ABLE_CREW_CAPITAN);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_ABLE_CREW_DOCTOR, sds.ABLE_CREW_DOCTOR);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_ABLE_CREW_OFFICER, sds.ABLE_CREW_OFFICER);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_ABLE_CREW_ENGINEER, sds.ABLE_CREW_ENGINEER);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_ABLE_CREW_PILOT, sds.ABLE_CREW_PILOT);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_ABLE_CREW_SCIENTIST, sds.ABLE_CREW_SCIENTIST);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_ABLE_CREW_PASSENGER, sds.ABLE_CREW_PASSENGER);

	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_WOUNDED_CREW_CAPITAN, sds.WOUNDED_CREW_CAPITAN);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_WOUNDED_CREW_DOCTOR, sds.WOUNDED_CREW_DOCTOR);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_WOUNDED_CREW_OFFICER, sds.WOUNDED_CREW_OFFICER);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_WOUNDED_CREW_ENGINEER, sds.WOUNDED_CREW_ENGINEER);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_WOUNDED_CREW_PILOT, sds.WOUNDED_CREW_PILOT);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_WOUNDED_CREW_SCIENTIST, sds.WOUNDED_CREW_SCIENTIST);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_WOUNDED_CREW_PASSENGER, sds.WOUNDED_CREW_PASSENGER);

	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_TOTAL_CREW_CAPITAN, sds.TOTAL_CREW_CAPITAN);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_TOTAL_CREW_DOCTOR, sds.TOTAL_CREW_DOCTOR);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_TOTAL_CREW_OFFICER, sds.TOTAL_CREW_OFFICER);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_TOTAL_CREW_ENGINEER, sds.TOTAL_CREW_ENGINEER);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_TOTAL_CREW_PILOT, sds.TOTAL_CREW_PILOT);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_TOTAL_CREW_SCIENTIST, sds.TOTAL_CREW_SCIENTIST);
	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_TOTAL_CREW_PASSENGER, sds.TOTAL_CREW_PASSENGER);

	w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_ACT_PEOPLE_WEIGHT, sds.ACT_PEOPLE_WEIGHT);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_crew_information_FAIL(const unsigned long fortressid, const std :: string& reason)
{
	protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_CREW_INFORMATION);
    w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_FORTRESSID, fortressid);
    w.writeValue(REQUEST_FORTRESS_CREW_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_quarry_information(const unsigned long fortressid, const quarry_status& qs)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_QUARRY_INFORMATION);

	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_FORTRESSID, fortressid);

	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_QGP_SPEED,          (signed long long) ceil(qs.QuarkGluonPlasmaQuarryingSpeed));
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_HWA_SPEED,          (signed long long) ceil(qs.HeavyWaterQuarryingSpeed));
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ZRC_SPEED,          (signed long long) ceil(qs.ZirconiumCrystalQuarryingSpeed));
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ILM_SPEED,          (signed long long) ceil(qs.IlmeniteQuarryingSpeed));

    w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ISP_QGP,            (unsigned long)(qs.isPossibleToQuarryQuarkGluonPlasma ? 1 : 0));
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ISP_HWA,            (unsigned long)(qs.isPossibleToQuarryHeavyWater ? 1 : 0));
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ISP_ZRC,            (unsigned long)(qs.isPossibleToQuarryZirconiumCrystals ? 1 : 0));
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ISP_ILM,            (unsigned long)(qs.isPossibleToQuarryIlmenite ? 1 : 0));

	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_IAQ_QGP,            (unsigned long)(qs.isActuallyQuarryingQuarkGluonPlasma ? 1 : 0));
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_IAQ_HWA,            (unsigned long)(qs.isActuallyQuarryingHeavyWater ? 1 : 0));
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_IAQ_ZRC,            (unsigned long)(qs.isActuallyQuarryingZirconiumCrystals ? 1 : 0));
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_IAQ_ILM,            (unsigned long)(qs.isActuallyQuarryingIlmenite ? 1 : 0));

	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_QGP_COUNT,          qs.QuarkGluonPlasmaQuarryingCount);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_HWA_COUNT,          qs.HeavyWaterQuarryingCount);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ZRC_COUNT,          qs.ZirconiumCrystalQuarryingCount);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ILM_COUNT,          qs.IlmeniteQuarryingCount);

	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_QGP_WORKING,        qs.QuarkGluonPlasmaQuarryingWorking);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_HWA_WORKING,        qs.HeavyWaterQuarryingWorking);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ZRC_WORKING,        qs.ZirconiumCrystalQuarryingWorking);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ILM_WORKING,        qs.IlmeniteQuarryingWorking);

	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_QGP_DAMAGED,        qs.QuarkGluonPlasmaQuarryingDamaged);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_HWA_DAMAGED,        qs.HeavyWaterQuarryingDamaged);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ZRC_DAMAGED,        qs.ZirconiumCrystalQuarryingDamaged);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ILM_DAMAGED,        qs.IlmeniteQuarryingDamaged);

	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_QGP_ACT_RANGE,      qs.QuarkGluonPlasmaQuarryingActualRange);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_HWA_ACT_RANGE,      qs.HeavyWaterQuarryingActualRange);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ZRC_ACT_RANGE,      qs.ZirconiumCrystalQuarryingActualRange);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ILM_ACT_RANGE,      qs.IlmeniteQuarryingActualRange);

	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_QGP_MAX_SPEED,      qs.QuarkGluonPlasmaQuarryingActualMaximalSpeed);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_HWA_MAX_SPEED,      qs.HeavyWaterQuarryingActualMaximalSpeed);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ZRC_MAX_SPEED,      qs.ZirconiumCrystalQuarryingActualMaximalSpeed);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_ILM_MAX_SPEED,      qs.IlmeniteQuarryingActualMaximalSpeed);

	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_AVAL_MAGNETICAL_COLLECTORS,			qs.avalMagneticalCollectorsOfPlasma);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_AVAL_SUBMARINE_MINING_MACHINE,		qs.avalSubmarineMiningMachine);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_AVAL_SUBMERSIBLE_FILTRATION_TANK,	qs.avalSubmersibleFiltrationTank);
	w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_AVAL_UNDERGROUND_DRILLING_MACHINE,	qs.avalUndergroundDrillingMachine);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_quarry_information_FAIL(const unsigned long fortressid, const std :: string& reason)
{
	protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_QUARRY_INFORMATION);
    w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_FORTRESSID, fortressid);
    w.writeValue(REQUEST_FORTRESS_QUARRY_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_quarry_change_state_FAIL(const unsigned long fortressid, const std :: string& reason)
{
	protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_QUARRY_CHANGE_STATE);
    w.writeValue(REQUEST_FORTRESS_QUARRY_CHANGE_STATE_FORTRESS_ID, fortressid);
    w.writeValue(REQUEST_FORTRESS_QUARRY_CHANGE_STATE_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_accommodations_information(const unsigned long fortressid, const accommodation_status & sds)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION);

	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_FORTRESSID, fortressid);

	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_ACCOMMODATIONS_SIZE, sds.accommodationsSize);
	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_ACCOMMODATIONS_WEIGHT, sds.accommodationsWeight);

	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_COMFORTABLE_ROOMS_COUNT, sds.comfortableRoomsCount);
	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_COMMON_CABINS_COUNT, sds.commonCabinsCount);
	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_LUXURY_ACCOMMODATIONS_COUNT, sds.luxuryAccommodationsCount);
	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_WAREHOUSES_WITH_LIFESUPPORT_COUNT, sds.warehousesWithLifeSupportCount);

	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_FREE_COMFORTABLE_ROOMS, sds.freeComfortableRooms);
	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_FREE_COMMON_CABINS, sds.freeCommonCabins);
	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_FREE_LUXURY_ACCOMMODATIONS, sds.freeLuxuryAccommodations);
	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_FREE_WAREHOUSES_WITH_LIFESUPPORT, sds.freeWarehousesWithLifeSupport);

	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_COMFORTABLE_ROOMS_PRICE, sds.comfortableRoomsPrice);
	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_COMMON_CABINS_PRICE, sds.commonCabinsPrice);
	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_LUXURY_ACCOMMODATIONS_PRICE, sds.luxuryAccommodationsPrice);
	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_WAREHOUSES_WITH_LIFESUPPORT_PRICE, sds.warehousesWithLifeSupportPrice);

	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_TOTAL_POINTS, sds.totalPoints);
	w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_CONSUMED_POINTS, sds.consumedPoints);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_accommodations_information_FAIL(const unsigned long fortressid, const std :: string& reason)
{
	protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION);
    w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_FORTRESSID, fortressid);
    w.writeValue(REQUEST_FORTRESS_ACCOMMODATIONS_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_other_equipment_information(const unsigned long fortressid, const other_equipment_status & sds)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION);

	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_FORTRESSID, fortressid);

	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_ACT_ENERGY_CONSUMPTION, sds.actualEnergyConsumption);
	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_OTHER_EQUIPMENT_WEIGHT, sds.otherEquipmentWeight);

	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_LIFE_SUPPORT_AVAILABLE, bool2ulong(sds.isLifeSupportAvailable));
	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_PLASMA_FILTER_AVAILABLE, bool2ulong(sds.isPlasmaFilterAvailable));
	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_SCIENTIFIC_LAB_AVAILABLE, bool2ulong(sds.isScietificLabAvailable));
	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_SUBSPACE_TRANSMITTER_AVAILABLE, bool2ulong(sds.isSubspaceTransmitterAvailable));

	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_LIFE_SUPPORT_CAPACITY, sds.lifeSupportActualCapacity);
	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_LIFE_SUPPORT_ACT_CONSUMPTION, sds.lifeSupportActualConsumption);
	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_LIFE_SUPPORT_STATUS, sds.lifeSupportStatus);

	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_SCIENTIFIC_LAB_ACT_CAPACITY, sds.scientificLabActualCapacity);
	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_SCIENTIFIC_LAB_ACT_LEVEL, sds.scientificLabActualLevel);
	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_SCIENTIFIC_LAB_STATUS, sds.scientificLabStatus);

	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_PLASMA_FILTER_ACT_TOTAL_FILTERING_SPEED, sds.plasmaFilterActualTotalFilteringSpeed);
	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_PLASMA_FILTER_STATUS, sds.plasmaFilterStatus);

	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_SUBSPACE_TRANSMITTER_MESSAGE_COST, sds.subspaceTransmitterActualMessageCost);
	w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_SUBSPACE_TRANSMITTER_STATUS, sds.subspaceTransmitterStatus);

    w.endMessage(true);
    return w.copyMessage();		
}

// --------------------------------

char* answerWriter :: fortress_other_equipment_information_FAIL(const unsigned long fortressid, const std :: string& reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION);
    w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_FORTRESSID, fortressid);
    w.writeValue(REQUEST_FORTRESS_OTHER_EQUIPMENT_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: base_factories_information(const unsigned long baseId, const factories_status & sds)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_BASE_FACTORIES_INFORMATION);

	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_FORTRESSID, baseId);

	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_SIZE, sds.factoriesSize);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_WEIGHT, sds.factoriesWeight);

	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_DEUTERIUM_DECOMPOSER_AVAILABLE, bool2ulong(sds.deuteriumDecomposer.isAvailable));
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_DEUTERIUM_DECOMPOSER_ACTUAL_METAMORPHOSIS_EFFECTIVITY, sds.deuteriumDecomposer.actualMetamorphosisEffectivity);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_DEUTERIUM_DECOMPOSER_ACTUAL_SPACE_METAMORPHOSIS_EFFECTIVITY, sds.deuteriumDecomposer.actualSpaceMetamorphosisEffectivity);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_DEUTERIUM_DECOMPOSER_ACTUAL_TOTAL_CONSUMPTION, sds.deuteriumDecomposer.actualTotalConsumption);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_DEUTERIUM_DECOMPOSER_ACTUAL_TOTAL_PRODUCTION, sds.deuteriumDecomposer.actualTotalProduction);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_DEUTERIUM_DECOMPOSER_COUNT, sds.deuteriumDecomposer.count);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_DEUTERIUM_DECOMPOSER_DAMAGED, sds.deuteriumDecomposer.damaged);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_DEUTERIUM_DECOMPOSER_WORKING, sds.deuteriumDecomposer.working);
								
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ILMENITE_FURNACE_AVAILABLE, bool2ulong(sds.ilmeniteFurnace.isAvailable));
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ILMENITE_FURNACE_ACTUAL_METAMORPHOSIS_EFFECTIVITY, sds.ilmeniteFurnace.actualMetamorphosisEffectivity);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ILMENITE_FURNACE_ACTUAL_SPACE_METAMORPHOSIS_EFFECTIVITY, sds.ilmeniteFurnace.actualSpaceMetamorphosisEffectivity);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ILMENITE_FURNACE_ACTUAL_TOTAL_CONSUMPTION, sds.ilmeniteFurnace.actualTotalConsumption);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ILMENITE_FURNACE_ACTUAL_TOTAL_PRODUCTION, sds.ilmeniteFurnace.actualTotalProduction);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ILMENITE_FURNACE_COUNT, sds.ilmeniteFurnace.count);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ILMENITE_FURNACE_DAMAGED, sds.ilmeniteFurnace.damaged);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ILMENITE_FURNACE_WORKING, sds.ilmeniteFurnace.working);
								
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_MAGNETICAL_FILTER_AVAILABLE, bool2ulong(sds.magneticalFilter.isAvailable));
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_MAGNETICAL_FILTER_ACTUAL_TOTAL_PRODUCTION, sds.magneticalFilter.actualTotalProduction);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_MAGNETICAL_FILTER_COUNT, sds.magneticalFilter.count);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_MAGNETICAL_FILTER_DAMAGED, sds.magneticalFilter.damaged);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_MAGNETICAL_FILTER_WORKING, sds.magneticalFilter.working);
							
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ZIRCONIUM_REACTOR_AVAILABLE, bool2ulong(sds.zirconiumReactor.isAvailable));
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ZIRCONIUM_REACTOR_ACTUAL_METAMORPHOSIS_EFFECTIVITY, sds.zirconiumReactor.actualMetamorphosisEffectivity);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ZIRCONIUM_REACTOR_ACTUAL_SPACE_METAMORPHOSIS_EFFECTIVITY, sds.zirconiumReactor.actualSpaceMetamorphosisEffectivity);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ZIRCONIUM_REACTOR_ACTUAL_TOTAL_CONSUMPTION, sds.zirconiumReactor.actualTotalConsumption);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ZIRCONIUM_REACTOR_ACTUAL_TOTAL_PRODUCTION, sds.zirconiumReactor.actualTotalProduction);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ZIRCONIUM_REACTOR_COUNT, sds.zirconiumReactor.count);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ZIRCONIUM_REACTOR_DAMAGED, sds.zirconiumReactor.damaged);
	w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ZIRCONIUM_REACTOR_WORKING, sds.zirconiumReactor.working);

    w.endMessage(true);
    return w.copyMessage();		
}

// --------------------------------

char* answerWriter :: base_factories_information_FAIL(const unsigned long baseId, const std :: string& reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_BASE_FACTORIES_INFORMATION);
    w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_FORTRESSID, baseId);
    w.writeValue(REQUEST_BASE_FACTORIES_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_warehouses_information(const unsigned long fortressId, const warehouses_status & sds) {
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_WAREHOUSES_INFORMATION);

	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_FORTRESSID, fortressId);

	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_SIZE, sds.size);
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_WEIGHT, sds.weight);

	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_ENERGETIC_CELL_AVAILABLE, bool2ulong(sds.energeticCell.isAvailable));
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_ENERGETIC_CELL_CAPACITY, sds.energeticCell.actualCapacity);
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_ENERGETIC_CELL_WORKING, sds.energeticCell.working);
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_ENERGETIC_CELL_DAMAGED, sds.energeticCell.damaged);
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_ENERGETIC_CELL_COUNT, sds.energeticCell.count);

	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_MAGNETIC_GRID_AVAILABLE, bool2ulong(sds.magneticGrid.isAvailable));
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_MAGNETIC_GRID_CAPACITY, sds.magneticGrid.actualCapacity);
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_MAGNETIC_GRID_WORKING, sds.magneticGrid.working);
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_MAGNETIC_GRID_DAMAGED, sds.magneticGrid.damaged);
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_MAGNETIC_GRID_COUNT, sds.magneticGrid.count);

	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_TRANSPORT_CONTAINER_AVAILABLE, bool2ulong(sds.transportContainer.isAvailable));
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_TRANSPORT_CONTAINER_CAPACITY, sds.transportContainer.actualCapacity);
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_TRANSPORT_CONTAINER_WORKING, sds.transportContainer.working);
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_TRANSPORT_CONTAINER_DAMAGED, sds.transportContainer.damaged);
	w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_TRANSPORT_CONTAINER_COUNT, sds.transportContainer.count);

	write_warehouse_items_list(w, REQUEST_FORTRESS_WAREHOUSES_INFORMATION_ITEMS_PREFIX, sds.warehouseItems);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

void answerWriter :: write_trade_start_data(protocolWriter & w, const std::string & prefix, const trade_data & tradeData)
{
	write_warehouse_items_list(w, prefix, tradeData.tradeItems);

	w.writeValue(create_param_name(prefix, TRADE_ITEM_DATA_DEUTERIUM), tradeData.deuterium);
	w.writeValue(create_param_name(prefix, TRADE_ITEM_DATA_HEAVY_WATER), tradeData.heavyWater);
	w.writeValue(create_param_name(prefix, TRADE_ITEM_DATA_ILMENITE), tradeData.ilmenite);
	w.writeValue(create_param_name(prefix, TRADE_ITEM_DATA_QUARK_GLUON_PLASMA), tradeData.quarkGluonPlasma);
	w.writeValue(create_param_name(prefix, TRADE_ITEM_DATA_TITANIUM), tradeData.titanium);
	w.writeValue(create_param_name(prefix, TRADE_ITEM_DATA_ULREA), tradeData.ulrea);
	w.writeValue(create_param_name(prefix, TRADE_ITEM_DATA_ZIRCONIUM_CRYSTAL), tradeData.zirconiumCrystal);
	w.writeValue(create_param_name(prefix, TRADE_ITEM_DATA_ENERGY), tradeData.energy);
}

// --------------------------------

void answerWriter :: write_warehouse_items_list(protocolWriter & w, const std::string & prefix, const warehouses_status::items_list_t & itemsList)
{
	w.writeValue(create_param_name(prefix, WAREHOUSES_ITEM_STATUS_COUNT), (unsigned long) itemsList.size());

	int itemIndex = 1;
	for (warehouses_status::items_list_t::const_iterator it = itemsList.begin(); it != itemsList.end(); ++it) {
		write_warehouse_item(w, prefix, itemIndex, *it);
		itemIndex++;
	}
}

// --------------------------------

void answerWriter :: write_warehouse_item(protocolWriter& writer, const std::string & prefix, int index, const warehouse_item_status & item) {
	writer.writeValue(create_param_name(prefix, WAREHOUSES_ITEM_STATUS_ID, index), item.id);
	writer.writeValue(create_param_name(prefix, WAREHOUSES_ITEM_STATUS_NAME, index), item.patternName);	
	writer.writeValue(create_param_name(prefix, WAREHOUSES_ITEM_STATUS_STACKABLE, index), item.isStackable);
	writer.writeValue(create_param_name(prefix, WAREHOUSES_ITEM_STATUS_WORKING, index), item.working);
	writer.writeValue(create_param_name(prefix, WAREHOUSES_ITEM_STATUS_DAMAGED, index), item.damaged);

	writer.writeValue(create_param_name(prefix, WAREHOUSES_ITEM_STATUS_PARAM_COUNT, index), (unsigned long) item.parameters.size());

	int paramIndex = 1;
	for (warehouse_item_status::parameters_list_t::const_iterator it = item.parameters.begin(); it != item.parameters.end(); ++it) {
		writer.writeValue(create_param_name(prefix, WAREHOUSES_ITEM_STATUS_PARAM_NAME, index, paramIndex), it->name);
		writer.writeValue(create_param_name(prefix, WAREHOUSES_ITEM_STATUS_PARAM_VALUE, index, paramIndex), it->value);
		writer.writeValue(create_param_name(prefix, WAREHOUSES_ITEM_STATUS_PARAM_TYPE, index, paramIndex), (unsigned long) it->type);
		writer.writeValue(create_param_name(prefix, WAREHOUSES_ITEM_STATUS_PARAM_SCIENCE_INDEPENDENT, index, paramIndex), (unsigned long) it->scienceIndependent);
		paramIndex++;
	}
}

// --------------------------------

char* answerWriter :: fortress_warehouses_information_FAIL(const unsigned long fortressId, const std :: string& reason) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_WAREHOUSES_INFORMATION);
    w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_FORTRESSID, fortressId);
    w.writeValue(REQUEST_FORTRESS_WAREHOUSES_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_androids_information(const unsigned long fortressId, const ship_androids_status & sds) {
    
	protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIP_ANDROIDS_INFORMATION);
	w.writeValue(REQUEST_SHIP_ANDROIDS_INFORMATION_FORTRESSID, fortressId);

	write_androids_status(w, sds);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_IMPULSDRIVE, sds.impulsDrive);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_SUBSPACEDRIVE, sds.subspaceDrive);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: base_androids_information(const unsigned long fortressId, const base_androids_status & sds) {
    
	protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_BASE_ANDROIDS_INFORMATION);
	w.writeValue(REQUEST_BASE_ANDROIDS_INFORMATION_FORTRESSID, fortressId);

	write_androids_status(w, sds);	
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_HANGARS, sds.hangars);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_FACTORIES, sds.factories);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

void answerWriter :: write_androids_status(protocolWriter& w, const androids_status & sds) {
	
	w.writeValue(REQUEST_FORTRESS_ANDRODIS_INFORMATION_CLIENT_ANDROIDS_STATE_SLIDER_MAX, sds.clientAndroidsStateSliderMax);
	w.writeValue(REQUEST_FORTRESS_ANDRODIS_INFORMATION_CLIENT_ANDROIDS_STATE_SLIDER_BACKGROUND, sds.clientAndroidsStateSliderBackground);
	w.writeValue(REQUEST_FORTRESS_ANDRODIS_INFORMATION_CLIENT_WORKING_ANDROIDS_SLIDER_MAX, sds.clientWorkingAndroidsSliderMax);
	w.writeValue(REQUEST_FORTRESS_ANDRODIS_INFORMATION_CLIENT_WORKING_ANDROIDS_SLIDER_VALUE, sds.clientWorkingAndroidsSliderValue);
	w.writeValue(REQUEST_FORTRESS_ANDRODIS_INFORMATION_CLIENT_WORKING_ANDROIDS_SLIDER_BACKGROUND, sds.clientWorkingAndroidsSliderBackground);
	w.writeValue(REQUEST_FORTRESS_ANDRODIS_INFORMATION_CLIENT_REPCON_SLIDER_MAX, sds.clientRepConSliderMax);
	w.writeValue(REQUEST_FORTRESS_ANDRODIS_INFORMATION_CLIENT_REPCON_SLIDER_VALUE, sds.clientRepConSliderValue);
	w.writeValue(REQUEST_FORTRESS_ANDRODIS_INFORMATION_CLIENT_REPCON_SLIDER_BACKGROUND, sds.clientRepConSliderBackground);

	w.writeValue(REQUEST_FORTRESS_ANDRODIS_INFORMATION_ACTUAL_WORKING_ANDROIDS, sds.actualWorkingAndroids);
	w.writeValue(REQUEST_FORTRESS_ANDRODIS_INFORMATION_ACTUAL_REPAIRING_ANDROIDS, sds.actualRepairingAndroids);
	w.writeValue(REQUEST_FORTRESS_ANDRODIS_INFORMATION_ACTUAL_CONSTRUCTING_ANDROIDS, sds.actualConstructingAndroids);

	w.writeValue(REQUEST_FORTRESS_ANDROIDS_INFORMATION_ANDROIDS_MIN_PRIORITY, sds.androidsMinPriority);
	w.writeValue(REQUEST_FORTRESS_ANDROIDS_INFORMATION_ANDROIDS_MAX_PRIORITY, sds.androidsMaxPriority);

	w.writeValue(REQUEST_FORTRESS_ANDROIDS_INFORMATION_ANDROIDS_MIN_RATIO, sds.androidsMinRatio);
	w.writeValue(REQUEST_FORTRESS_ANDROIDS_INFORMATION_ANDROIDS_MAX_RATIO, sds.androidsMaxRatio);

    write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_CLOAKING, sds.cloaking);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_DEFLECTORSHIELDS, sds.deflectorShields);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_ENERGETICSYSTEM, sds.energeticSystem);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_MAINFRAMESYSTEM, sds.mainframeSystem);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_MECHANICS, sds.mechanics);	
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_MININGDEVICES, sds.miningDevices);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_OTHEREQUIPMENT, sds.otherEquipment);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_PROBEDEVICES,  sds.probeDevices);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_SENSORS, sds.sensors);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_TRANSPORTBEAM, sds.transportBeam);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_WAREHOUSE, sds.warehouse);
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_WEAPONS, sds.weapons);	
	write_androids_assignment(w, REQUEST_ANDROIDS_ASSIGNMENT_SECTION_STRUCTURALINTEGRITY, sds.structuralIntegrity);	
}

// --------------------------------

void answerWriter :: write_androids_assignment(protocolWriter& w, const std::string & section, const androids_assignment & assignment)
{
    std :: stringstream ss;

	ss << section << REQUEST_ANDROIDS_ASSSIGNMENT_PRIORITY;
    w.writeValue(ss.str(), (unsigned long) assignment.priority);
    ss.str("");

	ss << section << REQUEST_ANDROIDS_ASSSIGNMENT_RATIO;
    w.writeValue(ss.str(), assignment.ratio);
    ss.str("");
}

// --------------------------------

char* answerWriter :: ship_androids_information_FAIL(const unsigned long fortressId, const std :: string& reason) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_SHIP_ANDROIDS_INFORMATION);
    w.writeValue(REQUEST_SHIP_ANDROIDS_INFORMATION_FORTRESSID, fortressId);
    w.writeValue(REQUEST_SHIP_ANDROIDS_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: base_androids_information_FAIL(const unsigned long fortressId, const std :: string& reason) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_BASE_ANDROIDS_INFORMATION);
    w.writeValue(REQUEST_BASE_ANDROIDS_INFORMATION_FORTRESSID, fortressId);
    w.writeValue(REQUEST_BASE_ANDROIDS_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: change_ship_androids_state_FAIL(const unsigned long fortressId, const std :: string& reason) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_CHANGE_SHIP_ANDROIDS_STATE);
	w.writeValue(REQUEST_CHANGE_SHIP_ANDROIDS_STATE_ANSWER_FORTRESSID, fortressId);
	w.writeValue(REQUEST_CHANGE_SHIP_ANDROIDS_STATE_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: change_base_androids_state_FAIL(const unsigned long fortressId, const std :: string& reason) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_CHANGE_BASE_ANDROIDS_STATE);
	w.writeValue(REQUEST_CHANGE_BASE_ANDROIDS_STATE_ANSWER_FORTRESSID, fortressId);
	w.writeValue(REQUEST_CHANGE_BASE_ANDROIDS_STATE_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: base_hangars_item_information(const hangar_item_status & sds) {

	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_BASE_HANGAR_ITEM_INFORMATION);
	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_PATTERN_NAME, sds.patternName);
	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_DEUTERIUM, sds.constructionDeuterium);
	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_HEAVY_WATER, sds.constructionHeavyWater);
	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_TITANIUM, sds.constructionTitanium);
	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_ULREI, sds.constructionUlrei);
	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_STACKABLE, sds.isStackable);
	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_ITEM_NAME, sds.itemName);
	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_MIN_WEIGHT, sds.minWeight);
	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_MAX_WEIGHT, sds.maxWeight);

	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_MIN_SIZE, sds.minSize);
	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_MAX_SIZE, sds.maxSize);
	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_MIN_ANDROIDS, sds.minRequiredAndroidCount);
	w.writeValue(REQUEST_BASE_HANGAR_ITEM_INFORMATION_ANSWER_HANGAR_ITEM_MAX_ANDROIDS, sds.maxRequiredAndroidCount);

	w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: base_hangars_information_FAIL(const unsigned long baseId, const std :: string& reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_BASE_HANGARS_INFORMATION);
    w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_FORTRESSID, baseId);
    w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: base_hangars_information(const unsigned long fortressId, const hangars_status & sds) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_BASE_HANGARS_INFORMATION);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_FORTRESS_ID, fortressId);

	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_FREE, bool2ulong(sds.isHangarFree));
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SHIP_IN_DOCK, bool2ulong(sds.isShipInDock));
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_LEVEL, sds.actualLevel);

	size_t index = 1;
	for (std::list<unsigned long>::const_iterator it = sds.hangarIds.begin(); it != sds.hangarIds.end(); ++it) 
	{
		w.writeValue(create_param_name(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_HANGAR_ID, (int)index), *it);
		index++;
	}		

	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_HANGAR_COUNT, (unsigned long) (index - 1));

	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_HANGAR_ID, sds.selectedHangarId);

	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_ITEM_UNDER_CONSTRUCTION, bool2ulong(sds.isItemUnderConstruction));
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SHIP_UNDER_CONSTRUCTION, bool2ulong(sds.isShipUnderConstruction));
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_WHATEVER_UNDER_CONSTRUCTION, bool2ulong(sds.isWhateverUnderConstruction));

	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_DAMAGE_STATUS, sds.damageStatus);

	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_PATTERN_NAME, sds.selectedItem.patternName);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_DEUTERIUM, sds.selectedItem.constructionDeuterium);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_HEAVY_WATER, sds.selectedItem.constructionHeavyWater);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_TITANIUM, sds.selectedItem.constructionTitanium);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_ULREI, sds.selectedItem.constructionUlrei);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_ITEM_NAME, sds.selectedItem.itemName);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_ITEM_MIN_WEIGHT, sds.selectedItem.minWeight);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_ITEM_MAX_WEIGHT, sds.selectedItem.maxWeight);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_ITEM_STACKABLE, sds.selectedItem.isStackable);

	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_ITEM_MIN_SIZE, sds.selectedItem.minSize);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_ITEM_MAX_SIZE, sds.selectedItem.maxSize);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_ITEM_MIN_ANDROIDS, sds.selectedItem.minRequiredAndroidCount);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_SELECTED_ITEM_MAX_ANDROIDS, sds.selectedItem.maxRequiredAndroidCount);

	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_PATTERN_NAME, sds.constructedItem.patternName);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_DEUTERIUM, sds.constructedItem.constructionDeuterium);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_HEAVY_WATER, sds.constructedItem.constructionHeavyWater);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_TITANIUM, sds.constructedItem.constructionTitanium);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_ULREI, sds.constructedItem.constructionUlrei);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_ITEM_NAME, sds.constructedItem.itemName);

	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_ITEM_MIN_SIZE, sds.constructedItem.minSize);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_ITEM_MAX_SIZE, sds.constructedItem.maxSize);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_ITEM_ACT_SIZE, sds.constructedItem.actSize);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_ITEM_ACT_ANDROIDS, sds.constructedItem.actRequiredAndroidCount);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_ITEM_MIN_ANDROIDS, sds.constructedItem.minRequiredAndroidCount);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_ITEM_MAX_ANDROIDS, sds.constructedItem.maxRequiredAndroidCount);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_ITEM_CONSTRUCTION_TIME, sds.constructedItem.constructionTime);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_ITEM_COUNT, sds.constructedItem.count);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTED_ITEM_STACKABLE, sds.constructedItem.isStackable);

	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_ACTUAL_POINTS, sds.actualConstructedPoints);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_TARGET_POINTS, sds.targetConstructedPoints);
	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_HANGAR_CONSTRUCTION_GRADIENT, sds.constructionGradient);

	unsigned long classIndex = 1;
	for (std::list<fortress_class_simple_data>::const_iterator it = sds.availableShipClasses.begin(); it != sds.availableShipClasses.end(); ++it) 
	{
		w.writeValue(create_param_name(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_FORTRESS_CLASS_ID, (int)classIndex), it->id);
		w.writeValue(create_param_name(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_FORTRESS_CLASS_NAME, (int)classIndex), it->name);
		w.writeValue(create_param_name(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_FORTRESS_CLASS_QUALITY, (int)classIndex), it->quality);
		classIndex++;
	}		

	w.writeValue(REQUEST_BASE_HANGARS_INFORMATION_ANSWER_FORTRESS_CLASS_COUNT, (unsigned long) sds.availableShipClasses.size());

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

std::string itemsCreationResult2ProtocolString(itemsCreationResult result) {
	switch (result) {
	case ICR_OK:
		return PROTOCOL_HANGAR_ICR_OK;
	case ICR_INVALID_PARAMS:
		return PROTOCOL_HANGAR_ICR_INVALID_PARAMS;			
	case ICR_FULL_HANGAR:
		return PROTOCOL_HANGAR_ICR_FULL_HANGAR;			
	case ICR_NOT_ENOUGH_ULREI:
		return PROTOCOL_HANGAR_ICR_NOT_ENOUGH_ULREI;		
	case ICR_NOT_ENOUGH_TITANIUM:
		return PROTOCOL_HANGAR_ICR_NOT_ENOUGH_TITANIUM;	
	case ICR_NOT_ENOUGH_DEUTERIUM:		
		return PROTOCOL_HANGAR_ICR_NOT_ENOUGH_DEUTERIUM;	
	case ICR_NOT_ENOUGH_HEAVY_WATER:
		return PROTOCOL_HANGAR_ICR_NOT_ENOUGH_HEAVY_WATER;
	default:
		return "";
	}
}

// --------------------------------
char* answerWriter :: base_hangar_build_item(unsigned long fortressId, unsigned long hangarId, itemsCreationResult result) {

	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_HANGAR_BUILD_ITEM);
	w.writeValue(REQUEST_HANGAR_BUILD_ITEM_ANSWER_FORTRESSID, fortressId);
	w.writeValue(REQUEST_HANGAR_BUILD_ITEM_ANSWER_HANGAR_ID, hangarId);
	w.writeValue(REQUEST_HANGAR_BUILD_ITEM_ANSWER_CREATION_RESULT, itemsCreationResult2ProtocolString(result));

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: base_hangar_build_item_FAIL(unsigned long fortressId, unsigned long hangarId, const std :: string& reason) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_HANGAR_BUILD_ITEM);
    w.writeValue(REQUEST_HANGAR_BUILD_ITEM_ANSWER_FORTRESSID, fortressId);
	w.writeValue(REQUEST_HANGAR_BUILD_ITEM_ANSWER_HANGAR_ID, hangarId);
    w.writeValue(REQUEST_HANGAR_BUILD_ITEM_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------
char* answerWriter :: base_hangar_build_new_ship(unsigned long fortressId, unsigned long hangarId, itemsCreationResult result) {

	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_HANGAR_BUILD_SHIP);
	w.writeValue(REQUEST_HANGAR_BUILD_SHIP_ANSWER_FORTRESSID, fortressId);
	w.writeValue(REQUEST_HANGAR_BUILD_SHIP_ANSWER_HANGAR_ID, hangarId);
	w.writeValue(REQUEST_HANGAR_BUILD_SHIP_ANSWER_CREATION_RESULT, itemsCreationResult2ProtocolString(result));

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: base_hangar_build_new_ship_FAIL(unsigned long fortressId, unsigned long hangarId, const std :: string& reason) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_HANGAR_BUILD_SHIP);
    w.writeValue(REQUEST_HANGAR_BUILD_SHIP_ANSWER_FORTRESSID, fortressId);
	w.writeValue(REQUEST_HANGAR_BUILD_SHIP_ANSWER_HANGAR_ID, hangarId);
    w.writeValue(REQUEST_HANGAR_BUILD_SHIP_ANSWER_CREATION_RESULT, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------
char* answerWriter :: base_hangar_cancel_item(unsigned long fortressId, unsigned long hangarId) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_HANGAR_CANCEL_ITEM);
	w.writeValue(REQUEST_HANGAR_CANCEL_ITEM_ANSWER_FORTRESSID, fortressId);
	w.writeValue(REQUEST_HANGAR_CANCEL_ITEM_ANSWER_HANGAR_ID, hangarId);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: base_hangar_cancel_item_FAIL(unsigned long fortressId, unsigned long hangarId, const std :: string& reason) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_HANGAR_CANCEL_ITEM);
    w.writeValue(REQUEST_HANGAR_CANCEL_ITEM_ANSWER_FORTRESSID, fortressId);
	 w.writeValue(REQUEST_HANGAR_CANCEL_ITEM_ANSWER_HANGAR_ID, hangarId);
    w.writeValue(REQUEST_HANGAR_CANCEL_ITEM_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: unmount_fortress_device(const unmount_device_info & mountData, const std :: string& mountingResult) 
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_UNMOUNT_FORTRESS_DEVICE);
	w.writeValue(REQUEST_UNMOUNT_FORTRESS_DEVICE_ANSWER_FORTRESSID, mountData.fortressId);
	w.writeValue(REQUEST_UNMOUNT_FORTRESS_DEVICE_ANSWER_WORKING, mountData.working);
	w.writeValue(REQUEST_UNMOUNT_FORTRESS_DEVICE_ANSWER_DAMAGED, mountData.damaged);
	w.writeValue(REQUEST_UNMOUNT_FORTRESS_DEVICE_ANSWER_MOUNTING_RESULT, mountingResult);
	w.writeValue(REQUEST_UNMOUNT_FORTRESS_DEVICE_ANSWER_PATTERN_NAME, mountData.patternName);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: unmount_fortress_device_FAIL(unsigned long fortressId, const std::string& patternName, const std :: string& reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_UNMOUNT_FORTRESS_DEVICE);
    w.writeValue(REQUEST_UNMOUNT_FORTRESS_DEVICE_ANSWER_FORTRESSID, fortressId);
    w.writeValue(REQUEST_UNMOUNT_FORTRESS_DEVICE_ANSWER_FAIL, reason);
	w.writeValue(REQUEST_UNMOUNT_FORTRESS_DEVICE_ANSWER_PATTERN_NAME, patternName);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* adminAnswerWriter :: players(const std :: list<realm_information>& realms)
{
    protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_ADMIN_PLAYERS);

	w.writeValue(create_count_name(REQUEST_ADMIN_PLAYERS_PLAYER_PREFIX), (unsigned long)realms.size());

    int index = 1;
    for (std :: list<realm_information> :: const_iterator it = realms.begin(); it != realms.end(); it++)
    {
		w.writeValue(create_param_name(REQUEST_ADMIN_PLAYERS_PLAYER_PREFIX, REQUEST_ADMIN_PLAYERS_PLAYER_ID, index), it->id);
		w.writeValue(create_param_name(REQUEST_ADMIN_PLAYERS_PLAYER_PREFIX, REQUEST_ADMIN_PLAYERS_PLAYER_LOGIN, index), it->login);
		w.writeValue(create_param_name(REQUEST_ADMIN_PLAYERS_PLAYER_PREFIX, REQUEST_ADMIN_PLAYERS_PLAYER_NAME, index), it->name);
		w.writeValue(create_param_name(REQUEST_ADMIN_PLAYERS_PLAYER_PREFIX, REQUEST_ADMIN_PLAYERS_PLAYER_PLAYER_HAS_BAN, index), (unsigned long) (it->hasBan ? 1 : 0));
        index++;
    }

    w.endMessage(true);
    return w.copyMessage();
}

char* adminAnswerWriter :: player_information(const realm_information & realmState, const std :: list<shipClass*>& ships, const std :: list<baseClass*>& bases)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_ADMIN_PLAYER_INFORMATION);

	w.writeValue(create_param_name(REQUEST_ADMIN_PLAYER_INFORMATION_PLAYER_PREFIX, REQUEST_ADMIN_PLAYER_INFORMATION_PLAYER_ID), realmState.id);
	w.writeValue(create_param_name(REQUEST_ADMIN_PLAYER_INFORMATION_PLAYER_PREFIX, REQUEST_ADMIN_PLAYER_INFORMATION_PLAYER_LOGIN), realmState.login);
	w.writeValue(create_param_name(REQUEST_ADMIN_PLAYER_INFORMATION_PLAYER_PREFIX, REQUEST_ADMIN_PLAYER_INFORMATION_PLAYER_NAME), realmState.name);	
	w.writeValue(create_param_name(REQUEST_ADMIN_PLAYER_INFORMATION_PLAYER_PREFIX, REQUEST_ADMIN_PLAYER_INFORMATION_PLAYER_PLAYER_HAS_BAN), (unsigned long) (realmState.hasBan ? 1 : 0));

	w.writeValue(create_count_name(REQUEST_ADMIN_PLAYER_INFORMATION_SHIP_PREFIX), (unsigned long)ships.size());

    int shipIndex = 1;
    for (std :: list<shipClass*> :: const_iterator iter = ships.begin(); iter != ships.end(); iter++)
    {
		w.writeValue(create_param_name(REQUEST_ADMIN_PLAYER_INFORMATION_SHIP_PREFIX, REQUEST_ADMIN_PLAYER_INFORMATION_SHIP_FORTRESS_ID, shipIndex), (*iter)->getID());
		w.writeValue(create_param_name(REQUEST_ADMIN_PLAYER_INFORMATION_SHIP_PREFIX, REQUEST_ADMIN_PLAYER_INFORMATION_SHIP_FORTRESS_NAME, shipIndex), (*iter)->getFortressName());
		w.writeValue(create_param_name(REQUEST_ADMIN_PLAYER_INFORMATION_SHIP_PREFIX, REQUEST_ADMIN_PLAYER_INFORMATION_SHIP_FORTRESS_CLASS, shipIndex), (*iter)->getFortressClassID());

        shipIndex++;
    }

	w.writeValue(create_count_name(REQUEST_ADMIN_PLAYER_INFORMATION_BASE_PREFIX), (unsigned long)bases.size());

    int baseIndex = 1;
    for (std :: list<baseClass*> :: const_iterator iter = bases.begin(); iter != bases.end(); iter++)
    {
		w.writeValue(create_param_name(REQUEST_ADMIN_PLAYER_INFORMATION_BASE_PREFIX, REQUEST_ADMIN_PLAYER_INFORMATION_BASE_FORTRESS_ID, baseIndex), (*iter)->getID());
		w.writeValue(create_param_name(REQUEST_ADMIN_PLAYER_INFORMATION_BASE_PREFIX, REQUEST_ADMIN_PLAYER_INFORMATION_BASE_FORTRESS_NAME, baseIndex), (*iter)->getFortressName());
		w.writeValue(create_param_name(REQUEST_ADMIN_PLAYER_INFORMATION_BASE_PREFIX, REQUEST_ADMIN_PLAYER_INFORMATION_BASE_FORTRESS_CLASS, baseIndex), (*iter)->getFortressClassID());

        baseIndex++;
    }

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* adminAnswerWriter :: create_ship(unsigned long playerId, shipClass * ship, bool shipCreated)
{
    protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_ADMIN_CREATE_SHIP);

	w.writeValue(REQUEST_ADMIN_CREATE_SHIP_PLAYER_ID, playerId);

	w.writeValue(REQUEST_ADMIN_CREATE_SHIP_CREATED, (unsigned long)(shipCreated ? 1 : 0));

	w.writeValue(create_param_name(REQUEST_ADMIN_CREATE_SHIP_CREATED_SHIP_PREFIX, REQUEST_ADMIN_CREATE_SHIP_FORTRESS_ID), (ship)->getID());
	w.writeValue(create_param_name(REQUEST_ADMIN_CREATE_SHIP_CREATED_SHIP_PREFIX, REQUEST_ADMIN_CREATE_SHIP_FORTRESS_NAME), ship->getFortressName());
	w.writeValue(create_param_name(REQUEST_ADMIN_CREATE_SHIP_CREATED_SHIP_PREFIX, REQUEST_ADMIN_CREATE_SHIP_FORTRESS_CLASS), (ship)->getFortressClassID());

	w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* adminAnswerWriter :: ship_information(shipClass * ship)
{
    protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_ADMIN_SHIP_INFORMATION);

	w.writeValue(REQUEST_ADMIN_SHIP_INFORMATION_FORTRESS_ID, (ship)->getID());
	w.writeValue(REQUEST_ADMIN_SHIP_INFORMATION_FORTRESS_NAME, (ship)->getFortressName());
	w.writeValue(REQUEST_ADMIN_SHIP_INFORMATION_FORTRESS_CLASS, (ship)->getFortressClassID());
	w.writeValue(REQUEST_ADMIN_SHIP_INFORMATION_COORDINATE_X, (double) ship->MovementGetShipPosition().x);
	w.writeValue(REQUEST_ADMIN_SHIP_INFORMATION_COORDINATE_Y, (double) ship->MovementGetShipPosition().y);

	w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* adminAnswerWriter :: base_information(baseClass * base)
{
    protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_ADMIN_BASE_INFORMATION);

	w.writeValue(REQUEST_ADMIN_BASE_INFORMATION_FORTRESS_ID, (base)->getID());
	w.writeValue(REQUEST_ADMIN_BASE_INFORMATION_FORTRESS_NAME, (base)->getFortressName());
	w.writeValue(REQUEST_ADMIN_BASE_INFORMATION_FORTRESS_CLASS, (base)->getFortressClassID());

	w.endMessage(true);
    return w.copyMessage();
}

char* adminAnswerWriter :: ban_player(unsigned long playerId, const std::string & result, bool hasBan) 
{
    protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_ADMIN_BAN_PLAYER);

	w.writeValue(REQUEST_ADMIN_BAN_PLAYER_PLAYER_ID, playerId);
	w.writeValue(REQUEST_ADMIN_BAN_PLAYER_BAN_RESULT, result);
	w.writeValue(REQUEST_ADMIN_BAN_PLAYER_PLAYER_HAS_BAN, (unsigned long) (hasBan ? 1 : 0));
	w.endMessage(true);
    return w.copyMessage();
}

char* adminAnswerWriter :: player_ban_information(unsigned long playerId, const banClass * ban) 
{
    protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_ADMIN_PLAYER_BAN_INFORMATION);

	w.writeValue(REQUEST_ADMIN_PLAYER_BAN_INFORMATION, playerId);

	if (ban != NULL) 
	{
		w.writeValue(REQUEST_ADMIN_PLAYER_BAN_INFORMATION_BAN_LEVEL, (unsigned long) ban->getLevel());
		w.writeValue(REQUEST_ADMIN_PLAYER_BAN_INFORMATION_BAN_DURATION_IN_DAYS, (unsigned long) ban->getDurationInDays());
		w.writeValue(REQUEST_ADMIN_PLAYER_BAN_INFORMATION_BAN_REASON, ban->getReason());
		w.writeValue(REQUEST_ADMIN_PLAYER_BAN_INFORMATION_PLAYER_HAS_BAN, (unsigned long) 1);
	}
	else 
	{
		w.writeValue(REQUEST_ADMIN_PLAYER_BAN_INFORMATION_PLAYER_HAS_BAN, (unsigned long) 0);
	}

	w.endMessage(true);
    return w.copyMessage();
}


// --------------------------------

bool ulong2bool(unsigned long value) {
	if (value == 1) {
		return true;
	}
	else {
		return false;
	}
}

// --------------------------------

unsigned long bool2ulong(bool value) {
	if (value) {
		return 1;
	}
	else {
		return 0;
	}
}

// --------------------------------

char* answerWriter :: ship_location_information(const unsigned long shipId, const location_status & ls)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIP_LOCATION_INFORMATION);

	w.writeValue(REQUEST_SHIP_LOCATION_INFORMATION_SHIPID, shipId);

    w.writeValue(REQUEST_SHIP_LOCATION_INFORMATION_NEAREST_STAR,        ls.nearestStar);
	w.writeValue(REQUEST_SHIP_LOCATION_INFORMATION_SPACE_OBJECT_ACT_IN, ls.actualSpaceObject);
    w.writeValue(REQUEST_SHIP_LOCATION_INFORMATION_STAR_IN,             ls.actualStar);

    w.endMessage(true);
    return w.copyMessage();		
}

// --------------------------------

char* answerWriter :: ship_location_information_FAIL(const unsigned long shipId, const std :: string& reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_SHIP_LOCATION_INFORMATION);
    w.writeValue(REQUEST_SHIP_LOCATION_INFORMATION_SHIPID, shipId);
    w.writeValue(REQUEST_SHIP_LOCATION_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_planets_nonexisting(unsigned long areaid)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_NAVIGATION_PLANETS);
    w.writeValue(REQUEST_NAVIGATION_PLANETS_BAD_ANSWER_TYPE, REQUEST_NAVIGATION_PLANETS_BAD_ANSWER_NOT_EXISTS);
    w.writeValue(REQUEST_NAVIGATION_PLANETS_BAD_ANSWER_BADAREAID, areaid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_planets_notstar(unsigned long areaid)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_NAVIGATION_PLANETS);
    w.writeValue(REQUEST_NAVIGATION_PLANETS_BAD_ANSWER_TYPE, REQUEST_NAVIGATION_PLANETS_BAD_ANSWER_NOT_STAR);
    w.writeValue(REQUEST_NAVIGATION_PLANETS_BAD_ANSWER_BADAREAID, areaid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_planets_ie(unsigned long areaid)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_NAVIGATION_PLANETS);
    w.writeValue(REQUEST_NAVIGATION_PLANETS_BAD_ANSWER_TYPE, REQUEST_NAVIGATION_PLANETS_BAD_ANSWER_IE);
    w.writeValue(REQUEST_NAVIGATION_PLANETS_BAD_ANSWER_BADAREAID, areaid);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: navigation_planets_FAIL(const unsigned long fortressId, const std :: string& reason) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_NAVIGATION_PLANETS);
    w.writeValue(REQUEST_NAVIGATION_PLANETS_SHIPID, fortressId);
    w.writeValue(REQUEST_NAVIGATION_PLANETS_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: player_discovered_stars(const discovered_stars& ds)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_DISCOVERED_STARS);

    w.writeValue(create_count_name(REQUEST_DISCOVERED_STARS_LIST_PREFIX), (unsigned long)ds.dsc_stars.size());

    int starIndex = 1;
    for (std :: vector<discovered_star> :: const_iterator iter = ds.dsc_stars.begin(); iter != ds.dsc_stars.end(); iter++)
    {
		w.writeValue(create_param_name(REQUEST_DISCOVERED_STARS_LIST_PREFIX, REQUEST_DISCOVERED_STAR_ANSWER_DISCOVERED_STAR_NAME, starIndex), (*iter).name);
        w.writeValue(create_param_name(REQUEST_DISCOVERED_STARS_LIST_PREFIX, REQUEST_DISCOVERED_STAR_ANSWER_DISCOVERED_STAR_ID, starIndex), (*iter).id);
        w.writeValue(create_param_name(REQUEST_DISCOVERED_STARS_LIST_PREFIX, REQUEST_DISCOVERED_STAR_ANSWER_DISCOVERED_STAR_POS_X, starIndex), (*iter).pos.x);
		w.writeValue(create_param_name(REQUEST_DISCOVERED_STARS_LIST_PREFIX, REQUEST_DISCOVERED_STAR_ANSWER_DISCOVERED_STAR_POS_Y, starIndex), (*iter).pos.y);

        starIndex++;
    }

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: send_trade_invitation_FAIL(const std::string & reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_SEND_TRADE_INVITATION);
    w.writeValue(REQUEST_SEND_TRADE_INVITATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: send_trade_invitation(const trade_invitation_data & invitation, const std::string & reason, tradingRole tradeRole)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_SEND_TRADE_INVITATION);
    w.writeValue(REQUEST_SEND_TRADE_INVITATION_ANSWER_REASON, reason);
	w.writeValue(REQUEST_SEND_TRADE_INVITATION_ANSWER_TRADE_ROLE, tradingRoleToString(tradeRole));
	write_trade_invitation(w, invitation);

    w.endMessage(true);
    return w.copyMessage();
}

char* answerWriter :: send_trade_invitation(const trade_invitation_data & invitation, const trade_data & selfTradeData, const trade_data & partnerTradeData, const std::string & reason, tradingRole tradeRole)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_SEND_TRADE_INVITATION);
    w.writeValue(REQUEST_SEND_TRADE_INVITATION_ANSWER_REASON, reason);
	w.writeValue(REQUEST_SEND_TRADE_INVITATION_ANSWER_TRADE_ROLE, tradingRoleToString(tradeRole));
	write_trade_invitation(w, invitation);
	write_trade_start_data(w, REQUEST_SEND_TRADE_INVITATION_SELF_DATA_PREFIX, selfTradeData);
	write_trade_start_data(w, REQUEST_SEND_TRADE_INVITATION_PARTNER_DATA_PREFIX, partnerTradeData);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: send_trade_invitation(const trade_invitation_data & invitation, const trade_data & selfTradeData, const std::string & reason, tradingRole tradeRole)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_SEND_TRADE_INVITATION);
    w.writeValue(REQUEST_SEND_TRADE_INVITATION_ANSWER_REASON, reason);
	w.writeValue(REQUEST_SEND_TRADE_INVITATION_ANSWER_TRADE_ROLE, tradingRoleToString(tradeRole));
	write_trade_invitation(w, invitation);
	write_trade_start_data(w, REQUEST_SEND_TRADE_INVITATION_SELF_DATA_PREFIX, selfTradeData);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: decide_trade_invitation(const trade_invitation_data & invitation)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_DECIDE_TRADE_INVITATION);
	w.writeValue(REQUEST_DECIDE_TRADE_INVITATION_ANSWER_ACCEPTED, false);
	write_trade_invitation(w, invitation);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: decide_trade_invitation(const trade_invitation_data & invitation, const trade_data & tradeData)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_DECIDE_TRADE_INVITATION);
	w.writeValue(REQUEST_DECIDE_TRADE_INVITATION_ANSWER_ACCEPTED, true);
	write_trade_invitation(w, invitation);
	write_trade_start_data(w, REQUEST_DECIDE_TRADE_INVITATION_ANSWER_SELF_DATA_PREFIX, tradeData);

    w.endMessage(true);
    return w.copyMessage();
}

void answerWriter :: write_trade_invitation(protocolWriter & w, const trade_invitation_data & invitation)
{
	w.writeValue(TRADE_INVITATION_INVITED_ID, invitation.invitedId);
	w.writeValue(TRADE_INVITATION_INVITED_NAME, invitation.invitedName);
	w.writeValue(TRADE_INVITATION_INVITED_FORTRESS_ID, invitation.invitedFortressId);
    w.writeValue(TRADE_INVITATION_INVITED_FORTRESS_NAME, invitation.invitedFortressName);
	w.writeValue(TRADE_INVITATION_HOST_FORTRESS_ID, invitation.hostFortressId);
	w.writeValue(TRADE_INVITATION_HOST_FORTRESS_NAME, invitation.hostFortressName);
	w.writeValue(TRADE_INVITATION_HOST_ID, invitation.hostId);
	w.writeValue(TRADE_INVITATION_HOST_NAME, invitation.hostName);

	w.writeValue(TRADE_INVITATION_HOST_IS_SHIP, invitation.hostIsShip);
	w.writeValue(TRADE_INVITATION_INVITED_IS_SHIP, invitation.invitedIsShip);
}

// --------------------------------

char* answerWriter :: receive_trade_invitation_decision(const trade_invitation_data & invitation)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, RECEIVE_TRADE_INVITATION_DECISION);
	w.writeValue(RECEIVE_TRADE_INVITATION_DECISION_ACCEPTED, false);
	write_trade_invitation(w, invitation);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: receive_trade_invitation_decision(const trade_invitation_data & invitation, const trade_data & tradeData)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, RECEIVE_TRADE_INVITATION_DECISION);
	w.writeValue(RECEIVE_TRADE_INVITATION_DECISION_ACCEPTED, true);
	write_trade_invitation(w, invitation);
	write_trade_start_data(w, RECEIVE_TRADE_INVITATION_DECISION_ANSWER_SELF_DATA_PREFIX, tradeData);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: receive_trade_invitation(const trade_invitation_data & invitation)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, RECEIVE_TRADE_INVITATION);
	write_trade_invitation(w, invitation);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: cancel_trade(unsigned long ownedFortressId, unsigned long partnerFortressId, const std::string & reason, tradingRole tradeRole)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_CANCEL_TRADE);
    w.writeValue(REQUEST_CANCEL_TRADE_ANSWER_REASON, reason);
	w.writeValue(REQUEST_CANCEL_TRADE_ANSWER_TRADE_ROLE, tradingRoleToString(tradeRole));
    w.writeValue(REQUEST_CANCEL_TRADE_ANSWER_OWNED_FORTRESS_ID, ownedFortressId);
	w.writeValue(REQUEST_CANCEL_TRADE_ANSWER_PARTNER_FORTRESS_ID, partnerFortressId);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: receive_cancel_trade(unsigned long ownedFortressId, unsigned long partnerFortressId)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, RECEIVE_TRADE_CANCELATION);
    w.writeValue(RECEIVE_TRADE_CANCELATION_OWNED_FORTRESS_ID, ownedFortressId);
	w.writeValue(RECEIVE_TRADE_CANCELATION_PARTNER_FORTRESS_ID, partnerFortressId);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: cancel_trade_FAIL(unsigned long ownedFortressId, unsigned long partnerFortressId, const std::string & reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_CANCEL_TRADE);
    w.writeValue(REQUEST_CANCEL_TRADE_ANSWER_REASON, reason);
    w.writeValue(REQUEST_CANCEL_TRADE_ANSWER_OWNED_FORTRESS_ID, ownedFortressId);
	w.writeValue(REQUEST_CANCEL_TRADE_ANSWER_PARTNER_FORTRESS_ID, partnerFortressId);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: trade_partner_fortresses_FAIL(unsigned long ownedFortressId, const std::string & reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_TRADE_PARTNER_FORTRESSES);
    w.writeValue(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_REASON, reason);
    w.writeValue(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_FORTRESS_ID, ownedFortressId);
    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: trade_partner_fortresses(unsigned long fortressId, const std::list<fortressClass*> & ownedFortresses, const std::list<fortressClass*> & notOwnedFortresses)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_TRADE_PARTNER_FORTRESSES);

	w.writeValue(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_FORTRESS_ID, fortressId);

	w.writeValue(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_OWNED_FORTRESS_COUNT, (unsigned long) ownedFortresses.size());

	int ownedIndex = 1;
	for (std::list<fortressClass*>::const_iterator it = ownedFortresses.begin(); it != ownedFortresses.end(); ++it)
	{
		w.writeValue(create_param_name(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_OWNED_FORTRESS_ID, ownedIndex), (*it)->getID());
		w.writeValue(create_param_name(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_OWNED_FORTRESS_NAME, ownedIndex), (*it)->getFortressName());
		w.writeValue(create_param_name(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_OWNED_FORTRESS_TYPE, ownedIndex), (unsigned long) (*it)->getFortressType());
		w.writeValue(create_param_name(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_OWNED_FORTRESS_SHELL, ownedIndex), (*it)->isShell(false));
		ownedIndex++;
	}

	w.writeValue(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_NOT_OWNED_FORTRESS_COUNT, (unsigned long) notOwnedFortresses.size());

	int notOwnedIndex = 1;
	for (std::list<fortressClass*>::const_iterator it = notOwnedFortresses.begin(); it != notOwnedFortresses.end(); ++it)
	{
		w.writeValue(create_param_name(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_NOT_OWNED_FORTRESS_ID, notOwnedIndex), (*it)->getID());
		w.writeValue(create_param_name(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_NOT_OWNED_FORTRESS_NAME, notOwnedIndex), (*it)->getFortressName());
		w.writeValue(create_param_name(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_NOT_OWNED_FORTRESS_REALM_NAME, notOwnedIndex), (*it)->getFortressRealm()->getPlayerName());	
		w.writeValue(create_param_name(REQUEST_TRADE_PARTNER_FORTRESSES_ANSWER_NOT_OWNED_FORTRESS_SHELL, notOwnedIndex), (*it)->isShell(false));
		notOwnedIndex++;
	}

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

std::string tradingRoleToString(tradingRole tradeRole) 
{
	switch (tradeRole) 
	{
	case TRADE_ROLE_NONE:
		return PROTOCOL_TRADE_ROLE_NONE;
	case TRADE_ROLE_HOST:
		return PROTOCOL_TRADE_ROLE_HOST;
	case TRADE_ROLE_PARTNER_TRADER:
		return PROTOCOL_TRADE_ROLE_PARTNER_TRADER;
	case TRADE_ROLE_SELF_TRADER:
		return PROTOCOL_TRADE_ROLE_SELF_TRADER;
	case TRADE_ROLE_LOOT_TRADER:
		return PROTOCOL_TRADE_ROLE_LOOT_TRADER;
	case TRADE_ROLE_SPACE_TRADER:
		return PROTOCOL_TRADE_ROLE_SPACE_TRADER;
	}

	return "";
}

// --------------------------------

std::string tradingResultToString(tradingResult tradeResult) 
{
	switch (tradeResult) 
	{
	case TR_DONE:
		return PROTOCOL_TRADE_RESULT_DONE;
	case TR_FIRST_FORTRESS_WEIGHT_LIMIT:
		return PROTOCOL_TRADE_RESULT_FIRST_FORTRESS_WEIGHT_LIMIT;
	case TR_SECOND_FORTRESS_WEIGHT_LIMIT:
		return PROTOCOL_TRADE_RESULT_SECOND_FORTRESS_WEIGHT_LIMIT;
	case TR_FIRST_FORTRESS_CAPACITY_LIMIT:
		return PROTOCOL_TRADE_RESULT_FIRST_FORTRESS_CAPACITY_LIMIT;
	case TR_SECOND_FORTRESS_CAPACITY_LIMIT:
		return PROTOCOL_TRADE_RESULT_SECOND_FORTRESS_CAPACITY_LIMIT;
	case TR_FIRST_FORTRESS_NOT_STORING_ITEMS:
		return PROTOCOL_TRADE_RESULT_FIRST_FORTRESS_NOT_STORING_ITEMS;
	case TR_SECOND_FORTRESS_NOT_STORING_ITEMS:
		return PROTOCOL_TRADE_RESULT_SECOND_FORTRESS_NOT_STORING_ITEMS;
	case TR_FIRST_FORTRESS_MAGNETICAL_GRIDS_LACK:
		return PROTOCOL_TRADE_RESULT_FIRST_FORTRESS_MAGNETICAL_GRIDS_LACK;
	case TR_SECOND_FORTRESS_MAGNETICAL_GRIDS_LACK:
		return PROTOCOL_TRADE_RESULT_SECOND_FORTRESS_MAGNETICAL_GRIDS_LACK;
	case TR_FIRST_FORTRESS_TRANSPORT_CONTAINERS_LACK:
		return PROTOCOL_TRADE_RESULT_FIRST_FORTRESS_TRANSPORT_CONTAINERS_LACK;
	case TR_SECOND_FORTRESS_TRANSPORT_CONTAINERS_LACK:
		return PROTOCOL_TRADE_RESULT_SECOND_FORTRESS_TRANSPORT_CONTAINERS_LACK;
	case TR_FIRST_FORTRESS_ENERGETIC_CELLS_LACK:
		return PROTOCOL_TRADE_RESULT_FIRST_FORTRESS_ENERGETIC_CELLS_LACK;
	case TR_SECOND_FORTRESS_ENERGETIC_CELLS_LACK:
		return PROTOCOL_TRADE_RESULT_SECOND_FORTRESS_ENERGETIC_CELLS_LACK;
	case TR_NOT_IN_RANGE:
		return PROTOCOL_TRADE_RESULT_NOT_IN_RANGE;
	case TR_UNKNOWN_FAIL:
		return PROTOCOL_TRADE_RESULT_UNKNOWN_FAIL;
	}

	return "";
}

// --------------------------------

std::string tradingCommitRoleToString(tradingCommitRole role) 
{
	switch (role) 
	{
	case TRADE_COMMIT_ROLE_HOST:
		return PROTOCOL_TRADE_COMMIT_ROLE_HOST;
	case TRADE_COMMIT_ROLE_INVITED:
		return PROTOCOL_TRADE_COMMIT_ROLE_INVITED;
	case TRADE_COMMIT_ROLE_NONE:
		return PROTOCOL_TRADE_COMMIT_ROLE_NONE;
	}

	return "";
}

// --------------------------------

char* answerWriter :: decide_trade_invitation_FAIL(unsigned long hostFortressId, unsigned long invitedFortressId, const std :: string& reason) 
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_DECIDE_TRADE_INVITATION);
	w.writeValue(REQUEST_DECIDE_TRADE_INVITATION_ANSWER_FAIL, reason);
	w.writeValue(REQUEST_DECIDE_TRADE_INVITATION_ANSWER_INVITED_FORTRESS_ID, invitedFortressId);
	w.writeValue(REQUEST_DECIDE_TRADE_INVITATION_ANSWER_HOST_FORTRESS_ID, hostFortressId);

    w.endMessage(false);
    return w.copyMessage();
}

char* answerWriter :: move_trade_item(const trade_movement_data & tradeData, bool isAuthor) 
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_MOVE_TRADE_ITEM);
	w.writeValue(REQUEST_MOVE_TRADE_ITEM_ANSWER_AUTHOR, isAuthor);
	write_trade_movement_data(w, tradeData);

    w.endMessage(true);
    return w.copyMessage();
}

char* answerWriter :: move_trade_item_FAIL(const trade_client_movement_data & tradeData, const std::string & reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_MOVE_TRADE_ITEM);
	w.writeValue(REQUEST_MOVE_TRADE_ITEM_ANSWER_FAIL_REASON, reason);
	requestWriter::write_trade_movement_data(w, tradeData);

    w.endMessage(false);
    return w.copyMessage();
}

char* answerWriter :: commit_trade_FAIL(unsigned long selfFortressId, unsigned long partnerFortressId, const std::string & reason) 
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_COMMIT_TRADE);
	w.writeValue(REQUEST_COMMIT_TRADE_ANSWER_FAIL_REASON, reason);
	w.writeValue(REQUEST_COMMIT_TRADE_ANSWER_SELF_FORTRESS_ID, selfFortressId);
	w.writeValue(REQUEST_COMMIT_TRADE_ANSWER_PARTNER_FORTRESS_ID, partnerFortressId);

    w.endMessage(false);
    return w.copyMessage();
}

char* answerWriter :: commit_trade(unsigned long selfFortressId, unsigned long partnerFortressId, tradingResult result)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_COMMIT_TRADE);
	w.writeValue(REQUEST_COMMIT_TRADE_ANSWER_RESULT, tradingResultToString(result));
	w.writeValue(REQUEST_COMMIT_TRADE_ANSWER_SELF_FORTRESS_ID, selfFortressId);
	w.writeValue(REQUEST_COMMIT_TRADE_ANSWER_PARTNER_FORTRESS_ID, partnerFortressId);

    w.endMessage(true);
    return w.copyMessage();
}

char* answerWriter :: prepare_commit_trade(unsigned long selfFortressId, unsigned long partnerFortressId, tradingCommitRole role)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_PREPARE_COMMIT_TRADE);
	w.writeValue(REQUEST_PREPARE_COMMIT_TRADE_ANSWER_TRADE_COMMIT_ROLE, tradingCommitRoleToString(role));
	w.writeValue(REQUEST_PREPARE_COMMIT_TRADE_ANSWER_SELF_FORTRESS_ID, selfFortressId);
	w.writeValue(REQUEST_PREPARE_COMMIT_TRADE_ANSWER_PARTNER_FORTRESS_ID, partnerFortressId);

    w.endMessage(true);
    return w.copyMessage();
}

char* answerWriter :: cancel_trade_commit(unsigned long selfFortressId, unsigned long partnerFortressId, const std::string & reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_CANCEL_TRADE_COMMIT);
	w.writeValue(REQUEST_CANCEL_TRADE_COMMIT_ANSWER_REASON, reason);
	w.writeValue(REQUEST_CANCEL_TRADE_COMMIT_ANSWER_SELF_FORTRESS_ID, selfFortressId);
	w.writeValue(REQUEST_CANCEL_TRADE_COMMIT_ANSWER_PARTNER_FORTRESS_ID, partnerFortressId);

    w.endMessage(true);
    return w.copyMessage();
}

char* answerWriter :: cancel_trade_commit_FAIL(unsigned long selfFortressId, unsigned long partnerFortressId, const std::string & reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_CANCEL_TRADE_COMMIT);
	w.writeValue(REQUEST_CANCEL_TRADE_COMMIT_ANSWER_REASON, reason);
	w.writeValue(REQUEST_CANCEL_TRADE_COMMIT_ANSWER_SELF_FORTRESS_ID, selfFortressId);
	w.writeValue(REQUEST_CANCEL_TRADE_COMMIT_ANSWER_PARTNER_FORTRESS_ID, partnerFortressId);

    w.endMessage(true);
    return w.copyMessage();
}

char* answerWriter :: move_trade_resource(const trade_resource_movement_data & tradeData, bool isAuthor) 
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_MOVE_TRADE_RESOURCE);
	w.writeValue(REQUEST_MOVE_TRADE_RESOURCE_ANSWER_AUTHOR, isAuthor);
	write_trade_resource_movement_data(w, tradeData);

    w.endMessage(true);
    return w.copyMessage();
}

char* answerWriter :: move_trade_resource_FAIL(const trade_resource_movement_data & tradeData, const std::string & reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_MOVE_TRADE_ITEM);
	w.writeValue(REQUEST_MOVE_TRADE_RESOURCE_ANSWER_FAIL_REASON, reason);
	write_trade_resource_movement_data(w, tradeData);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: mount_fortress_device(unsigned long fortressId, unsigned long itemId, const std :: string& mountingResult) 
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_MOUNT_FORTRESS_DEVICE);
	w.writeValue(REQUEST_MOUNT_FORTRESS_DEVICE_ANSWER_FORTRESSID, fortressId);
	w.writeValue(REQUEST_MOUNT_FORTRESS_DEVICE_ANSWER_MOUNTING_RESULT, mountingResult);
	w.writeValue(REQUEST_MOUNT_FORTRESS_DEVICE_ANSWER_ITEM_ID, itemId);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: mount_fortress_device_FAIL(unsigned long fortressId, unsigned long itemId, const std :: string& reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_MOUNT_FORTRESS_DEVICE);
    w.writeValue(REQUEST_MOUNT_FORTRESS_DEVICE_ANSWER_FORTRESSID, fortressId);
    w.writeValue(REQUEST_MOUNT_FORTRESS_DEVICE_ANSWER_FAIL, reason);
	w.writeValue(REQUEST_MOUNT_FORTRESS_DEVICE_ANSWER_ITEM_ID, itemId);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

void answerWriter ::  write_fortress_detailed_fight_data(protocolWriter & w, fortressClass * fortress, unsigned long index) 
{
	w.writeValue(create_param_name(FORTRESS_DETAILED_FIGHT_DATA_FORTRESS_ID, index), fortress->getID());
	w.writeValue(create_param_name(FORTRESS_DETAILED_FIGHT_DATA_FORTRESS_NAME, index), fortress->getFortressName());
	w.writeValue(create_param_name(FORTRESS_DETAILED_FIGHT_DATA_FORTRESS_TYPE, index), (unsigned long) fortress->getFortressType());
	w.writeValue(create_param_name(FORTRESS_DETAILED_FIGHT_DATA_FORTRESS_ACTUAL_INTEGRITY, index), fortress->actualStructuralIntegrity());
	w.writeValue(create_param_name(FORTRESS_DETAILED_FIGHT_DATA_FORTRESS_TOTAL_INTEGRITY, index), fortress->totalStructuralIntegrity());
	w.writeValue(create_param_name(FORTRESS_DETAILED_FIGHT_DATA_FORTRESS_INTEGRITY_GRADIENT, index), fortress->actualStructuralIntegrityGradient());
	w.writeValue(create_param_name(FORTRESS_DETAILED_FIGHT_DATA_FORTRESS_SHIELDS_ENERGY, index), fortress->deflectorShields.getEnergy(fortress));
	w.writeValue(create_param_name(FORTRESS_DETAILED_FIGHT_DATA_FORTRESS_SHIELDS_ACCUMULATOR, index), fortress->deflectorShields.deflectorShieldsGenerator()->actualAccumulator());
	w.writeValue(create_param_name(FORTRESS_DETAILED_FIGHT_DATA_FORTRESS_SHIELDS_CLIENT_ACCUMULATOR, index), fortress->deflectorShields.deflectorShieldsGenerator()->clientAccumulator());
	w.writeValue(create_param_name(FORTRESS_DETAILED_FIGHT_DATA_FORTRESS_SHIELDS_GRADIENT, index), fortress->deflectorShields.getGradient());
}

// --------------------------------

char* answerWriter :: fortresses_in_weapons_range(fortressClass * fortress, const std::list<shipClass*> & ships, const std::list<baseClass*> & bases)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_FORTRESSES_IN_WEAPONS_RANGE);
	w.writeValue(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_FORTRESS_ID, (unsigned long) fortress->getID());

	w.writeValue(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_SHIP_COUNT, (unsigned long) ships.size());

	unsigned long index = 1;
	for (std::list<shipClass*>::const_iterator it = ships.begin(); it != ships.end(); ++it) 
	{
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_SHIP_ID, index), (*it)->getID());
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_SHIP_NAME, index), (*it)->getFortressName());
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_SHIP_REALM_NAME, index), (*it)->getFortressRealm()->getPlayerName());
		index++;
	}

	w.writeValue(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_BASE_COUNT, (unsigned long)bases.size());

	index = 1;
	for (std::list<baseClass*>::const_iterator it = bases.begin(); it != bases.end(); ++it) 
	{
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_BASE_ID, index), (*it)->getID());
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_BASE_NAME, index), (*it)->getFortressName());
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_BASE_REALM_NAME, index), (*it)->getFortressRealm()->getPlayerName());
		index++;
	}	

	// Informace o vybrane lodi
	write_fortress_detailed_fight_data(w, fortress, 1);

	dtIdentifier targetFortressID = fortress->getWeaponsTargetID();

	if (targetFortressID != NOT_VALID_ID) 
	{
		fortressClass * targetFortress = actx->cacheFortressesList.getItem<fortressClass>(targetFortressID);

		if (!targetFortress == NULL) 
		{				
			w.writeValue(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_FORTRESS_IN_WEAPONS_TARGET_NAME, targetFortress->getFortressName());								
			w.writeValue(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_FORTRESS_IN_WEAPONS_TARGET_ID, targetFortress->getID());	
			w.writeValue(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_FORTRESS_IN_WEAPONS_TARGET_REALM_NAME, targetFortress->getFortressRealm()->getPlayerName());
			w.writeValue(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_FORTRESS_IN_WEAPONS_TARGET_TYPE, (unsigned long) targetFortress->getFortressType());
		}
		else
		{
			errExceptionError("Fortress with id %u not found!", (unsigned long long) targetFortressID);
			w.writeValue(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_FORTRESS_IN_WEAPONS_TARGET_ID, (unsigned long) NOT_VALID_ID);
		}
	}		
	else 
	{
		w.writeValue(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_FORTRESS_IN_WEAPONS_TARGET_ID, (unsigned long) NOT_VALID_ID);
	}

	w.writeValue(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_FORTRESS_TYPE, (unsigned long) fortress->getFortressType());

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortresses_in_weapons_range_FAIL(unsigned long fortressId, const std::string & reason) 
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_FORTRESSES_IN_WEAPONS_RANGE);
    w.writeValue(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_FORTRESS_ID, fortressId);
    w.writeValue(REQUEST_FORTRESSES_IN_WEAPONS_RANGE_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: attack_fortress(unsigned long selfFortressId, unsigned long enemyFortressId) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_ATTACK_FORTRESS);
    w.writeValue(REQUEST_ATTACK_FORTRESS_ANSWER_SELF_FORTRESS_ID, selfFortressId);
    w.writeValue(REQUEST_ATTACK_FORTRESS_ANSWER_ENEMY_FORTRESS_ID, enemyFortressId);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: attack_fortress_FAIL(unsigned long selfFortressId, unsigned long enemyFortressId, const std::string & reason) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_ATTACK_FORTRESS);
    w.writeValue(REQUEST_ATTACK_FORTRESS_ANSWER_SELF_FORTRESS_ID, selfFortressId);
    w.writeValue(REQUEST_ATTACK_FORTRESS_ANSWER_ENEMY_FORTRESS_ID, enemyFortressId);
	w.writeValue(REQUEST_ATTACK_FORTRESS_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: stop_attack_fortress(unsigned long selfFortressId) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_STOP_ATTACK_FORTRESS);
    w.writeValue(REQUEST_STOP_ATTACK_FORTRESS_ANSWER_SELF_FORTRESS_ID, selfFortressId);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: stop_attack_fortress_FAIL(unsigned long selfFortressId, const std::string & reason) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_STOP_ATTACK_FORTRESS);
    w.writeValue(REQUEST_STOP_ATTACK_FORTRESS_ANSWER_SELF_FORTRESS_ID, selfFortressId);
	w.writeValue(REQUEST_STOP_ATTACK_FORTRESS_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fight_action_report(fortressClass * selfFortress, fortressClass * enemyFortress, fight_action_type action) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_FIGHT_ACTION_REPORT);
	w.writeValue(REQUEST_FIGHT_ACTION_REPORT_SELF_FORTRESS_ID, selfFortress->getID());
	w.writeValue(REQUEST_FIGHT_ACTION_REPORT_SELF_FORTRESS_NAME, selfFortress->getFortressName());
	w.writeValue(REQUEST_FIGHT_ACTION_REPORT_SELF_FORTRESS_REALM_NAME, selfFortress->getFortressRealm()->getPlayerName());
	w.writeValue(REQUEST_FIGHT_ACTION_REPORT_SELF_SHIP, selfFortress->getFortressType() == FT_SHIP);

	if (enemyFortress != NULL) {
		w.writeValue(REQUEST_FIGHT_ACTION_REPORT_ENEMY_FORTRESS_EXISTS, true);
		w.writeValue(REQUEST_FIGHT_ACTION_REPORT_ENEMY_FORTRESS_ID, enemyFortress->getID());
		w.writeValue(REQUEST_FIGHT_ACTION_REPORT_ENEMY_FORTRESS_NAME, enemyFortress->getFortressName());
		w.writeValue(REQUEST_FIGHT_ACTION_REPORT_ENEMY_FORTRESS_REALM_NAME, enemyFortress->getFortressRealm()->getPlayerName());
		w.writeValue(REQUEST_FIGHT_ACTION_REPORT_ENEMY_SHIP, enemyFortress->getFortressType() == FT_SHIP);
	}
	else {
		w.writeValue(REQUEST_FIGHT_ACTION_REPORT_ENEMY_FORTRESS_EXISTS, false);
	}

	std::string actionString;
	if (fight_action_type_to_string(action, actionString)) {
		w.writeValue(REQUEST_FIGHT_ACTION_REPORT_ACTION, actionString);
	}
	else {
		w.writeValue(REQUEST_FIGHT_ACTION_REPORT_ACTION, "");
	}

    w.endMessage(true);
    return w.copyMessage();
}
// --------------------------------

char* answerWriter :: fortresses_in_conquer_range_FAIL(unsigned long selfFortressId, const std::string & reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_FORTRESSES_IN_CONQUER_RANGE);
	w.writeValue(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_FORTRESS_ID, selfFortressId);
	w.writeValue(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_FAIL, reason);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortresses_in_conquer_range(fortressClass * selfFortress, const std::list<fortressClass*> & ships, const std::list<fortressClass*> & bases)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_FORTRESSES_IN_CONQUER_RANGE);

	w.writeValue(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_FORTRESS_ID, selfFortress->getID());
						 
	w.writeValue(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_SHIP_COUNT, (unsigned long) ships.size());

	int shipIndex = 1;
	for (std::list<fortressClass*>::const_iterator it = ships.begin(); it != ships.end(); ++it)
	{
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_SHIP_ID, shipIndex), (*it)->getID());
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_SHIP_NAME, shipIndex), (*it)->getFortressName());
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_SHIP_IN_TRADE_RANGE, shipIndex), (*it)->isInRangeForTrade(selfFortress));	
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_SHIP_IN_CONQUER_RANGE, shipIndex), (*it)->isInRangeForConquer(selfFortress));	
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_SHIP_IN_IS_SHELL, shipIndex), (*it)->isShell(true));	
		shipIndex++;
	}

	w.writeValue(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_BASE_COUNT, (unsigned long) bases.size());

	int baseIndex = 1;
	for (std::list<fortressClass*>::const_iterator it = bases.begin(); it != bases.end(); ++it)
	{
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_BASE_ID, baseIndex), (*it)->getID());
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_BASE_NAME, baseIndex), (*it)->getFortressName());
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_BASE_REALM_NAME, baseIndex), (*it)->getFortressRealm()->getPlayerName());	
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_BASE_IN_TRADE_RANGE, baseIndex), (*it)->isInRangeForTrade(selfFortress));	
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_BASE_IN_CONQUER_RANGE, baseIndex), (*it)->isInRangeForConquer(selfFortress));	
		w.writeValue(create_param_name(REQUEST_FORTRESSES_IN_CONQUER_RANGE_ANSWER_BASE_IN_IS_SHELL, baseIndex), (*it)->isShell(true));
		baseIndex++;
	}

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: build_new_base_shell_FAIL(unsigned long selfFortressId, const std::string & reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_BUILD_NEW_BASE_SHELL);
	w.writeValue(REQUEST_BUILD_NEW_BASE_SHELL_ANSWER_SELF_FORTRESS_ID, selfFortressId);
	w.writeValue(REQUEST_BUILD_NEW_BASE_SHELL_ANSWER_FAIL, reason);
		
	w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: build_new_base_shell(unsigned long selfFortressId, baseBuildingResult result, unsigned long long newTitan)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_BUILD_NEW_BASE_SHELL);

	w.writeValue(REQUEST_BUILD_NEW_BASE_SHELL_ANSWER_SELF_FORTRESS_ID, selfFortressId);
	w.writeValue(REQUEST_BUILD_NEW_BASE_SHELL_ANSWER_BUILDING_RESULT, (unsigned long) result);
	w.writeValue(REQUEST_BUILD_NEW_BASE_SHELL_ANSWER_NEW_TITAN, newTitan);
		
	w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: available_fortress_classes_FAIL(unsigned long fortressId, const std::string & reason)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_AVAILABLE_FORTRESS_CLASSES);
	w.writeValue(REQUEST_AVAILABLE_FORTRESS_CLASSES_ANSWER_SELF_FORTRESS_ID, fortressId);
	w.writeValue(REQUEST_AVAILABLE_FORTRESS_CLASSES_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}
// --------------------------------

char* answerWriter :: available_fortress_classes(fortressClass * selfFortress, const std::list<fortressClassClass*> & shipClasses, const std::list<fortressClassClass*> & baseClasses)
{
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_AVAILABLE_FORTRESS_CLASSES);

	w.writeValue(REQUEST_AVAILABLE_FORTRESS_CLASSES_ANSWER_SELF_FORTRESS_ID, selfFortress->getID());
						 
	w.writeValue(REQUEST_AVAILABLE_FORTRESS_CLASSES_ANSWER_SHIP_CLASS_COUNT, (unsigned long) shipClasses.size());

	int shipIndex = 1;
	for (std::list<fortressClassClass*>::const_iterator it = shipClasses.begin(); it != shipClasses.end(); ++it)
	{
		w.writeValue(create_param_name(REQUEST_AVAILABLE_FORTRESS_CLASSES_ANSWER_SHIP_CLASS_ID, shipIndex), (*it)->getID());
		w.writeValue(create_param_name(REQUEST_AVAILABLE_FORTRESS_CLASSES_ANSWER_SHIP_CLASS_NAME, shipIndex), (*it)->getClassName());
		w.writeValue(create_param_name(REQUEST_AVAILABLE_FORTRESS_CLASSES_ANSWER_SHIP_CLASS_QUALITY, shipIndex), (*it)->getQualityRating());	
		shipIndex++;
	}

	w.writeValue(REQUEST_AVAILABLE_FORTRESS_CLASSES_ANSWER_BASE_CLASS_COUNT, (unsigned long) baseClasses.size());

	int baseIndex = 1;
	for (std::list<fortressClassClass*>::const_iterator it = baseClasses.begin(); it != baseClasses.end(); ++it)
	{
		w.writeValue(create_param_name(REQUEST_AVAILABLE_FORTRESS_CLASSES_ANSWER_BASE_CLASS_ID, baseIndex), (*it)->getID());
		w.writeValue(create_param_name(REQUEST_AVAILABLE_FORTRESS_CLASSES_ANSWER_BASE_CLASS_NAME, baseIndex), (*it)->getClassName());
		w.writeValue(create_param_name(REQUEST_AVAILABLE_FORTRESS_CLASSES_ANSWER_BASE_CLASS_QUALITY, baseIndex), (*it)->getQualityRating());	
		baseIndex++;
	}

    w.endMessage(true);
    return w.copyMessage();
}
// --------------------------------
char* answerWriter :: fortress_class_data_FAIL(unsigned long fortressClassId, const std::string & reason) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_CLASS_DATA);

	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_ID, fortressClassId);
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_FAIL, reason);

    w.endMessage(true);
    return w.copyMessage();
}
// --------------------------------
char* answerWriter :: fortress_class_data(fortressClassClass* fortessClazz) {
	protocolWriter w;
	w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_CLASS_DATA);

	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_CLASS_NAME, fortessClazz->getClassName());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_ID, fortessClazz->getID());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_MASS_RATING, fortessClazz->getMassRating());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_MAX_DRONE_MISSILE_LAUNCHERS, fortessClazz->getMaxDroneMissileLaunchers());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_MAX_HEIGHT, fortessClazz->getMaxHeight());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_MAX_WIDTH, fortessClazz->getMaxWidth());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_MAX_LASER_GUNS, fortessClazz->getMaxLaserGuns());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_MAX_LENGTH, fortessClazz->getMaxLength());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_MAX_TOTAL_STRUCTURAL_INTEGRITY, fortessClazz->getMaxTotalStructuralIntegrity());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_MAX_WEAPONS, fortessClazz->getMaxWeapons());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_MIN_TOTAL_STRUCTURAL_INTEGRITY, fortessClazz->getMinTotalStructuralIntegrity());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_MIN_WEIGHT, fortessClazz->getMinWeight());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_MAX_WEIGHT, fortessClazz->getMaxWeight());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_QUALITY_RATING, fortessClazz->getQualityRating());
	w.writeValue(REQUEST_FORTRESS_CLASS_DATA_ANSWER_IS_BASE_CLASS, fortessClazz->getClassType() == FT_BASE);

    w.endMessage(true);
    return w.copyMessage();				
}

// --------------------------------

char* answerWriter :: player_fortresses_build_information(const std :: list<shipClass*>& ships, const std :: list<baseClass*>& bases)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION);

	w.writeValue(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_SHIP_COUNT, (unsigned long) ships.size());

    int shipIndex = 1;
    for (std :: list<shipClass*> :: const_iterator iter = ships.begin(); iter != ships.end(); iter++)
    {
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_SHIP_ID, shipIndex), (*iter)->getID());
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_SHIP_NAME, shipIndex), (*iter)->getFortressName());

		spacePlanetObject * planet;
		bool isTherePlanetToBuildABase = (*iter)->isThereSomeAblePlanetToBuildAShell(&planet);

		if (isTherePlanetToBuildABase && planet != 0) {
			w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_SHIP_PLANET_TO_BUILD_A_BASE_NAME, shipIndex), planet->getName());			
		}

		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_SHIP_REQUIRED_TITAN, shipIndex), (*iter)->requiredTitaniumToBuildAShell(planet));

		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_SHIP_PLANET_TO_BUILD_A_BASE, shipIndex), isTherePlanetToBuildABase);
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_SHIP_TITAN, shipIndex), (*iter)->actualTit());		
		
        shipIndex++;
    }

	w.writeValue(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_BASE_COUNT, (unsigned long) bases.size());

    int baseIndex = 1;
    for (std :: list<baseClass*> :: const_iterator iter = bases.begin(); iter != bases.end(); iter++)
    {
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_BASE_ID, baseIndex), (*iter)->getID());
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_BASE_NAME, baseIndex), (*iter)->getFortressName());

		spacePlanetObject * planet;
		bool isTherePlanetToBuildABase = (*iter)->isThereSomeAblePlanetToBuildAShell(&planet);

		if (isTherePlanetToBuildABase && planet != 0) {
			w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_BASE_PLANET_TO_BUILD_A_BASE_NAME, baseIndex), planet->getName());			
		}

		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_BASE_REQUIRED_TITAN, baseIndex), (*iter)->requiredTitaniumToBuildAShell(planet));

		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_BASE_PLANET_TO_BUILD_A_BASE, baseIndex), isTherePlanetToBuildABase);
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_BUILD_INFORMATION_ANSWER_BASE_TITAN, baseIndex), (*iter)->actualTit());

        baseIndex++;
    }

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: player_fortresses(const std :: list<shipClass*>& ships, const std :: list<baseClass*>& bases)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_PLAYER_FORTRESSES);

	w.writeValue(REQUEST_PLAYER_FORTRESSES_ANSWER_FORTRESS_COUNT, (unsigned long) ships.size() + (unsigned long) bases.size());

    int fortressIndex = 1;
    for (std :: list<shipClass*> :: const_iterator iter = ships.begin(); iter != ships.end(); iter++)
    {
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_ANSWER_FORTRESS_ID, fortressIndex), (*iter)->getID());
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_ANSWER_FORTRESS_NAME, fortressIndex), (*iter)->getFortressName());	
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_ANSWER_FORTRESS_TYPE, fortressIndex), (unsigned long) (*iter)->getFortressType());
        fortressIndex++;
    }

    for (std :: list<baseClass*> :: const_iterator iter = bases.begin(); iter != bases.end(); iter++)
    {
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_ANSWER_FORTRESS_ID, fortressIndex), (*iter)->getID());
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_ANSWER_FORTRESS_NAME, fortressIndex), (*iter)->getFortressName());
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_ANSWER_FORTRESS_TYPE, fortressIndex), (unsigned long) (*iter)->getFortressType());
        fortressIndex++;
    }

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: conquer_fortress_FAIL(unsigned long selfFortressId, const std::string & reason) {
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_CONQUER_FORTRESS);
	w.writeValue(REQUEST_CONQUER_FORTRESS_ANSWER_SELF_FORTRESS_ID, selfFortressId);
	w.writeValue(REQUEST_CONQUER_FORTRESS_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: conquer_fortress(unsigned long selfFortressId, unsigned long targetFortressId, fortressAddingResult addingResult, conquerResultClass conquerResult) {
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_CONQUER_FORTRESS);

	w.writeValue(REQUEST_CONQUER_FORTRESS_ANSWER_SELF_FORTRESS_ID, selfFortressId);
	w.writeValue(REQUEST_CONQUER_FORTRESS_ANSWER_ENEMY_FORTRESS_ID, targetFortressId);
	w.writeValue(REQUEST_CONQUER_FORTRESS_ANSWER_FORTRESS_ADDING_RESULT, (unsigned long) addingResult);
	
	w.writeValue(REQUEST_CONQUER_FORTRESS_ANSWER_IS_CONQUERED, conquerResult.isConquered());
	w.writeValue(REQUEST_CONQUER_FORTRESS_ANSWER_IS_DETAILS_AVAILABLE, conquerResult.areDetailsAvailable());
	w.writeValue(REQUEST_CONQUER_FORTRESS_ANSWER_IS_MANFRAME_FAILURE, conquerResult.mainframeFailure());
	w.writeValue(REQUEST_CONQUER_FORTRESS_ANSWER_IS_ENERGETIC_ACCUMULATOR_FAILURE, conquerResult.energeticAccumulatorFailure());
	w.writeValue(REQUEST_CONQUER_FORTRESS_ANSWER_ENERGY_IN_TARGET, conquerResult.getEnergyInTarget());

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_add_accommodations(unsigned long fortressid, unsigned long count, accommodation_type accommodationType) {
	protocolWriter w;

	w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_ADD_ACCOMMODATIONS);
	w.writeValue(REQUEST_FORTRESS_ADD_ACCOMMODATIONS_ANSWER_FORTRESS_ID, fortressid);
	w.writeValue(REQUEST_FORTRESS_ADD_ACCOMMODATIONS_ANSWER_ACCOMMODATION_COUNT, count);
	w.writeValue(REQUEST_FORTRESS_ADD_ACCOMMODATIONS_ANSWER_ACCOMMODATION_TYPE, (unsigned long) accommodationType);
	w.endMessage(true);
	return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_add_accommodations_FAIL(unsigned long fortressid, const std::string & reason) {
	protocolWriter w;

	w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_ADD_ACCOMMODATIONS);
	w.writeValue(REQUEST_FORTRESS_ADD_ACCOMMODATIONS_ANSWER_FORTRESS_ID, fortressid);
	w.writeValue(REQUEST_FORTRESS_ADD_ACCOMMODATIONS_ANSWER_FAIL, reason);
	w.endMessage(false);
	return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_add_crew(unsigned long fortressid, unsigned long able, unsigned long wounded, crew_type crewType) {
	protocolWriter w;

	w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_ADD_CREW);
	w.writeValue(REQUEST_FORTRESS_ADD_CREW_ANSWER_FORTRESS_ID, fortressid);
	w.writeValue(REQUEST_FORTRESS_ADD_CREW_ANSWER_ABLE_COUNT, wounded);
	w.writeValue(REQUEST_FORTRESS_ADD_CREW_ANSWER_WOUNDED_COUNT, wounded);
	w.writeValue(REQUEST_FORTRESS_ADD_CREW_ANSWER_CREW_TYPE, (unsigned long) crewType);
	w.endMessage(true);
	return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_add_crew_FAIL(unsigned long fortressid, const std::string & reason) {
	protocolWriter w;

	w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_ADD_CREW);
	w.writeValue(REQUEST_FORTRESS_ADD_CREW_ANSWER_FORTRESS_ID, fortressid);
	w.writeValue(REQUEST_FORTRESS_ADD_CREW_ANSWER_FAIL, reason);
	w.endMessage(false);
	return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_remove_crew(unsigned long fortressid, unsigned long able, unsigned long wounded, crew_type crewType) {
	protocolWriter w;

	w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_REMOVE_CREW);
	w.writeValue(REQUEST_FORTRESS_REMOVE_CREW_ANSWER_FORTRESS_ID, fortressid);
	w.writeValue(REQUEST_FORTRESS_REMOVE_CREW_ANSWER_ABLE_COUNT, wounded);
	w.writeValue(REQUEST_FORTRESS_REMOVE_CREW_ANSWER_WOUNDED_COUNT, wounded);
	w.writeValue(REQUEST_FORTRESS_REMOVE_CREW_ANSWER_CREW_TYPE, (unsigned long) crewType);
	w.endMessage(true);
	return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_remove_crew_FAIL(unsigned long fortressid, const std::string & reason) {
	protocolWriter w;

	w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_REMOVE_CREW);
	w.writeValue(REQUEST_FORTRESS_REMOVE_CREW_ANSWER_FORTRESS_ID, fortressid);
	w.writeValue(REQUEST_FORTRESS_REMOVE_CREW_ANSWER_FAIL, reason);
	w.endMessage(false);
	return w.copyMessage();
}

// --------------------------------

void answerWriter :: write_trade_movement_data(protocolWriter & w, const trade_movement_data & tradeData)
{
	w.writeValue(TRADE_MOVEMENT_DATA_SELF_FORTRESS_ID, tradeData.selfFortressId);
	w.writeValue(TRADE_MOVEMENT_DATA_PARTNER_FORTRESS_ID, tradeData.partnerFortressId);
	w.writeValue(TRADE_MOVEMENT_DATA_TRADE_DIRECTION, tradeData.tradeDirection);
	
	write_warehouse_item(w, TRADE_MOVEMENT_DATA_PREFIX, 0, tradeData.item);
}


char* answerWriter :: game_seconds_per_actual_second(unsigned long value) {
	protocolWriter w;

	w.beginMessage(MT_ANSWER, REQUEST_GAME_SECONDS_PER_ACTUAL_SECOND);
	w.writeValue(REQUEST_GAME_SECONDS_PER_ACTUAL_SECOND_ANSWER_SECONDS, value);
	w.endMessage(true);
	return w.copyMessage();
}

char* answerWriter :: rename_fortress(unsigned long fortressId, const std::string & newName) {
	protocolWriter w;

	w.beginMessage(MT_ANSWER, REQUEST_RENAME_FORTRESS);
	w.writeValue(REQUEST_RENAME_FORTRESS_FORTRESS_ID, fortressId);
	w.writeValue(REQUEST_RENAME_FORTRESS_NEW_NAME, newName);
	w.endMessage(true);
	return w.copyMessage();
}

char* answerWriter :: rename_fortress_FAIL(unsigned long fortressId, const std::string & reason) {
	protocolWriter w;

	w.beginMessage(MT_ANSWER, REQUEST_RENAME_FORTRESS);
	w.writeValue(REQUEST_RENAME_FORTRESS_FORTRESS_ID, fortressId);
	w.writeValue(REQUEST_RENAME_FORTRESS_ANSWER_FAIL, reason);
	w.endMessage(false);
	return w.copyMessage();
}

// --------------------------------

void write_fortress_attack_information(protocolWriter & w, fortressClass * fortress, unsigned long fortressIndex) 
{
	answerWriter::write_fortress_detailed_fight_data(w, fortress, fortressIndex);

	dtIdentifier targetFortressID = fortress->getWeaponsTargetID();

	if (targetFortressID != NOT_VALID_ID) 
	{
		fortressClass * targetFortress = actx->cacheFortressesList.getItem<fortressClass>(targetFortressID);

		if (!targetFortress == NULL) 
		{				
			w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_ATTACK_INFORMATION_ANSWER_FORTRESS_IN_WEAPONS_TARGET_NAME, fortressIndex), targetFortress->getFortressName());								
			w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_ATTACK_INFORMATION_ANSWER_FORTRESS_IN_WEAPONS_TARGET_ID, fortressIndex), targetFortress->getID());
			w.writeValue(REQUEST_PLAYER_FORTRESSES_ATTACK_INFORMATION_ANSWER_FORTRESS_IN_WEAPONS_TARGET_REALM_NAME, targetFortress->getFortressRealm()->getPlayerName());
			w.writeValue(REQUEST_PLAYER_FORTRESSES_ATTACK_INFORMATION_ANSWER_FORTRESS_IN_WEAPONS_TARGET_TYPE, (unsigned long) targetFortress->getFortressType());
		}
		else
		{
			errExceptionError("Fortress with id %u not found!", (unsigned long long) targetFortressID);
			w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_ATTACK_INFORMATION_ANSWER_FORTRESS_IN_WEAPONS_TARGET_ID, fortressIndex), (unsigned long) NOT_VALID_ID);
		}
	}		
	else 
	{
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_ATTACK_INFORMATION_ANSWER_FORTRESS_IN_WEAPONS_TARGET_ID, fortressIndex), (unsigned long) NOT_VALID_ID);
	}

	const dtIdentifierSet & attackers = fortress->getAttackersThatLockedOnThis();

	unsigned long attackerIndex = 1;
	for (dtIdentifierSet::const_iterator it = attackers.begin(); it != attackers.end(); ++it) {
		w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_ATTACK_INFORMATION_ANSWER_FORTRESS_ATTACKER_ID, fortressIndex, attackerIndex), *it);
		attackerIndex++;
	}

	w.writeValue(create_param_name(REQUEST_PLAYER_FORTRESSES_ATTACK_INFORMATION_ANSWER_FORTRESS_ATTACKER_COUNT, fortressIndex), (unsigned long) attackers.size());
}

// --------------------------------

char* answerWriter :: player_fortresses_attack_information(const std :: list<shipClass*>& ships, const std :: list<baseClass*>& bases)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_PLAYER_FORTRESSES_ATTACK_INFORMATION);

	w.writeValue(REQUEST_PLAYER_FORTRESSES_ATTACK_INFORMATION_ANSWER_FORTRESS_COUNT, (unsigned long) (ships.size() + bases.size()));

    unsigned long fortressIndex = 1;
    for (std :: list<shipClass*> :: const_iterator iter = ships.begin(); iter != ships.end(); iter++)
    {
		write_fortress_attack_information(w, *iter, fortressIndex);		
        fortressIndex++;
    }

    for (std :: list<baseClass*> :: const_iterator iter = bases.begin(); iter != bases.end(); iter++)
    {
		write_fortress_attack_information(w, *iter, fortressIndex);		
        fortressIndex++;
    }

    w.endMessage(true);
    return w.copyMessage();
}

void answerWriter :: write_sensors_data(protocolWriter & w, const std::string & prefix, const sensors_data & data) {
	w.writeValue(create_param_name(prefix, REQUEST_FORTRESS_SENSORS_INFORMATION_ANSWER_AVAILABLE), data.available);
	w.writeValue(create_param_name(prefix, REQUEST_FORTRESS_SENSORS_INFORMATION_ANSWER_CONSUMPTION), data.consumption);
	w.writeValue(create_param_name(prefix, REQUEST_FORTRESS_SENSORS_INFORMATION_ANSWER_LEVEL), data.level);
	w.writeValue(create_param_name(prefix, REQUEST_FORTRESS_SENSORS_INFORMATION_ANSWER_RANGE), data.range);
	w.writeValue(create_param_name(prefix, REQUEST_FORTRESS_SENSORS_INFORMATION_ANSWER_STATUS), data.status);
	w.writeValue(create_param_name(prefix, REQUEST_FORTRESS_SENSORS_INFORMATION_ANSWER_WEIGHT), data.weight);
}

// --------------------------------
char* answerWriter :: fortress_sensors_information(unsigned long fortressId, const sensors_data & hrData, const sensors_data & lrData) {
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_SENSORS_INFORMATION);

	w.writeValue(REQUEST_FORTRESS_SENSORS_INFORMATION_SELF_FORTRESS_ID, fortressId);
	write_sensors_data(w, REQUEST_FORTRESS_SENSORS_INFORMATION_HR_PREFIX, hrData);
	write_sensors_data(w, REQUEST_FORTRESS_SENSORS_INFORMATION_LR_PREFIX, lrData);

    w.endMessage(true);
    return w.copyMessage();
}


// --------------------------------
char* answerWriter :: fortress_sensors_information_FAIL(unsigned long fortressId, const std::string & reason) {
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_SENSORS_INFORMATION);

	w.writeValue(REQUEST_FORTRESS_SENSORS_INFORMATION_SELF_FORTRESS_ID, fortressId);
	w.writeValue(REQUEST_FORTRESS_SENSORS_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------
char* answerWriter :: fortress_cloaking_information(unsigned long fortressId, const cloaking_data & data) {
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_CLOAKING_INFORMATION);

	w.writeValue(REQUEST_FORTRESS_CLOAKING_INFORMATION_SELF_FORTRESS_ID, fortressId);
	w.writeValue(REQUEST_FORTRESS_CLOAKING_INFORMATION_ANSWER_AVAILABLE, data.available);
	w.writeValue(REQUEST_FORTRESS_CLOAKING_INFORMATION_ANSWER_CONSUMPTION, data.consumption);
	w.writeValue(REQUEST_FORTRESS_CLOAKING_INFORMATION_ANSWER_LEVEL, data.level);
	w.writeValue(REQUEST_FORTRESS_CLOAKING_INFORMATION_ANSWER_STATUS, data.status);
	w.writeValue(REQUEST_FORTRESS_CLOAKING_INFORMATION_ANSWER_WEIGHT, data.weight);

    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: fortress_cloaking_information_FAIL(unsigned long fortressId, const std::string & reason) {
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_FORTRESS_CLOAKING_INFORMATION);

	w.writeValue(REQUEST_FORTRESS_CLOAKING_INFORMATION_SELF_FORTRESS_ID, fortressId);
	w.writeValue(REQUEST_FORTRESS_CLOAKING_INFORMATION_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_warp_information(const WarpInfo& winfo)
{
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIPWARPINFO);

    w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_ID,            winfo.shipId);
	w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_SPOSX,         (long long)winfo.sposX);
	w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_SPOSY,         (long long)winfo.sposY);
	w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_POSX,          (long long)winfo.posX);
	w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_POSY,          (long long)winfo.posY);
	w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_DPOSX,        (long long) winfo.dstPosX);
	w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_DPOSY,         (long long)winfo.dstPosY);
    w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_STATECHANGE,   winfo.stateChange);
    w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_IN_WARP,       winfo.inWarp);
    w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_SPEED,         winfo.speed);
	w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_TYPE,          winfo.shipType);
	w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_NAME,          winfo.shipName);
    w.endMessage(true);
    return w.copyMessage();
}

// --------------------------------

char* answerWriter :: ship_warp_information_FAIL(unsigned long fortressId, const std::string & reason) {
    protocolWriter w;
    w.beginMessage(MT_ANSWER, REQUEST_SHIPWARPINFO);

	w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_ID, fortressId);
	w.writeValue(REQUEST_SHIPWARPINFO_ANSWER_FAIL, reason);

    w.endMessage(false);
    return w.copyMessage();
}

// --------------------------------
