Login  Register
 



Post new topicReply to topic
 
Author Message
 PostPosted: 12 Jul, 2007 
 
User avatar

Joined: 16 Feb, 2007
Posts: 555
Location: Holland
Offline
Ive made this topic with the simple reason that Saya and others are coming up with all kind of custom scripts for map's like weather and no mass fab's.
Anyway its all kind of strait forward and big thanks to them who made these code's.
***To the respected scripters: Would you all be so kind to drop scripts in to here? Thanks in Advance.***

Lets start! :)

Index *(Listed in same order as posted below)
*No Mass Fabricators Part I
*Supcom Bridge support. Part I
*Tutorial: Weather Effects Part II
*Map Script Driven Dialog's Part III
*How to Spawn Upgraded ACUs? Part III
*Map Size Script. Page 1
*Make water ACT like Lava. Page 1
*Make water LOOK like Lava. Page 1
*Spawn AI at a alternate spawn point. Page 1
*How to Spawn Upgraded ACUs for non-AI players?. Page 1
*How to Transport a unit? (by air) Page 1
*How to build Nukes, Anti-Nukes or Tactical Missiles ?

Scripts

No Mass Fabricators
Saya wrote:
Here you go mass fabricators are disabled.

Code:
--scenario utilities
local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua')
local ScenarioFramework = import('/lua/ScenarioFramework.lua')

function OnPopulate()   
   ScenarioUtils.InitializeArmies()   
   local tblArmy = ListArmies()
   
   --add mass fabrication restriction
   for index,army in tblArmy do
      ScenarioFramework.AddRestriction(army, categories.MASSFABRICATION*categories.STRUCTURE)
   end
end


--start of map script
function OnStart(self)
end



No Artillery (Saya's restriction script is valid on everything, in this case Artillery Structures.)
Code:
--scenario utilities
local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua')
local ScenarioFramework = import('/lua/ScenarioFramework.lua')

function OnPopulate()   
   ScenarioUtils.InitializeArmies()   
   local tblArmy = ListArmies()
   
   --add artillery restriction
   for index,army in tblArmy do
      ScenarioFramework.AddRestriction(army, categories.ARTILLERY*categories.STRUCTURE)
   end
end


--start of map script
function OnStart(self)
end




Supcom Bridge support.
CardiacReactor wrote:
Make parts of your map passable by LAND and NAVAL units. Land units walk over, naval units get sucked through underneath.


How to do it?
1. make sure you drop the cardiacutils_teleport.lua into your map's folder.

2. Your mapscript will look this way: (the teleportationZones definition should be self-explainatory)
Code:
local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua')
local ScenarioFramework = import('/lua/ScenarioFramework.lua')

local TeleportUtils = import(string.gsub(ScenarioInfo.map, '[^/]*.scmap' , 'cardiacutils_teleport.lua'))

function OnPopulate()
ScenarioUtils.InitializeArmies()
--ScenarioFramework.SetPlayableArea(ScenarioUtils.AreaToRect('AREA_1'))
end

function OnStart(self)
   local topBridge = 92
   local botBridge = 512-92
   local bridgeHeight = 24

   local teleportationZones =
   {
      {
         sourceZone = Rect(0,topBridge+2,512,botBridge-2), -- redirect if into zone and
         targetZone = Rect(0,0,512,topBridge-2), -- move order into this zone is issued
         name      ='centerToTop',
         teleporterSource = TeleportUtils.Pos(240,topBridge+bridgeHeight/2),
         teleporterDest = TeleportUtils.Pos(240,topBridge-bridgeHeight/2),
         unitCategory = categories.NAVAL
       },
      {
         sourceZone = Rect(0,0,512,topBridge-bridgeHeight/2),  -- redirect if into zone and
         targetZone = Rect(0,topBridge+2,512,botBridge+bridgeHeight/2),-- move order into this zone is issued
         name      ='topToCenter',
         teleporterSource = TeleportUtils.Pos(240,topBridge-bridgeHeight/2),
         teleporterDest = TeleportUtils.Pos(235,topBridge+bridgeHeight/2),
         unitCategory = categories.NAVAL
       },
      {
         sourceZone = Rect(0,topBridge+bridgeHeight/2,512,botBridge-bridgeHeight/2), -- redirect if into zone and
         targetZone = Rect(0,botBridge+bridgeHeight/2,512,512), -- move order into this zone is issued
         name      ='centerToBot',
         teleporterSource = TeleportUtils.Pos(260,botBridge-bridgeHeight/2),
         teleporterDest = TeleportUtils.Pos(260,botBridge+bridgeHeight/2),
         unitCategory = categories.NAVAL
       },
      {
         sourceZone = Rect(0,botBridge+bridgeHeight/2,512,512),  -- redirect if into zone and
         targetZone = Rect(0,topBridge+bridgeHeight/2,512,botBridge-bridgeHeight/2),-- move order into this zone is issued
         name      ='botToCenter',
         teleporterSource = TeleportUtils.Pos(260,botBridge+bridgeHeight/2),
         teleporterDest = TeleportUtils.Pos(260,botBridge-bridgeHeight/2),
         unitCategory = categories.NAVAL
       },
   }
   TeleportUtils.init(teleportationZones)
end

This zones are made to work with orcsdeath's awesome Tributaries map - get it from the vault.

Make sure you test your map with large naval units (atlantis, tempest) because these will get stuck if teleported too close to the bridge.


:arrow:

_________________
TA Veteran | SupCom Mapper
Box-o-Scripts™ Custom map scripts!
[Competition]Best User Made Map!
Death, Panic, Disaster, Your work here is done my boy.. Oh yess...


Last edited by Dark on 01 Oct, 2007, edited 13 times in total.

Top
 Profile  
 PostPosted: 12 Jul, 2007 
 
User avatar

Joined: 16 Feb, 2007
Posts: 555
Location: Holland
Offline
Part II

Tutorial: Weather Effects

painangel wrote:
As seen in:Scorpion Canyon

It's been noted by many of the mappers and modders that the code for weather effects can still be found in the lua files and emitter effects.
It seems that they were never removed from the code and are still completely functional. Good news!
I'm going to take you through the steps to activate weather effects in your maps and explain some of the variables your able to set.

!!DISCLAIMER!!
Adding weather effect has the potential to effect the performance of your map, especially on lower end machines. Care should be taken to not over do the effects.


Step 1
Placing Weather Generator and Definition markers:


If you've used the official editor you've probably seen them in the markers tool, Weather Generator and Weather Definition. Grab one of each and place it in the center of your map.
Alterntively you can add them in the save.lua file, place them under markers with the rest of the markers, like this:

Code:
                ['Weather Generator 00'] = {
                    ['cloudCountRange'] = FLOAT( 0.000000 ),
                    ['color'] = STRING( 'FF808000' ),
                    ['ForceType'] = STRING( 'None' ),
                    ['cloudHeightRange'] = FLOAT( 15.000000 ),
                    ['cloudSpread'] = FLOAT( 150.000000 ),
                    ['spawnChance'] = FLOAT( 1.000000 ),
                    ['cloudEmitterScaleRange'] = FLOAT( 0.000000 ),
                    ['cloudEmitterScale'] = FLOAT( 1.000000 ),
                    ['cloudCount'] = FLOAT( 10.000000 ),
                    ['cloudHeight'] = FLOAT( 180.000000 ),
                    ['hint'] = BOOLEAN( true ),
                    ['type'] = STRING( 'Weather Generator' ),
                    ['prop'] = STRING( '/env/common/props/markers/M_Defensive_prop.bp' ),
                    ['orientation'] = VECTOR3( 0, -0, 0 ),
                    ['position'] = VECTOR3( 125.485, 64, 129.847 ),
                },
                ['Weather Definition 00'] = {
                    ['WeatherType03Chance'] = FLOAT( 0.300000 ),
                    ['color'] = STRING( 'FF808000' ),
                    ['WeatherType01'] = STRING( 'SnowClouds' ),
                    ['WeatherType02'] = STRING( 'WhiteThickClouds' ),
                    ['WeatherType04'] = STRING( 'None' ),
                    ['WeatherDriftDirection'] = VECTOR3( 1, 0, 0 ),
                    ['WeatherType01Chance'] = FLOAT( 0.300000 ),
                    ['WeatherType03'] = STRING( 'WhitePatchyClouds' ),
                    ['WeatherType04Chance'] = FLOAT( 0.100000 ),
                    ['MapStyle'] = STRING( 'Tundra' ),
                    ['WeatherType02Chance'] = FLOAT( 0.300000 ),
                    ['hint'] = BOOLEAN( true ),
                    ['type'] = STRING( 'Weather Definition' ),
                    ['prop'] = STRING( '/env/common/props/markers/M_Defensive_prop.bp' ),
                    ['orientation'] = VECTOR3( 0, -0, 0 ),
                    ['position'] = VECTOR3( 125.029, 64, 131.001 ),
                },


Step 2
Setting the variables:


Now that we have the markers placed open your save.lua in a text editor of your choice and locate the code as posted above.
Here's what each variable does:

['Weather Generator 00'] - Unique name of the marker
['cloudCountRange'] - The number of clouds +/- from cloudCount that can be created at random
['color'] - Nothing/Unsure
['ForceType'] - Some types note the need to set this to the desired weather type, I believe it forces it to display that type 100% of the time
['cloudHeightRange'] - Ammount of variation allowed by random in the cloud height, eg. 1 is 100%; .5 is 50%
['cloudSpread'] - Radius of the area in which clouds are created
['spawnChance'] - Chance to spawn weather effects at all, 1 is 100% .5 is 50%, etc
['cloudEmitterScaleRange'] - Sets the ammount of allowable size difference in the cloud scale
['cloudEmitterScale'] - Sets the scale of the cloud relative to the emitter properties
['cloudCount'] - Sets the number of clouds to be created by default
['cloudHeight'] - Sets the default height of the clouds
['hint'] - Nothing/Unsure
['type'] - The type of marker, leave this as is
['prop'] - Sets the prop type to place at marker, leave as is
['orientation'] - Sets the direction of clouds (not movement), affects little/nothing
['position'] - Sets possition of the marker, exact middle of the map is best, ei. a 512x512 map would set 256, 64, 256 (64 should be set to the height of the ground)

['Weather Definition 00'] - Unique name of the marker
['WeatherType03Chance'] - Type of weather to generate at random
['color'] - Nothing/Unsure
['WeatherType01'] - Type of weather to generate if 01 is choosen
['WeatherType02'] - Type of weather to generate if 02 is choosen
['WeatherType04'] - Type of weather to generate if 04 is choosen
['WeatherDriftDirection'] - Direction that the clouds will move
['WeatherType01Chance'] - Chance that WeatherType01 is chosen at map start, ex. .5 is 50%; .25 is 25%
['WeatherType03'] - Type of weather to generate by default I believe as no random cahnce is given
['WeatherType04Chance'] - Chance that WeatherType04 is chosen at map start, ex. .5 is 50%; .25 is 25%
['MapStyle'] - Map type, used to determine tileset specific weather, not used for deafult cloud types
['WeatherType02Chance'] - Chance that WeatherType02 is chosen at map start, ex. .5 is 50%; .25 is 25%
['hint'] - Nothing/Unsure
['type'] - Marker type, leave this as is
['prop'] - Sets the prop type to place at marker, leave as is
['orientation'] - Sets the direction of clouds (not movement), affects little/nothing
['position'] - Sets possition of the marker, exact middle of the map is best, eg. a 512x512 map would set 256, 64, 256 (64 should be set to the height of the ground)


GUIDE

Here are the available weather types:


To use tileset specific weather you must set MapStyle to the type listed. Weather listed under All Style can be used no matter which MapStyle is set.
(This list is directly from the weatherdefinitions.lua)

Style Weather Types:
Desert
LightStratus -
Evergreen
CumulusClouds -
StormClouds -
RainClouds - WARNING, only use these a ForceType on a weather generator, max 2 per map
Geothermal
Lava
RedRock
LightStratus -
Tropical
LightStratus -
Tundra
WhitePatchyClouds -
SnowClouds - WARNING, only use these a ForceType on a weather generator, max 2 per map

All Styles:
Notes: ( Cirrus style cloud emitters, should be used on a ForceType Weather Generator, placed )
( in the center of a map. Take note that the these are sized specific for map scale )
CirrusSparse256 -
CirrusMedium256 -
CirrusHeavy256 -
CirrusSparse512 -
CirrusMedium512 -
CirrusHeavy512 -
CirrusSparse1024 -
CirrusMedium1024 -
CirrusHeavy1024 -
CirrusSparse4096 -
CirrusMedium4096 -
CirrusHeavy4096 -

Step 3
Initiating the weather effects in your script.lua:


To enable the weather effects you have to add this code to your script.lua file from a text editor.
At the top where the imports are called add this line:
Code:
local Weather = import('/lua/weather.lua')


Then change your onPopulate to this:
Code:
function OnPopulate()
  Weather.CreateWeather()
  ScenarioUtils.InitializeArmies()
end



Step 4

Enjoy! Play around with the variables, check them in game, until you get the effect your looking for.
WARNING!
squidbot wrote:
I just want to post a warning. Don't go crazy with the weather emitters. They can easily blow out the particle caps for most video cards (remember the sandstorm maps before I fixed them? :) ) I'd say for most effects, 8-16 emitters per map would be the max you'd want to do.


_________________
TA Veteran | SupCom Mapper
Box-o-Scripts™ Custom map scripts!
[Competition]Best User Made Map!
Death, Panic, Disaster, Your work here is done my boy.. Oh yess...


Last edited by Dark on 12 Jul, 2007, edited 3 times in total.

Top
 Profile  
 PostPosted: 12 Jul, 2007 
 
User avatar

Joined: 16 Feb, 2007
Posts: 555
Location: Holland
Offline
Map Script Driven Dialog's
angrycola wrote:
So I added this, but it got occluded from the patch notes. You can now have a customized window controlled purely by map script. Here's how it works:

Create a dialogue:
Code:
local myDialogue = CreateDialogue(text, buttons, position)

text: Text of the window. You can use '\n' to make line breaks.
buttons: Table of button labels. Indexed by numbers (these numbers are used to identify buttons to change text, enable / disable, or which button is clicked on)
position: Defaults to center, but can be "left" for top left or "right" for bottom right.


Changing the text:
Code:
myDialogue:SetText(newText)

Changes the text in the window


Updating button text:
Code:
myDialogue:UpdateButtonText(button, newText)

Changes the text on the specified button


Updating window Position:
Code:
myDialogue:UpdatePosition(newPosition)

Can be 'left', 'right', or 'center'


To handle button presses:
Overload myDialogue.OnButtonPressed with your own handler.
Code:
myDialogue.OnButtonPressed = myButtonHandler



Enabling / Disabling Buttons:
Code:
myDialogue:SetButtonDisabled(buttonID, disabled)



Destroying the window:
Code:
myDialogue:Destroy()



Example:
The following code would make a dialogue in the upper left corner. The text would say "You have clicked button1 # times.", the first button would update the text, the second button would cycle window positions, the third button would disable / enable the other buttons, and the fourth button would destroy the window.

Code:
local myDlg = CreateDialogue('This is a brand spankin new window!', {'Incriment','Position','Disable','Close'}, 'left')
myDlg.count = 1
myDlg.position = 'left'
myDlg.buttonState = true
myDlg.OnButtonPressed = function(self, button)
    if button == 1 then
        self:SetText(string.format('You have clicked on button1 %d times.', self.count))
        self.count = self.count + 1
    elseif button == 2 then
        if self.position == 'left' then
            self.position = 'right'
        elseif self.position == 'right' then
            self.position = 'center'
        else
            self.position = 'left'
        end
        self:SetPosition(self.position)
    elseif button == 3 then
        if self.buttonState then
            self:UpdateButtonText(3, 'Enable')
        else
            self:UpdateButtonText(3, 'Disable')
        end
        self.buttonState = not self.buttonState
        self:SetButtonDisabled(1,self.buttonState)
        self:SetButtonDisabled(2,self.buttonState)
        self:SetButtonDisabled(4,self.buttonState)
    elseif button == 4 then
        self:Destroy()
    end
end


Manimal wrote:
How to Spawn Upgraded ACUs ?



The script below should work "as is" because it's a sample of my actual working version 3 of my map script Solo ACU.
My map is available in the Vault and I'm currently working on version 4.

Thanks again Saya for your enlightments ! :wink: 8)


