Advanced Topics: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
Line 48: Line 48:
local flagPositionX, flagPositionY, flagPositionZ
local flagPositionX, flagPositionY, flagPositionZ
for flagKey,flagValue in flags do
for flagKey,flagValue in flags do
flagPositionX = getElementData ( flagValue, "posX" )
flagX = getElementData ( flagValue, "posX" )
flagPositionY = getElementData ( flagValue, "posY" )
flagY = getElementData ( flagValue, "posY" )
flagPositionZ = getElementData ( flagValue, "posZ" )       
flagZ = getElementData ( flagValue, "posZ" )       
for playerKey,playerValue in players do
for playerKey,playerValue in players do
playerX, playerY, playerZ = getEntityPosition ( playerValue )
playerX, playerY, playerZ = getEntityPosition ( playerValue )
distance = getDistanceBetweenPoints3D ( flagPositionX, flagPostionY, flagPositionZ, playerX, playerY, playerZ )
distance = getDistanceBetweenPoints3D ( flagX, flagY, flagZ, playerX, playerY, playerZ )
if ( distance < 1) then
if ( distance < 1) then
triggerEvent ( "onFlagPickup", flagValue, playerValue )
triggerEvent ( "onFlagPickup", flagValue, playerValue )

Revision as of 16:26, 18 May 2006

This page explains some advanced things you can do with scripts, this page should probably be changed later, depending how useful it is.

Custom element types

One of the most powerful areas of MTA scripting is custom element types. These types can be defined in map files and their functionality implemented by scripts. In this example, we're going to look at a custom flag element, such as you would use in a capture-the-flag game-mode, though this same method could be used for many different things.

First of all you need to decide what format you want the element to be defined in, we're going to use the following:

<flag id="redFlag" name="red team flag" posX="1210.0" posY="-2241.34" posZ="18.4332" />

Now you can define the flag element in the map file.

Next, you can write some code to handle your flag element. First of all, lets add an event that happens when you pick it up, called onFlagPickup. We should do this in an external script file, lets call this capture-the-flag.lua. At the top of the file (outside any functions), define the event:

addEvent ( "onFlagPickup", "player" )

Easy enough! We've added an event that will have a parameter called player. We'll use this to say which player picked up the flag. Next, we have a choice. Either we can add an event handler to the root of the map, and capture every flag pickup event, or we can add it to the individual flag. Its easiest if we use the root of the map, so lets do this here:

mapRoot = getRootElement ( )
addEventHandler ( "onFlagPickup", mapRoot, "flagPickup" )

This says that we want to direct all onFlagPickup events to our function called flagPickup, that we're about to define on the following line:

function flagPickup ( player )
	flagName = getElementData ( source, "name" )
	playerName = getPlayerName ( player )
	outputChatBox ( playerName .. " picked up the flag " .. flagName )
end

The final part of the puzzle is to make it so that the event is triggered at the correct time. To do this, we'll need to create a timer that will be used to check if a player is trying to pick up the flag. Put the following code below your previous addEventHandler call:

setTimer ( "flagCheckPulse", 1000 )

This will make our soon-to-be-defined function flagCheckPulse be called every second. Now we'll define this function:

function flagCheckPulse ( )
	local flags = getElementsByType ( "flag" )
	local players = getElementsByType ( "player" )
	local flagPositionX, flagPositionY, flagPositionZ
	for flagKey,flagValue in flags do
		flagX = getElementData ( flagValue, "posX" )
		flagY = getElementData ( flagValue, "posY" )
		flagZ = getElementData ( flagValue, "posZ" )       
		for playerKey,playerValue in players do
			playerX, playerY, playerZ = getEntityPosition ( playerValue )
			distance = getDistanceBetweenPoints3D ( flagX, flagY, flagZ, playerX, playerY, playerZ )
			if ( distance < 1) then
				triggerEvent ( "onFlagPickup", flagValue, playerValue )
			end
		end
	end
	setTimer ( "flagCheckPulse", 1000 )
end

And thats it!

Note: Although this should work, its not tested. Some things could be improved if better support was provided by us, for example, theres no getPlayerByIndex, no getElementCount(type), an onPlayerPulse event would be useful. This currently only works for one flag, as theres I'm not sure how to find how many flags getElementByType ( "flag" ) returned.

Next: representing the flag in the world - spawning an object at the flags position.