Handel treiben

Man kann sicher auf verschieden Art und Weise Handel treiben. Hier ist ein putziges Beispiel dazu.
Funktionieren tut es. Es ist aber sicher noch verbesserungsbedürftig.

handel.rar
Alternatives Script hier wird die Auswahl durch Anklicken des Basars getätigt. Briefingtext stimmt dann nicht.
Beide Versionen ausgiebig getestet. ;-)

Code

---------------------------------------------------------------------------------
-- MapName:Handel
-- Autor: Peermanent(Map und Idee) & Robert(Script)
----------------------------------------------------------------------------------------------------
Script.Load( Folders.MapTools.."Main.lua" )
IncludeGlobals("MapEditorTools")
----------------------------------------------------------------------------------------------------
function InitDiplomacy()
----------------------------------------------------------------------------------------------------
	SetHostile(1,2)
end
----------------------------------------------------------------------------------------------------
function InitResources()
----------------------------------------------------------------------------------------------------
    AddGold  (1000)
    AddSulfur(0)
    AddIron  (0)
    AddWood  (11000)	
    AddStone (1000)	
    AddClay  (1000)
 
    AddGold  (2,5000)
end
----------------------------------------------------------------------------------------------------
function InitTechnologies()
----------------------------------------------------------------------------------------------------
	ForbidTechnology(Technologies.B_Weathermachine)
end
----------------------------------------------------------------------------------------------------
function InitWeatherGfxSets()
----------------------------------------------------------------------------------------------------
	SetupNormalWeatherGfxSet()
end
----------------------------------------------------------------------------------------------------
function InitWeather()
----------------------------------------------------------------------------------------------------
	AddPeriodicSummer(800)
	AddPeriodicRain(10)
end
----------------------------------------------------------------------------------------------------
function InitPlayerColorMapping()
----------------------------------------------------------------------------------------------------
end
----------------------------------------------------------------------------------------------------
function FirstMapAction()
----------------------------------------------------------------------------------------------------
	Tools.ExploreArea( -1, -1, 900 )
	SpeedUpGame()
	SpeedUpGame()
	SpeedUpGame()
	SpeedUpGame()
	SpeedUpGame()
	CreateEntity(1,Entities.XD_ScriptEntity,ZurEntity("HQone",800),"vorHQ")
	CreateEntity(1,Entities.XD_ScriptEntity,ZurEntity("basarOne",800),"vorBasar1")
	CreateEntity(1,Entities.XD_ScriptEntity,ZurEntity("basarTwo",800),"vorBasar2")
	----------------------------------------------------------------------------------------------------
	ActivateBriefingsExpansion()
	LocalMusic.UseSet = HIGHLANDMUSIC
	----------------------------------------------------------------------------------------------------
	warteKarre1=5
	warteKarre2=5
	hin1=true
	handel1=false
	handel2=false
	hin2=true
	EisenMarkt=3000
	SchwefelMarkt=2000
	Eisen=0
	Schwefel=0
	preisEisen={{150,100,"Holz","Eisen"},{150,100,"Eisen","Schwefel"}}
	Move("erec","haendlerOne")
	Camera.FollowEntity(GetEntityId("erec"))
	CreatePlayerTwo ()
	BriefingHaendlerOne()
	StartSimpleJob("Uerberwachung")
	StartSimpleJob("VictoryJob")
 
end	
---------------------------------------------------------------------------------------------
function StartEisenHundert()
	if EisenMarkt >=100 then
		tribute =  {
						playerId = 1,
						text = Umlaute("Zahle 150 Holz für 100 Eisen."),
						cost = {  },
						Callback =   StartEisenHundert
 
					}
		AddTribute( tribute );
		EisenMarkt=EisenMarkt-100
		Eisen=Eisen+100
	else
		Message("Ihr habt meinen Ganzen Vorrat an Eisen geplündert, jetzt ist Schluß")
	end
end
 