Commented Script


The needed units's data must be defined first :
Code:
--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[   Local Definitions                                                         ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--


local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua')
local ScenarioFramework = import('/lua/ScenarioFramework.lua')
local Utilities = import('/lua/Utilities.lua')




--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[   Misc Global Definitions                                                   ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--


ScenarioInfo.Attacker = 1
ScenarioInfo.Defender = 2

theAttacker = ScenarioInfo.Attacker
theDefender = ScenarioInfo.Defender



--[[                                                                             ]]--
--[[   ubcsTable                                                                 ]]--
--[[   { name, enemi, unitID,                                                    ]]--
--[[          EnhancementsList, EnhRestrictionsList, BuildRestrictionsList }     ]]--
--[[                                                                             ]]--
--[[   Do NOT erase any line in this ubcsTable !                                 ]]--
--[[   Add a comment sign instead for an evenutal future use                     ]]--
--[[                                                                             ]]--

ubcsTable = {

    { name                  = 'ATTACKER',
      army                  = 'ATTACKER',
      enemi                 = 'DEFENDER',
      unitId                = 'url0001',
      isReady               = false,
      EnhancementsList      = { 'AdvancedEngineering',
                                'CoolingUpgrade',
                                'MicrowaveLaserGenerator',
                                'ResourceAllocation',
                                'T3Engineering'
                              },
      EnhRestrictionsList   = { 'NaniteTorpedoTube',
                                'StealthGenerator'
                              },
      BuildRestrictionsList = { categories.AEON,
                                categories.UEF,
                                categories.NAVAL,
                                categories.EXPERIMENTAL,
                                categories.ura0102,  # Interceptor
                                categories.ura0103,  # Attack Bomber
                                categories.ura0203,  # Gunship
                                categories.ura0204,  # Torpedo Bomber
                                categories.dra0202,  # Bomber Corsair
                                categories.ura0303,  # Air Superiority Fighter
                                categories.ura0304,  # Strategic Bomber
                                categories.urb0304,  # Quantum Gateway
                                categories.urb1102,  # Hydrocarbon Power Plant
                                categories.urb2108,  # Tactical Missile Launcher
                                categories.urb2109,  # Tech 1 Torpedo Launcher
                                categories.urb2205,  # Tech 2 Torpedo Launcher
                                categories.urb2301,  # Tech 2 Point Defense (Heavy Gun Tower)
                                categories.urb2302,  # Long Range Artillery
                                categories.urb2303,  # Light Artillery
                                categories.urb2305,  # Strategic Missile Launcher
                                categories.urb3102,  # Tech 1 Sonar System
                                categories.urb3104,  # Omni Sensor Array
                                categories.urb3202,  # Tech 2 Sonar System
                                categories.urb4203,  # Stealth Field Generator
                                categories.urb4302,  # Strategic Missile Defense
                                categories.urb5101,  # Wall Section
                                categories.urb5103,  # Quantum Gate Beacon
                                categories.url0103,  # Mobile Light Artillery
                                categories.url0106,  # Light Assault Bot
                                categories.url0107,  # Heavy Assault Bot
                                categories.url0111,  # Mobile Missile Launcher
                                categories.url0202,  # Heavy Tank
                                categories.url0203,  # Amphibious Tank
                                categories.url0301,  # Support Command Unit
                                categories.url0303,  # Siege Assault Bot
                                categories.url0304,  # Mobile Heavy Artillery
                                categories.url0306,  # Mobile Stealth Field System
                                categories.url5103,  # Quantum Gate Beacon
                                categories.urs0305   # Sonar Platform
                              }
    },

    { name                  = 'DEFENDER',
      army                  = 'DEFENDER',
      enemi                 = 'ATTACKER',
      unitId                = 'uel0001',
      isReady               = false,
      EnhancementsList      = { 'AdvancedEngineering'},
      EnhRestrictionsList   = { 'DamageStablization',
                                'HeavyAntiMatterCannon',
                                'T3Engineering',
                                'TacticalNukeMissile'
                              },
      BuildRestrictionsList = { categories.AEON,
                                categories.CYBRAN,
                                categories.NAVAL,
                                categories.TECH3,
                                categories.EXPERIMENTAL,
                                categories.ueb1102,  # Hydrocarbon Power Plant
                                categories.ueb1201,  # Tech 2 Power Plant
                                categories.ueb2109,  # Tech 1 Torpedo Launcher
                                categories.ueb2205,  # Tech 2 Torpedo Launcher
                                categories.ueb2301,  # Tech 2 Point Defense (Heavy Gun Tower)
                                categories.ueb2302,  # Long Range Artillery
                                categories.ueb2303,  # Light Artillery
                                categories.ueb3102,  # Tech 1 Sonar System
                                categories.ueb3202,  # Tech 2 Sonar System
                                categories.ueb5101,  # Wall Section
                                categories.uel0307   # Mobile Shield Generator
                              }
    }

}
# end of ubcsTable




--[[  Miscellaneous Variables and Flags  ]]--

attackUBC             = false

defensUBC             = false



Once units are defined, create a customized InitializeArmies() function that will be called within OnPopulate().
For a quick test, I've added the OnStart() part that's empty.
Code:
--[[ *************************************************************************** ]]--
--[[ *************************************************************************** ]]--
--[[                                                                             ]]--
--[[   STARTER FUNCTIONS                                                         ]]--
--[[                                                                             ]]--
--[[ *************************************************************************** ]]--
--[[ *************************************************************************** ]]--





--[[                                                                             ]]--
--[[   OnPopulate()                                                              ]]--
--[[                                                                             ]]--
--[[   alliances and unit spawning go in there so you dont get conflicts and     ]]--
--[[   weird behaviours with initializearmies                                    ]]--
--[[                                                                             ]]--

function OnPopulate()


    --[[  Custom Initialization of Armies  ]]--

    InitializeArmies()


    --[[  Set ALL Players's ALLIANCES  ]]--

    SetAlliance( ubcsTable[theAttacker].name, ubcsTable[theDefender].name, 'Enemy' )


end  # END of onPopulate




--[[                                                                             ]]--
--[[   OnStart(self)                                                             ]]--
--[[                                                                             ]]--
--[[   Game mechanisms are there                                                 ]]--
--[[                                                                             ]]--

function OnStart(self)

    --[[  LET's ROCK !  ]]--

end



Now let's developpe the InitializeArmies() function :
Notice that the SpawnUpgradedUBC ( strArmy, iArmy ) is in a FOR loop so that it's possible to spawn as many ACUs as required in a custom scenario.
  • strArmy is a STRING that reflects the name of the indexed Army.
  • iArmy is the INDEX that's pointing the Army which is currently
processed.
Code:
--[[                                                                             ]]--
--[[   InitializeArmies()                                                        ]]--
--[[                                                                             ]]--
--[[   Spawn CUSTOM COMMANDERS and their ARMIES                                  ]]--
--[[                                                                             ]]--

function InitializeArmies()

    local tblGroups = {}
    local tblArmy = ListArmies()

    for iArmy, strArmy in pairs(tblArmy) do

        local tblData = Scenario.Armies[strArmy]

        if tblData then
      
            SetArmyEconomy( strArmy, tblData.Economy.mass, tblData.Economy.energy)

            --[[  Spawn Upgraded ACUs  ]]--

            local cdrUnit = false
         
            cdrUnit = SpawnUpgradedUBC ( strArmy, iArmy )

            if cdrUnit != nil then
                LOG("MANIMAL:  Succesful SPAWN of ACU for Player ".. iArmy .. " " .. strArmy .. " .")
                if strArmy == ubcsTable[theAttacker].name then
                    attackUBC = cdrUnit
                elseif strArmy == ubcsTable[theDefender].name then
                    defensUBC = cdrUnit
                end
            end

            --[[  PLAYERS'S RESTRICTIONS                                      ]]--
            --[[  Take away units that the players shouldn't have access to   ]]--

            if ubcsTable[iArmy].BuildRestrictionsList then
                for i,catRestrict in ubcsTable[iArmy].BuildRestrictionsList do
                    LOG("MANIMAL:  Add Build Restriction at index=" .. i .. " for player ".. iArmy .. " " .. strArmy .. " .")
                    ScenarioFramework.AddRestriction( strArmy, catRestrict )
                end
            end

            --[[  Spawn Pre-Built UNITS/BUILDINGS there ]]--


            --[[  Spawn Wreckage etc... there ]]--

        end   #end IF tblData

    end   #end FOR


    return tblGroups

end


Now here's the "heart" of the SpawnUpgradedUBC ( strArmy, iArmy ) function.
Notice that the strArmy and iArmy are passed as parameters by using the same names.
  • CreateUnitHPR() creates ANY unit, but in my case it's creating the unit that's indexed by the variable ubcId (in english acuId)
  • strArmy is the Army's name for which this unit is to be created
  • mPos(strArmy)[1], mPos(strArmy)[2],mPos(strArmy)[3], 0,0,0) is a utility function -detailed at the end of this post- that returns respectively the X, Y and Z coordinates, according a coordinate index.
  • if cdrUnit != nil is the necessary test either to resume the script in case of success or to abort it if not.
  • strEnemi(iArmy)is a utility function -detailed at the end of this post- that returns the enemy of the indexed army.
Code:
--[[                                                                             ]]--
--[[   SpawnUpgradedUBC ( strArmy, iArmy )                                       ]]--
--[[                                                                             ]]--
--[[   Spawn an Upgraded ACU                                                     ]]--
--[[                                                                             ]]--

function SpawnUpgradedUBC ( strArmy, iArmy )

    local ubcId = ''       # ACU Identifier
    local cdrUnit = false

    ubcId = ubcsTable[iArmy].unitId

    if (ubcId == 'ual0001') or (ubcId == 'uel0001') or (ubcId == 'url0001') then  # ACU Identifier is valid

        # spawn uef commander
        cdrUnit = CreateUnitHPR( ubcId, strArmy, mPos(strArmy)[1], mPos(strArmy)[2],mPos(strArmy)[3], 0,0,0)

        # successful spawn
        if cdrUnit != nil then

            --[[  DO ENHANCEMENTS  ]]--

            if ubcsTable[iArmy].EnhancementsList then
                for i,enhancement in ubcsTable[iArmy].EnhancementsList do
                    LOG("MANIMAL:  ACU Enhancement at index=" .. i .. ", enhancement=" .. enhancement .. " for player ".. iArmy .. " " .. strArmy .. " .")
                    cdrUnit:CreateEnhancement(enhancement)
                end
            end

            # saves the original method.
            # annihilation type victory condition
            cdrUnit.OldOnKilled = cdrUnit.OnKilled

            # action when killed
            cdrUnit.OnKilled = function(self, instigator, type, overkillRatio)
                GetArmyBrain(strArmy):OnDefeat()
                GetArmyBrain(strEnemi(iArmy)):OnVictory()
                cdrUnit.OldOnKilled(self, instigator, type, overkillRatio)   
            end
            
            --[[  DO RESTRICTIONS  ]]--

            if ubcsTable[iArmy].EnhRestrictionsList then
                for i,restriction in ubcsTable[iArmy].EnhRestrictionsList do
                    LOG("MANIMAL:  ACU RestrictEnhancement at index=" .. i .. ", restriction=" .. restriction .. " for player ".. iArmy .. " " .. strArmy .. " .")
                    ScenarioFramework.RestrictEnhancements(restriction)
                end
            end

        else
            LOG("FAILED: Unit Creation (ACU) for player ".. iArmy .. " " .. strArmy .. " .")
        end   #end IF cdrUnit

        # play warp in effect is DISABLED in order to make a faster TransportLoad
        #cdrUnit:PlayCommanderWarpInEffect()

   end   #end IF ubcId

   return cdrUnit

end


Below are the various utility functions that are in use in the above script :
Code:
--[[                                                                             ]]--
--[[   GetMarker(name)                                                           ]]--
--[[                                                                             ]]--
--[[   get marker given a name from map_save done in map editor                  ]]--
--[[   you can the use marker.position to get a location in the {x,y,z} format   ]]--
--[[                                                                             ]]--

function GetMarker(name)
    return Scenario.MasterChain._MASTERCHAIN_.Markers[name]
end



--[[                                                                             ]]--
--[[   mPos(name)                                                                ]]--
--[[                                                                             ]]--
--[[   Get Marker position                                                       ]]--
--[[                                                                             ]]--

function mPos(name)
    return GetMarker(name).position
end



--[[                                                                             ]]--
--[[   strEnemi(iArmy)                                                           ]]--
--[[                                                                             ]]--
--[[   Returns the enemi of the current Army                                     ]]--
--[[                                                                             ]]--

function strEnemi(iArmy)
    return ubcsTable[iArmy].enemi
end

_________________
TA Veteran | SupCom Mapper
Box-o-Scripts™ Custom map scripts!
[Competition]Best User Made Map!
Death, Panic, Disaster, Your work here is done my boy.. Oh yess...


Last edited by Dark on 28 Aug, 2007, edited 2 times in total.

Top
 Profile  
 PostPosted: 12 Jul, 2007 
 
User avatar

Joined: 08 Apr, 2007
Posts: 526
Location: Colorado, US
Offline
This script will change the map size based on which players are on the map. The one shown is made for an eight player map with players starting at each of the eight sides/corners of the map, starting in the top left and going clockwise.

The script includes comments to explain how it needs to be changed for different map sizes (as in 5km, 10km, 20km, ect.), and changed player positions. The numbers are based on a percent scale, with the left and top being zero, and the other sides being one hundred (same direction as x and z travel).

It doesn't consider rectangle maps, as they didn't exist at the time it was built, but could be easily edited to include them.

Enjoy:
Code:
#This goes in the _script.lua file

function OnPopulate()
  #Map Maker: Set this to the map size
  local MapMaxSize = 1024,

  #Map Maker, note the comments in this section to know the names of each marker
  #The points start backwards. Note, this is a percentage of the size of the map
  local MapTU = 100.0,#Top left corner, Upwards direction
  local MapTL = 100.0,#Top left corner, Leftwards direction
  local MapBD = 0.0,#Bottom right corner, Downwards direction
  local MapBR = 0.0,#Bottom right corner, Rightwards direction

  #Map Maker: For each of the right numbers inside the "math.min/max", set that number to the
  #percentage of the map that the marker should be moved if that player is there.
  #These need changed only if you are moving the player's start positions
  #The top left corner is 0, the bottom right corner is 100
  for a, v in ListArmies() do
   
    if 'ARMY_1' == v then
      LOG('Debug LVW: OnPopulate: I see ARMY_1 ')
      MapTU = math.min(MapTU, 2.5),
      MapTL = math.min(MapTL, 2.5),
      MapBD = math.max(MapBD, 33.4),
      MapBR = math.max(MapBR, 33.4),
    end #ARMY_1
   
    if 'ARMY_2' == v then
      LOG('Debug LVW: OnPopulate: I see ARMY_2 ')
      MapTU = math.min(MapTU, 2.5),
      MapTL = math.min(MapTL, 33.3),
      MapBD = math.max(MapBD, 33.4),
      MapBR = math.max(MapBR, 66.4),
    end #ARMY_2
   
    if 'ARMY_3' == v then
    LOG('Debug LVW: OnPopulate: I see ARMY_3 ')
      MapTU = math.min(MapTU, 2.5),
      MapTL = math.min(MapTL, 66.3),
      MapBD = math.max(MapBD, 33.4),
      MapBR = math.max(MapBR, 98.5),
    end #ARMY_3
   
    if 'ARMY_4' == v then
      LOG('Debug LVW: OnPopulate: I see ARMY_4 ')
      MapTU = math.min(MapTU, 33.3),
      MapTL = math.min(MapTL, 66.6),
      MapBD = math.max(MapBD, 66.6),
      MapBR = math.max(MapBR, 98.5),
    end #ARMY_4
   
    if 'ARMY_5' == v then
      LOG('Debug LVW: OnPopulate: I see ARMY_5 ')
      MapTU = math.min(MapTU, 66.6),
      MapTL = math.min(MapTL, 66.6),
      MapBD = math.max(MapBD, 98.5),
      MapBR = math.max(MapBR, 98.5),
    end #ARMY_5
   
    if 'ARMY_6' == v then
      LOG('Debug LVW: OnPopulate: I see ARMY_6 ')
      MapTU = math.min(MapTU, 66.6),
      MapTL = math.min(MapTL, 33.3),
      MapBD = math.max(MapBD, 98.5),
      MapBR = math.max(MapBR, 66.6),
    end #ARMY_6
   
    if 'ARMY_7' == v then
      LOG('Debug LVW: OnPopulate: I see ARMY_7 ')
      MapTU = math.min(MapTU, 66.6),
      MapTL = math.min(MapTL, 2.5),
      MapBD = math.max(MapBD, 98.5),
      MapBR = math.max(MapBR, 33.4),
    end #ARMY_7

    if 'ARMY_8' == v then
      LOG('Debug LVW: OnPopulate: I see ARMY_8 ')
      MapTU = math.min(MapTU, 33.3),
      MapTL = math.min(MapTL, 2.5),
      MapBD = math.max(MapBD, 66.6),
      MapBR = math.max(MapBR, 33.4),
    end #ARMY_8
   
  end #for each ARMY
 
  MapTL = (MapTL * MapMaxSize) / 100,
  MapTU = (MapTU * MapMaxSize) / 100,
  MapBR = (MapBR * MapMaxSize) / 100,
  MapBD = (MapBD * MapMaxSize) / 100,
   
  #Make it so.
  local RectMap = Rect(MapTL, MapTU, MapBR, MapBD)
  ScenarioFramework.SetPlayableArea(RectMap , false)
 
  ScenarioUtils.InitializeArmies()
end #OnPopulate


You can see this script in action via the Vault, map name: Map Size Script user: viruswatts
or you can download it here: MapSizeScript.v0001.zip

How to change it to your needs
To be able to change it, you first need to understand it. Let me simplify the "equation." Say we have a map made for 4 players, who all stand on the edge centers, like so:
Image

And we want the map to divide like this, based on players presence: (note: this is each of the two player sets per box)
Image Image Image

Lets further simplify this and only look at one player at a time. This is the border box for player 1, created by the code just below it:
Image
Code:
    if 'ARMY_1' == v then
      LOG('Debug LVW: OnPopulate: I see ARMY_1 ')
      MapTU = math.min(MapTU, 33.3); #pushing the top border up
      MapTL = math.min(MapTL, 2.5); #pushing the left border left
      MapBD = math.max(MapBD, 66.6); #pushing the bottom border down
      MapBR = math.max(MapBR, 33.4); #pushing the right border right
    end #ARMY_1

Here, each of the borders for player 1:
Image
In each person, we have four variables that we modify. TU, TL, BD, and BR; for Top, Up, Left, and Bottom respectively by letter.

Image
Each of these variables push the map border in their stated direction whenever that border hasn't been moved over far enough for that player yet.

Example: Since we want to give player's 1 and 2 the same top border, they would have the same number on their TU variable.

Example: If players 1, 2, and 3 are on the map, player 1 and 2's TU variable will be over ridden by player 3's TU variable, since she is higher on the map.

Questions? Comments? Please post in the original thread.

_________________
Image
Mapping: 1, 2


Last edited by LeVirus Watts on 25 Jul, 2007, edited 1 time in total.

Top
 Profile  
 PostPosted: 12 Jul, 2007 
 
Forum Engineer
Forum Engineer
User avatar

Joined: 15 Feb, 2007
Posts: 778
Offline
This script will disable all navy and kill any unit that land/go on water. Useful to make pseudo lava maps.

Code:
local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua')
local ScenarioFramework = import('/lua/ScenarioFramework.lua')

--units to be restricted
local NAVALbuildRestriction = categories.NAVAL + categories.ANTINAVY



function OnPopulate()
   ScenarioUtils.InitializeArmies()
   local tblArmy = ListArmies()
   for index,army in tblArmy do
      ScenarioFramework.AddRestriction(army, NAVALbuildRestriction)
   end
end



function OnStart(self)
   --delete all units on the water layers except air units every 2 seconds
   ForkThread(function()
      while true do
         WaitSeconds(2)
         killUnitsOnLayer({'Water','Seabed','Sub'},{'AIR'})
      end
   end)
end

--get all units on the map
allUnits = function()
     local xmapsize = ScenarioInfo.size[1]
     local ymapsize = ScenarioInfo.size[2]
     local mapRect = {x0 = 0, x1 = xmapsize, y0 = 0, y1 = ymapsize}
     units = GetUnitsInRect(mapRect)
    return units
end

--delete all units on a layer exept those containing the exception categories
killUnitsOnLayer = function(layers,exceptions)
   --get all units on the map
   local units = allUnits()
   --if there are units on the map
   if units and table.getn(units) > 0 then
      for index,unit in units do
         local delete = false
         
         --is the unit on one of the specified layers?
         for index,layer in layers do
            if unit:GetCurrentLayer() == layer then
               delete = true
            end
         end
         
         --is the unit in an exception category?
         for index,category in exceptions do
            if EntityCategoryContains(categories[category], unit) then
               delete = false
            end
         end
         
         --if the unit is in one of the layers and in no exception category then kill it
         if  delete == true then
            if unit and not unit:IsDead() then
               unit:Kill()
            end
         end
      end
   end
end

_________________
Supcom Modder
*SCA UI mod
*map scripting: zone control, supreme art of defence, turret defence, (action) tug of war.


Top
 Profile  
 PostPosted: 12 Jul, 2007 
 
User avatar

Joined: 03 Mar, 2007
Posts: 360
Offline
Making water look like lava

This should work well with Saya's damage on water script above.
The following can be placed into an lua and imported into the official editor using File -> Import -> Water. Be sure to change the surface elevation to reflect your needs.

Downloadable version here: http://www.gamereplays.org/community/in ... pic=257483

Code:
Water = {
surface_elev = 25, --Change this value to your water height
deep_elev = 0,
abyss_elev = 0,
surface_color = { 1, 0.25, 0 },
color_lerp = { 0.064, 0.219 },
refraction_scale = 0.324,
fresnel_bias = 0.75,
fresnel_power = 0.48,
unit_reflection = 0,
sky_reflection = 1.2,
sun_shininess = 10,
sun_strength = 10,
sun_direction = { 0.0995482, -0.962631, 0.251857 },
sun_color = { 1, 0.25, 0 },
sun_reflection = 2.91,
sun_glow = 0.1,
local_cubemap = '/textures/environment/skycube_redrocks05.dds',
water_ramp = '/env/lava/layers/macrotexture000_albedo.dds',
normal_repeat = { 0.045, 0.005, 0.05, 0.005 },
normals = {
['0'] = {
normal_movement = { -0.00763243, 0.00476927 },
local_normals = '/env/lava/layers/lav_cracked02_normals.dds',
},
['1'] = {
normal_movement = { -0.0763243, 0.0476927 },
local_normals = '/textures/engine/waves.dds',
},
['2'] = {
normal_movement = { -0.00763243, 0.00476927 },
local_normals = '/textures/engine/waves000.dds',
},
['3'] = {
normal_movement = { 0.0422524, -0.0794653 },
local_normals = '/textures/engine/waves000.dds',
},
},
}


Top
 Profile  
 PostPosted: 25 Jul, 2007 
 
User avatar

Joined: 14 May, 2007
Posts: 169
Location: Australia
Offline
Here is a working map script that spawns AIs at an alternate set of spawn points.

If the AI plays badly on your map because there's not enough room at the spawn area, or you simply want to change the spawn layout for AI players, then read on.

To use this, after placing all of your spawn markers (e.g. ARMY_1, etc.), you must also place an AI spawn marker for each army. These markers must be the same name as the spawn markers, but with '_AI' appended (e.g. ARMY_1_AI, etc.).
Also, the names of all spawn markers must be listed at the "local spawn_points =" line.

This is a complete *_script.lua file for a 1v1 map:
Code:
local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua')
local Utilities = import('/lua/utilities.lua')

function OnPopulate()
   ScenarioUtils.InitializeArmies()
end
function OnStart(self)
   UndoSpawnHackForHumans()
end

------------------------------------------------------------------
--List all your army markers here
local spawn_points = {
   ['ARMY_1'] = {},
   ['ARMY_2'] = {},
}
------------------------------------------------------------------
for name,position in spawn_points do
   --make a backup of the spawn point
   local original = ScenarioUtils.MarkerToPosition( name )
   position[1] = original[1]
   position[2] = original[2]
   position[3] = original[3]
   
   --move the spawn point to the AI override position
   local override = ScenarioUtils.MarkerToPosition( name..'_AI' )
   original[1] = override[1]
   original[2] = override[2]
   original[3] = override[3]
end

function getArmyName(unit)
   local unitArmy = unit
   if unit.GetArmy then
      unitArmy = unit:GetArmy()
   end
   return ListArmies()[unitArmy]
end
function UndoSpawnHackForHumans()
   local sx,sz = GetMapSize()
   local playerACUs = GetUnitsInRect(Rect(0,0,sx,sz))
   if playerACUs == nil then
      LOG( 'NO ACUs FOUND!' )
   else
      for i,acu in playerACUs do
         local army = getArmyName(acu)
         local brain = GetArmyBrain(army)
         if brain.BrainType == 'Human' then
            Warp(acu, spawn_points[army], acu:GetOrientation())
         end
      end
   end
end


This contains some code fragments from supreme Risk, so thanks to CardiacReactor!

[edit]
I updated the above code with a suggestion from LeVirus Watts - it now works for any map size (before it was hard-coded for 10km*10km maps)
[edit2]
Created a separate thread for questions/comments.

_________________
ImageImage


Last edited by ActionMan on 25 Jul, 2007, edited 3 times in total.

Top
 Profile  
 PostPosted: 30 Aug, 2007 
 
User avatar

Joined: 11 Apr, 2007
Posts: 1916
Offline
Dark wrote:
Can you please put your scripts in the Box-o-Scripts from now on? This will make it more easy for people to find them since i made it to collect all custom scripts so you don't have to go trough all the pages.

Thank you in advance.


(For the rest ill add and Index list to the Box.)


No problem...
I just wanted to make a serie of them, then to index them in a single topic.
Yours or mine this makes no difference, except that if it's mine then you'll have to copy+paste in yours, as you've already done wih my previous submission (that hurts right below the Map Driven Dialog).

So I hope you won't mind if I post successively in there the "How to Spawn Upgraded ACU" followed by the "How to Transport a unit"


Top
 Profile  
 PostPosted: 30 Aug, 2007 
 
User avatar

Joined: 11 Apr, 2007
Posts: 1916
Offline
How to Spawn Upgraded ACUs for non-AI players ?


Preamble

A professional work requires a FULLY commented code where every single thing is explained in details, that is what's required before, what's passed in parameters, what's returned by the functions, the various changes of data's state, etc.

However I did not become a pro coder since I've prefered another professional cursus.
Moreover my knowledge is old (1994) and has been used rarely.
So pardon me for not applying strictly the above tips regarding the comments.

I've done my best to make the script as much readable as possible by using EXPLICIT names for functions, variables etc.
I've also made it as much generic as possible, stuffed with comments when I felt it necessary..

The script below should work "as is" because it's a sample of my actual working version 3 of my map script Solo ACU.
My map is available in the Vault and I'm currently working on version 4.

Thanks again Saya for your enlightments ! :wink: 8)


Commented Script


The needed units's data must be defined first :
Code:
--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[   Local Definitions                                                         ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--


local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua')
local ScenarioFramework = import('/lua/ScenarioFramework.lua')
local Utilities = import('/lua/Utilities.lua')




--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[   Misc Global Definitions                                                   ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--


ScenarioInfo.Attacker = 1
ScenarioInfo.Defender = 2

theAttacker = ScenarioInfo.Attacker
theDefender = ScenarioInfo.Defender



--[[                                                                             ]]--
--[[   ubcsTable                                                                 ]]--
--[[   { name, enemi, unitID,                                                    ]]--
--[[          EnhancementsList, EnhRestrictionsList, BuildRestrictionsList }     ]]--
--[[                                                                             ]]--
--[[   Do NOT erase any line in this ubcsTable !                                 ]]--
--[[   Add a comment sign instead for an evenutal future use                     ]]--
--[[                                                                             ]]--

ubcsTable = {

    { name                  = 'ATTACKER',
      army                  = 'ATTACKER',
      enemi                 = 'DEFENDER',
      unitId                = 'url0001',
      isReady               = false,
      EnhancementsList      = { 'AdvancedEngineering',
                                'CoolingUpgrade',
                                'MicrowaveLaserGenerator',
                                'ResourceAllocation',
                                'T3Engineering'
                              },
      EnhRestrictionsList   = { 'NaniteTorpedoTube',
                                'StealthGenerator'
                              },
      BuildRestrictionsList = { categories.AEON,
                                categories.UEF,
                                categories.NAVAL,
                                categories.EXPERIMENTAL,
                                categories.ura0102,  # Interceptor
                                categories.ura0103,  # Attack Bomber
                                categories.ura0203,  # Gunship
                                categories.ura0204,  # Torpedo Bomber
                                categories.dra0202,  # Bomber Corsair
                                categories.ura0303,  # Air Superiority Fighter
                                categories.ura0304,  # Strategic Bomber
                                categories.urb0304,  # Quantum Gateway
                                categories.urb1102,  # Hydrocarbon Power Plant
                                categories.urb2108,  # Tactical Missile Launcher
                                categories.urb2109,  # Tech 1 Torpedo Launcher
                                categories.urb2205,  # Tech 2 Torpedo Launcher
                                categories.urb2301,  # Tech 2 Point Defense (Heavy Gun Tower)
                                categories.urb2302,  # Long Range Artillery
                                categories.urb2303,  # Light Artillery
                                categories.urb2305,  # Strategic Missile Launcher
                                categories.urb3102,  # Tech 1 Sonar System
                                categories.urb3104,  # Omni Sensor Array
                                categories.urb3202,  # Tech 2 Sonar System
                                categories.urb4203,  # Stealth Field Generator
                                categories.urb4302,  # Strategic Missile Defense
                                categories.urb5101,  # Wall Section
                                categories.urb5103,  # Quantum Gate Beacon
                                categories.url0103,  # Mobile Light Artillery
                                categories.url0106,  # Light Assault Bot
                                categories.url0107,  # Heavy Assault Bot
                                categories.url0111,  # Mobile Missile Launcher
                                categories.url0202,  # Heavy Tank
                                categories.url0203,  # Amphibious Tank
                                categories.url0301,  # Support Command Unit
                                categories.url0303,  # Siege Assault Bot
                                categories.url0304,  # Mobile Heavy Artillery
                                categories.url0306,  # Mobile Stealth Field System
                                categories.url5103,  # Quantum Gate Beacon
                                categories.urs0305   # Sonar Platform
                              }
    },

    { name                  = 'DEFENDER',
      army                  = 'DEFENDER',
      enemi                 = 'ATTACKER',
      unitId                = 'uel0001',
      isReady               = false,
      EnhancementsList      = { 'AdvancedEngineering'},
      EnhRestrictionsList   = { 'DamageStablization',
                                'HeavyAntiMatterCannon',
                                'T3Engineering',
                                'TacticalNukeMissile'
                              },
      BuildRestrictionsList = { categories.AEON,
                                categories.CYBRAN,
                                categories.NAVAL,
                                categories.TECH3,
                                categories.EXPERIMENTAL,
                                categories.ueb1102,  # Hydrocarbon Power Plant
                                categories.ueb1201,  # Tech 2 Power Plant
                                categories.ueb2109,  # Tech 1 Torpedo Launcher
                                categories.ueb2205,  # Tech 2 Torpedo Launcher
                                categories.ueb2301,  # Tech 2 Point Defense (Heavy Gun Tower)
                                categories.ueb2302,  # Long Range Artillery
                                categories.ueb2303,  # Light Artillery
                                categories.ueb3102,  # Tech 1 Sonar System
                                categories.ueb3202,  # Tech 2 Sonar System
                                categories.ueb5101,  # Wall Section
                                categories.uel0307   # Mobile Shield Generator
                              }
    }

}
# end of ubcsTable




--[[  Miscellaneous Variables and Flags  ]]--

attackUBC             = false

defensUBC             = false



Once units are defined, create a customized InitializeArmies() function that will be called within OnPopulate().
For a quick test, I've added the OnStart() part that's empty.
Code:
--[[ *************************************************************************** ]]--
--[[ *************************************************************************** ]]--
--[[                                                                             ]]--
--[[   STARTER FUNCTIONS                                                         ]]--
--[[                                                                             ]]--
--[[ *************************************************************************** ]]--
--[[ *************************************************************************** ]]--





--[[                                                                             ]]--
--[[   OnPopulate()                                                              ]]--
--[[                                                                             ]]--
--[[   alliances and unit spawning go in there so you dont get conflicts and     ]]--
--[[   weird behaviours with initializearmies                                    ]]--
--[[                                                                             ]]--

function OnPopulate()


    --[[  Custom Initialization of Armies  ]]--

    InitializeArmies()


    --[[  Set ALL Players's ALLIANCES  ]]--

    SetAlliance( ubcsTable[theAttacker].name, ubcsTable[theDefender].name, 'Enemy' )


end  # END of onPopulate




--[[                                                                             ]]--
--[[   OnStart(self)                                                             ]]--
--[[                                                                             ]]--
--[[   Game mechanisms are there                                                 ]]--
--[[                                                                             ]]--

function OnStart(self)

    --[[  LET's ROCK !  ]]--

end



Now let's developpe the InitializeArmies() function :
Notice that the SpawnUpgradedUBC ( strArmy, iArmy ) is in a FOR loop so that it's possible to spawn as many ACUs as required in a custom scenario.
  • strArmy is a STRING that reflects the name of the indexed Army.
  • iArmy is the INDEX that's pointing the Army which is currently
processed.
Code:
--[[                                                                             ]]--
--[[   InitializeArmies()                                                        ]]--
--[[                                                                             ]]--
--[[   Spawn CUSTOM COMMANDERS and their ARMIES                                  ]]--
--[[                                                                             ]]--

function InitializeArmies()

    local tblGroups = {}
    local tblArmy = ListArmies()

    for iArmy, strArmy in pairs(tblArmy) do

        local tblData = Scenario.Armies[strArmy]

        if tblData then
      
            SetArmyEconomy( strArmy, tblData.Economy.mass, tblData.Economy.energy)

            --[[  Spawn Upgraded ACUs  ]]--

            local cdrUnit = false
         
            cdrUnit = SpawnUpgradedUBC ( strArmy, iArmy )

            if cdrUnit != nil then
                LOG("MANIMAL:  Succesful SPAWN of ACU for Player ".. iArmy .. " " .. strArmy .. " .")
                if strArmy == ubcsTable[theAttacker].name then
                    attackUBC = cdrUnit
                elseif strArmy == ubcsTable[theDefender].name then
                    defensUBC = cdrUnit
                end
            end

            --[[  PLAYERS'S RESTRICTIONS                                      ]]--
            --[[  Take away units that the players shouldn't have access to   ]]--

            if ubcsTable[iArmy].BuildRestrictionsList then
                for i,catRestrict in ubcsTable[iArmy].BuildRestrictionsList do
                    LOG("MANIMAL:  Add Build Restriction at index=" .. i .. " for player ".. iArmy .. " " .. strArmy .. " .")
                    ScenarioFramework.AddRestriction( strArmy, catRestrict )
                end
            end

            --[[  Spawn Pre-Built UNITS/BUILDINGS there ]]--


            --[[  Spawn Wreckage etc... there ]]--

        end   #end IF tblData

    end   #end FOR


    return tblGroups

end


Now here's the "heart" of the SpawnUpgradedUBC ( strArmy, iArmy ) function.
Notice that the strArmy and iArmy are passed as parameters by using the same names.
  • CreateUnitHPR() creates ANY unit, but in my case it's creating the unit that's indexed by the variable ubcId (in english acuId)
  • strArmy is the Army's name for which this unit is to be created
  • mPos(strArmy)[1], mPos(strArmy)[2],mPos(strArmy)[3], 0,0,0) is a utility function -detailed at the end of this post- that returns respectively the X, Y and Z coordinates, according a coordinate index.
  • if cdrUnit != nil is the necessary test either to resume the script in case of success or to abort it if not.
  • strEnemi(iArmy)is a utility function -detailed at the end of this post- that returns the enemy of the indexed army.
Code:
--[[                                                                             ]]--
--[[   SpawnUpgradedUBC ( strArmy, iArmy )                                       ]]--
--[[                                                                             ]]--
--[[   Spawn an Upgraded ACU                                                     ]]--
--[[                                                                             ]]--

function SpawnUpgradedUBC ( strArmy, iArmy )

    local ubcId = ''       # ACU Identifier
    local cdrUnit = false

    ubcId = ubcsTable[iArmy].unitId

    if (ubcId == 'ual0001') or (ubcId == 'uel0001') or (ubcId == 'url0001') then  # ACU Identifier is valid

        # spawn uef commander
        cdrUnit = CreateUnitHPR( ubcId, strArmy, mPos(strArmy)[1], mPos(strArmy)[2],mPos(strArmy)[3], 0,0,0)

        # successful spawn
        if cdrUnit != nil then

            --[[  DO ENHANCEMENTS  ]]--

            if ubcsTable[iArmy].EnhancementsList then
                for i,enhancement in ubcsTable[iArmy].EnhancementsList do
                    LOG("MANIMAL:  ACU Enhancement at index=" .. i .. ", enhancement=" .. enhancement .. " for player ".. iArmy .. " " .. strArmy .. " .")
                    cdrUnit:CreateEnhancement(enhancement)
                end
            end

            # saves the original method.
            # annihilation type victory condition
            cdrUnit.OldOnKilled = cdrUnit.OnKilled

            # action when killed
            cdrUnit.OnKilled = function(self, instigator, type, overkillRatio)
                GetArmyBrain(strArmy):OnDefeat()
                GetArmyBrain(strEnemi(iArmy)):OnVictory()
                cdrUnit.OldOnKilled(self, instigator, type, overkillRatio)   
            end
            
            --[[  DO RESTRICTIONS  ]]--

            if ubcsTable[iArmy].EnhRestrictionsList then
                for i,restriction in ubcsTable[iArmy].EnhRestrictionsList do
                    LOG("MANIMAL:  ACU RestrictEnhancement at index=" .. i .. ", restriction=" .. restriction .. " for player ".. iArmy .. " " .. strArmy .. " .")
                    ScenarioFramework.RestrictEnhancements(restriction)
                end
            end

        else
            LOG("FAILED: Unit Creation (ACU) for player ".. iArmy .. " " .. strArmy .. " .")
        end   #end IF cdrUnit

        # play warp in effect is DISABLED in order to make a faster TransportLoad
        #cdrUnit:PlayCommanderWarpInEffect()

   end   #end IF ubcId

   return cdrUnit

end


Below are the various utility functions that are in use in the above script :
Code:
--[[                                                                             ]]--
--[[   GetMarker(name)                                                           ]]--
--[[                                                                             ]]--
--[[   get marker given a name from map_save done in map editor                  ]]--
--[[   you can the use marker.position to get a location in the {x,y,z} format   ]]--
--[[                                                                             ]]--

function GetMarker(name)
    return Scenario.MasterChain._MASTERCHAIN_.Markers[name]
end



--[[                                                                             ]]--
--[[   mPos(name)                                                                ]]--
--[[                                                                             ]]--
--[[   Get Marker position                                                       ]]--
--[[                                                                             ]]--

function mPos(name)
    return GetMarker(name).position
end



--[[                                                                             ]]--
--[[   strEnemi(iArmy)                                                           ]]--
--[[                                                                             ]]--
--[[   Returns the enemi of the current Army                                     ]]--
--[[                                                                             ]]--

function strEnemi(iArmy)
    return ubcsTable[iArmy].enemi
end


More script samples to come :wink:


Top
 Profile  
 PostPosted: 30 Aug, 2007 
 
User avatar

Joined: 11 Apr, 2007
Posts: 1916
Offline
How to Transport a unit ? (by air in this tuto)


Preamble

I've done my best to make the script as much readable as possible by using EXPLICIT names for functions, variables etc.
I've also made it as much generic as possible, stuffed with comments when I felt it necessary..
Of course my work isn't the most perfect and I'll be glad you explain me alternate solutions.

The script below should work "as is" because it's a sample of the actual working version 4 of my map script Solo ACU.
My map is available in the Vault and I'm currently working on version 5.
REMARK: I've shortened the restrictions+enhancements list so that it won't enlong too much this post.


Commented Script

The needed units's data must be defined first :
Code:
--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[   Local Definitions                                                         ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--


local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua')
local ScenarioFramework = import('/lua/ScenarioFramework.lua')
local Utilities = import('/lua/Utilities.lua')
--interface utilities
local UIUtil = import('/lua/ui/uiutil.lua')




--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[   Misc Global Definitions                                                   ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--


ScenarioInfo.Attacker = 1
ScenarioInfo.Defender = 2
theAttacker           = ScenarioInfo.Attacker
theDefender           = ScenarioInfo.Defender



--[[                                                                             ]]--
--[[   ubcsTable                                                                 ]]--
--[[   { name, enemi, unitID,                                                    ]]--
--[[          EnhancementsList, EnhRestrictionsList, BuildRestrictionsList }     ]]--
--[[                                                                             ]]--
--[[   Do NOT erase any line in this ubcsTable !                                 ]]--
--[[   Add a comment sign instead for an evenutal future use                     ]]--
--[[                                                                             ]]--

ubcsTable = {

    { name                  = 'ATTACKER',
      army                  = 'ATTACKER',
      enemi                 = 'DEFENDER',
      unitId                = 'url0001',
      isReady               = false,
      EnhancementsList      = { },
      EnhRestrictionsList   = { },
      BuildRestrictionsList = { }
    },

    { name                  = 'DEFENDER',
      army                  = 'DEFENDER',
      enemi                 = 'ATTACKER',
      unitId                = 'uel0001',
      isReady               = false,
      EnhancementsList      = { },
      EnhRestrictionsList   = { },
      BuildRestrictionsList = { }
    }

}

# end of ubcsTable


--[[  Table of Units to be spawned  ]]--
--[[  same format as ubcsTable      ]]--
--[[  so these are concatenable     ]]--

unitsTable = {

    { name                  = 'Air_Transport_1',
      army                  = ubcsTable[theAttacker].army,
      enemi                 = ubcsTable[theDefender].army,
      unitId                = 'ura0104',
      isReady               = false,
      EnhancementsList      = { },
      EnhRestrictionsList   = { },
      BuildRestrictionsList = { }
    },

}


--[[  Miscellaneous Variables and Flags  ]]--
ACUisReady            = false
attackUBC             = false
defensUBC             = false
PreBuiltBase          = false
A_Air_Transport_1     = false




--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[   Local Tuning Variables                                                    ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--


# The players's unit cap
local AttackerUnitCap = 500
local DefenderUnitCap = 500


Here's a little utility copyed from Saya's script.
Code:
--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[   Misc Local Definitions                                                    ]]--
--[[                                                                             ]]--
--[[                                                                             ]]--
--[[ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]--




fastPrintText = function(text)
   PrintText(text,20,nil,5,'center')
end


Here are the usual starter functions.
Note that I've had to fix up a sort of "bug" that resets customized players names to default players names.
I've also added a function call that force the display of units's life bars (see OnStart)
Code:
--[[                                                                             ]]--
--[[   OnPopulate()                                                              ]]--
--[[                                                                             ]]--
--[[   alliances and unit spawning go in there so you dont get conflicts and     ]]--
--[[   weird behaviours with initializearmies                                    ]]--
--[[                                                                             ]]--

function OnPopulate()

    --[[  GENERAL SETUP                                                          ]]--
    --[[  Scores, UnitCap, Alliances, etc                                        ]]--

    --[[  Fix Scenario's Options  ]]--
    ScenarioInfo.Options.TeamSpawn        = 'fixed'
    ScenarioInfo.Options.TeamLock         = 'locked'
    ScenarioInfo.Options.FogOfWar         = 'explored'
    ScenarioInfo.Options.CivilianAlliance = 'neutral'
    ScenarioInfo.Options.CheatsEnabled    = 'false'
    ScenarioInfo.Options.Victory          = 'demoralization'
    ScenarioInfo.Options.UnitCap          = '500'
    ScenarioInfo.Options.NoRushOption     = 'Off'
    ScenarioInfo.Options.Timeouts         = '-1'
    ScenarioInfo.Options.PrebuiltUnits    = 'Off'
    ScenarioInfo.Options.GameSpeed        = 'fixed'

    --[[  Fix players's Unit Cap, NO EXTRA UNITS ALLOWED  ]]--
    SetIgnoreArmyUnitCap( theAttacker, false )
    SetIgnoreArmyUnitCap( theDefender, false )
    #SetArmyUnitCap( theAttacker, AttackerUnitCap )
    #SetArmyUnitCap( theDefender, DefenderUnitCap )

    --[[  Set ALL Players's ALLIANCES  ]]--
    SetAlliance( ubcsTable[theAttacker].name, ubcsTable[theDefender].name, 'Enemy' )

    --[[  Custom Initialization of Armies  ]]--
    InitializeArmies()

    --[[  Transport UBC jusqu'à la Drop Zone  ]]--

    if attackUBC != nil then
        TransportUBCversDropZone( attackUBC )
    else
        LOG("MANIMAL:  Transport of attackUBC (nil) is not possible for player ".. iArmy .. " " .. strArmy .. " .")
    end


    --[[  Fixes customized name because it is reset for some unknown reason  ]]--

    if ACUisReady then
        attackUBC:SetCustomName( ArmyBrains[theAttacker].Nickname .. " - ATTACKER" )
        defensUBC:SetCustomName( ArmyBrains[theDefender].Nickname .. " - DEFENDER" )
    end

end

# END of onPopulate





--[[                                                                             ]]--
--[[   OnStart(self)                                                             ]]--
--[[                                                                             ]]--
--[[   Game mechanisms are there                                                 ]]--
--[[                                                                             ]]--

function OnStart(self)

    --[[  Show Enemy life bars  ]]--

    Utilities.UserConRequest("ui_ForceLifbarsOnEnemy")

    --[[  LET's ROCK !  ]]--

end


The functions below are a shortened version of the ones that are detailed in [TUT] How to get upgraded ACUs for non-AI players
Code:
--[[                                                                             ]]--
--[[   InitializeArmies()                                                        ]]--
--[[                                                                             ]]--
--[[   Spawn CUSTOM COMMANDERS and their ARMIES                                  ]]--
--[[                                                                             ]]--

function InitializeArmies()

    local tblGroups = {}
    local tblArmy = ListArmies()

    for iArmy, strArmy in pairs(tblArmy) do

        local tblData = Scenario.Armies[strArmy]

        if tblData then
      
            SetArmyEconomy( strArmy, tblData.Economy.mass, tblData.Economy.energy)

            --[[  Spawn Upgraded ACUs  ]]--

            local cdrUnit = false
         
            cdrUnit = SpawnUpgradedUBC ( strArmy, iArmy )

            if cdrUnit != nil then
                LOG("MANIMAL:  SPAWN de Enhanced UBC pour joueur ".. iArmy .. " " .. strArmy .. " COMPLETé !")
                if strArmy == ubcsTable[theAttacker].name then
                    attackUBC = cdrUnit
                elseif strArmy == ubcsTable[theDefender].name then
                    defensUBC = cdrUnit
                end

                --[[  customize players's name as explicitly as possible            ]]--
                --[[  I've repeated the customized name feature in another part of  ]]--
                --[[  the script because it's reset for some unknown reason !       ]]--
                cdrUnit:SetCustomName( ArmyBrains[iArmy].Nickname .. " - " .. strArmy )
            end

        end   #end IF tblData

    end   #end FOR

    return tblGroups

end




--[[                                                                             ]]--
--[[   SpawnUpgradedUBC ( strArmy, iArmy )                                       ]]--
--[[                                                                             ]]--
--[[   Spawn an Upgraded ACU                                                     ]]--
--[[                                                                             ]]--

function SpawnUpgradedUBC ( strArmy, iArmy )

    local ubcId = ''       # ACU Identifier
    local cdrUnit = false

    ubcId = ubcsTable[iArmy].unitId

    if (ubcId == 'ual0001') or (ubcId == 'uel0001') or (ubcId == 'url0001') then  # ACU Identifier is valid

        --[[  spawn uef commander  ]]--
        cdrUnit = CreateUnitHPR( ubcId, strArmy, mPos(strArmy)[1], mPos(strArmy)[2],mPos(strArmy)[3], 0,0,0)

        --[[  successful spawn  ]]--
        if cdrUnit != nil then
            LOG("MANIMAL:  SPAWN de UBC pour joueur ".. iArmy .. " " .. strArmy .. " .")

            --[[  annihilation type victory condition  ]]--
            cdrUnit.OldOnKilled = cdrUnit.OnKilled

            --[[  action when killed  ]]--
            cdrUnit.OnKilled = function(self, instigator, type, overkillRatio)
                GetArmyBrain(strArmy):OnDefeat()
                GetArmyBrain(strEnemi(iArmy)):OnVictory()
                cdrUnit.OldOnKilled(self, instigator, type, overkillRatio)   
            end            
        else
            LOG("FAILED: Unit Creation (ACU) for player ".. iArmy .. " " .. strArmy .. " .")
        end   #end IF cdrUnit

        --[[  Warp in effect is DISABLED in order to make a faster TransportLoad  ]]--
        #cdrUnit:PlayCommanderWarpInEffect()

   end   #end IF ubcId

   return cdrUnit

end


Here's the heart of this guide: Transporting the ACU to the Drop Zone.
Notice that you only have to load up a (few) unit(s) in the transport(s) (function AttachUnitsToTransports), then to issue an unload order at a specific area (function IssueTransportUnload) in order to make the transport moves !

You could include intermediary waypoints by adding one or more markers through the scenario editor (or even manually if you know how the coordinates system works) so that the transport's flightpath is not straight on. In such case, you'd have to call the function IssueMove in order to make the Transport move to one or more intermediary points, the Drop Zone being the last step...

Code:
--[[                                                                             ]]--
--[[   TransportUBCversDropZone( cdrUnit )                                       ]]--
--[[                                                                             ]]--
--[[   Load and Transport the Attacker's ACU to the Drop Zone                    ]]--
--[[                                                                             ]]--

function TransportUBCversDropZone(cdrUnit)

    --[[  Spawn Air Transport for Attacker ACU  ]]--

    local spawnPosLoc    = mPos( 'DZ_P0' )
    local origMarkerPos  = ScenarioUtils.MarkerToPosition( 'DZ_P0' )
    local destMarkerPos  = ScenarioUtils.MarkerToPosition( 'DZ_P1' )
    local airUnit        = false
         
    airUnit = CreateUnitHPR( unitsTable[1].unitId, unitsTable[1].army, spawnPosLoc[1], spawnPosLoc[2], spawnPosLoc[3], 0, 0, 0 )

    --[[  Successful ACU spawn so the transport can be loaded up !  ]]--

    if airUnit != nil then
        A_Air_Transport_1 = airUnit
        LOG("MANIMAL:  SPAWN de A_Air_Transport_1 .")

        --[[  LOADING UP ATTACKER IN AIR TRANSPORT  ]]--

        if not cdrUnit:IsDead() then

            --[[  AttachUnitsToTransports(units, transports)                       ]]--
            --[[  units is a set of units, transports is a set of transports       ]]--
            --[[  Automatically attaches <units> to attach points on <transports>  ]]--

            ScenarioFramework.AttachUnitsToTransports( { cdrUnit }, { A_Air_Transport_1 } )

        end

        --[[  UNLOADING ATTACKER FROM AIR TRANSPORT  ]]--

        if not cdrUnit:IsDead() and cdrUnit:IsUnitState('Attached') then

            --[[  IssueTransportUnload( transports, landingLocation )                          ]]--
            --[[  transports is a set of transports, landingLocation = is a marker's position  ]]--

            IssueTransportUnload( { A_Air_Transport_1 }, destMarkerPos )

            --[[  it's waiting for the Transport to be Unloaded   ]]--
            local unitsStillAttached  = true
            local armyIndex = cdrUnit:GetArmy()

            UnitsAreStillAttached = ForkThread ( function(self)
                while unitsStillAttached do
                   unitsStillAttached = WaitForTransportUnload( { cdrUnit } , { A_Air_Transport_1 } )
                end
                if not unitsStillAttached then
                    LOG("MANIMAL:  DEBUG ACUisReady = TRUE !!! .")
                    ubcsTable[armyIndex].isReady = true
                    ACUisReady = true
                end
                KillThread(self)
            end)
        end
    end
end


REMARK This is a really powerfull command that can do a lot in a single line ! it's all automatic !
i.e. You can order a (few) transport(s) to load up a (few) group(s) of units in the same single command.!!!
You would replace the units of my example shown below by any other units of your choice.
Code:
--[[  AttachUnitsToTransports(units, transports)                       ]]--
            --[[  units is a set of units, transports is a set of transports       ]]--
            --[[  Automatically attaches <units> to attach points on <transports>  ]]--

            ScenarioFramework.AttachUnitsToTransports( { cdrUnit, scuUnit }, { A_Air_Transport_1 } )


I've found some OnUnload method that could do a similar job to my function WaitForTransportUnload but in a single line of callback. (I'm not yet at my ease with LUA to use them.)
This method is available in the table of every single unit and it is overloadable. (aren't object oriented programs cool are they ?) It would look like : cdrUnit.OnUnload etc...
Code:
--[[                                                                             ]]--
--[[   WaitForTransportUnload(units, transports)                                 ]]--
--[[                                                                             ]]--
--[[   inspired from ScenarioFramework.lua                                       ]]--
--[[   function PlatoonAttackWithTransportsThread                                ]]--
--[[                   ( platoon, landingChain, attackChain, instant )           ]]--
--[[                                                                             ]]--

function WaitForTransportUnload(units, transports)
    local attached = true

    while attached do
        WaitSeconds(3)

        local allDead = true

        for k,v in transports do
            if not v:IsDead() then
                allDead = false
                break
            end
        end

        if allDead then
           return
        end

        attached = false

        for num, unit in units do
            if not unit:IsDead() and unit:IsUnitState('Attached') then
                attached = true
                break
            end
        end
    end

    return attached
end


UTILITY FUNCTIONS
Code:
--[[                                                                             ]]--
--[[   GetMarker(name)                                                           ]]--
--[[                                                                             ]]--
--[[   This is a copy of the function that's in ScenarioFramework                ]]--
--[[                                                                             ]]--
--[[   get marker given a name from map_save done in map editor                  ]]--
--[[   you can the use marker.position to get a location in the {x,y,z} format   ]]--
--[[                                                                             ]]--

function GetMarker(name)
    return Scenario.MasterChain._MASTERCHAIN_.Markers[name]
end



--[[                                                                             ]]--
--[[   mPos(name)                                                                ]]--
--[[                                                                             ]]--
--[[   name is the existing name of the marker                                   ]]--
--[[                                                                             ]]--
--[[   Get Marker position                                                       ]]--
--[[                                                                             ]]--

function mPos(name)
    return GetMarker(name).position
end



--[[                                                                             ]]--
--[[   strEnemi(iArmy)                                                           ]]--
--[[                                                                             ]]--
--[[   iArmy is the index of the current Army                                    ]]--
--[[                                                                             ]]--
--[[   Returns the enemi of the current Army                                     ]]--
--[[                                                                             ]]--

function strEnemi(iArmy)
    return ubcsTable[iArmy].enemi
end


More Short Guides to come. :wink:


Last edited by Manimal on 05 Nov, 2007, edited 1 time in total.

Top
 Profile  
 PostPosted: 31 Aug, 2007 
 
User avatar

Joined: 11 Apr, 2007
Posts: 1916
Offline
How to create a Patrol ? (for air units in this tuto)


Preamble

I've done my best to make the script as much readable as possible by using EXPLICIT names for functions, variables etc.
I've also made it as much generic as possible, stuffed with comments when I felt it necessary..
Of course my work isn't the most perfect and I'll be glad you explain me alternate solutions.

The script below should work "as is" because it's a sample of the actual working version 4 of my map script Solo ACU.
My map is available in the Vault and I'm currently working on version 5.
REMARK: I've shortened the biggest part of the script that's identical to one about the Transports so that it won't enlong too much this post.


Commented Script

The needed units's data are be defined first.
Just add them to the transport script, or replace them.


Code:
--[[  Table of Units to be spawned  ]]--
--[[  same format as ubcsTable      ]]--
--[[  so these are concatenable     ]]--

unitsTable = {

    { name                  = 'Air_Spies_1',
      nickname              = 'Air Spies - ATTACKER',
      army                  = ubcsTable[theAttacker].army,
      enemi                 = ubcsTable[theDefender].army,
      unitId                = 'ura0302',
      isReady               = false,
      EnhancementsList      = { },
      EnhRestrictionsList   = { },
      BuildRestrictionsList = { },
      BuildTimeMultiplier   = 1,
      ConsumptionPSMass     = 0,
      ConsumptionPSEnergy   = 0
    }

}




--[[  Miscellaneous Variables and Flags  ]]--

A_Air_Spies_1         = {
                          Air_Spy_01 = false,
                          Air_Spy_02 = false,
                          Air_Spy_03 = false,
                          Air_Spy_04 = false,
                          Air_Spy_05 = false,
                          Air_Spy_06 = false,
                          Air_Spy_07 = false,
                          Air_Spy_08 = false,
                          Air_Spy_09 = false,
                          Air_Spy_10 = false
                        }



Some more additions compared to the Transport script.
I've simply removed the parts that are common to both scripts.

Code:
--[[                                                                             ]]--
--[[   OnPopulate()                                                              ]]--
--[[                                                                             ]]--
--[[   alliances and unit spawning go in there so you dont get conflicts and     ]]--
--[[   weird behaviours with initializearmies                                    ]]--
--[[                                                                             ]]--

function OnPopulate()

    --[[  GENERAL SETUP                                                          ]]--
    --[[                                                                         ]]--
    --[[  Scores, UnitCap, Alliances, etc                                        ]]--


    --[[  Fix Scenario's Options  ]]--


    --[[  Fix players's Unit Cap, NO EXTRA UNITS ALLOWED  ]]--


    --[[  Set ALL Players's ALLIANCES  ]]--


    --[[  Custom Initialization of Armies  ]]--


    --[[  Envoyer Patrouille Air Spies autour de la Drop Zone  ]]--

    AirSpiesPatrouilleDropZone()


end

# END of onPopulate





--[[                                                                             ]]--
--[[   OnStart(self)                                                             ]]--
--[[                                                                             ]]--
--[[   Game mechanisms are there                                                 ]]--
--[[                                                                             ]]--

function OnStart(self)

  LOG("=======>  OnStart     ===============================================")

    --[[  Show Enemy life bars  ]]--

    Utilities.UserConRequest("ui_ForceLifbarsOnEnemy")

    --[[  LET's ROCK !  ]]--

end


Now here is the part of the script that makes the air units spawn and patrol (in a triangle shaped flightpath).
The "*_save.lua" file must contain the markers that are used in the code below.
Notice that this time, I've made a GROUP instead of a single unit compared to the Transport script.

Just like with the Transport, I did not use the function IssueMove because I wanted to make it simple and efficient.
This function IssueMove could make the planes fly through intermediary waypoints that must be added as markers.

Code:
--[[                                                                             ]]--
--[[  AirSpiesPatrouilleDropZone()                                               ]]--
--[[                                                                             ]]--
--[[  AirSpies Patrolling around the Drop Zone                                   ]]--
--[[                                                                             ]]--

function AirSpiesPatrouilleDropZone()

    --[[  Spawn Air Spies for Attacker ACU  ]]--

    local spawnPosLoc   = mPos( 'DZ_P0_1' )
    local origMarkerPos = ScenarioUtils.MarkerToPosition( 'DZ_P0_1' )
    local destMarkerPos = ScenarioUtils.MarkerToPosition( 'DZ_P1' )
    local attackChain   = 'Drop_Zone_1_Patrol'
         
    --[[  Create 10 SpyPlanes, Cybran, Tech 2  ]]--

    local unitcount = 1
    local Air_Spy = false

    while  unitcount != 11  do

        Air_Spy = A_Air_Spies_1[unitcount]

        if not Air_Spy then

            --[[  spawn one Spy Plane  ]]--
            Air_Spy = CreateUnitHPR( unitsTable[2].unitId, unitsTable[2].army, spawnPosLoc[1], spawnPosLoc[2], spawnPosLoc[3], 0, 0, 0 )

             --[[  successful spawn of the Spy Plane !  ]]--
            if Air_Spy != nil then
                LOG("MANIMAL:  SPAWN at DZ_P0 A_Air_Spies_1 n° " .. unitcount .. " .")
                A_Air_Spies_1[unitcount] = Air_Spy
                unitcount = unitcount + 1
            end
        end
    end

    --[[  successful spawn of the group so the Spies can go and Patrol !  ]]--

    if A_Air_Spies_1 != nil then
        LOG("MANIMAL:  SPAWN de A_Air_Spies_1 .")

        --[[  Make AirSpies Patrolling around the Drop Zone  ]]--

        local attackLocs = ScenarioUtils.ChainToPositions(attackChain)

        for k,v in attackLocs do
            LOG("MANIMAL:  A_Air_Spies_1 PATROLLING Drop_Zone_1_Patrol, point de passage number " .. k .. " .")
            IssuePatrol( A_Air_Spies_1, v )
        end

    end

end


Naturally, you could replace the air planes by ground units, this would work as well the same way !
You could split this function into a couple of generic functions, the one that would create a group and the other one that would make this group patroling a zone.


Top
 Profile  
 PostPosted: 01 Oct, 2007 
 
User avatar

Joined: 11 Apr, 2007
Posts: 1916
Offline
How to build Nukes, Anti-Nukes or Tactical Missiles ?


Preamble

I've done my best to make the script as much readable as possible by using EXPLICIT names for functions, variables etc.
I've also made it as much generic as possible, stuffed with comments when I felt it necessary..
Of course my work isn't the most perfect and I'll be glad you explain me alternate solutions.

The script below should work "as is", it's a sample of the actual working version 4 of my map script Solo ACU.
My map is available in the Vault and I'm currently working on version 5.
REMARK: I've shortened the biggest part of the script that's useless here, so that won't enlong too much this post.


Commented Script


First of all, here is the generic function that spawns any unit at a specific location:

Code:
function BuildUnitAtLocation( unitId, forArmy, markerName )

    --[[  Spawn unitId @ markerName ]]--

    local spawnLoc = mPos( markerName )

    unit = CreateUnitHPR( unitId, forArmy, spawnLoc[1], spawnLoc[2], spawnLoc[3], 0, 0, 0 )

    LOG("MANIMAL:  SPAWN  unitId = "..unitId..")  for Army = "..forArmy.."  at marker = "..markerName.."  .")

    return unit

end



This example below shows how to spawn a Tactical Missiles Launcher and how to fill it up of Missiles.
You can build Tactical Missiles for another race by replacing 'ueb2108' for the identifier of any race ('uab2108' or 'urb2108'). Also, you may want to adjust the value of NumToBuild according your needs.


Now the function that gives a Silo some ammunitions :
Code:
function BuildTacticalMissiles( unit, NumToBuild, markerName )

    if unit and unit != nil then

        unit:GiveTacticalSiloAmmo( NumToBuild )
        LOG("MANIMAL:   Missiles Silo Ammo = ".. NumToBuild .." at "..markerName.."  .")
    else
        error('MANIMAL:  *ERROR* Attempting to build Missiles in a non-existent unit ')
    end

end


Here is the function that builds up a Tactical Missiles Launcher and its ammunitions :
Code:
function BuildArmedTacticalMissilesLauncher( unitId,  forArmy, markerName, NumToBuild )

    Tactical_Missiles_1 = BuildUnitAtLocation( unitId, forArmy, markerName )
    BuildMissiles( Tactical_Missiles_1, NumToBuild, markerName  )

end


Last here is its implementation :
Code:
local unitId     = "ueb2108"        ## the UEF Tactical Missiles Launcher's unit identifier
local forArmy    = "ARMY_1"
local markerName = "M_TacticalML"   ## is a valid marker name that exists in the "*_save.lua" file.
local NumToBuild = 6

BuildArmedTacticalMissilesLauncher( unitId,  forArmy, markerName, NumToBuild )




Now here is the specific function that builds up Nukes (Strategic Missiles Launcher).

First the function that gives a Silo some ammunitions :
Code:
function BuildNukes( unit, NumToBuild, markerName )

    if unit and unit != nil then

        unit:GiveNukeSiloAmmo( NumToBuild )
        LOG("MANIMAL:   Nukes Silo Ammo = ".. NumToBuild .." at "..markerName.."  .")
    else
        error('MANIMAL:  *ERROR* Attempting to build nukes in a non-existent unit ')
    end

end


Here is the function that builds up a Strategic Missiles Launcher and its ammunitions :
Code:
function BuildArmedStrategicMissilesLauncher( unitId,  forArmy, markerName, NumToBuild )

    Strategic_Missiles_1 = BuildUnitAtLocation( unitId, forArmy, markerName )
    BuildNukes( Strategic_Missiles_1, NumToBuild, markerName  )

end


and its implementation :
Code:
local unitId     = "urb2305"         ## the Cybran Strategic Missiles Launcher's unit identifier
local forArmy    = "ARMY_2"
local markerName = "M_StrategicML"   ## is a valid marker name that exists in the "*_save.lua" file.
local NumToBuild = 5

BuildArmedStrategicMissilesLauncher( unitId,  forArmy, markerName, NumToBuild )




Last, here is the way to go to build up Anti-Nukes (Strategic Missile Defense) :

Here is the function that gives a Silo some ammunitions, which is the same as for Tactical Missiles :
Code:
function BuildAntiNukes( unit, markerName, NumToBuild ) 
    BuildTacticalMissiles( unit, markerName, NumToBuild )
end


Here is the function that builds up a Strategic Missiles Defense and its ammunitions :
Code:
function BuildArmedStrategicMissilesDefense( unitId,  forArmy, markerName, NumToBuild )

    Strategic_Defense_1 = BuildUnitAtLocation( unitId, forArmy, markerName )
    BuildAntiNukes( Strategic_Defense_1, NumToBuild, markerName  )

end


and finaly its implementation :

Code:
local unitId     = "uab4302"         ## the Aeon Strategic Missiles Defense's unit identifier
local forArmy    = "ARMY_3"
local markerName = "M_Antinukes"     ## is a valid marker name that exists in the "*_save.lua" file.
local NumToBuild = 4

BuildArmedStrategicMissilesDefense( unitId, forArmy, markerName, NumToBuild )


Depending on your needs, you can replace a marker name for the ones you made for your own map.
Eventualy use the function GetMarker that can get the marker names for you :
Code:
--[[   This is a copy of the function that's in ScenarioFramework                ]]--
--[[                                                                             ]]--
--[[   get marker given a name from map_save done in map editor                  ]]--
--[[                                                                             ]]--

function GetMarker( name )
    return Scenario.MasterChain._MASTERCHAIN_.Markers[name]
end



Don't hesitate to PM me if you don't catch the way my script works. :wink:

_________________
Console Plus - Solo A.C.U. - Experimental Wars Image


Top
 Profile  
 PostPosted: 24 Dec, 2007 
 
User avatar

Joined: 04 Jul, 2007
Posts: 52
Location: Setauket NY, USA
Offline
Weather tutorial is excellent, however it contains one minor and easy to figure out mistake:

"['cloudSpread'] - Radius of the area in which clouds are created" -not radius but diameter.


Top
 Profile  
 PostPosted: 19 Dec, 2009 
 

Joined: 29 Apr, 2009
Posts: 12
Offline
Just to put something used in some games...

How to make a map as a land only map?
Like Battle of Thermopylae...
Put this code on map_name_script.lua file

It's like rules:
no nuke,teleport,satellite,billy,t3-t4 arty,Eye of Rhianne
Code:

local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua')
local ScenarioFramework = import('/lua/ScenarioFramework.lua')

function OnPopulate()
   ScenarioUtils.InitializeArmies()


   local tblArmy = ListArmies()
   
for index,army in tblArmy
do
   ScenarioFramework.AddRestriction(army, categories.uab2302) # aeon t3 arty
   ScenarioFramework.AddRestriction(army, categories.xab3301) # aeon eye of Rhianne
   ScenarioFramework.AddRestriction(army, categories.xab2307) # aeon Rapid Fire Artillery
   ScenarioFramework.AddRestriction(army, categories.ueb2302) # uef t3 arty
   ScenarioFramework.AddRestriction(army, categories.ueb2401) # uef mavor arty
   ScenarioFramework.AddRestriction(army, categories.xeb2402) # uef novax
   ScenarioFramework.AddRestriction(army, categories.xea0002) # uef defensive satellite
   ScenarioFramework.AddRestriction(army, categories.urb2302) # cybran t3 arty
   ScenarioFramework.AddRestriction(army, categories.url0401) # cybran rapid fire arty
   ScenarioFramework.AddRestriction(army, categories.xsb2302) # seraphim t3 arty
   ScenarioFramework.AddRestriction(army, categories.uab2305) # seraphim strat mis launcher
   ScenarioFramework.AddRestriction(army, categories.ueb2305) # seraphim strat mis launcher
   ScenarioFramework.AddRestriction(army, categories.urb2305) # seraphim strat mis launcher
   ScenarioFramework.AddRestriction(army, categories.xsb2305) # seraphim strat mis launcher
   ScenarioFramework.AddRestriction(army, categories.xsb2401) # seraphim exp Nuke
   ScenarioFramework.RestrictEnhancements({     'TacticalNukeMissile',
                  'Teleporter'})

end



--start of map script
function OnStart(self)
end


--

end



Top
 Profile  
 PostPosted: 04 Feb, 2011 
 

Joined: 13 Jun, 2008
Posts: 729
Offline
A map support script which when put into a lobbymod will display full help tooltips on custom map options.

put this in "\lua\ui\dialogs\mapselect.lua" instead of the default OptionContainer.CalcVisible function and it'll display the help messages embedded in custom map options (mostly survival maps and the like.)
Code:
OptionContainer.CalcVisible = function(self)
        local function SetTextLine(line, data, lineID)
            if data.type == 'title' then
                line.text:SetText(LOC(data.text))
                line.text:SetFont(UIUtil.titleFont, 14, 3)
                line.text:SetColor(UIUtil.fontOverColor)
                line.bg:SetSolidColor('00000000')
                line.combo:Hide()
                LayoutHelpers.AtLeftTopIn(line.text, line, 0, 20)
                LayoutHelpers.AtHorizontalCenterIn(line.text, line)
            elseif data.type == 'spacer' then
                line.text:SetText('')
                line.combo:Hide()
            else
                line.text:SetText(LOC(data.text))
                line.text:SetFont(UIUtil.bodyFont, 14)
                line.text:SetColor(UIUtil.fontColor)
                line.bg:SetTexture(UIUtil.UIFile('/dialogs/mapselect03/options-panel-bar_bmp.dds'))
                LayoutHelpers.AtLeftTopIn(line.text, line, 10, 5)
                line.combo:ClearItems()
                line.combo:Show()
                local itemArray = {}
                line.combo.keyMap = {}
                local tooltipTable = {}
                for index, val in data.data.values do
                    itemArray[index] = val.text
                    line.combo.keyMap[val.key] = index
                    tooltipTable[index]={text='lob_'..data.data.key..'_'..val.key,body=val.help}
                end
                local defValue = changedOptions[data.data.key].index or line.combo.keyMap[curOptions[data.data.key]] or 1
                line.combo:AddItems(itemArray, defValue)
                line.combo.OnClick = function(self, index, text)
                    changedOptions[data.data.key] = {value = data.data.values[index].key, pref = data.data.pref, index = index}
                end
                line.HandleEvent = Group.HandleEvent
                Tooltip.AddControlTooltip(line, {text=data.data.pref,body=data.data.help})
                Tooltip.AddComboTooltip(line.combo, tooltipTable, line.combo._list)
                line.combo.UpdateValue = function(key)
                    line.combo:SetItem(line.combo.keyMap[key])
                end
            end
        end
        for i, v in OptionDisplay do
            if Options[i + self.top] then
                SetTextLine(v, Options[i + self.top], i + self.top)
            else
                v.text:SetText('')
                v.combo:Hide()
                v.bg:SetSolidColor('00000000')
            end
        end
    end

_________________
TVg V5 Alpha Testers Wanted!
Image
Bulletstorm released
other mods


Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic



Quick Tools

Search for:
Jump to:  

© 2002-2010 Gas Powered Games Corp. All Rights Reserved. Gas Powered Games is the exclusive trademark of Gas Powered Games Corp.
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
 
Home| Games | Company | News & Press | Support
  Terms of Use   |    Copyright Information   |    Privacy Policy