Ca3DE Map Scripting - a progress report
Posted: 2007-08-24, 15:25
Hi all,
I'm happy and proud to announce that the following fragment of a Ca3DE map script is a real and fully working example of the latest Ca3DE scripting support!
The MyLight:OnTrigger() function is called from a 3D world GUI in the map and performs one of the preset logic variants (variant=3 in the example below).
The main focus in this example script is on the coroutine.yield() function, which serves as the equivalent of both a wait(t) (wait t seconds until the script is resumed) as well as a waitFrame() (wait until end-of-frame) function as known e.g. from Doom 3 and Quake 4.
The other highlight in the code is the thread() function, which registers any Lua function for execution as a separate thread!
The next release of Ca3DE will come with the above presented features -- stay tuned!
I'm happy and proud to announce that the following fragment of a Ca3DE map script is a real and fully working example of the latest Ca3DE scripting support!
The MyLight:OnTrigger() function is called from a 3D world GUI in the map and performs one of the preset logic variants (variant=3 in the example below).
The main focus in this example script is on the coroutine.yield() function, which serves as the equivalent of both a wait(t) (wait t seconds until the script is resumed) as well as a waitFrame() (wait until end-of-frame) function as known e.g. from Doom 3 and Quake 4.
The other highlight in the code is the thread() function, which registers any Lua function for execution as a separate thread!
Code: Select all
function LightBlinkThread(lightEntity)
-- Notice the great generality of this function:
-- It can be used with *any* light entity, which is passed in via the lightEntity parameter!
while (true) do
lightEntity:SetColor(0, 255, 0);
coroutine.yield(0.5); -- Wait 0.5 seconds.
if (not lightEntity.IsBlinking) then break; end
lightEntity:SetColor(255, 0, 0);
coroutine.yield(0.5); -- Wait 0.5 seconds.
if (not lightEntity.IsBlinking) then break; end
end
end
MyLight.IsRed=false;
MyLight.IsBlinking=false;
function MyLight:OnTrigger()
-- Choose the variant of logic you want to test.
local variant=3;
-- The logic is here and not in the GUI script because the GUI script code is also run on client prediction.
-- This map script code is only run on server thinking.
if (variant==1) then
-- Implements a toggle switch.
if (self.IsRed) then
self:SetColor(0, 255, 0);
else
self:SetColor(255, 0, 0);
end
self.IsRed=not self.IsRed;
elseif (variant==2) then
-- Toggles between permanent red/green blinking and not blinking.
if (self.IsBlinking) then
-- Currently blinking, turn it off now.
-- This will break the infinite loop below.
self.IsBlinking=false;
self:SetColor(oldR, oldG, oldB);
else
-- Currently not blinking, turn it on now.
oldR, oldG, oldB=self:GetColor();
self.IsBlinking=true;
while (true) do
self:SetColor(0, 255, 0);
coroutine.yield(0.5); -- Wait 0.5 seconds.
if (not self.IsBlinking) then break; end
self:SetColor(255, 0, 0);
coroutine.yield(0.5); -- Wait 0.5 seconds.
if (not self.IsBlinking) then break; end
end
end
elseif (variant==3) then
-- As variant 2 above (toggles between permanent red/green blinking and not blinking),
-- but implemented with an explicit thread (coroutine).
-- This is the Ca3DE equivalent/analog to the Doom3 thread example in base\script\map_marscity2.script,
-- but more elaborate and versatile (the LightBlinkThread function is reusable with any light entity).
if (self.IsBlinking) then
-- Currently blinking, turn it off now.
-- This will break the infinite loop in the thread.
self.IsBlinking=false;
self:SetColor(oldR, oldG, oldB);
else
-- Currently not blinking, turn it on now.
oldR, oldG, oldB=self:GetColor();
self.IsBlinking=true;
-- Register the function LightBlinkThread as a new thread. Call with "self" as the first parameter.
thread(LightBlinkThread, self);
end
else
-- Implements a one-time blink.
local r, g, b=self:GetColor(); -- Save the previous color.
self:SetColor(255, 255, 0); -- Set to yellow.
coroutine.yield(1); -- Wait 1 sec.
self:SetColor(r, g, b); -- Set back previous color.
end
end