Merge pull request #2628 from acemod/cargoClassnames

Add support for virtual cargo
This commit is contained in:
Thomas Kooi
2015-11-10 08:38:17 +01:00
13 changed files with 159 additions and 96 deletions

View File

@ -1,5 +1,45 @@
#include "script_component.hpp" #include "script_component.hpp"
["LoadCargo", {_this call FUNC(loadItem)}] call EFUNC(common,addEventHandler);
["UnloadCargo", {_this call FUNC(unloadItem)}] call EFUNC(common,addEventHandler);
["AddCargoByClass", {_this call FUNC(addCargoItem)}] call EFUNC(common,addEventHandler); ["AddCargoByClass", {_this call FUNC(addCargoItem)}] call EFUNC(common,addEventHandler);
["LoadCargo", {
(_this select 0) params ["_item","_vehicle"];
private ["_loaded", "_hint", "_itemName", "_vehicleName"];
_loaded = [_item, _vehicle] call FUNC(loadItem);
// Show hint as feedback
_hint = [LSTRING(LoadingFailed), LSTRING(LoadedItem)] select _loaded;
_itemName = getText (configFile >> "CfgVehicles" >> typeOf _item >> "displayName");
_vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName");
["displayTextStructured", [[_hint, _itemName, _vehicleName], 3.0]] call EFUNC(common,localEvent);
if (_loaded) then {
// Invoke listenable event
["cargoLoaded", [_item, _vehicle]] call EFUNC(common,globalEvent);
};
}] call EFUNC(common,addEventHandler);
["UnloadCargo", {
(_this select 0) params ["_item","_vehicle"];
private ["_unloaded", "_itemClass", "_hint", "_itemName", "_vehicleName"];
_unloaded = [_item, _vehicle] call FUNC(unloadItem);
_itemClass = if (typeName _item == "STRING") then {_item} else {typeOf _item};
// Show hint as feedback
_hint = [LSTRING(UnloadingFailed), LSTRING(UnloadedItem)] select _unloaded;
_itemName = getText (configFile >> "CfgVehicles" >> _itemClass >> "displayName");
_vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName");
["displayTextStructured", [[_hint, _itemName, _vehicleName], 3.0]] call EFUNC(common,localEvent);
if (_unloaded) then {
// Invoke listenable event
["cargoUnloaded", [_item, _vehicle]] call EFUNC(common,globalEvent);
};
// TOOO maybe drag/carry the unloaded item?
}] call EFUNC(common,addEventHandler);

View File

@ -22,20 +22,9 @@ private ["_position", "_item", "_i"];
params ["_itemClass", "_vehicle", ["_amount", 1], ["_showHint", false, [false]] ]; params ["_itemClass", "_vehicle", ["_amount", 1], ["_showHint", false, [false]] ];
TRACE_3("params",_itemClass,_vehicle,_amount); TRACE_3("params",_itemClass,_vehicle,_amount);
_position = getPos _vehicle;
_position set [1, (_position select 1) + 1];
_position set [2, (_position select 2) + 7.5];
for "_i" from 1 to _amount do { for "_i" from 1 to _amount do {
_item = createVehicle [_itemClass, _position, [], 0, "CAN_COLLIDE"]; [_item, _vehicle] call FUNC(loadItem);
// Load item or delete it if no space left
if !([_item, _vehicle, _showHint] call FUNC(loadItem)) exitWith {
TRACE_1("no room to load item - deleting",_item);
deleteVehicle _item;
};
TRACE_1("Item Loaded",_item);
// Invoke listenable event
["cargoAddedByClass", [_itemClass, _vehicle, _amount]] call EFUNC(common,globalEvent);
}; };
// Invoke listenable event
["cargoAddedByClass", [_itemClass, _vehicle, _amount]] call EFUNC(common,globalEvent);

View File

@ -3,7 +3,7 @@
* Check if item can be loaded into other Object. * Check if item can be loaded into other Object.
* *
* Arguments: * Arguments:
* 0: Item Object <OBJECT> * 0: Item <OBJECT or STRING>
* 1: Holder Object (Vehicle) <OBJECT> * 1: Holder Object (Vehicle) <OBJECT>
* *
* Return value: * Return value:
@ -16,14 +16,24 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params ["_item", "_vehicle"]; params [["_item", "", [objNull,""]], "_vehicle"];
if (speed _vehicle > 1 || (((getPos _vehicle) select 2) > 3)) exitWith {false}; if (speed _vehicle > 1 || (((getPos _vehicle) select 2) > 3)) exitWith {false};
private "_itemSize"; private ["_itemSize", "_validItem"];
_itemSize = ([_item] call FUNC(getSizeItem)); _itemSize = [_item] call FUNC(getSizeItem);
(_itemSize > 0) && if (typeName _item == "STRING") then {
{alive _item && alive _vehicle} && _validItem =
{(_item distance _vehicle <= MAX_LOAD_DISTANCE)} && isClass (configFile >> "CfgVehicles" >> _item) &&
{getNumber (configFile >> "CfgVehicles" >> _item >> QGVAR(canLoad)) == 1};
} else {
_validItem =
(alive _item) &&
{(_item distance _vehicle) <= MAX_LOAD_DISTANCE};
};
_validItem &&
{_itemSize > 0} &&
{alive _vehicle} &&
{_itemSize <= ([_vehicle] call FUNC(getCargoSpaceLeft))} {_itemSize <= ([_vehicle] call FUNC(getCargoSpaceLeft))}

View File

@ -16,18 +16,19 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
private ["_loaded", "_validVehiclestate", "_emptyPos"];
params ["_item", "_vehicle"]; params ["_item", "_vehicle"];
private ["_loaded", "_itemClass", "_validVehiclestate", "_emptyPos"];
_loaded = _vehicle getVariable [QGVAR(loaded), []]; _loaded = _vehicle getVariable [QGVAR(loaded), []];
if !(_item in _loaded) exitWith {false}; if !(_item in _loaded) exitWith {false};
_itemClass = if (typeName _item == "STRING") then {_item} else {typeOf _item};
_validVehiclestate = true; _validVehiclestate = true;
_emptyPos = []; _emptyPos = [];
if (_vehicle isKindOf "Ship" ) then { if (_vehicle isKindOf "Ship" ) then {
if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false}; if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false};
_emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, typeOf _item]); // TODO: if spot is underwater pick another spot. _emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, _itemClass]); // TODO: if spot is underwater pick another spot.
} else { } else {
if (_vehicle isKindOf "Air" ) then { if (_vehicle isKindOf "Air" ) then {
if !(speed _vehicle <1 && {isTouchingGround _vehicle}) then {_validVehiclestate = false}; if !(speed _vehicle <1 && {isTouchingGround _vehicle}) then {_validVehiclestate = false};
@ -35,7 +36,7 @@ if (_vehicle isKindOf "Ship" ) then {
_emptyPos = [(_emptyPos select 0) + random(5), (_emptyPos select 1) + random(5), _emptyPos select 2 ]; _emptyPos = [(_emptyPos select 0) + random(5), (_emptyPos select 1) + random(5), _emptyPos select 2 ];
} else { } else {
if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false}; if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false};
_emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, typeOf _item]); _emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, _itemClass]);
}; };
}; };

View File

@ -3,7 +3,7 @@
* Get the cargo size of an object. * Get the cargo size of an object.
* *
* Arguments: * Arguments:
* 0: Object <OBJECT> * 0: Item <OBJECT or STRING>
* *
* Return value: * Return value:
* Cargo size <NUMBER> (default: -1) * Cargo size <NUMBER> (default: -1)
@ -15,14 +15,24 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
private "_config";
params ["_item"]; params ["_item"];
private ["_isVirtual","_itemClass","_config"];
scopeName "return";
_config = (configFile >> "CfgVehicles" >> typeOf _item >> QGVAR(size)); _isVirtual = (typeName _item == "STRING");
_itemClass = if (_isVirtual) then {_item} else {typeOf _item};
_config = (configFile >> "CfgVehicles" >> _itemClass >> QGVAR(size));
if (isNumber (_config)) exitWith { if (_isVirtual) then {
_item getVariable [QGVAR(size), getNumber (_config)] if (isNumber _config) then {
(getNumber _config) breakOut "return";
};
} else {
_config = (configFile >> "CfgVehicles" >> typeOf _item >> QGVAR(size));
if (isNumber _config) then {
(_item getVariable [QGVAR(size), getNumber _config]) breakOut "return";
};
}; };
-1 -1

View File

@ -20,12 +20,13 @@ params ["_vehicle"];
private["_loaded"]; private["_loaded"];
_loaded = _vehicle getVariable [QGVAR(loaded), []]; _loaded = _vehicle getVariable [QGVAR(loaded), []];
if (count _loaded == 0) exitWith {}; if (_loaded isEqualTo []) exitWith {};
{ {
// TODO deleteVehicle or just delete vehicle? Do we want to be able to recover destroyed equipment? // TODO Do we want to be able to recover destroyed equipment?
deleteVehicle _x; if (typeName _x == "OBJECT") then {
//_x setDamage 1; deleteVehicle _x;
};
} count _loaded; } count _loaded;
[_vehicle] call FUNC(validateCargoSpace); [_vehicle] call FUNC(validateCargoSpace);