function StartEisenTausend()
	if EisenMarkt >=1000 then
		tribute =  {
						playerId = 1,
						text = Umlaute("Zahle 1500 Holz für 1000 Eisen."),
						cost = {  },
						Callback =   StartEisenTausend
 
					}
		AddTribute( tribute );
		Eisen=Eisen+1000
		EisenMarkt=EisenMarkt-1000
	else
		Message("Soviel hab ich nicht mehr. Bedient euch bei den 100 ten ")
	end
end
 
function StartSchwefelHundert()
	local tribute 
	if SchwefelMarkt >=100 then
		tribute =  {
						playerId = 1,
						text = Umlaute("Zahle 150 Eisen für 100 Schwefel."),
						cost = {  },
						Callback =   StartSchwefelHundert
 
					}
		AddTribute( tribute );
		Schwefel=Schwefel+100
		SchwefelMarkt=SchwefelMarkt-100
	else
		Message("Ihr habt meinen Ganzen Vorrat an Schwefel geplündert, jetzt ist Schluß")
	end
end
 
function StartSchwefelTausend()
	local tribute 
	if SchwefelMarkt >=1000 then
		tribute =  {
							playerId = 1,
							text = Umlaute("Zahle 1500 Eisen für 1000 Schwefel."),
							cost = {  },
							Callback =   StartSchwefelTausend
 
						}
		AddTribute( tribute );
		Schwefel=Schwefel+1000
		SchwefelMarkt=SchwefelMarkt-1000
	else
		Message("Soviel hab ich nicht mehr. Bedient euch bei den 100 ten ")
	end
end
 
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
function CreatePlayerTwo()
	playerTwo = {}
	playerTwo.id = 2
	local description = {serfLimit = 10}
	SetupPlayerAi(playerTwo.id,description)
end
---------------------------------------------------------------------------------------
function BriefingHaendlerOne()
    local quest = {
        EntityName = "erec",
        TargetName = "haendlerOne",
		Distance = 500,
 
        Callback = function(_quest)
		local briefing = { noEscape = true };
		local AP, ASP = AddPages(briefing);
		local page1			=	AP{
			title			=	"Übers Ohr Hauer",
			text			=	"Komse her komse ran... @cr Hier werden sie genauso Beschissen wie Nebenan..",
			action			=	function () DIALOG_ZOOMDISTANCE = 1000; DIALOG_ZOOMANGLE = 15 
								LookAt("haendlerOne", "erec"); LookAt("erec", "haendlerOne")
								end, 
			npc				=	{ id = GetEntityId("haendlerOne"), isObserved = true },
 
		};
		local page2			=	AP{
			title			=	"Erec",
			text			=	"Hoooo Hoooo @cr Was haste den anzubieten. @ Ich brau unbedingt Schwefel und Eisen! @cr Haste denn sowas da?",
			aktion			=	function() BRIEFING_ZOOMDISTANCE = 1000; BRIEFING_ZOOMANGLE = 15; end
		};
		ASP("haendlerOne","Übers Ohr Hauer","Das Beste Eisen.. nur das Beste.");
		ASP("erec","Erec","Ok für den Preis von 150 Holz gebe ich dir 100 Eisen.");
		ASP("haendlerOne","Übers Ohr Hauer","Abgemacht, ich schicke meine Karre los, wenn Du bestellst, und liefere dir das Eisen wenn du mir Holz aus deinen Hauptquartier gibst.");
		ASP("erec","Erec","Dann drück ich mal F3 um zu sehen wie ich mit Dir handeln kann.");
		local npc	=	{ 
			name				=	"haendlerOne", 
			briefing			=	briefing,
			heroName    		=	"erec",		
			wrongHeroMessage 	=	"Laßt mich in Ruhe... " 
			};
			CreateNPC(npc);
		briefing.finished	 =	function()
				local tribute =  {
									playerId = 1,
									text = Umlaute("Zahle 150 Holz für 100 Eisen."),
									cost = {  },
									Callback =   StartEisenHundert
 
								}
				AddTribute( tribute );
				tribute =  {
									playerId = 1,
									text = Umlaute("Zahle 1500 Holz für 1000 Eisen."),
									cost = {  },
									Callback = StartEisenTausend
								}
				AddTribute( tribute );
								RestoreBriefingSettings(); 
								ResolveBriefing(page1);	
								ResolveBriefing(page2);	
								BriefingHaendlerTwo()
							end
		StartBriefing(briefing);
	end};
    SetupExpedition( quest )
