View unanswered posts | View active topics It is currently Mon Oct 14, 2019 7:33 pm



Reply to topic  [ 3 posts ] 
 Check a function, wait, then do something 
Author Message
User avatar

Joined: Fri Jan 26, 2007 8:27 pm
Posts: 40
Location: England
Reply with quote
Post 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 :P

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 :P

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?


Tue Jul 05, 2011 11:40 pm
Profile
REAL AMERICAN HERO
User avatar

Joined: Sat Jan 27, 2007 10:25 pm
Posts: 5655
Reply with quote
Post 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.


Wed Jul 06, 2011 12:31 am
Profile
User avatar

Joined: Fri Jan 26, 2007 8:27 pm
Posts: 40
Location: England
Reply with quote
Post 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.


Wed Jul 06, 2011 4:13 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 3 posts ] 

Who is online

Users browsing this forum: No registered users


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by STSoftware for PTF.
[ Time : 0.017s | 13 Queries | GZIP : Off ]