Inhaltsverzeichnis

BuildingCheck

Diese Funktion ermöglicht es, das Bauen von Gebäuden entweder nur in einem bestimmten Gebiet zuzulassen oder es dort zu verbieten.

Hinweis: Hierbei handelt es sich nicht um eine „100% gebrauchsfertige“ Funktion, die man einfach so in sein Script kopieren kann. Vielmehr sind entsprechende, mapbezogene Anpassungen erforderlich. Wem nach dem Lesen dieser Seite nicht 100%ig klar ist, was er anpassen muss und wie die Funktion arbeitet, der sollte sie nicht in seine Map einbauen, da es ansonsten zu schweren Fehlern im Spiel kommen kann!!!
Ferner sollte diese Funktion mit Bedacht und nicht permanent eingesetzt werden!

Verwendung

Der erforderliche Scriptcode besteht aus 2 Teilen. Der erste Teil muss in die FMA (FirstMapAction) Funktion kopiert werden. Der zweite Teil, die Funktion BuildingCheck() wird im Bedarfsfall als SimpleHiResJob gestartet und kann an beliebiger Stelle im Script untergebracht werden (nur nicht innerhalb einer anderen Funktion!).

Zu Beginn muss das oder die entsprechenden Area-Table(s) angegeben werden. Die zwei in der Funktion enthaltenen Area-Tables sind nur Beispiele und müssen entsprechend angepasst werden! Bei der Indexierung der Area-Tables muss darauf geachtet werden, dass kein Index doppelt verwendet wird. Eine fortlaufende Nummerierung ist nicht zwingend erforderlich - schadet aber nicht ;-).

Ein Gebiet (Area) wird immer durch 4 Koordinaten (Reihenfolge beachten!) in einem Table festgelegt.

  1. X-Koordinate der linken unteren Ecke
  2. X-Koordinate der rechten oberen Ecke
  3. Y-Koordinate der linken unteren Ecke
  4. Y-Koordinate der rechten oberen Ecke

Zusätzlich gibt eine fünfte Zahl an, ob das Bauen in dem Gebiet (Area) erlaubt oder verboten ist:
1 = Bauen nur in dem Gebiet (der Area) erlaubt
2 = Bauen in dem Gebiet (der Area) verboten

Beispiel für ein gültiges Area-Table:

Area[1] = {38000,43000,26000,30600,1}

Daraus ergibt sich automatisch, dass ein Gebiet immer viereckig ist! Beachten muss man hierbei auch, dass die Mausposition abgefragt und mit den Area-Koordinaten abgeglichen wird. Folglich darf man das Gebiet nicht zu klein machen, da das Bauauswahl-Menü (am unteren Bildschirmrand) bspw. auch noch mit abgedeckt werden muss. Überhaupt findet man die korrekten Koordinaten am besten durch intensives Testen heraus!

Da diese Funktion eine spielinterne Funktion quasi „abfängt“ und ggf. abändert, kann man sie sozusagen nur An- & Ausschalten. Dies geschieht mittels der globalen Variablen AreaSelect.

AreaSelect = false

= Funktion ausgeschaltet

AreaSelect = [eine Zahl]

= Funktion eingeschaltet (wobei [eine Zahl] durch eine gültige Indexnummer einer oben definierten Area-Table zu ersetzen ist)

Mit der Indexzahl wird also das entsprechende Gebiet (Area) ausgewählt.

Da der Einsatz der Funktion immer nur für einen bestimmten Zeitraum erfolgen sollte, kann man sie z.B. in einem Quest aufrufen, indem man einfach der Variablen AreaSelect den entsprechenden Indexwert des Area-Tables zuweist. Also z.B.:

AreaSelect = 2

Ist der Quest erfüllt, in der Callback-Funktion des Questa die Funktion wieder ausschalten, indem man der Variablen AreaSelect den Wert false zuweist:

AreaSelect = false

Einschränkungen/ Fehlerüberprüfung

Momentan kann immer nur ein (zusammenhängendes und viereckiges) Gebiet (Area) ausgewählt werden! Mehrere Gebiete gleichzeitig würden den Scriptaufwand erheblich erhöhen und man darf auch nicht vergessen, dass dieser Teil in einem HiResJob abgearbeitet wird - schließlich soll das Spiel ja nicht ins Stocken kommen.