end
--------------------------------------------------------------------------------------------
function Uerberwachung()
	if Eisen>0 and (not handel1) then
		handel1=true
		Move("karreOne","vorHQ")
		hin1=true
	end
	if Schwefel>0 and (not handel2) then
		Move("karreTwo","vorHQ")
		handel2=true
		hin2=true
	end
	if IsNear("karreOne","vorHQ",300) and hin1 then
		if warteKarre1 > 0 then
			warteKarre1=warteKarre1-1
		end
		if warteKarre1==0 then
			if GetWood(1) > 149 then
				warteKarre1=5
				hin1=false
				AddWood(1,-150)
				AddIron(1,100)
				Eisen=Eisen-100
				Move("karreOne","vorBasar1")
			end
		end
	end
	if IsNear("karreOne","vorBasar1",300) and (not hin1) then
		if warteKarre1 > 0 then
			warteKarre1=warteKarre1-1
		end
		if warteKarre1==0 and Eisen >= 100 then
			warteKarre1=5
			hin1=true
			Move("karreOne","vorHQ")
		elseif handel1 and Eisen == 0 then
			handel1=false
		end
	end
-----------------------------------------------------------------------------------------------------------------
	if IsNear("karreTwo","vorHQ",300) and hin2 then
		if warteKarre2 > 0 then
			warteKarre2=warteKarre2-1
		end
		if warteKarre2==0 then
			if GetIron(1) > 149 then
				warteKarre2=5
				hin2=false
				AddIron(1,-150)
				AddSulfur(1,100)
				Schwefel=Schwefel-100
				Move("karreTwo","vorBasar2")
			end
		end
	end
	if IsNear("karreTwo","vorBasar2",300) and (not hin2) then
		if warteKarre2 > 0 then
			warteKarre2=warteKarre2-1
		end
		if warteKarre2==0 and Schwefel >=100 then
			warteKarre2=5
			hin2=true
			Move("karreTwo","vorHQ")
		elseif handel2 and Schwefel == 0 then
			handel2=false
		end
	end
end
function _OP_CleanUp(_position, _range,_entity) -- Die Funkltion habe ich für unsere Zwecke umgebaut
    local Data = { Logic.GetEntitiesInArea( _entity, _position.X, _position.Y, _range, 20)};
    local i;
    for i=2, Data[1]+1 do
		Message( GetEntityName(Data[i])) -- hier gibt es die Nummer der Brücke zurück
    end
	return 0 -- keine Brücke da, also 0 zurück
