Data Realms Fan Forums http://45.55.195.193/ |
|
Check a function, wait, then do something http://45.55.195.193/viewtopic.php?f=73&t=24495 |
Page 1 of 1 |
Author: | Entropy [ Tue Jul 05, 2011 11:40 pm ] |
Post subject: | Check a function, wait, then do something |
Greetings fellow modders! So I'm making a proximity fuze for use against dropships. It checks the proximity to targets at a random interval and gibs the warhead if it's within 250 pixels. The random interval makes for a nice scatter effect where shells burst at uneven distances away from dropships, which is what I'm going for. The code: Code: function Create(self) self.fuzeTimer = Timer(); self.fuzeInterval = math.random(100,600); end function Update(self) if self.fuzeTimer:IsPastSimMS(self.fuzeInterval) then for actor in MovableMan.Actors do if actor.ClassName == "ACDropShip" or actor.ClassName == "ACRocket" then local avgx = actor.Pos.X - self.Pos.X; local avgy = actor.Pos.Y - self.Pos.Y; local dist = math.sqrt(avgx ^ 2 + avgy ^ 2); if dist < 250 then self:GibThis(); end end end self.fuzeTimer:Reset(); end end It works, but it's not that random. Shells usually detonate far in front of the dropship they're aimed at. Some do go past, but most of them detonate quite early or they strike the dropship and go off on contact. I want shells to be bursting all around, behind and in front of dropships for that authentic WWII FlaK effect My solution was to check the dropship distance frequently, every 100ms, and then wait a random time before detonating the shell if a dropship is found. In theory it's a brilliant idea, but in practice I have no idea how to wait a random time before executing the next part of a function. The Lua just doesn't work: Code: function Create(self) self.delayTimer = Timer(); self.delayInterval = math.random(0,300); end function Create(self) self.fuzeTimer = Timer(); end function Update(self) if self.fuzeTimer:IsPastSimMS(100) then self.fuzeTimer:Reset(); for actor in MovableMan.Actors do if actor.ClassName == "ACDropShip" or actor.ClassName == "ACRocket" then local avgx = actor.Pos.X - self.Pos.X; local avgy = actor.Pos.Y - self.Pos.Y; local dist = math.sqrt(avgx ^ 2 + avgy ^ 2); if dist < 250 then function Update(self) if self.delayTimer:IsPastSimMS(self.delayInterval) then self:GibThis(); end self.delayTimer:Reset(); end end end end end end Sorry about the excessive number of ends, but CC complained about me not closing functions so I just added more and more until it stopped This code runs without generating errors, but the shells don't detonate at all with this version of the code. What have I done wrong, and what is the correct way of making a function wait for a time before executing? |
Author: | Grif [ Wed Jul 06, 2011 12:31 am ] |
Post subject: | Re: Check a function, wait, then do something |
Okay so let's see here. Now, I'm gonna try to be gentle. 1. SYNTAX SYNTAX SYNTAX. It's not necessary, in terms of your code running, because Lua is EXTREMELY forgiving with whitespace, but for the love of god, IF YOU ADD AN IF, TAB ONCE. It's a simple rule, but lord does it help with the legibility of everything (EVERYTHING) you do. 2. The function Update(self) cannot be called within itself. At all. Ever. 3. You can't put two function Create(self) lines. Well, you can, but why? This: Code: function Create(self) self.delayTimer = Timer(); self.delayInterval = math.random(0,300); end function Create(self) self.fuzeTimer = Timer(); end should never happen. Why not just do this: Code: function Create(self) self.delayTimer = Timer(); self.delayInterval = math.random(0,300); self.fuzeTimer = Timer(); end See how easy that is? So here's code that should work: http://pastebin.com/ZMFhkHMQ Notice some things: 1. I fixed your syntax. Everything is tabbed intelligently; if you open a new logical statement, everything after that gets one additional tab. Then it's extremely easy to make sure you're closing everything: just line it all up. Also, use a good text editor; Notepad++ has extremely useful function collapsing and syntax highlighting. 2. I reorganized your code somewhat. First to get rid of the completely unnecessary function Create/Update lines, which I really don't know why you put in there. In addition, I fixed some logical errors, and improved your distance finding code to use an engine function, which should be marginally faster. I made the distance check run half as fast, because one fifth of a game second is plenty frequent enough. 3. I removed your delay timer. It's not a bad way to approach the problem, but there's honestly an easier one: a coinflip with a somewhat skewed probability. Basically, I added a 33% chance for the round to detonate when it's within range. But that's going to reroll, probably at least twice, depending on exactly how fast your projectiles are traveling. This is a more efficient way to do it in terms of CPU cycles (meaning you can fire a whole hell of a lot of your flak rounds without much lag) and it'll probably work out just about the same. If it's not bursting reliably enough near dropships, then you can try: A: lowering the upper bound on the random. Making it (1,2) will significantly increase the probability. Alternately, just lower the fuzetimer check rate to 150 or 100ms again. |
Author: | Entropy [ Wed Jul 06, 2011 4:13 pm ] |
Post subject: | Re: Check a function, wait, then do something |
Thanks Grif! Your method works so much better. Also, I apologise for butchering the syntax so badly. Without any proper documentation or prior experience of coding it's not easy for me. I mostly work by recycling other code and modifying/splicing parts of it together, refining the result by trial and error. I am gradually gaining an understanding of how it works though. You've pointed out some helpful stuff, so thanks again. |
Page 1 of 1 | All times are UTC [ DST ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |