I'm a newbie using LUA to make missions in
Operation Flashpoint: Dragon Rising's mission editor. I've been trying to get the script down for about a week, I've googled, edited, and scoured the help index of the editor till it feels like my eyes are bleeding and it's all led to this.
I'm having an issue with this "if...then" statement not doing anything. First, here's the whole thing:
function onMissionStart()
OFP:showLetterBoxOsd(false);
OFP:allowPlayerMovement(true);
OFP:allowPlayerFire(true);
OFP:setObjectiveState("Wave1","IN_PROGRESS");
OFP:setObjectiveState("Wave2","IN_PROGRESS");
OFP:activateEntitySet("enemy1");
end --This all seems to work fine, nothing to see here.
--OFP:isAlive(name of unit or entity set)
function isAlive() --After naming this function, a pesky "'<name>' expected near 'if'" error dissapeared so thats nice.
if OFP:isAlive("enemy1") == (false) --This "if..Then" statement should spawn "enemy2" when "enemy1" dies.
then
OFP:activateEntitySet("enemy2");
end
if OFP:isAlive("enemy2") == (false)
then
OFP:setObjectiveState("Wave2","COMPLETED")
OFP:missionCompleted()
end
end
Now here's what's giving me trouble:
function isAlive()
if OFP:isAlive("enemy1") == (false)
then
OFP:activateEntitySet("enemy2");
end
This is supposed to spawn enemy2 when enemy1 dies, but in game it might as well not exist, it doesn't work.
This names my function, the next line was throwing '<name>' expected near if until I did.
function isAlive()
This should track whether enemy1 is still alive, and if it returns a false it should spawn enemy2.
if OFP:isAlive("enemy1") == (false)
then
OFP:activateEntitySet("enemy2");
end
function onMissionStart ist most likely a function the game calls when the mission starts. I could not find any official reference manual but the game seems to have some event based scripting system.
The remaining code you provided probably only executed when the file is loaded and therefor without any effect during the game.
Edit due to comment:
function onMissionStart()
OFP:showLetterBoxOsd(false);
OFP:allowPlayerMovement(true);
OFP:allowPlayerFire(true);
OFP:setObjectiveState("Wave1","IN_PROGRESS");
OFP:setObjectiveState("Wave2","IN_PROGRESS");
OFP:activateEntitySet("enemy1");
end --This all seems to work fine, nothing to see here.
The above code defines the function onMissionStart(). It most likely implements a function that is called by the game, when the mission starts.
You added the following code if I'm not mistaken:
--OFP:isAlive(name of unit or entity set)
function isAlive() --After naming this function, a pesky "'<name>' expected near 'if'" error dissapeared so thats nice.
if OFP:isAlive("enemy1") == (false) --This "if..Then" statement should spawn "enemy2" when "enemy1" dies.
then
OFP:activateEntitySet("enemy2");
end
if OFP:isAlive("enemy2") == (false)
then
OFP:setObjectiveState("Wave2","COMPLETED")
OFP:missionCompleted()
end
end
This also defines a function. isAlive. But who calls that function and when?
I found a list of events in DROPP. I presume that's the mission editor thing you're talking about. On certain events it will run certain functions. Like onAllplayersDead() would be called if all players are dead.
Explaining this all would be beyond the scope of this community. Just read through all of http://www.suderman.com/OFPDR/DROPP/reference.html and all files in http://www.suderman.com/OFPDR/DROPP/download.html
EventScripts = {
onAllPlayersDead = 0,
onArriveAtWaypoint = 0,
onCmdCompleted = 0,
onDeath = 0,
onDespawnEntitySet = 0,
onDespawnEntity = 0,
onDismount = 0,
onEnter = 0,
onEnterRVPoint = 0,
onFirepowerKill = 0,
onHit = 0,
onIdentified = 0,
onIncap = 0,
onLand = 0,
onLeave = 0,
onMissionStart = 0,
onMobilityKill = 0,
onMount = 0,
onMultiplayerMissionLoaded = 0,
onNoAmmo = 0,
onNoAmmoAll = 0,
onObjectDamage = 0,
onObjectDamage = 0,
onObjectiveCompleted = 0,
onObjectiveFailed = 0,
onObjectiveVisible = 0,
onOffboardSupp = 0,
onPinned = 0,
onPlaceableKill = 0,
onPlayEnter = 0,
onPlayDone = 0,
onPlayFailed = 0,
onPlayInvalid = 0,
onPvPMissionEnd = 0,
onRespawn = 0,
onSpawnedReady = 0,
onSpeechEnd = 0,
onSuppressed = 0,
onSuspected = 0,
onUnsuppressed = 0,
}
Related
So I am testing an idea to make a script that tweens upon calling a function and passing in items, and I keep getting the error that says "TweenInfo.new first argument excepts a number for time" even though I am passing in a number. Here's my code (also the wait is so it doesn't dissapear before I can see it.:
wait(5)
local TweenPartMove = function(Part, Time, EasingStyle, EasingDirection, TimesToRepeat, IfReverse, DelayPerTween, GoalsXCoords, GoalsYCoords, GoalsZCoords)
local TweeningInfo = TweenInfo.new{
Time,
EasingStyle,
EasingDirection,
TimesToRepeat,
IfReverse,
DelayPerTween
}
local TweenGoals = {
CFrame = Part.CFrame + Vector3.new(GoalsXCoords, GoalsYCoords, GoalsZCoords)
}
TweenService:Create(Part, TweeningInfo, TweenGoals):Play()
end
TweenPartMove(script.Parent, 3, Enum.EasingStyle.Bounce, Enum.EasingDirection.Out, 0, false, 0, 53, 0, 0)
Hi so i recently decoded some game scripts written in lua. But it looks like this
My code looks like this
PlayerTable = { JOGO = 0, BALANCE = 0, BALANCE_P = 0, PROFIT = 0, XXX = 0, XXX_Count = 0, XXX_Player = 0, AH, AL, NUM, LOSETOP = { Times = 0, Money = 0, Name }, WINTOP = { Times = 0, Money = 0, Name } } end if PlayerTable.JOGO == Games.NULL then if 0 < PlayerTable.BALANCE then if table.contains(words.H, Message) then PlayerTable.JOGO = Games.HIGH if HL_ENABLED then Last_Payout = os.time() MinOption = BetOption[PlayerTable.JOGO].Min MaxOption = BetOption[PlayerTable.JOGO].Max PayoutOption = BetOption[PlayerTable.JOGO].Payout else if not table.contains(LimitSay.DISABLED, name) then Self.Say(Disabled_G[PlayerTable.JOGO]) table.insert(LimitSay.DISABLED, name) end PlayerTable.JOGO = Games.NULL end elseif table.contains(words.L, Message) then PlayerTable.JOGO = Games.LOW if HL_ENABLED then
I know there are HTML, JS etc. beautifiers so Is there any tool i can use to beautify this code ?
Or do i need to do it manually ? Its almost 2000 lines of code so i would rather not to do this manually.
You could use ZeroBrane. Basically select the code and then Edit-> Source -> Correct Indentation
Thanks to this great community, I managed to make a save system for my game! However, it is kind of long and painful to write. I need help on how to (if possible) make this a little bit shorter and easier.
So, this is what I got (this example uses ONLY 1 variable to get the idea):
GameState = loadsave.loadTable("GameState.json")
if GameState == nil then
GameState = {
TotalPixoosGS = 0,
}
loadsave.saveTable(GameState, "GameState.json")
end
TotalPixoos = GameState.TotalPixoosGS
Let me quickly explain what I got here: GameState = loadsave.loadTable("GameState.json") is declaration of a table from .json file. I used .loadTable function which I got from here:
https://code.coronalabs.com/code/easy-saveload-table-data-corona-sdk
if GameState == nil then
GameState = {
TotalPixoosGS = 0,
}
If the file doesn't exist, it simply creates default game settings, in this case sets TotalPixoosGS variable to value of 0.
loadsave.saveTable(GameState, "GameState.json")
Again a function from the link above which simply creates .json file from GameState table, calls it GameState.json.
TotalPixoos = GameState.TotalPixoosGS
Finally, assigns the value of GameState.TotalPixoosGS to our variable TotalPixoos (if GameState.json doesn't exist, it will assign the value of 0). So far, pretty straight-forward, right?
Now, this code was called upon OPENING the application.
The following code is what I use upon EXITING application:
if ( event.type == "applicationExit" ) then
GameState = {
TotalPixoosGS = TotalPixoos,
}
loadsave.saveTable(GameState, "GameState.json")
end
Basically, what this does is: When the app is about to exit, you simply change the value of TotalPixoosGS to our current value of TotalPixoos (that is the variable which changes over time). Finally, we save the GameState table with the new, changed TotalPixoosGS.
Once the app launches again, the process will repeat.
Now, what is the problem? Well, when you have 1 variable, like in this case, it looks simple. However, when you gotta manage over 50 variables, it can be a pain to write. Is there any way I could shorten this?
Anyway, this is just a small chunk of code, to get the idea:
GameState = loadsave.loadTable("GameState.json")
if GameState == nil then
GameState = {
TotalPixoosGS = 0,
PixoosQuantityGS = 0,
PixoosPerSecondGS = 0,
BottlesQuantityGS = 0,
MaxBottlesFoundGS = 0,
BottlesPriceGS = 0.005,
WillFindBottlesChanceGS = 10,
CanFindBottlesGS = 0,
MaxClickableGS = 5,
MaxTrashCanValueGS = 5,
}
loadsave.saveTable(GameState, "GameState.json")
end
TotalPixoos = GameState.TotalPixoosGS
PixoosQuantity = GameState.PixoosQuantityGS
PixoosPerSecond = GameState.PixoosPerSecondGS
BottlesQuantity = GameState.BottlesQuantityGS
MaxBottlesFound = GameState.MaxBottlesFoundGS
BottlesPrice = GameState.BottlesPriceGS
WillFindBottlesChance = GameState.WillFindBottlesChanceGS
CanFindBottles = GameState.CanFindBottlesGS
MaxClickable = GameState.MaxClickableGS
MaxTrashCanValue = GameState.MaxTrashCanValueGS
See how much of ugly code there is? And this is upon exit:
if ( event.type == "applicationExit" ) then
GameState = {
TotalPixoosGS = TotalPixoos,
PixoosQuantityGS = PixoosQuantity,
PixoosPerSecondGS = PixoosPerSecond,
BottlesQuantityGS = BottlesQuantity,
MaxBottlesFoundGS = MaxBottlesFound,
BottlesPriceGS = BottlesPrice,
WillFindBottlesChanceGS = WillFindBottlesChance,
CanFindBottlesGS = CanFindBottles,
MaxClickableGS = MaxClickable,
MaxTrashCanValueGS = MaxTrashCanValue,
}
loadsave.saveTable(GameState, "GameState.json")
end
Anyone with a better way, or idea on how to deal with this?
The problem here is that you are storing the data in independent global variables that you need to store in the table to save and then fetch from the table to load.
You can avoid needing to do all of that if you just use the table itself as the global variable in your general code.
So instead of writing code that uses TotalPixoosGS or PixoosQuantityGS when checking the values/etc. you write code that uses GameState.TotalPixoosGS and GameState.PixoosQuantityGS instead and then just save and load directly from/to the global GameState table.
Im learning to code lua and believe I have come quite far and recently picked up the LOVE2D engine. Ive decided to try some OOP to sort out my coding however all efforts seem to fail with the error
main.lua:31: Attempt to call field "Draw"(nil value)
function love.load()
Unicorn = {
name = "Default",
breedname = "Default Class of a unicorn",
description = "Quite a default Unicorn",
imgclass = love.graphics.newImage("UnicornA.gif"),
x = 20,
y = 20,
height = 0,
width= 0,
age = 0,
maxage = 20,
health = 100
}
function Unicorn.Draw(self)
love.graphics.draw(self.imgclass, self.x, self.y)
end
function Unicorn:new(o)
o = o or {}
setmetatable(o, self)
self._index = self
return o
end
alfred = Unicorn:new()
alfred.x = 50
harry = Unicorn:new()
end
function love.draw()
love.graphics.print("Unicorn Farm Simulator 2014", 0, 0)
alfred.Draw(alfred)
harry.Draw(harry)
end
To clear things up love.draw is a callback and so is love.load. I am creating the class Unicorn with a Draw function and a New function, the new function creates an Instantation of the Class ( Am i right with that vocabulary?)
Sorry about using full capital acronym for the language, I just presumed it stood for something!
Make self._index = self to self.__index = self, because _index is nonsense here.
You could read more about OO in Lua in this answer I have made.
Bonus:
Make Unicorn.Draw(self) to Unicorn:Draw(), to get rid of self. And use it in this way
alfred:Draw()
harry:Draw()
Use local as possible as it can be. Because local is faster and friendly to memory usage.
I'm trying to create a Lua table that represents a matrix, however I keep running into a problem where if I create two Matrices, and initialize some values they both have the same values.
--Test.Lua
require"Matrix"
M1 = Matrix.Matrix:New()
M2 = Matrix.Matrix:New()
M1._11 = 2
print(M1._11) --Prints 2
print(M2._11) --Prints 2
--Matrix.lua
module("Matrix", package.seeall)
Matrix = {}
Matrix = { _11 = 0, _12 = 0, _13 = 0,
_21 = 0, _22 = 0, _23 = 0,
_31 = 0, _32 = 0, _33 = 0
}
function Matrix:New()
object = object or {}
setmetatable(object, self)
self.__index = self
return object
end
object = object or {}
This is why that happens. You only ever create one Matrix object. There is only every one object table which you return, and there is only ever one self table that you use as a metatable.
So how can you expect different instances when Matrix:New will always return the exact same value on every call?
You need to return a new table for each New call; that's why we use that name ;) Because of the way you're using a metatable, you also have to return a new metatable; you can't return the same metatable attached to new tables and expect it to work.
As nicol is explaining, on one hand you are trying to "reuse the same object over and over" (probably to "make it faster") and on the other you want to have different objects.
The solution is - don't reuse object on New call.
local Matrix = {} -- don't use the module function. Make Matrix local ...
Matrix.__index = Matrix
function Matrix:New()
local object = { -- create one local variable on every call to New
_11 = 0, _12 = 0, _13 = 0,
_21 = 0, _22 = 0, _23 = 0,
_31 = 0, _32 = 0, _33 = 0
}
setmetatable(object, self)
return object
end
return Matrix -- ... and return the Matrix local var at the end
A couple notes:
You really must learn how to use local
Usage of the module function is not recommended. Return a local table instead, as in my example.
Usage: assuming that that file is called "Matrix.lua":
local Matrix = require 'Matrix'
local M1 = Matrix:New()
local M2 = Matrix:New()
-- etc
As a sidenote, the Matrix:New() function can be made shorter (and faster). The following implementation works exactly as the one above, but it's slightly more efficient:
function Matrix:New()
return setmetatable({
_11 = 0, _12 = 0, _13 = 0,
_21 = 0, _22 = 0, _23 = 0,
_31 = 0, _32 = 0, _33 = 0
},
self)
end
This works because setmetatable(t,m) returns t with m already set as its metatable.