View File

@ -1,9 +1,10 @@
/* /*
* Author: Glowbal * Author: Glowbal
* Load object into vehicle. * Load object into vehicle.
* Objects loaded via classname remain virtual until unloaded.
* *
* Arguments: * Arguments:
* 0: Object <OBJECT> * 0: Item <OBJECT or STRING>
* 1: Vehicle <OBJECT> * 1: Vehicle <OBJECT>
* 2: Show Hint <BOOL> (default: true) * 2: Show Hint <BOOL> (default: true)
* *
@ -17,15 +18,10 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [["_item","",[objNull,""]], ["_vehicle",objNull,[objNull]]];
private ["_loaded", "_space", "_itemSize"]; private ["_loaded", "_space", "_itemSize"];
params ["_item", "_vehicle", ["_showHint", true, [true]] ]; if !([_item, _vehicle] call FUNC(canLoadItemIn)) exitWith {false};
TRACE_2("params",_item,_vehicle);
if !([_item, _vehicle] call FUNC(canLoadItemIn)) exitWith {
TRACE_2("canLoadItemIn failed",_item,_vehicle);
false
};
_loaded = _vehicle getVariable [QGVAR(loaded), []]; _loaded = _vehicle getVariable [QGVAR(loaded), []];
_loaded pushback _item; _loaded pushback _item;
@ -37,21 +33,10 @@ _space = [_vehicle] call FUNC(getCargoSpaceLeft);
_itemSize = [_item] call FUNC(getSizeItem); _itemSize = [_item] call FUNC(getSizeItem);
_vehicle setVariable [QGVAR(space), _space - _itemSize, true]; _vehicle setVariable [QGVAR(space), _space - _itemSize, true];
detach _item; if (typeName _item == "OBJECT") then {
_item attachTo [_vehicle,[0,0,100]]; detach _item;
["hideObjectGlobal", [_item, true]] call EFUNC(common,serverEvent); _item attachTo [_vehicle,[0,0,-100]];
["hideObjectGlobal", [_item, true]] call EFUNC(common,serverEvent);
// show hint
private ["_itemName", "_vehicleName"];
_itemName = getText (configFile >> "CfgVehicles" >> typeOf _item >> "displayName");
_vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName");
if (_showHint) then {
["displayTextStructured", [[localize LSTRING(LoadedItem), _itemName, _vehicleName], 3.0]] call EFUNC(common,localEvent);
}; };
// Invoke listenable event
["cargoLoaded", [_item, _vehicle]] call EFUNC(common,globalEvent);
true true

View File

@ -22,7 +22,7 @@ params ["_display"];
uiNamespace setVariable [QGVAR(menuDisplay), _display]; uiNamespace setVariable [QGVAR(menuDisplay), _display];
[{ [{
private ["_display","_loaded", "_ctrl", "_label"]; private ["_display","_loaded", "_ctrl", "_class", "_label"];
disableSerialization; disableSerialization;
_display = uiNamespace getVariable QGVAR(menuDisplay); _display = uiNamespace getVariable QGVAR(menuDisplay);
if (isnil "_display") exitWith { if (isnil "_display") exitWith {
@ -40,7 +40,8 @@ uiNamespace setVariable [QGVAR(menuDisplay), _display];
lbClear _ctrl; lbClear _ctrl;
{ {
_ctrl lbAdd (getText(configfile >> "CfgVehicles" >> typeOf _x >> "displayName")); _class = if (typeName _x == "STRING") then {_x} else {typeOf _x};
_ctrl lbAdd (getText(configfile >> "CfgVehicles" >> _class >> "displayName"));
true true
} count _loaded; } count _loaded;

View File

@ -16,16 +16,25 @@
#include "script_component.hpp" #include "script_component.hpp"
params ["_player", "_object"]; params ["_player", "_object"];
private ["_vehicle", "_size", "_displayName"];
private ["_nearestVehicle"]; _vehicle = [_player] call FUNC(findNearestVehicle);
_nearestVehicle = [_player] call FUNC(findNearestVehicle);
if (isNull _nearestVehicle || _nearestVehicle isKindOf "Cargo_Base_F") then { if (isNull _vehicle || _vehicle isKindOf "Cargo_Base_F") then {
{ {
if ([_object, _x] call FUNC(canLoadItemIn)) exitWith {_nearestVehicle = _x}; if ([_object, _x] call FUNC(canLoadItemIn)) exitWith {_vehicle = _x};
} foreach (nearestObjects [_player, ["Cargo_base_F", "Land_PaperBox_closed_F"], MAX_LOAD_DISTANCE]); } foreach (nearestObjects [_player, ["Cargo_base_F", "Land_PaperBox_closed_F"], MAX_LOAD_DISTANCE]);
}; };
if (isNull _nearestVehicle) exitWith {false}; if (isNull _vehicle) exitWith {false};
[_object, _nearestVehicle] call FUNC(loadItem) // Start progress bar
if ([_object, _vehicle] call FUNC(canLoadItemIn)) then {
_size = [_object] call FUNC(getSizeItem);
[5 * _size, [_object,_vehicle], "LoadCargo", {}, localize LSTRING(LoadingItem)] call EFUNC(common,progressBar);
} else {
_displayName = getText (configFile >> "CfgVehicles" >> typeOf _object >> "displayName");
["displayTextStructured", [[LSTRING(LoadingFailed), _displayName], 3.0]] call EFUNC(common,localEvent);
};

View File

@ -20,7 +20,7 @@ private ["_display", "_loaded", "_ctrl", "_selected", "_item"];
disableSerialization; disableSerialization;
_display = uiNamespace getVariable QGVAR(menuDisplay); _display = uiNamespace getVariable QGVAR(menuDisplay);
if (isnil "_display") exitWith {}; if (isNil "_display") exitWith {};
_loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]; _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []];
if (count _loaded == 0) exitWith {}; if (count _loaded == 0) exitWith {};
@ -32,4 +32,17 @@ _selected = (lbCurSel _ctrl) max 0;
if (count _loaded <= _selected) exitWith {}; if (count _loaded <= _selected) exitWith {};
_item = _loaded select _selected; _item = _loaded select _selected;
[_item, GVAR(interactionVehicle)] call FUNC(unloadItem);
// Start progress bar
private ["_size", "_itemClass", "_displayName"];
if ([_item, GVAR(interactionVehicle)] call FUNC(canUnloadItem)) then {
_size = [_item] call FUNC(getSizeItem);
[5 * _size, [_item, GVAR(interactionVehicle)], "UnloadCargo", {}, localize LSTRING(UnloadingItem)] call EFUNC(common,progressBar);
} else {
_itemClass = if (typeName _item == "STRING") then {_item} else {typeOf _item};
_displayName = getText (configFile >> "CfgVehicles" >> _itemClass >> "displayName");
["displayTextStructured", [[LSTRING(UnloadingFailed), _displayName], 3.0]] call EFUNC(common,localEvent);
};

View File

@ -3,7 +3,7 @@
* Unload object from vehicle. * Unload object from vehicle.
* *
* Arguments: * Arguments:
* 0: Object <OBJECT> * 0: Item <OBJECT or STRING>
* 1: Vehicle <OBJECT> * 1: Vehicle <OBJECT>
* *
* Return value: * Return value:
@ -16,20 +16,21 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
private ["_loaded", "_space", "_itemSize", "_emptyPos", "_validVehiclestate"];
params ["_item", "_vehicle"]; params ["_item", "_vehicle"];
private ["_loaded", "_space", "_itemSize", "_emptyPos", "_validVehiclestate"];
if !([_item, _vehicle] call FUNC(canUnloadItem)) exitWith { if !([_item, _vehicle] call FUNC(canUnloadItem)) exitWith {
false false
}; };
_itemClass = if (typeName _item == "STRING") then {_item} else {typeOf _item};
_validVehiclestate = true; _validVehiclestate = true;
_emptyPos = []; _emptyPos = [];
if (_vehicle isKindOf "Ship" ) then { if (_vehicle isKindOf "Ship" ) then {
if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false}; if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false};
TRACE_1("SHIP Ground Check", getPosATL _vehicle ); TRACE_1("SHIP Ground Check", getPosATL _vehicle );
_emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, typeOf _item]); // TODO: if spot is underwater pick another spot. _emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, _itemClass]); // TODO: if spot is underwater pick another spot.
} else { } else {
if (_vehicle isKindOf "Air" ) then { if (_vehicle isKindOf "Air" ) then {
if !(speed _vehicle <1 && {isTouchingGround _vehicle}) then {_validVehiclestate = false}; if !(speed _vehicle <1 && {isTouchingGround _vehicle}) then {_validVehiclestate = false};
@ -39,38 +40,29 @@ if (_vehicle isKindOf "Ship" ) then {
} else { } else {
if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false}; if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false};
TRACE_1("Vehicle Ground Check", isTouchingGround _vehicle); TRACE_1("Vehicle Ground Check", isTouchingGround _vehicle);
_emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 13, typeOf _item]); _emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 13, _itemClass]);
}; };
}; };
TRACE_1("getPosASL Vehicle Check", getPosASL _vehicle); TRACE_1("getPosASL Vehicle Check", getPosASL _vehicle);
if (!_validVehiclestate) exitWith {false}; if (!_validVehiclestate) exitWith {false};
if (count _emptyPos == 0) exitWith {false}; //consider displaying text saying there are no safe places to exit the vehicle if (count _emptyPos == 0) exitWith {false};
_loaded = _vehicle getVariable [QGVAR(loaded), []]; _loaded = _vehicle getVariable [QGVAR(loaded), []];
_loaded = _loaded - [_item]; _loaded deleteAt (_loaded find _item);
_vehicle setVariable [QGVAR(loaded), _loaded, true]; _vehicle setVariable [QGVAR(loaded), _loaded, true];
_space = [_vehicle] call FUNC(getCargoSpaceLeft); _space = [_vehicle] call FUNC(getCargoSpaceLeft);
_itemSize = [_item] call FUNC(getSizeItem); _itemSize = [_item] call FUNC(getSizeItem);
_vehicle setVariable [QGVAR(space), (_space + _itemSize), true]; _vehicle setVariable [QGVAR(space), (_space + _itemSize), true];
detach _item; if (typeName _item == "OBJECT") then {
_item setPosASL (_emptyPos call EFUNC(common,PositiontoASL)); detach _item;
["hideObjectGlobal", [_item, false]] call EFUNC(common,serverEvent); _item setPosASL (_emptyPos call EFUNC(common,PositiontoASL));
["hideObjectGlobal", [_item, false]] call EFUNC(common,serverEvent);
// show hint } else {
private ["_itemName", "_vehicleName"]; createVehicle [_item, _emptyPos, [], 0, ""];
};
_itemName = getText (configFile >> "CfgVehicles" >> typeOf _item >> "displayName");
_vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName");
["displayTextStructured", [[localize LSTRING(UnloadedItem), _itemName, _vehicleName], 3.0]] call EFUNC(common,localEvent);
// TOOO maybe drag/carry the unloaded item?
// Invoke listenable event
["cargoUnloaded", [_item, _vehicle]] call EFUNC(common,globalEvent);
true true

View File

@ -24,7 +24,7 @@ _loaded = _vehicle getVariable [QGVAR(loaded), []];
_newLoaded = []; _newLoaded = [];
_totalSpaceOccupied = 0; _totalSpaceOccupied = 0;
{ {
if !(isNull _x) then { if ((typeName _x == "STRING") || {!isNull _x}) then {
_newLoaded pushback _x; _newLoaded pushback _x;
_totalSpaceOccupied = _totalSpaceOccupied + ([_x] call FUNC(getSizeItem)); _totalSpaceOccupied = _totalSpaceOccupied + ([_x] call FUNC(getSizeItem));
}; };
@ -35,4 +35,4 @@ if (count _loaded != count _newLoaded) then {
_vehicle setVariable [QGVAR(loaded), _newLoaded, true]; _vehicle setVariable [QGVAR(loaded), _newLoaded, true];
}; };
_vehicle setVariable [QGVAR(space), getNumber (configFile >> "CfgVehicles" >> typeof _vehicle >> QGVAR(space)) - _totalSpaceOccupied, true]; _vehicle setVariable [QGVAR(space), getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(space)) - _totalSpaceOccupied, true];

View File

@ -95,5 +95,17 @@
<Hungarian>1%&lt;br/&gt;kirakodva ebből:&lt;br/&gt;%2</Hungarian> <Hungarian>1%&lt;br/&gt;kirakodva ebből:&lt;br/&gt;%2</Hungarian>
<Russian>%1&lt;br/&gt;разгружен из&lt;br/&gt;%2</Russian> <Russian>%1&lt;br/&gt;разгружен из&lt;br/&gt;%2</Russian>
</Key> </Key>
<Key ID="STR_ACE_Cargo_LoadingItem">
<English>Loading Cargo</English>
</Key>
<Key ID="STR_ACE_Cargo_UnloadingItem">
<English>Unloading Cargo</English>
</Key>
<Key ID="STR_ACE_Cargo_LoadingFailed">
<English>%1&lt;br/&gt;could not be loaded</English>
</Key>
<Key ID="STR_ACE_Cargo_UnloadingFailed">
<English>%1&lt;br/&gt;could not be unloaded</English>
</Key>
</Package> </Package>
</Project> </Project>