end
---------------------------------------------------------------------------------------------
function BriefingHaendlerTwo()
    local quest = {
        EntityName = "erec",
        TargetName = "haendlerTwo",
		Distance = 500,
        Callback = function(_quest)
		local briefing = { noEscape = true };
		local AP, ASP = AddPages(briefing);
		local page1			=	AP{
			title			=	"Schlitzohr",
			text			=	"Na du ..hat dich mein Kumpel schon ausgeplündert, oder kann ich dir noch was aus der Tasche ziehen",
			action			=	function () DIALOG_ZOOMDISTANCE = 1000; DIALOG_ZOOMANGLE = 15 
								LookAt("haendlerTwo", "erec"); LookAt("erec", "haendlerTwo")
								end, 
			npc				=	{ id = GetEntityId("haendlerTwo"), isObserved = true },
 
		};
		local page2			=	AP{
			title			=	"Erec",
			text			=	"Du bist genauso ein gieriger Hund wie dein Kumpel. @cr Aber sag, hast du Schwefel für mich?",
			aktion			=	function() BRIEFING_ZOOMDISTANCE = 1000; BRIEFING_ZOOMANGLE = 15; end
		};
		ASP("haendlerTwo","Schlitzohr","Aber sicher wenn du mir Eisen dafür gibst.");
		ASP("erec","Erec","Ok ich gebe dir 100 Eisen für 150 Schwefel.");
		ASP("haendlerTwo","Schlitzohr","Ne so nicht mein Freund @cr Sagen wir 100 Eisen für 80 Schwefel, oder such dir selbst welches.");
		ASP("erec","Erec","Ok Ok du weißt ganz genau das hier kein Schwefel zu finden ist. @cr Dann schau ich mal in die Tribute oben, um zu sehen wie ich mit Dir handeln kann.");
		local npc	=	{ 
			name				=	"haendlerTwo", 
			briefing			=	briefing,
			heroName    		=	"erec",		
			wrongHeroMessage 	=	"Laßt mich in Ruhe... " 
			};
			CreateNPC(npc);
			briefing.finished	 =	function()
								RestoreBriefingSettings(); 
								ResolveBriefing(page1);	
								ResolveBriefing(page2);	
								local 	tribute =  {
														playerId = 1,
														text = Umlaute("Zahle 150 Eisen für 100 Schwefel."),
														cost = {  },
														Callback =   StartSchwefelHundert
 
													}
								AddTribute( tribute );
										tribute =  {
														playerId = 1,
														text = Umlaute("Zahle 1500 Eisen für 1000 Schwefel."),
														cost = {  },
														Callback = StartSchwefelTausend
													}
								AddTribute( tribute );
							end
		StartBriefing(briefing);
	end};
    SetupExpedition( quest )
end
--------------------------------------------------------------------------------------------
 
---------------------------------------------------------------------------------------------
function VictoryJob()
	if 	IsDead("playerTwo") then
--		EndeOne()
		Victory()
		return true
	end
end
---------------------------------------------------------------------------------------------
function RestoreBriefingSettings()
    BRIEFING_CAMERA_FLYTIME = 0
    BRIEFING_TIMER_PER_CHAR = 1.4
 
    DIALOG_ZOOMDISTANCE     = 1200
    DIALOG_ZOOMANGLE        = 29
    BRIEFING_ZOOMDISTANCE   = 3770
    BRIEFING_ZOOMANGLE	    = 43
end
-------------------------------------------------------------------------------------------
 
function AddPages( _briefing )
    local AP = function(_page) table.insert(_briefing, _page); return _page; end
    local ASP = function(_entity, _title, _text, _dialog) return AP(CreateShortPage(_entity, _title, _text, _dialog)); end
    return AP, ASP;
end
-------------------------------------------------------------------------------------------
function CreateShortPage( _entity, _title, _text, _dialog) 
    local page = {
        title = _title,
        text = _text,
        position = GetPosition( _entity ),
    };
    if _dialog then page.dialogCamera = true; end
    return page;
end
--***********************************************************************************************************
function AddTribute( _tribute )
	assert( type( _tribute ) == "table", "Tribut muß ein Table sein" );
    assert( type( _tribute.text ) == "string", "Tribut.text muß ein String sein" );
    assert( type( _tribute.cost ) == "table", "Tribut.cost muß ein Table sein" );
	assert( type( _tribute.playerId ) == "number", "Tribut.playerId muß eine Nummer sein" );
	assert( not _tribute.Tribute , "Tribut.Tribute darf nicht vorbelegt sein");
 
    uniqueTributeCounter = uniqueTributeCounter or 1;
    _tribute.Tribute = uniqueTributeCounter;
    uniqueTributeCounter = uniqueTributeCounter + 1;
 
    local tResCost = {};
    for k, v in pairs( _tribute.cost ) do
        assert( ResourceType[k] );
        assert( type( v ) == "number" );
        table.insert( tResCost, ResourceType[k] );
        table.insert( tResCost, v );
    end
 
    Logic.AddTribute( _tribute.playerId, _tribute.Tribute, 0, 0, _tribute.text, unpack( tResCost ) );
    SetupTributePaid( _tribute );
 
    return _tribute.Tribute;
