[[http://www.siedler-games.de|{{:sg-link.jpg|}}]] ====== 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. {{:utilmaps:handel.rar}} \\ {{:utilmaps:handel_lua.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