Post new topic    
Liquid Metal Slime
Send private message
How to realign NPC with tile grid after script completes? 
 PostThu Dec 18, 2014 6:23 am
Send private message Reply with quote
I have my line of sight script up and running which makes the guards chase my hero when they see him in their cone of vision. I have a timer running at the same time which tells the guards to essentially "get tired and stop pursuing the hero." The problem is that this timer can reach it's countdown when the NPCs are in between tiles which makes them freeze up momentarily and act funny. I know I've seen a way to realign character after scripts but I can't find it for the life of me. Could someone point me towards it?

Also I don't want my NPCs suddenly jutting abruptly to the nearest tile. Is there any way I can pull this off cleanly?
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
⍠ C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
Metal King Slime
Send private message
 
 PostThu Dec 18, 2014 6:40 am
Send private message Reply with quote
This sounds like a really fun problem to solve. How I'd do it, is have some kind of while loop that checks EVERY NPC, to see if their pixel X and Pixel Y are divisible by 20 (Aka aligned with the grid), find the direction of the ones that aren't and move them slowly, gracefully to the nearest position in front of them (because presumably they'll only be misaligned in one axis) where the numbers are divisible by 20. You could do this by setting their speed to 1 and letting them all sloooowly walk, which could take as many as 19 ticks to resolve, a little more than a second. Or you could do some maths and put npcs to make it take a certain amount of ticks to be just smooth enough.

I don't know that there's a more convenient way to do it, but all the tools to make your own solution are there and those are the best kind of problems.
Liquid Metal Slime
Send private message
 
 PostThu Dec 18, 2014 6:49 am
Send private message Reply with quote
That sounds like a pretty reasonable solution. I think I'll make that my project for tomorrow morning. Thanks.
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
⍠ C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
Liquid Metal King Slime
Send private message
 
 PostThu Dec 18, 2014 7:58 am
Send private message Reply with quote
I feel like coding something random today it seems.
How I'd do it is simple. I have a double for loop run through all the npcs and place them into the nearest tile.

Code:
variable(Anpcid,Anpccount,Anpc)
for (Anpcid,0,100) do,begin
for (Anpccount,0,100) do,begin

anpc:=NPC reference (Anpcid, Anpccount)
set NPC position (anpc, npcpixelx(anpc)/20, npcpixely(anpc)/20)

end, end
Metal King Slime
Send private message
 
 PostThu Dec 18, 2014 9:47 am
Send private message Reply with quote
But that abruptly realigns the guard with the grid, which he was trying to avoid. Also, "NPC reference" returns 0, which is a valid NPC ID, if "Anpccount" is too large. Use "npc copy count" instead.

The way I would solve this problem is simply to not stop an NPC in between tiles, but rather wait until it's already aligned. Since this is triggered by a timer you could simply reset the timer to trigger the script again next tick if the NPC isn't aligned.
Liquid Metal Slime
Send private message
 
 PostThu Dec 18, 2014 9:41 pm
Send private message Reply with quote
In the end I took TMC advice to only stop the guard while the it's x and y pixel is divisible by 20. My code is actually pretty short, it looks like this if anyone was interested:
Code:

while ((npcpixelx(0)/20) && (npcpixely(0)/20)) do(
      Alter NPC (0, NPCstat:move type, NPCmovetype:walkinplace)
      break
      wait(1)
    )


Of course this could be expanded using a for loop to cycle through all the guards.

EDIT:
I just realized I wrote that wrong. What I want to write is something like:
Code:

while (((npcpixelx(0)/20) == true) && ((npcpixely(0)/20) == true)) do(
      Alter NPC (0, NPCstat:move type, NPCmovetype:walkinplace)
      guardResetPhase0 := 8
      break
      wait(1)
    )

But I know my expression is not coded properly like this. How can I say: while (((npcpixelx(0)/20) == integer) && ((npcpixely(0)/20) == integer)) do(

???

That's kind of what it should say I think...

EDIT #2:
Never mind I think I solved my own problem by setting up the expression like this:
Code:

while (((NPC pixel X(0)/20) == NPC X (0)) && ((NPC pixel Y(0)/20) == NPC Y (0))) do(
      Alter NPC (0, NPCstat:move type, NPCmovetype:walkinplace)
      break
      wait(1)
    )   


After some testing with a single NPC it seems fine. Now to upscale this thing!
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
⍠ C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
Liquid Metal Slime
Send private message
 
 PostThu Dec 18, 2014 10:09 pm
Send private message Reply with quote
Just tried it with 4 guards chasing me simultaneously and it works seamlessly. Thanks for idea sharing!
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
⍠ C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
Metal King Slime
Send private message
 
 PostSat Dec 20, 2014 8:38 am
Send private message Reply with quote
Actually, every single code snippet you posted never waits. It doesn't make sense to write "while(...) do (... break ...)" because "break" jumps out of the loop. That means it will never loop, and will never even reach the "wait(1)"

However, I guess that these guard NPCs are set to chase? That explains why you don't have to wait for them to realign before stopping them. Just change their move type immediately (as you are doing), and they will continue whatever movements they're current in the middle of. It's writing "walk npc (npc, south, 0)" that causes an NPC to stop in place. I thought that you were using "walk npc" commands to get an NPC to move multiple tiles. If so, they would complete the whole movement and there's not simple way to get them to move to the next tile and then stop; you would have to wait.


"(NPC pixel X(0)/20) == NPC X (0) && (NPC pixel Y(0)/20) == NPC Y (0)" works. But the way to write this without using NPCX/Y commands is to use "mod" (modulus):
"(NPC pixel X(0)/20), mod, 20 == 0 && (NPC pixel Y(0)/20), mod, 20 == 0"
Display posts from previous: