- Beiträge: 5363
- Dank erhalten: 4
By now, our community has mostly migrated to Discord. This forum mainly serves as an archive nowadays, and isn't actively supervised anymore.
Feel free to head over to our
Discord
for a more active community. You're much more likely to get fast replies and support there than here.
-
Inzwischen ist unsere Community größtenteils auf unserem Discord-Server zu finden. Dieses Forum dient hauptsächlich noch als Archiv und wird nicht mehr aktiv betreut.
Schau gerne auf unserem
Discord-Server
vorbei - Dort findest Du die aktive Community und wirst viel wahrscheinlicher schnelle Antworten oder Unterstützung erhalten, als hier.
Select Settings menu > Highlighter settings.
Select Specification tab.
On the left list, select one of the "<not assigned>" tags and on the right site scroll down and choose Lua from the list > ok.
- You might want to select the "Lua" tag on the left we just added and edit the "Colors" tag. Here you can set for example comments to be displayed in green and strings in purple, so highlighter colors have the same meaning like for Xml.
variable_01, variable_02 = value
Table_List_02 = {value_1, "value_2", value_3, "value_4"}
table.insert (Table_List_01, "Tee")
table.remove(TableName, [2])
Bitte Anmelden um der Konversation beizutreten.
Example for a correct if-elseif statement:-- If the variable_01 we just initiated above is not false, we set variable_02:
if variable_01 ~= false then
variable_02 = WhatEver
end
if condition_1 then
do something
elseif condition_2 then
do something else
elseif condition_3 then
do something else
else
do this if none of the conditions above was fullfilled
end
if condition_1 then
do something
if condition_1 then
do something
end
end
if condition_1 and condition_2
or condition_3 then
do something
end
if condition_1 then
do something
elseif condition_2 then
do something else
else
do this if none of the conditions above was fullfilled
end
[/color]<Rebel_Story_Name></Rebel_Story_Name>
<Empire_Story_Name></Empire_Story_Name>
<Underworld_Story_Name></Underworld_Story_Name>
<Story_Mode_Plots>
<Lua_Script>story</Lua_Script>
<Active_Plot>story.xml</Active_Plot>
</Story_Mode_Plots>
<Lua_Script>story</Lua_Script>
<Active_Plot>story.xml</Active_Plot>
<Lua_Script>ScriptName</Lua_Script>
<Lua_Script>ScriptName_1</Lua_Script>
<Lua_Script>ScriptName_2</Lua_Script>
require("PGStateMachine")
require("PGStoryMode")
function Definitions()
StoryModeEvents = {
Universal_Story_Start = Universal_Story_Start,
Event_01 = State_01,
Event_02 = State_02
}
variable_01 = false
variable_02 = "Unit_Name"
variable_03 = blabla
end
function Definitions()
-- Every State has to be initiated here or it wont work
Define_State("State_Init", State_Init)
Define_State("State_Inactive", State_Inactive)
Define_State("State_Active", State_Active)
variable_01 = false
variable_02 = "Unit_Name"
variable_03 = blabla
end
Bitte Anmelden um der Konversation beizutreten.
Define_State("State_Init", State_Init)
Define_State("State_01", State_01)
Define_State("State_02", State_02)
StoryModeEvents = { Universal_Story_Start = Universal_Story_Start,
Event_01 = State_01,
Event_02 = State_02
}
The Variable ServiceRate defines how fast the "OnUpdate" states will refresh, 0.1 means 1 second and 0.05 is half a second..ServiceRate = 0.05
function State_Init(message)
if message == OnEnter then
-- Your Code Block
Set_Next_State("State_01")
end
end
function State_01(message)
if message == OnUpdate then
-- Your Code Block
if condition then
Set_Next_State("State_02")
end
end
end
function State_02(message)
if message == OnEnter then
-- Once Only Code Block
elseif message == OnUpdate then
-- Repeated Code Block
end
end
FunctionName()
-- Execute Code Block
end
FunctionName_Thread = Create_Thread("FunctionName")
GlobalValue.Get(PlayerSpecificName(player, value_name))
Play_Music("abc") -- abc is the .xml instance of a .mp3 file, inside of MusicEvents.xml
.Get_Health()
.Make_Enemy(player_object)
.Attach_Particle_Effect("XXX")
"Home_One_Target_Particles" = red targeting
"Weaken_Enemy_Particle_Effect" = permanent green particle
"Corrupt_Systems_Effect" = permanent green orb
"canderous_lure" = permanent pink localisation particle
"Lure_Ability_Particle" = pink Interdictor particle
"Emperor_Force_Convert_Particles" = Green Empire symbol
"Shield_Penetration_Effect_Particle" = Permanent portalgun effect
"Weaken_Enemy_Detonation_Effect" = green wave
"Force_Instant_Heal_Particles" = blue wave
"Self_Destruct_Effect" = pink wave
"Force_Whirlwind_Particles" = short red wave
"FOW_Ping_Blast_Particles" = short blue wave
"Replenish_Wingmen_Particle_Effect" = short ultraviolet wave
"Sensor_Jamming_Effect" = short bigger ultraviolet wave
"Blast_Charging_Effect" = pink dust
"Ewok_Suicide_Bomb_Explosion" = nice little explosion
"Huge_Explosion_Land" = another nice explosion
"Spmat_Damage_Land" = little green explosion
"p_orbital_impact" = heavy Napalm explosion
"p_orbital_impact_ion" = Ion explosion
"Piet_Powerup_Particle_Effect" = red particles
"Rescue_Effect" = blue beaming away effect
"p_kraytdestoyer_detonate_special" = Planet destruction
"Shield_Flare_Effect"
"Ysalamiri_Force_Drain_Effect" = short black circle
Anakin in the everythingeaw forums schrieb: FOC: if Object.Get_Rate_Of_Damage_Taken() > 20.0 then
interesting Count-Getter:
fleet.Get_Contained_Object_Count() -> please note, that fleets have to be assembled first
fleet.Contains_Hero() -> works for all fleets not in hyperspace
fleet.Contains_Object_Type(
SpaceForce.Get_Force_Count()
FreeStore.Get_Object_Count()
MainForce.Get_Unit_Table() -> only in KI section
********************************************
*** Findings from the LUA script files ***
****************************************
StoryGlobale:
State-Funktions parameter P0, Werte: OnEnter, OnUpdate, OnExit
- which is when?
!!! function Story_Mode_Service()
- it seems as if this function is executed repeatedly, to check specific criteria
ScriptExit()
- terminates the script
StoryModeEvents = {Blabla_00 = State_Blabla_00}
- assigns StoryEvents to script function
GetCurrentTime()
- returns current time (system time?, ingame time?, I guess the last, because it looks like it is used with seconds)
Find_All_Objects_Of_Type("XXX") - XXX object name
- returns an array with all found objects
Find_First_Object("XXX") - XXX name of a GameObjects
- returns the first found object
Find_Player("XXX") - XXX for Empire, Rebel, Pirates ...
- returns the according GameObject (PlayerObject)
FindPlanet("XXX") - XXX Planetenname
- returns the according GameObject (PlanetObject)
TestValid(X) - GameObject
-
Add_Planet_Highlight(XXX, "0") - XXX PlanetObject
-
Remove_Planet_Highlight("0")
-
Get_Story_Plot("XXX") - XXX Story_bla.xml
-
Story_Event("XXX") - XXX Eventname
- triggers StoryEvent
Find_Hint("XXX", "YYY") - XXX object from the tactical map, YYY - hint
- to find certain locations on the tactical map, objects with same type can be distinguished with hints?
Find_All_Objects_With_Hint("XXX") - XXX hint
-
Add_Radar_Blip(XXX, "YYY") - XXX object, YYY new hint?
-
Rotate_Camera_By(180, 30) - X angular degree, Y time in seconds
- rotates camera around targeted point
Letter_Box_In(0)
-
Letter_Box_Out(0.5);
-
Suspend_AI(X) - X 0 or 1
- puts KI off or on
Lock_Controls(X) - X 0 or 1
- puts controls off or on
Create_Thread("XXX") - XXX function name
-
Create_Thread("XXX", Y) - XXX function name, Y parameter
-
Sleep(X) - X seconds
- suspends the thread for the given time
GlobalValue.Set("XXX", Y) - XXX name of variable, Y value
- not the same variables as in XML !?
- XXX values: Allow_AI_Controlled_Fog_Reveal
Hide_Object(X, Y) - X object, Y 0 or 1
Hide_Sub_Object(X, Y, "ZZZ") - X object, Y 0 or 1, ZZZ SubObject name (also .alo possible)
-
Do_End_Cinematic_Cleanup()
-
Register_Timer(X, Y) - X function, Y integer delay time
- function is executed after given time
Register_Death_Event(X, Y) - X object, Y function
- function to be executed after the death of the object?
Find_Nearest(X, Y, Z) - X object, Y PlayerObject owner, Z true/false ? mostly true
-
Find_Nearest(MainForce, "Structure", PlayerObject, true)
Find_Nearest(Target, "Prop_Good_Ground_Area")
Find_Nearest(Object,"TYP-STRING")
Assemble_Fleet(X) - X return value of SpawnList
- returns FleetObject
Find_Path(X, Y, Z) - X PlayerObject, Y PlanetObject(start), Z PlanetObject(target)
- returns list of PlanetObjects ([0]start, [1]next planet, ect.)
Find_Object_Type("XXX") - XXX object name
- returns type of object
ReinforceList(X, Y, Z, true, true) - X list of UnitObjectNames, Y object (SpawnPosition), Z PlayerObject
table.getn(X) - X array aka table aka list
- retuns number of objects in given list
FogOfWar.Reveal(X, Y, 200000, 200000) - X PlayerObject, Y PositionObject,
- returns fogid
GameRandom.GetFloat()
- returns a random float value between 0.0 und 1.0
GameRandom(X,Y) X integer, Y integer
- returns a random integer value between X and Y (both inclusive)
PlayerObject:
.Enable_Advisor_Hints("XXX", Y) - XXX for space, ground, Y false or true
-
.Get_ID()
- returns ID of PlayerObject
.Get_Enemy()
.Get_Type()
.Select_Object(X) - X object
.Enable_As_Actor()
.Retreat()
.Get_Name()
.Get_Faction_Name()
.Get_Tech_Level()
.Is_Human()
.Give_Random_Sliceable_Tech()
.Give_Money(X) - X credits
PlanetObject:
.Get_Owner()
- returns PlayerObject (applicable for most objects)
.Get_Is_Planet_AI_Usable()
.Get_Game_Object()
.Get_Type()
.Get_Final_Blow_Player()
UnitObject:
.Despawn()
- removes the object from game
.Get_Planet_Location()
I tried to detect planets in Spacebattles, but both .Get_Parent_Object() and .Get_Planet_Location() seem to run without result: The value is always nil in space mode.
- returns PlanetObject
.Move_To(XXX) - XXX object
- (also applicable for PlayerObject)
.Get_Position()
- returns Position(Object)
.Enable_Behavior(X, Y) - X number of behavior, Y false or true
.Is_Under_Effects_Of_Ability("XXX") - XXX AbilityName
- returns true or false
.Activate_Ability()
.Activate_Ability("XXX", Y) - XXX AbilityName, Y false or true
-
.Activate_Ability("XXX", Y) - XXX AbilityName, Y object
-
.Reset_Ability_Counter()
-
.Set_Single_Ability_Autofire("XXX", Y) - XXX AbilityName, Y false or true
.Is_Ability_Active("XXX") - XXX AbilityName
.Is_Ability_Ready("XXX") - XXX AbilityName
.Has_Ability("XXX") - XXX AbilityName
.Get_Hull()
- returns x.x -> 1.0 = 100%?
.Take_Damage(X) - X damage points
-
.Take_Damage(X, "YYY") - X damage points, Y hardpoint
.Get_Shield()
- returns x.x -> 1.0 = 100%?
.Are_Engines_Online()
- retruns true or false
.Override_Max_Speed(X.X) X velocity?
- new value for max velocity?
.Guard_Target(XXX) - XXX PositionsObject
.Suspend_Locomotor(X) - X false or true
- movability on or off?
.Cinematic_Hyperspace_In(X) - X integer time
-
.Prevent_AI_Usage(X) - X false or true
-
.Hide(X) - X false or true
-
.Play_Animation("cinematic", true, 2)
-
.Change_Owner(XXX) - XXX PlayerObject (new owner)
-
.In_End_Cinematic(X) - X false or true
- shall object be displaed in Cinematic?
.Teleport(X) - X (Positions)Object
-
.Face_Immediate(X) - X (Positions)Object
- (also for PlayerObject)
.Prevent_Opportunity_Fire(X) - X false or true
- fire at will?
.Make_Invulnerable(X) - X false or true
-
.Stop()
.Set_Check_Contested_Space(X) - X false or true
.Get_Parent_Object()
- for fleets this is a PlanetObject, for ground forces it's the transport?
.Attack_Target(X) - X Object
.Lock_Current_Orders()
StoryPlotObject:
.Get_Event("XXX") - XXX name of event in plot
- returns EventObject
.Activate()
-
Wait_On_Flag("ACCUMULATE_CREDITS_NOTIFICATION_00", nil)
.Suspend()
-
.Reset()
- event can fire again
EventObject:
.Set_Reward_Parameter(X,Y) - X number of parameter (beginning with 0), Y GameObject
GameObject:
Get_Game_Object()
- ? see R0.Get_Game_Object() (where R0 should be a PlanetObject)
Bitte Anmelden um der Konversation beizutreten.
If you use PSPad you can open the new version of your script, and then go to Tools > TextDiff:Compare > With chosen file then choose the older backup of your script on your Harddisc. PS Pad will highlight any change colorful so you easily can see the last changes you did to your script since the last backup (which worked). One of the highted lines might cause a crash.
Many other text editors have this comparsion function, you just have to search for it.
Text Comparsion is also usefull to apply your newest function (and all changes you added with this function) to older scripts. I did this quite often each time I learned a new trick.
We sometimes need to find the Player object because some functions require it that way.function Definitions()
Define_State("State_Init", State_Init)
-- Name Strings of .xml instances have always to be in "signs"
Desired_Unit = "Unit_Name"
-- Defining the player fraction objects
Player_Rebel = Find_Player("Rebel")
Player_Empire = Find_Player("Empire")
-- Don't write this if your script is for classic EAW:
Player_Underworld = Find_Player("Underworld")
end
Because this gets the owner of our Object. You could also get owner of enemy units, which makes it universally and easy to use.Object.Get_Owner()
Now this will be a global variable, which means you can access it from any state.My_Unit = Find_First_Object(Desired_Unit)
local My_Unit = Find_First_Object(Desired_Unit)
local My_Unit = Find_First_Object("Unit_Name")
Save the code we just inserted and go back into the game. It will say you changed something to the .lua script and if you like to load these changes.-- Highlighting Object for 4 Seconds, then un-highlighting again:
Object.Highlight(true)
Sleep (4.0)
Object.Highlight(false)
My_Unit.Highlight(true)
This variable will be a switch, we use this to prevent the script from crashing if a unit could exist on the fieldSpawned_Unit = false
if Spawned_Unit ~= false then
-- Spawned_Unit.Do_Anything
-- After you're done you can set the variable back to false for the next check:
Spawned_Unit = false
end
Spawned_Unit = true
if Spawned_Unit == true then
Because the engine will assume that you mean == trueif Spawned_Unit then
I strongly recommend that you add a comment over each sleep function with the reason why it is being used.-- Sleeping because..
Sleep (0.6)
-- Sleeping because .. blabla
Sleep (1.0)
It would also work:
Sleep (1)
This also crashes the script if you try to play a second sound as long the first song is still being played..Play_SFX_Event("Xml_Sound_Name")
The change owner command can crash the script if it is placed under or over a wrong command.Object.Change_Owner(Find_Player("Neutral"))
-- Hiding a whole Object:
Hide_Object(Object, 1)
-- Unhiding a Object:
Hide_Object(Object, 0)
-- Hiding partial meshes of the Object model:
Hide_Sub_Object(Object, 1, "Mesh_Name")
-- Un-hiding partial meshes:
Hide_Sub_Object(Object, 0, "Mesh_Name")
Point_Camera_At(Object)
.Override_Max_Speed(int) -- You have to look into the original .xml for speed. Fighters have about 5.0
-- Replace "Idle" with name of Animation, don't name it like "Idle_00", works without numbers in the name.
-- The second parameter repeads this animation in a loop if set to true
.Play_Animation("Idle", false, 0)
.Teleport(target_obj) -- Use this to instantly get a unit to a other location
.Face_Immediate(target_obj)
.Teleport_And_Face(target_obj) -- This is a combination of the 2 above
.Attack(target_obj)
.Move_To(target_obj)
.Attack_Move(target_obj)
.Stop()
.Guard_Target(target_obj)
.Suspend_Locomotor() -- true or false
.Take_Damage(amount) -- or .Take_Damage(amount, "Name_of_any_Hardpoint")
.Despawn()
.Make_Invulnerable() -- true or false
.Prevent_All_Fire() -- true or false
.Set_Selectable() -- true or false
.Reset_Ability_Counter() -- true or false
.Activate_Ability("Ability_Name", true)
.Cancel_Ability("Ability_Name")
.Change_Owner("Player_String_Name")
.Make_Ally(player_object) -- has to be used for both players
.Make_Enemy(player_object) -- has to be used for both players
player_object.Select_Object(Object) -- .Set_Selectable() has to be true
player_object.Give_Money(amount)
-- Suspending generally the whole AI
Suspend_AI(1) -- 1 or 0
.Get_Type()
.Get_Distance()
.Get_Owner()
.Get_Shield()
.Get_Hull()
.Get_Health()
.Get_Combat_Rating()
.Get_Enemy()
.Get_Name()
.Get_Position()
.Get_All_Planets()
.Get()
.Get_Affiliated_Indigenous_Type()
.Get_AI_Power_Vs_Unit()
.Get_Avoidance_Chance()
.Get_Base_Level()
.Get_Bone_Position()
.Get_Build_Cost()
.Get_Build_Pad_Contents()
.Get_Contained_Object_Count()
.Get_Credits()
.Get_Current_ID()
.Get_Difficulty()
.Get_Event()
.Get_Faction_Name()
.Get_Final_Blow_Player()
.Get_Float()
.Get_Force_Count()
.Get_Game_Object()
.Get_Game_Scoring_Type()
.Get_Hint()
.Get_ID()
.Get_Is_Planet_AI_Usable()
.Get_Max_Range()
.Get_Min_Range()
.Get_Next_Starbase_Type()
.Get_Object_Count()
.Get_Parent_Object()
.Get_Planet_Location()
.Get_Reserved_Build_Pads()
.Get_Score_Cost_Credits()
.Get_Self_Threat_Max()
.Get_Self_Threat_Sum()
.Get_Stage()
.Get_Tactical_Build_Cost()
.Get_Tech_Level()
.Get_Time_Till_Dead()
- returns an object-type, but only used for parent-object, not working for others?
.Get_Parent_Object()
.Get_Type_Of_Unit()
.Get_Unit_Table()
Important to know: Type of a Object is often its XML Unit Name! So if many functions refer to type, it actually means unit name.if Object.Get_Type() ~= Find_Object_Type(Desired_Unit) then
Object.Highlight(true)
end
Of course you can replace later the Object.Highlight(true) with your own code blocks.if Object.Get_Type() == Find_Object_Type(Desired_Unit) then
Object.Highlight(true)
end
This variant checks the name of both the Object and My_Unit and if they are of the same type the Object will highlight.-- Only if the Object is of the same Type (mxl name) as My_Unit
if Object.Get_Type() == My_Unit.Get_Type() then
Object.Highlight(true)
end
Which will highlight if they are NOT of the same type.if Object.Get_Type() ~= My_Unit.Get_Type() then
My_Unit = Find_First_Object("Unit_Name")
if TestValid(My_Unit) then
Object.Highlight(true)
end
if TestValid(Find_First_Object("Unit_Name")) then
Object.Highlight(true)
end
Will return a random number between 1 and 6, to play Russian roulette ^^GameRandom(1, 6)
Bitte Anmelden um der Konversation beizutreten.
Then replace "Unit_Name" with the name of a valid .xml unit.All_My_Units = Find_All_Objects_Of_Type("Unit_Name")
Table_List_01 =
{
[1] = Tomatos,
[2] = Milk,
[3] = Beer,
[4] = Chips,
[5] = Vodka,
}
The for loop will do this FOR ALL content in the table. This is how for loops work here.Cycle 1:
index_number = [1]
unit_variable = Tomatos
Cycle 2:
index_number = [2]
unit_variable = Milk
-- for each index and index variable in the table "All_My_Units" do
for index_number,unit_variable in pairs(All_My_Units) do
-- If exist and the unit_variable is has the fraction as our Object
if TestValid(unit_variable) and unit_variable.Get_Owner() == Object.Get_Owner() then
-- Highlighting, replace this by your code block
unit_variable.Highlight(true)
end
end
All_Space_Units = Find_All_Objects_Of_Type("Transport | Fighter | Bomber | Corvette | Frigate | Capital")
-- for each Unit in the table "All_Space_Units" do
for each,Unit in pairs(All_Space_Units) do
-- If exist and has the fraction as our Object
if TestValid(Unit) and Unit.Get_Owner() == Object.Get_Owner() then
-- Highlighting, replace this by your code block
Unit.Highlight(true)
end
end
if TestValid(Unit) and Unit.Get_Owner() ~= Object.Get_Owner() then
You can replace "Empire" with Rebel, Underworld or whatever fraction.All_Enemy_Objects = Find_All_Objects_Of_Type(Find_Player("Empire"))
This uses .Get_Owner() to get the owner of any unit (Replace Object with enemy units if you want to get enemy fraction).-- Getting all units of the user
local All_Own_Units = Find_All_Objects_Of_Type(Object.Get_Owner())
Then replace my variable "Unit_Name_?" with units of your Mod or the vanilla game and copy this into the body of your state:Valid_Units_List = {"Unit_Name_1", "Unit_Name_2", "Unit_Name_3", "Unit_Name_4"}
-- Initiating a empty table, found units will be inserted here
All_Found_Units = {}
-- For all String_Names in the Valid_Units_List Table
for each,String_Name in pairs(Valid_Units_List) do
-- Find all units of this type into another table variable
local Found_Units = Find_All_Objects_Of_Type(String_Name)
-- Again for all units, this time not the strings but the actual units
for each,Unit in pairs(Found_Units) do
-- If exist and the Unit has the player fraction
if TestValid(Unit) and Unit.Get_Owner() == Object.Get_Owner() then
-- Then we will insert it into the table "All_Found_Units"
table.insert(All_Found_Units, Unit)
end
end
end
table.remove(Table_Name, index_position) -- Usually index_position would be "each" for me
-- Again for all units, this time not the strings but the actual units
for each,Unit in pairs(All_Found_Units) do
-- If exist and the Unit has the type we are searching for (we use this to filter out anything other then the type we are looking for)
if TestValid(Unit) and Unit.Get_Type() == Find_Object_Type("Unit_Name") then
-- Then we will remove it from the table "All_Found_Units"
table.remove(All_Found_Units, each)
end
end
local Unit_Count = table.getn(All_Found_Units)
local Random_Number_1 = GameRandom(1,Unit_Count)
-- Assigning random Unit according to the Random_Number_1 variable from the lines above
local Random_Unit = All_Found_Units[Random_Number_1];
Exclusion_List = {"Unit_Name_1", "Unit_Name_2"}
All_Space_Units = Find_All_Objects_Of_Type("Transport | Fighter | Bomber | Corvette | Frigate | Capital")
-- For all space units we found
for each,Unit in pairs(All_Space_Units) do
-- If exist
if TestValid(Unit)
-- And it is none of the Units in the Exclusion List table
and Unit.Get_Type() ~= Find_Object_Type(Exclusion_List[1])
and Unit.Get_Type() ~= Find_Object_Type(Exclusion_List[2]) then
-- Getting distance between Unit and our Object
local Distance_to_Object = Unit.Get_Distance(Object)
-- If a Unit gets as close as 350 to our unit then.. (350 is a good value)
if Distance_to_Object < 351 then
-- Just highlighting to see it works, replace by your code then
Unit.Highlight(true)
end
end
end
What this function will do is executing the code and highlight the unit as soon it is nearing our Object."and Unit.Get_Owner() == Object.Get_Owner()" or "and Unit.Get_Owner() ~= Object.Get_Owner()"
Distance_to_Object = Unit.Get_Distance(Object)
Register_Death_Event("Unit_Name", Thread_Name_1)
--============= Threads =============
-- A thread is a simple function that can be called by any state and as often as needed:
function Thread_Name_1 ()
-- Insert your Code here
end
Register_Prox(Object, Thread_Name_2, ability_range)
--============= Threads =============
-- A thread is a simple function that can be called by any state and as often as needed:
function Thread_Name_2 ()
-- Insert your Code here
end
First parameter is any object to highlight on the minimap,Add_Radar_Blip(Object, "Marker_on_Radar")
Remove_Radar_Blip("Marker_on_Radar")
Note: "abc" is the name of a .xml instance of a sound, usually located in . \Xml\MusicEvents.xml ( It might work with normal sound .xml instances either).Play_Music("abc")
Object.Play_SFX_Event("Sound_Effect")
if Object.Is_Category("Capital") then
-- do something
elseif Object.Is_Category("Frigate") then
-- do something else
else -- do this if unit is Corvette or smaller
end
Bitte Anmelden um der Konversation beizutreten.
You are allowed to use them for writing your mod scripts, distributing them and to do anything else you wand to them.ObjectScript_Simple_Template.lua = A simple template for smaller scipts, to add a few lines of code into it.
ObjectScript_Ability_1_Template_Text.lua = The same as the one below, but with more text descriptions. Useful for first steps, later you will prefer the one without comments.
ObjectScript_Ability_1_Template.lua = You can use this template to run a Ability script, as soon the dummy ability was activated.
ObjectScript_Ability_2_Template_Text.lua = With description text, allows using 2 active abilities.
ObjectScript_Ability_2_Template.lua = Same as above with less text.
At the top this script provides info about the required dummy abilities.--[[
COPY THE FOLLOWING ABILITY into the <Unit_Abilities_Data> tag of your unit.xml:
<!-- You can replace Alternate_Name_Text, Alternate_Description_Text, and Alternate_Icon_Name with costum content. -->
<!-- ===== Recharge and Expiration set to 1000000 because of usage limits ===== -->
<Unit_Ability>
<Type>WEAKEN_ENEMY</Type>
<Expiration_Seconds>1000000</Expiration_Seconds>
<Recharge_Seconds>1000000</Recharge_Seconds>
<Owner_Particle_Bone_Name>BEAMING_ARRAY</Owner_Particle_Bone_Name>
<Effective_Radius>40000</Effective_Radius>
<Spawned_Object_Type>Hyperspace_Jump_Target</Spawned_Object_Type>
<Bomb_Countdown_Seconds>-1</Bomb_Countdown_Seconds>
<Alternate_Name_Text></Alternate_Name_Text>
<Alternate_Description_Text></Alternate_Description_Text>
<Alternate_Icon_Name>I_SA_FORCE_CONFUSE.TGA</Alternate_Icon_Name>
<SFXEvent_Target_Ability></SFXEvent_Target_Ability>
<SFXEvent_GUI_Unit_Ability_Activated></SFXEvent_GUI_Unit_Ability_Activated>
<SFXEvent_GUI_Unit_Ability_Deactivated/>
<!-- Area effect decal size depends on "Antills_Weaken_Enemy_Effect" -->
<Area_Effect_Decal_Distance> 20 </Area_Effect_Decal_Distance> <!--was 800-->
<Layer_Z_Adjust>0.0</Layer_Z_Adjust>
</Unit_Ability>
<Unit_Ability>
<Type>HARMONIC_BOMB</Type>
<Expiration_Seconds>1000000</Expiration_Seconds>
<Recharge_Seconds>1000000</Recharge_Seconds>
<Alternate_Name_Text></Alternate_Name_Text>
<Alternate_Description_Text></Alternate_Description_Text>
<Alternate_Icon_Name>I_SA_FORCE_CONFUSE.TGA</Alternate_Icon_Name>
<SFXEvent_GUI_Unit_Ability_Activated></SFXEvent_GUI_Unit_Ability_Activated>
</Unit_Ability>
<!-- ===== And copy this tag, which contains the name of this script aswell to the space unit (WITHOUT .lua suffix): ===== -->
<Lua_Script>ObjectScript_Ability_Name</Lua_Script>
]]
Another special thing, invented by me is the maximal usage limit.ability_used_counter_1 = 0
maximal_usage_limit_1 = 3
And I use time counters sometimes to let the script wait for a while.Time_Counter_1 = 0
You sometimes add Sleep (1.0) or Sleep(GameRandom(1,2)) after "if message == OnUpdate then"if message == OnUpdate then Sleep (1.0)
-- This time counter calls once every 20 seconds the function thread at the bottom of this script
if Time_Counter_1 == 20 then
-- Resetting counter for the next 20 seconds
Time_Counter_1 = 0
-- Calling the thread at the end of this script
Starting_Thread_Name_Thread = Create_Thread("Thread_Name")
else
Time_Counter_1 = Time_Counter_1 + 1
end
Replace Name_Thread both times with the name of any thread/function you wish to start.Starting_Thread_Name_Thread = Create_Thread("Thread_Name")
--================== AI Auto Activation for Ability 1 ====================
-- If the Owner of this Unit is not Human (=AI) and a Enemy is nearby
if not Object.Get_Owner().Is_Human() and Object.Has_Attack_Target()
-- And if its Ability isn't currently running
and Object.Has_Ability(ability_1) and Object.Is_Ability_Ready(ability_1) then
Object.Activate_Ability(ability_1,true)
end
--================== AI Auto Activation for Ability 1 ====================
-- If the Owner of this Unit is not Human (=AI) and a Enemy is nearby
if not Object.Get_Owner().Is_Human() and Object.Has_Attack_Target()
-- And if its Ability isn't currently running
and Object.Has_Ability(ability_1) and Object.Is_Ability_Ready(ability_1) then
-- Using the state of active ability:
Set_Next_State("State_Ability_1_A")
end
This is the trigger, which causes the script to jump into another state, into "State_Ability_1_A".--================== Ability 1 ====================
-- Wont work unless the unit has the ability and it is currently acitive!
if Object.Has_Ability(ability_1) and not Object.Is_Ability_Ready(ability_1)
-- To prevent unwanted activation in Nebulas
and not Object.Is_In_Nebula() then
-- As long the first variable is still smaller or equal to the second variable the effect thread starts.
if ability_used_counter_1 < maximal_usage_limit_1 then
-- Using the state of active ability:
Set_Next_State("State_Ability_1_A")
end
end
Same as ability_1, only difference is this fires if the second dummy ability, Harmonic Bomb. You can set what ever dummy ability you want: simply change the value of ability_2.--================== Ability 2 ====================
if Object.Has_Ability(ability_2) and not Object.Is_Ability_Ready(ability_2)
and not Object.Is_In_Nebula() then
-- As long the first variable is still smaller or equal to the second variable the effect thread starts.
if ability_used_counter_2 < maximal_usage_limit_2 then
-- Using the state of active ability:
Set_Next_State("State_Ability_2_A")
end
end
This and the Give Money command is only so you can see whether the script is functioning right.Object.Highlight(true)
'Spawned_Unit_1 = SpawnList({Unit_For_Spawn}, Object, Object.Get_Owner(), true, true)
You can call other Functions for these 2 Units we just spawned using their name: "Spawned_Unit_1.Function()" Sometimes the name wont assign to the Object you just created (am not sure why) In these cases you can find them using find_first_object or a for loop.Spawned_Unit_2 = Create_Generic_Object(Unit_For_Spawn, Object, Object.Get_Owner())
Note: Spawn_Unit is a bit buggy compared to SpawnList and CreateGenericObject.Spawned_Unit_3 = Spawn_Unit(Unit_For_Spawn, Object, Object.Get_Owner())
Add_Reinforcement(Unit_For_Spawn, Object.Get_Owner())
Sleep (ability_1_duration + 1)
-- As soon the Ability was finished, we will quit this state
-- Comment out the line above and un-comment this line to swap deactivation method
elseif Object.Is_Ability_Ready(ability_1) then
In the case of my template I divided the ability into 2 states:-- Will only work as long the ability stays active
if not Object.Is_Ability_Ready(ability_1) then
-- Codeblock.. do something
-- As soon the Ability was finished, we will quit this state
elseif Object.Is_Ability_Ready(ability_1) then
Set_Next_State("State_Ability_1_B")
end
ability_used_counter_1 = ability_used_counter_1 + 1
Which increases the value i by 1 each time the code is executed.i = i + 1
In this case our Ability has <Recharge_Seconds>1000000</Recharge_Seconds> and Expiration seconds to 1000000. Which will take for ever. So the ability wont recover, unless it was reseted by Object.Reset_Ability_Counter()-- Resetting only if usage points are left
if ability_used_counter_1 < maximal_usage_limit_1 then
-- Without this resetting the permanent ability, it would infinitely stay in active state so cant be reactivated.
Object.Reset_Ability_Counter()
end
function Moving_To_Fleet ()
-- Initiating a table (global variable because it is supposed to be used in the states above):
Main_Fleet = {}
-- Resetting the Big units
local All_Big_Units = {}
-- Re-Searching for the fleet
All_Big_Units = Find_All_Objects_Of_Type("Transport | Corvette | Frigate | Capital")
-- We wont use "All_Units" because we don't want them to go to fighters
for each,Unit in pairs(All_Big_Units) do
-- If exist and the Owner of the Unit is the same as the Object Owner (Human)
if TestValid(Unit) and Unit.Get_Owner() == Object.Get_Owner() then
-- Then we will insert it into the table of our "Main_Fleet"
table.insert(Main_Fleet, Unit)
end
end
-- Getting unit count of the Main_Fleet table
local Units_in_Fleet = table.getn(Main_Fleet)
-- Choosing a random number, where Units_in_Fleet is the maximal number to use
Random_Number_2 = GameRandom(1,Units_in_Fleet)
end
-- Calling the thread, to move the spawned ship to a random unit in the fleet:
Moving_To_Fleet_Thread = Create_Thread("Moving_To_Fleet")
-- Waiting a bit to prevent timing issues
Sleep (1.0)
-- Selecting a single Unit
Object.Get_Owner().Select_Object(My_Unit)
-- Moving it to a random ship in the Main Fleet (I left both to be global variables so they're accessible)
My_Unit.Move_To(Main_Fleetcolor=#ff6600]Random_Number_2[/color)
-- Calling the thread, to move the spawned ship to a random unit in the fleet:
Moving_To_Fleet_Thread = Create_Thread("Moving_To_Fleet")
local My_Squadron = Find_First_Object("Squadron_Name")
-- For all units in Spawned_Squadron do
for each,Unit in pairs(My_Squadron) do
-- If exist move each unit to the position of a random unit unit in our Main Fleet
if TestValid(Unit) then
-- The purpose of this and the function before is to send the squad to main fleet.
Unit.Move_To(Main_Fleet[Random_Number_2])
end
end
function Attack_Nearest_Enemy ()
-- First getting Owner of the Object and then his enemy player
local enemy_player = Object.Get_Owner().Get_Enemy()
-- (Re)Searching for all ships
local Bigger_Units = Find_All_Objects_Of_Type("Transport | Corvette | Frigate | Capital")
-- For all bigger Units, do
for each, Unit in pairs(Bigger_Units) do
if TestValid(Unit) then
-- Finding the nearest spaceship unit of the enemy player
Closest_Enemy = Find_Nearest(Unit, enemy_player, true)
end
end
end
Attack_Nearest_Enemy_Thread = Create_Thread("Attack_Nearest_Enemy")
-- Waiting until the unit is ready to move away
Sleep (1.0)
-- Sending the Object to attack this unit from the thread
Object.Attack_Move(Closest_Enemy)
Bitte Anmelden um der Konversation beizutreten.
Of course it will be compiled. You just don't need to do it manually:pImperial schrieb: LUA doesn't need to be compiled, which is a great advantage.
And what aboutImperial schrieb: . Calls a function, you need to have one variable or object in front of the. dot and the function you want to call after the .dot, so variable.function() = variable call function()
function TalkToMe()
alist = {word1 = "hello", word2 = "how", word3 = "are", word4 = "you"}
return alist.word1
end
Two dots aren't counting anything; it's just the expression for concatenating strings.Imperial schrieb: .. Two dots are counting variables. If two..dots are between 2 variables lua will interpret them like a , sign.
1..2 = 12
You should probably mention how to get those scripts. Since using the meg extractor isn't very helpful because most of the scripts are compiled you'll need to install the map editor in order for the vanilla scripts to pop up in your mods/source folder.Imperial schrieb: The two directories of the vanilla game for scripts are:
.\LucasArts\Star Wars Empire at War\GameData\Data\SCRIPTS
.\LucasArts\Star Wars Empire at War Forces of Corruption\Data\SCRIPTS
Oooor: OnExit. But agreed, one barely uses that.Imperial schrieb: What is a State?
Its a function that can be executed once (OnEnter) or repeating on each refresh (OnUpdate).
Better: Avoid anything which refers to a map object because the map is not fully loaded at this point.Imperial schrieb: Never write "Find_All_Objects_Of_Type()" into the Definitions function, write it into State_Init or the other states instead, because Definitions function is for variable setup only. And "Find_First_Object()" better avoid as well.
Sure about this? I always thought that it's faster.Imperial schrieb: The Variable ServiceRate defines how fast the "OnUpdate" states will refresh, 0.1 means 1 second and 0.05 is half a second..
A Thread is a special kind of function which can run parallel to other Threads or States.Imperial schrieb: Functions are a lot simpler then states, they are also called "Threads".
Example:
FunctionName()
-- Execute Code Block
endYou can always call a function using
FunctionName_Thread = Create_Thread("FunctionName")And you can run a Function from inside a thread/function.
Want me to scroll forever? Spoiler this! :pImperial schrieb: Here is the list from the everythingeaw forums:
Just because it is driving me crazy to see this wrong over and over again: The past tense of "say" is "said" :pImperial schrieb: As I just sayed:
It is very obvious or you misunderstand how that works;)Imperial schrieb: Most coders use "for k, Name in pairs .." and other single letters.
I don't like this because if you view your script 1 year later, you have no idea what the letter k stands for.
Better use variables that exactly describes what it is good for.
Bitte Anmelden um der Konversation beizutreten.
Yeah, I had this already for about 3 months on my todo list and always evaded it by now because I knew it will be pretty much. I was in a productive mood so it took "only" 2 days from the first line until everything was online. At the end of the day my fingers literally burnedWow, looks as if someone got too much free time:p
No, this tutorial is free for discussion. First of all thank you for taking the time to read this.Locutus schrieb: Feel free to delete this comment after reading if you want to keep this tutorial clean, I just thought it couldn't hurt to give a little input.
Im so grateful for that. Its soo painful to always have to compile before you can test.Of course it will be compiled. You just don't need to do it manually:p
Wtf I ran yesterday the whole tutorial throughJust because it is driving me crazy to see this wrong over and over again: The past tense of "say" is "said" :p
Also, its "their" not "theyr"
At least in one of my tests I had 0.05 and the Icon of a unit teleported at a certain speed, then I deleted the ServiceRate variable from the definitions but ingame nothing seemd to change.. ergo the default rate is whether 0.05 or it somehow stored my last value of ServiceRate somehow ingame (which is unlikely).Locutus schrieb:
Sure about this? I always thought that it's faster.Imperial schrieb: The Variable ServiceRate defines how fast the "OnUpdate" states will refresh, 0.1 means 1 second and 0.05 is half a second..
Yeah from the point of view of a experienced scripter it is damn obvious, but when I was about to do my first script I had serious trouble to get a single table based for statement working because I had no idea what all these damn single letters stand for.It is very obvious or you misunderstand how that works;)
You can name them whatever you want because well ... it is just darn obvious^^ (My opinion at least)
Bitte Anmelden um der Konversation beizutreten.
--======= Auto Assigning Abilities, you'll never have to bother with this again! =======
-- Note: ALLWAYS put the left ability of your unit at the beginning in 1st position of this list, or the abilities will be twisted and it wont work!
Abilities = {"WEAKEN_ENEMY", "HARMONIC_BOMB", "CLUSTER_BOMB", "POWER_TO_WEAPONS", "TURBO", "STEALTH", "DEFEND", "INVULNERABILITY",
"HUNT", "SPOILER_LOCK", "SELF_DESTRUCT", "BLAST", "BARRAGE", "ROCKET_ATTACK", "DEPLOY_SQUAD", "ENERGY_WEAPON",
"SHIELD_FLARE", "FULL_SALVO", "LUCKY_SHOT", "ION_CANNON_SHOT", "SUPER_LASER", "CONCENTRATE_FIRE", "CAPTURE_VEHICLE", "EJECT_VEHICLE_THIEF", "FOW_REVEAL_PING",
"SENSOR_JAMMING", "CORRUPT_SYSTEMS", "LEECH_SHIELDS", "DRAIN_LIFE", "LURE", "FORCE_LIGHTNING", "MISSILE_SHIELD", "AREA_EFFECT_STUN", "SPRINT"}
-- We cycle through all abilities in this list and assign the latest one that matches a ability of the Ship to ability_2
for each,String_Name in pairs(Abilities) do
-- If this unit has one of these abilities, it will be assigned as primary ability:
if Object.Has_Ability(String_Name) then
ability_2 = String_Name
end
end
ability_1 = false
-- Then we cycle again through the list and assign the other matching ability, which must NOT be ability_2:
for each,String_Name in pairs(Abilities) do
-- If this unit has one of these abilities, it will be assigned as primary ability:
if Object.Has_Ability(String_Name) and ability_2 ~= String_Name then
ability_1 = String_Name
end
end
-- If the unit has only 1 ability, ability 1 wont be assigned, so we'll take ability_2:
if ability_1 == false then
ability_1 = ability_2
end
-- Instead of these 2 loops above you can use the regular way: simply assign 2 abilities: ability_1 = "Name_1" and ability_2 = "Name_2"
-- ability_1 = "Name"
-- ability_2 = "Name"
Bitte Anmelden um der Konversation beizutreten.
-- Replace "Idle" with name of Animation, don't name it like "Idle_00", works without numbers in the name.
-- The second parameter repeads this animation in a loop if set to true
.Play_Animation("Idle", false, 0)
You'll probably need the idle, move and attack animation for their original purposes, so you can always take build, land and similar for your own animations. It doesent matter which one you take, and you dont need to write the names CAPITAL or with NAME_00 numbers. It only matters that you take a name of a existing animation.Idle
Movestart
Attack
Attackidle
Move
Walkmove
Build
Land
Take_off
Deploy
Undeploy
Celebrate
Crouchattack
Crouchidle
Crouchmove
Bitte Anmelden um der Konversation beizutreten.