Code:
--xxxxxxxxxxxxxxxxxxxxxxx--TravelingSalesman--xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx--
-- Das muss in das globale Skript:
TravelingSalesman = {
Loop = "TravelingSalesman_Loop",
List = {}
};
function TravelingSalesman:new(_player, _offerTable, _duration, _path, _noWave)
_path = _path or ShipPath[_player];
if not _path then
-- use BB traveling salesman script instead
ActivateTravelingSalesman(_player, _offerTable, _duration);
return;
end
if (g_TravelingSalesman and g_TravelingSalesman.PlayerID) then
Logic.DEBUG_AddNote("DEBUG: You must either use a BB traveling salesman or a new salesman");
elseif TravelingSalesman.List[_player] then
Logic.DEBUG_AddNote("DEBUG: There is already a traveling salesman for player " .. _player);
return;
end
-- don't allow BB traveling salesman now
g_TravelingSalesman = {};
-- create new salesman and initialize
local travelingSalesman = {};
Table_Copy(travelingSalesman, self);
travelingSalesman.PlayerID = _player;
travelingSalesman.Storehouse = Logic.GetStoreHouse(_player);
travelingSalesman.Status = g_TravelingSalesmanStatus.Sailing;
travelingSalesman.ActiveTime = (_duration or 1) * Logic.GetMonthDurationInSeconds();
travelingSalesman.OfferTable = {};
travelingSalesman.CreateWave = not _noWave; -- standard: Use ship wave
for i = 1, #_offerTable do
local month = _offerTable[i][1];
travelingSalesman.OfferTable[month] = _offerTable[i][2];
end
travelingSalesman.Path = _path;
travelingSalesman.SpawnPoint = travelingSalesman.Path[1];
travelingSalesman.DestinationPoint = travelingSalesman.Path[#travelingSalesman.Path];
if travelingSalesman.SpawnPoint == travelingSalesman.Destination then
Logic.DEBUG_AddNote("DEBUG: Destination is spawn point?");
end
-- don't allow sale
for pId = 1, 8 do
Logic.SetTraderPlayerState(travelingSalesman.Storehouse, pId, 8); --2
end
-- setup the player
SetupPlayer(_player, "H_NPC_Generic_Trader", "XTradeShipX", "TravelingSalesmanColor")
-- start job
travelingSalesman.Job = Trigger.RequestTrigger(Events.LOGIC_EVENT_EVERY_SECOND, nil, self.Loop, 1, 0, { JobQueue_AddParameter(travelingSalesman) });
-- add to list
TravelingSalesman.List[_player] = travelingSalesman;
-- return!
return travelingSalesman;
end
function TravelingSalesman:Sail()
local currMonth = Logic.GetCurrentMonth();
for month, offers in pairs(self.OfferTable) do
if month == currMonth then
-- create offers
g_TravelingSalesman = { StorehouseID = self.Storehouse };
GenerateTravelingSalesManOffersForMonth(offers);
-- create ship (and wave)
local x, y = Logic.GetEntityPosition(self.SpawnPoint);
local orientation = Logic.GetEntityOrientation(self.SpawnPoint);
self.Ship = Logic.CreateEntity(Entities.D_X_TradeShip, x, y, orientation, self.PlayerID);
self.ShipPathInstance = Path:new(self.Ship, self.Path, false, true, self.ShipArrived, self.Left, true, nil, self, 500);
if self.CreateWave then
self.Wave = Logic.CreateEntity(Entities.E_Kogge, x, y, orientation, self.PlayerID);
self.WavePathInstance = Path:new(self.Wave, self.Path, false, true, self.WaveArrived, nil, true, nil, nil, 500);
end
self.Status = g_TravelingSalesmanStatus.OnHisWay;
-- message of salesman
Logic.ExecuteInLuaLocalState("LocalScriptCallback_QueueVoiceMessage(".. self.PlayerID ..", 'TravelingSalesmanSpotted')");
-- callback
if Mission_Callback_TravelingSalesman then
Mission_Callback_TravelingSalesman(self.Status, self.PlayerID);
end
return;
end
end
end
function TravelingSalesman.ShipArrived(_path, _destPoint)
local self = _path.TagData;
-- timestamp
self.StartOfActiveTime = Logic.GetTime();
-- allow selling
for pId = 1, 8 do
Logic.SetTraderPlayerState(self.Storehouse, pId, 0);
end
QuestTemplate:New("TravelingSalesman",
self.PlayerID,
1,
{ {Objective.Object, { _destPoint } } },
{ { Triggers.Time, 0 } },
self.ActiveTime
);
if Mission_Callback_TravelingSalesman then
Mission_Callback_TravelingSalesman(self.Status, self.PlayerID);
end
self.Status = g_TravelingSalesmanStatus.AtHarbour;
-- hack to circumvent Trigger.DisableTrigger() problem and to rotate the entity (Logic.MoveEntity() seems to be called to the current position after this function is called)
Trigger.RequestTrigger(Events.LOGIC_EVENT_EVERY_TURN, nil, "HACK_TravelingSalesman_RotateEntityAndDisableTrigger", 1, 0, { _path.Job, _path.Entity, Logic.GetEntityOrientation(_destPoint) });
end
function TravelingSalesman.WaveArrived(_path, _destPoint)
-- hack to circumvent Trigger.DisableTrigger() problem and to rotate the entity (Logic.MoveEntity() seems to be called to the current position after this function is called)
Trigger.RequestTrigger(Events.LOGIC_EVENT_EVERY_TURN, nil, "HACK_TravelingSalesman_RotateEntityAndDisableTrigger", 1, 0, { _path.Job, _path.Entity, Logic.GetEntityOrientation(_destPoint) });
end
function HACK_TravelingSalesman_RotateEntityAndDisableTrigger(_job, _entity, _orientation)
Logic.RotateEntity(_entity, _orientation);
Trigger.DisableTrigger(_job);
return true;
end
function TravelingSalesman:AtHarbour()
-- shall it return?
if Logic.GetTime() > self.StartOfActiveTime + self.ActiveTime then
Trigger.EnableTrigger(self.ShipPathInstance.Job);
if self.Wave then
Trigger.EnableTrigger(self.WavePathInstance.Job);
end
for pId = 1, 8 do
Logic.SetTraderPlayerState(self.Storehouse, pId, 2);
end
self.Status = g_TravelingSalesmanStatus.Leaving;
if Mission_Callback_TravelingSalesman then
Mission_Callback_TravelingSalesman(self.Status, self.PlayerID);
end
end
end
function TravelingSalesman.Left(_path)
local self = _path.TagData;
-- destroy ship
Logic.DestroyEntity(self.Ship);
self.Ship = nil;
self.ShipPathInstance = nil;
-- destroy wave
if self.Wave then
Logic.DestroyEntity(self.Wave);
self.Wave = nil;
self.WavePathInstance = nil;
end
-- reset state
self.Status = g_TravelingSalesmanStatus.Sailing;
if Mission_Callback_TravelingSalesman then
Mission_Callback_TravelingSalesman(self.Status, self.PlayerID);
end
end
function TravelingSalesman_Loop(_index)
local self = JobQueue_GetParameter(_index);
-- when store house is destroyed, end
if Logic.IsEntityDestroyed(self.Storehouse) then
if self.Ship and Logic.IsEntityAlive(self.Ship) then
Logic.DestroyEntity(self.Ship);
if self.ShipPathInstance then
Trigger.UnrequestTrigger(self.ShipPathInstance.Job);
self.ShipPathInstance = nil;
end
if self.CreateWave and self.Wave and Logic.IsEntityAlive(self.Wave) then
Logic.DestroyEntity(self.Wave);
if self.WavePathInstance then
Trigger.UnrequestTrigger(self.WavePathInstance.Job);
self.WavePathInstance = nil;
end
end
end
TravelingSalesman.List[self.PlayerID] = nil;
JobQueue_RemoveParameter(_index);
Logic.ExecuteInLuaLocalState("LocalScriptCallback_QueueVoiceMessage(" .. self.PlayerID .. ", 'TravelingSalesmanDestroyed')");
return true;
end
if self.Status == g_TravelingSalesmanStatus.Sailing then
self:Sail();
elseif self.Status == g_TravelingSalesmanStatus.AtHarbour then
self:AtHarbour();
elseif self.Status ~= g_TravelingSalesmanStatus.OnHisWay and self.Status ~= g_TravelingSalesmanStatus.Leaving then
Logic.DEBUG_AddNote("DEBUG: Unknown traveling salesman state!");
end
end
-- Diese Funktion generiert euch daraus einen Pfad:
function GetEntitiesNamedWith(_name)
local list = {};
local i = 1;
local bFound = true;
while bFound do
local entity = Logic.GetEntityIDByName(_name .. i);
if entity ~= 0 then
table.insert(list, entity);
else
bFound = false;
end
i = i + 1;
end
return list;
end
--------------------------------
-- Dazu in Mission_InitMerchants() :
TravelingSalesman:new(8, { { 4, { {Goods.G_Iron, 10}, {Goods.G_Stone, 10} } } }, nil, GetEntitiesNamedWith("Weg"))
-- gebraucht werden: S_ShipPath -- benannt mit Weg1, Weg2 usw.
--xxxxxxxxxxxxxxxxxxxxxxxx--TravelingSalesman--Ende--xxxxxxxxxxxxxxxxxxxxxxxxxxxxx--
Lesezeichen