end
-----------------------------------
function ActivateBriefingsExpansion()
    if not unpack{true} then --unpack()-Fix
        local unpack2;
        unpack2 = function( _table, i )
                            i = i or 1;
                            assert(type(_table) == "table");
                            if i <= table.getn(_table) then
                                return _table[i], unpack2(_table, i);
                            end
                        end
        unpack = unpack2;
    end
 
    Briefing_ExtraOrig = Briefing_Extra;
    Briefing_Extra = function( _v1, _v2 )
                         for i = 1, 2 do
                             local theButton = "CinematicMC_Button" .. i;
                             XGUIEng.DisableButton(theButton, 1);
                             XGUIEng.DisableButton(theButton, 0);
                         end
                         if _v1.action then
                             assert( type(_v1.action) == "function" );
                             if type(_v1.parameters) == "table" then 
                                 _v1.action(unpack(_v1.parameters));
                             else
                                 _v1.action(_v1.parameters);
                             end
                         end
                         Briefing_ExtraOrig( _v1, _v2 );
                     end;
 
    GameCallback_EscapeOrig = GameCallback_Escape;
    StartBriefingOrig = StartBriefing;
    EndBriefingOrig = EndBriefing;
    MessageOrig = Message;
 
    CreateNPCOrig = CreateNPC;
    StartBriefing = function(_briefing)
                        assert(type(_briefing) == "table");
                        if _briefing.noEscape then
                            GameCallback_Escape = function() end;
                            briefingState.noEscape = true;
                        end
                        StartBriefingOrig(Umlaute(_briefing));
                    end
    EndBriefing = function()
                      if briefingState.noEscape then
                          GameCallback_Escape = GameCallback_EscapeOrig;
                          briefingState.noEscape = nil;
                      end
 
                      EndBriefingOrig();
                  end;
    Message = function(_text)
                  MessageOrig(Umlaute(tostring(_text)));
              end;
    CreateNPC = function(_npc)
                    CreateNPCOrig(Umlaute(_npc));
                end;
    Umlaute = function(_text)
                  local texttype = type(_text);
                  if texttype == "string" then
                      _text = string.gsub( _text, "ä", "\195\164" );
                      _text = string.gsub( _text, "ö", "\195\182" );
                      _text = string.gsub( _text, "ü", "\195\188" );
                      _text = string.gsub( _text, "ß", "\195\159" );
                      _text = string.gsub( _text, "Ä", "\195\132" );
                      _text = string.gsub( _text, "Ö", "\195\150" );
                      _text = string.gsub( _text, "Ü", "\195\156" );
                      return _text;
                  elseif texttype == "table" then
                      for k, v in _text do
                          _text[k] = Umlaute( v );
                      end
                      return _text;
                  else return _text;
                  end
              end;
end
CxTools = CxTools or {}; 
function CxTools:Init()
    CxTools:InitUnpackFix();
    CxTools:InitTriggers();
end
function ZurEntity(_entity, _range, _currPos)  -- neu geschrieben
	-- _entity  = die Entity zu deren Winkel  man sich bewegen will
	-- _currPos Die Position auf der man sich befindet
	-- _tRange= die Entfernung zur Entity (im Winkel der Entity) Weiter weg ist dann negativ
	if type (_entity) == "table" then 
		Message("Keine Position sondern Entity angeben")
		return nil
	end
	if type (_entity) == "string" then
		_entity = GetEntityId(_entity);
	end
	local tPos = GetPosition(_entity)
	if _currPos == nil then
		_currPos = tPos
	elseif type (_currPos) == "string" or type (_currPos) == "number"  then
		_currPos = GetPosition(_currPos)
	end
	local nEntityAngle=Logic.GetEntityOrientation(_entity);
	local nSin=math.sin((math.rad(nEntityAngle)));
	local nCos=math.cos((math.rad(nEntityAngle)));
	local tPos = GetPosition(_entity)
	return {X=_currPos.X-nCos*_range,Y=_currPos.Y-nSin*_range}; -- Rückgabe=neue Position
end