ToDo: Da ansonsten ja fast alles im Spiel mit Kreisen arbeitet (also Mittelpunkt und Radius, bzw. Position und Range), werde ich evt. auch noch zusätzlich diese Möglichkeit zur Angabe einer Area einbauen.

In dem weiter unten bereitgestellten Code sind etliche Zeilen zur Fehlerüberprüfung enthalten. Wer die Funktion in seinem Script vollständig & ausgiebig getestet hat, der kann diese Zeilen (zwischen „--# Fehlerprüfcode Anfang“ und --# Fehlerprüfcode Ende„) dann rauslöschen. Ansonsten sagt die jeweilige Fehlermeldung aus, wo der Fehler liegt.

Einsatzmöglichkeiten

Ich habe diese Funktion aus dem Wunsch heraus entwickelt, dem Spieler das Bauen auf dem Gebiet eines späteren Verbündeten zu verbieten. Ebenso kann man aber auch dem Spieler nur erlauben, in einem bestimmten Gebiet zu bauen (bis er bspw. einen Quest erfüllt hat). Auf jeden Fall sollte man dem Spieler diese Einschränkung(en) auch klar & deutlich mitteilen, etwa durch ein entsprechendes Briefing o.ä.!

Wer das Funktionsprinzip verstanden hat, findet auch ganz leicht heraus, wie man das „Bauverbot“ / die „Bauerlaubnis“ auch noch zusätzlich auf bestimmte Gebäudetypen einschränken kann ;-)!

Code

Dieser Teil muss in die FMA:

Area = {}
-- # hier werden die jeweiligen Areas eingefügt
Area[1] = {38000,43000,26000,30600,1}
Area[2] = {21000,25000,16000,20000,2}
-- # hier bei Bedarf weitere Areas einfügen
GUIAction_PlaceBuildingOrig = GUIAction_PlaceBuilding
GUIAction_PlaceBuilding = function(_type)
	GUIAction_PlaceBuildingOrig(_type)
	if not BuildingCheck_JobId and AreaSelect then
		AreaAllowedForbidden = Area[AreaSelect][5]
		--# Fehlerprüfcode Anfang
		assert( type( Area[AreaSelect] ) == "table", "Area muß ein Table sein" )
		assert( table.getn(Area[AreaSelect]) == 5, "Das Area-Table muss genau 5 Zahlenwerte beinhalten ")
		table.foreach(Area[AreaSelect], function(k,v)
			assert( type( v ) == "number", "Das Area-Table darf nur Zahlen beinhalten" )
		end)
		assert( AreaAllowedForbidden == 1 or AreaAllowedForbidden == 2, "Der Wert für AreaAllowedForbidden muss 1 oder 2 sein!")
		--# Fehlerprüfcode Ende
		BuildingCheck_JobId = StartSimpleHiResJob("BuildingCheck")
	end
end

Dieser Teil kann irgendwo im Script platziert werden (nur nicht innerhalb anderer Funktionen!):

function BuildingCheck()
	if GUI.GetCurrentStateName() == "PlaceBuilding" then
		local mouseX, mouseY = GUI.Debug_GetMapPositionUnderMouse()
		local areaCheck = ((mouseX > Area[AreaSelect][1] and mouseX < Area[AreaSelect][2]) and (mouseY > Area[AreaSelect][3] and mouseY < Area[AreaSelect][4]))
		if ( AreaAllowedForbidden == 1 and not areaCheck ) or ( AreaAllowedForbidden == 2 and areaCheck ) then
			GUI.CancelState()
			Message("Hier darf nicht gebaut werden!")
			BuildingCheck_JobId = nil
			return true
		end
	else 
		BuildingCheck_JobId = nil
		return true
	end
end

Forumsbeitrag

Wer Fragen, Anregungen und/ oder Probleme zu/ mit der Funktion hat, der kann diese auch gerne im entsprechenden Forumsbeitrag im siedler-portal posten. Dort ist auch noch eine ältere, aber einfachere Version des Scripts vorhanden (nur für ein Gebiet).