Flexman Posted September 3, 2010 Share Posted September 3, 2010 I've been having a little problem with spawning helicopter entities and the LUA for these helicopters. I'll try and relate what happens here as best I can in case one of you much smarter folks can spot anything. This is a BMax to LUA problem I think. Description of problem Apache helicopters use LUA to load the rotor model, control lights, door animations, animate rotors. All spawned Apaches process the update loop correctly. You can use as an example: PlayerVehicle.SetKey("rotorspeed","4.5") to set the rotors turn at 4.5 degrees every update. It works fine. Problem comes with READING values though GetKey(). It will only work for entities loaded via LoadScene(), which is the first Apache. The Apache is copied, dressed with other data and loaded munitions in BMax, then the original is dumped. All spawned entities after that are created using CopyEntity() and CopyKeys(). while SetKey() works on these, GetKey() will always return an empty string. Even putting a Print("HEY GETKEY HAS BEEN CALLED") after the function isn't processed on these kinds of spawned entities. From what I understand, LoadModel() loads the LUA and must do some magic to ties that instance of the entity to the LUA state. But this isn't happening with CopyEntity()? Given that SetKey() works on these entities but GetKey() does not for copied entities, even when it's a simple Print() statement, what is going on here do you think? Quote 6600 2.4G / GTX 460 280.26 / 4GB Windows 7 Author: GROME Terrain Modeling for Unity, UDK, Ogre3D from PackT Tricubic Studios Ltd. ~ Combat Helo Link to comment Share on other sites More sharing options...
macklebee Posted September 4, 2010 Share Posted September 4, 2010 I think I must be missing something from what you are trying to do, Flexman, because I can use GetKeys on a copied entity and get all of its keys. I must be missing something from what you are trying to do... Framework leadwerks.engine Import "c:\program files\leadwerks engine sdk 2.31\bmx\framework\framework.bmx" Include "lua-gluefunctions.bmx" GCSetMode(2) RegisterAbstractPath ("c:\program files\leadwerks engine sdk 2.31") Graphics(800, 600) Global fw:TFramework = CreateFramework() If Not fw RuntimeError "Failed to initialize engine." SetScriptObject("fw", fw) MoveEntity(fw.Main.camera, Vec3(1.5, 0, - 2)) Global model:TEntity = LoadModel("abstract::environment_corona.gmf") Global modelcopy:TEntity[3] Global count:Int = 0 HideMouse() Repeat If KeyHit(KEY_ESCAPE) Exit If AppTerminate() Exit fw.Update() fw.Render() If KeyHit(KEY_SPACE) And count < 3 modelcopy[count] = CopyEntity(model, 1) CopyEntityKeys(model, modelcopy[count]) PositionEntity(modelcopy[count], Vec3(1 + count, 0, 0), 1) FreeEntity(model) model = modelcopy[count] count = count + 1 GCCollect() End If GetAllCopiedKeys(model) Flip(0) Forever GCCollect() End Function GetAllCopiedKeys(entity:TEntity) SetBlend(1) Local i:Int = 0 Local mcpos:TVec3 = CameraUnproject(fw.Main.camera, EntityPosition(entity, 1)) For key:String = EachIn entity.keys.keys() i = i + 20 DrawText(key + ": " + GetEntityKey(entity, key), mcpos.x, mcpos.y + i) Next SetBlend(0) End Function Function SetScriptObject(name:String, o:Object) Local size:Int=GetStackSize() lua_pushbmaxobject(luastate.L, o) lua_setglobal(luastate.L,name) SetStackSize(size) EndFunction Function GetStackSize:Int() Return lua_gettop(luastate.L) EndFunction Function SetStackSize(size:Int) Local currentsize:Int=GetStackSize() If size<currentsize lua_pop(luastate.L,currentsize-size) EndIf EndFunction Quote Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590 LE / 3DWS / BMX / Hexagon macklebee's channel Link to comment Share on other sites More sharing options...
Flexman Posted September 4, 2010 Author Share Posted September 4, 2010 Thanks for looking Mac. All I really want for now is to be able to find "rotor_limb_1" from BMax on a model named "rotor_mast.gmf" loaded in the Apache LUA script and parented to the Apache model. But GetKey() not working is very strange. It must be something I've cocked up somewhere. I'll try to explain what's going on. I use LoadScene() and starting Apache aircraft are placed on the map as needed. During a ProcessScene() function, bit of a relic but handy, I replace these Apache entities with a new one. e is the current entity ' CONSTRUCT A PLAYER FRIENDLY APACHE LONGBOW ENTITY' If(vh = "AH64D") Then vh = "" CreateApacheEntity(EntityPosition(e), EntityRotation(e), e) FreeEntity(e) ; GCCollect() done = 0; Exit; End If And here's CreateApacheEntity() Function CreateApacheEntity(loc:TVec3 = Null, rot:TVec3 = Null, srcent:TEntity = Null) Local helo:THelicopter = New THelicopter; Local idString:String idString = String("LONGBOW00" + game.HelicopterCount) helo.Load3DModels(srcent) ; If Not helo.entity AppLog(" *** CreateApacheEntity:NO ENTITY:") Else ' COPY KEYS FROM EDITOR OR SOURCE AS NECESSARY' If srcent Then CopyEntityKeys(srcent, helo.entity) ; helo.entity.SetKey("fcr", GetEntityKey(srcent, "fcr", "1").ToString()) helo.entity.SetKey("rotorspeed", GetEntityKey(srcent, "rotorspeed", "0").ToString()) helo.entity.SetKey("stabpos", GetEntityKey(srcent, "stabpos", "0").ToString()) End If End If AppLog(" *** CreateApacheEntity:Crewcount:" + GetEntityKey( helo.entity,"crewcount") + " *** ") ; AppLog(" *** CreateApacheEntity:Crewslotname:" + helo.entity.GetKey("slotname_1") + " *** ") ; ' IN LUA, SLOTS ARE INDEXED FROM 1, IN BMAX THEY ARE INDEXED FROM ZERO' helo.PlayerSlots = Int(helo.entity.GetKey("crewcount", 0)) helo.CrewSlot = New TVehicleSlots[helo.PlayerSlots] ; For Local n:Int = 0 To helo.PlayerSlots - 1 helo.CrewSlot[n] = New TVehicleSlots helo.CrewSlot[n].Pos = New TVec3 AppLog(" *** Crewslotname: " + helo.entity.GetKey("slotname_" + String(n + 1), "") + " *** ") ; helo.CrewSlot[n].name = String(helo.entity.GetKey("slotname_" + String(n + 1), "slotname_" + (n + 1))) helo.CrewSlot[n].Pos = StringToVec3(helo.entity.GetKey("crewslot_" + String(n + 1), "0,0,0")) Next AppLog(helo.PlayerSlots + " CrewSlots Initialised") helo.idString = idString helo.childTADSpieExternal = helo.entity.FindChild("tads_pie") If loc <> Null PositionEntity(helo.body, loc) ; RotateEntity(helo.body, rot) ; Else PositionEntity(helo.body, game.scene.campos) ; RotateEntity(helo.body, Vec3(0)) ; End If SetEntityCallback(helo.entity, helo.MessageReceiveCallback, ENTITYCALLBACK_MESSAGERECEIVE) ; game.AddHelo(idString, helo) ; SetEntityKey(helo.entity, "vehicle", VEHICLE_KEY_APACHE_LONGBOW) ; SetEntityKey(helo.entity, "action", ACTION_MOUNT) ; SetEntityKey(helo.entity, "guid", idString) ; DebugLog(" CreateApacheEntity :" + idString) ; helo.SoundIdle = LoadSound("abstract::AH64CompressorIn.ogg") ; helo.SourceIdle = CreateSource(helo.SoundIdle, SOURCE_EAX | (SOURCE_LOOP)) ; SetSourcePosition(helo.SourceIdle, EntityPosition(helo.body)) ; helo.SoundRotors = LoadSound("abstract::apache_noise_internal.ogg") ; helo.SourceRotors = CreateSource(helo.SoundRotors, SOURCE_EAX | (SOURCE_LOOP)) ; SetSourcePosition(helo.SourceRotors, EntityPosition(helo.entity)) ; SetSourceVolume(helo.SourceIdle, 0.0) ; SetSourceRange(helo.SourceIdle, 60.0) ; SetSourceVolume(helo.SourceRotors, 0.0) ; SetSourceRange(helo.SourceRotors, 60.0) ; PlaySource(helo.SourceIdle) ; PlaySource(helo.SourceRotors) ; End Function The final part is the Load3DModels function...which is called early in CreateApacheEntity() Here I tried all manner of CopyEntity() etc. And I've since changed it back to what it was originally, which results in the same behavior. GetKey() not working. Maybe there's a LUA issue not being picked up. Method Load3DModels(srcEntity:TEntity) Self.model = LoadModel("abstract::aircraft_helicopter_ah64d.gmf") ; Self.entity = Self.model Self.body = TBody(Self.model) ; Self.entity.Show() Self.body.SetCollisionType(3, 1) ; Self.ViewPivot.SetParent(Self.entity) ; ' STORES - WEAPONS PODS' Self.Stores.Initialise(TModel(Self.model)) ; Self.Stores.SetPylon(1, PYLON_HELLFIRE) ; Self.Stores.SetPylon(2, PYLON_HELLFIRE) ; Self.Stores.SetPylon(0, PYLON_ROCKET) ; Self.Stores.SetPylon(3, PYLON_ROCKET) ; End Method Quote 6600 2.4G / GTX 460 280.26 / 4GB Windows 7 Author: GROME Terrain Modeling for Unity, UDK, Ogre3D from PackT Tricubic Studios Ltd. ~ Combat Helo Link to comment Share on other sites More sharing options...
macklebee Posted September 4, 2010 Share Posted September 4, 2010 I trimmed down your code and converted it to something I could try to reproduce, but as you can see its basically your code. I still get the keys from the copied entity using getkeys... which makes me think that maybe its an issue with the script? Framework leadwerks.engine Import "c:\program files\leadwerks engine sdk\bmx\framework\framework.bmx" Include "lua-gluefunctions.bmx" GCSetMode(2) RegisterAbstractPath ("c:\program files\leadwerks engine sdk") Graphics(800, 600) Global fw:TFramework = CreateFramework() If Not fw RuntimeError "Failed to initialize engine." SetScriptObject("fw", fw) MoveEntity(fw.Main.camera, Vec3(1.5, 0, - 2)) Global light:TLight = CreateDirectionalLight() RotateEntity(light, Vec3(45, 45, 45), 1) Global e:TModel = LoadModel("abstract::environment_corona.gmf") Global done:Int = 0 HideMouse() Repeat If KeyHit(KEY_ESCAPE) Exit If AppTerminate() Exit fw.Update() fw.Render() If KeyHit(KEY_SPACE) If done = 0 done = 1 CreateApacheEntity(EntityPosition(e), EntityRotation(e), e) FreeEntity(e) GCCollect() End If End If Flip(0) Forever GCCollect() End Function CreateApacheEntity(loc:TVec3 = Null, rot:TVec3 = Null, srcent:TEntity = Null) Local helo:THelicopter = New THelicopter helo.Load3DModels(srcent) PositionEntity(helo.entity, Vec3(2, 0, 0), 1) If Not helo.entity AppLog(" *** CreateApacheEntity:NO ENTITY:") Else If srcent Then CopyEntityKeys(srcent, helo.entity) helo.entity.SetKey("fcr", GetEntityKey(srcent, "fcr", "1").ToString()) End If End If AppLog(" *** CreateApacheEntity:FCR:" + GetEntityKey(helo.entity, "fcr") + " *** ") AppLog(" *** CreateApacheEntity:Material:" + GetEntityKey(helo.entity, "material") + " *** ") AppLog(" *** CreateApacheEntity:Radius:" + helo.entity.GetKey("radius") + " *** ") End Function Type THelicopter Field model:TModel Field entity:TEntity Method Load3DModels(srcEntity:TEntity) 'Self.model = LoadModel("abstract::environment_corona.gmf")' Self.model = LoadModel("abstract::firepit.gmf") Self.entity = Self.model End Method End Type Function SetScriptObject(name:String, o:Object) Local size:Int = GetStackSize() lua_pushbmaxobject(luastate.L, o) lua_setglobal(luastate.L, name) SetStackSize(size) EndFunction Function GetStackSize:Int() Return lua_gettop(luastate.L) EndFunction Function SetStackSize(size:Int) Local currentsize:Int = GetStackSize() If size < currentsize lua_pop(luastate.L, currentsize - size) EndIf EndFunction EDIT---i take it back... if you run this code, you will see that it doesn't get the value for the material... it gets the radius from GetKey and it gets the FCR value from SetKey... but not the material.... hmmm... Quote Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590 LE / 3DWS / BMX / Hexagon macklebee's channel Link to comment Share on other sites More sharing options...
macklebee Posted September 4, 2010 Share Posted September 4, 2010 Ok it looks like CopyEntityKeys() doesn't overwrite existing keys, but it will write keys to an entity if it doesn't have that key... like the corona's radius is being written to the firepit. But since a material key exists already for the firepit, it will not overwrite it. But it looks like you can use SetKeys to overwrite the copied entity' keys. I guess it depends on how much the lua script is really controlling and whether or not the original entity is the exact same entity as the copied entity or is it just a placeholder for keys? I am assuming its just a placeholder for the keys since you are loading the AH64D model instead of actually just doing a CopyEntity(). I also notice when I do a CopyEntity() instead of a LoadModel() then then it appears to work just fine and I don't need to use a CopyEntityKeys()... Quote Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590 LE / 3DWS / BMX / Hexagon macklebee's channel Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.