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