Inhaltsverzeichnis

Positionsbestimmung

Manchmal möchte man eine Position haben die irgendwie relativ zu einer Entity ist.
Es soll natürlich auch in Blickrichtung sein. (Bauernhof, Bauer pinkelt, muß ja stimmen, sonst werden die Schuhe nass) ;)
Gibt sicher sinnvollere Anwendungen.

Dazu habe ich 4 Funktionen gemacht

Alle gehören irgendwie zusammen.

ZurEntity

Punkt in Blick- (Bau-) richtung einer Entity

Diese Funktion gibt den Punkt zurück der im gewählten relativen Abstand zu einer Entity ist. Davor oder dahinter (+/-)

Die Parameter (_entity, _range[, _currPos])

_entity  : Ist die Person, Gebäude zu deren Blickrichtung ein Punkt erwünscht ist. 
_range   : Ist die Entfernung 
_currPos : Die Position auf der man sich befindet.

Rückgabe ist der Punkt. Siehe Anwendungsbeispiel.

function ZurEntity(_entity, _range, _currPos) 
	if type (_entity) == "table" then 
		Message("Keine Position sondern Entity angeben")  -- ein Punkt hat keine Blickrichtung
		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

Anwendungsbeispiel und Erläuterung

  1. Einfachste Anwendung:
    Auf einem Punkt vor einem Bauernhof soll ein Serf erscheinen. Man hat aber keine ScriptEntity.
    CreateEntity(1, Entities.PU_Serf , ZurEntity("BauernHof_XYZ",-1500),"Serf1")

    Jetzt erscheint ein Serf im Abstand von 1500 in der Mitte vor dem Bauernhof. Egal wie der Bauernhof steht.

  2. Mit allen Parametern:
    Ein Serf soll von seiner jetztigen Position aus (er kann ja rechts oder links stehen) zum gewünschten Abstand vom Bauernhof laufen. Nehmen wir jetzt die erste Variante, dann läuft er im Abstand zum Bauernhof aber genau in der Mitte. Das wollen wir aber nicht. Also:
    Move ("Serf1", ZurEntity("BauernHof_XYZ", -1500, "Serf1"))

    Jetzt läuft er zu dem Punkt der 1500 vor dem Bauernhof ist, aber relativ von seiner Position.

RechtsVonPos

Punkt rechts oder links von der Blick- (Bau-) richtung einer Entity

Diese Funktion gibt den Punkt zurück der im gewählten relativen Abstand zu einer Entity ist. Rechts oder links (+/-)

Die Parameter (_entity, _range[, _currPos])

_entity  : Ist die Person, Gebäude zu deren Blickrichtung rechts oder links ein Punkt erwünscht ist. 
_range   : Ist die Entfernung 
_currPos : Die Position auf der man sich befindet.

Rückgabe ist der Punkt. Siehe Anwendungsbeispiel.

function RechtsVonPos(_entity, _range, _currPos)  -- neu geschrieben
    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)));
    return {X = _currPos.X + nSin * _range, Y = _currPos.Y - nCos * _range};  -- Rückgabe = neue Position
end

Anwendungsbeispiel und Erläuterung

  1. Einfachste Anwendung:
    Auf einem Punkt rechts von einem Bauernhof soll ein Serf erscheinen. Man hat aber wie oben keine ScriptEntity.
    CreateEntity(1, Entities.PU_Serf , RechtsVonPos("BauernHof_XYZ",-1500),"Serf1")

    Jetzt erscheint ein Serf im Abstand von 1500 in der Mitte links dem Bauernhof. Egal wie der Bauernhof steht.

  2. Mit allen Parametern:
    Ein Serf soll von seiner jetztigen Position aus (er kann ja rechts oder links stehen) zum gewünschten Abstand vom Bauernhof laufen. Nehmen wir jetzt die erste Variante, dann läuft er im Abstand zum Bauernhof aber genau in der Mitte. Das wollen wir aber nicht. Also:
    Move ("Serf1", RechtsVonPos("BauernHof_XYZ", -1500, "Serf1"))

    Jetzt läuft er zu dem Punkt der 1500 links dem Bauernhof ist, aber relativ von seiner Position.

RelVonPos

Vereinigung der obigen Funktionen

Erklärung bedarf es hierbei nicht viel, da oben alles erklärt ist.

Ich will rechts 700 und in Blickrichtung 1500 einen Punkt haben.

punkt = RelVonPos(_entity, 700, 1500)
function RelVonPos(_entity, _rechts, _vor)
    local rueckPos = {};
    rueckPos = RechtsVonPos( _entity, _rechts);
    rueckPos = ZurEntity( _entity, _vor, rueckPos );
    return rueckPos;  -- Rückgabe = neue Position
end

KreisPosition

Eine Position innerhalb eines Umkreises der Entity

function KreisPosition(_entity, _range, _angle)
 
    local entity, position = GetEntityId(_entity), GetPosition(_entity)
    assert(type(entity) == "number" and type(position) == "table")
 
    local angle = math.rad(_angle or Logic.GetEntityOrientation(entity))
    assert(type(angle) == "number")
 
    assert(type(_range) == "number")
 
    return {
        X = position.X - math.cos(angle) * _range,
        Y = position.Y - math.sin(angle) * _range  
    }
 
end

Die Erklärung dieser Funktion ist am besten in der Anwendung.

Ich möchte einen Kreis von Feuer um eine Entity machen.
Wieviel Feuer will ich? Sagen wir 10
Abstand wollen wir 1000.

Dann machen wir eine Schleife

for i = 0, 360, 36 do -- 36 weil 360 / 10 = 36
    CreateEntity(........ ,KreisPosition(Entity ,1000, i ), .... )
end

Will ich nur einen Halbkreis, dann geht die Schleife natürlich nur bis 180.
Will ich einen Halbkreis, der hinten anfängt und vorne aufhört, dann fängt man mit for i = 90 an und endet mit 270. u.s.w