Solarus Forum

Solarus => Development => Topic started by: Akamatsu on September 09, 2018, 05:05:48 pm

Title: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 09, 2018, 05:05:48 pm
Hey Guys!,

I'm working on a new zelda game that is a prequel to majora's mask!
but I've run into some issues most of them I was able to figure out but there is one that is really annoying me currently I'm working on the stone tower area trying to finish up the story and plot in this area first I managed to make just about any enemy I wanted work but the redead!
The issue I'm having is more of a lack of experience with the engine, I suppose I'm trying to make the redeads act like they would in the game I don't want them to bite link however, I just need help making them scream and paralyze link, I have no idea how to go about this so I figured I would ask around the forums hopefully somebody can explain what I should put in the code thanks!
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Max on September 09, 2018, 10:04:00 pm
Hey Akamatsu. One thing that will help is putting some periods in your sentences what you ask questions, I was a bit confused trying to read that. But the take away is you're trying to recreate some of the freezing behavior of the redeads in Ocarina?

There's a couple things you'll probably need. The way I would do it requires a basic understanding of timers and some basic enemy programming.

For the freezing part specifically, I think you want the redeads to freeze link when he's close enough? You'll have to have your enemy script check the distance to the hero every several milliseconds, you can find a lot of enemy scripts that do that.

Once the player is close enough, you'll probably want to use hero:freeze() to stop the player moving. Then you'll set a timer and after  3-4 seconds, call hero:unfreeze().

If you have other questions, feel free to ask, I'm not sure if you've seen the documentation for Solarus, but look through there for timers and such.
http://www.solarus-games.org/doc/latest/lua_api_timer.html

Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 10, 2018, 09:42:35 am
Yeah,

sorry about the no periods I was extremely tired when I wrote this.
I basically, figured it out for the most part I was having trouble with the timer system, but I know how to make it work now.


Thanks!,
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Max on September 10, 2018, 05:59:58 pm
Congrats! Enemy AI can be a really fun (occasionally headache inducing) project. Have fun with your project!
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 11, 2018, 02:37:11 pm
Thanks dude,

I've been spending the past 5 days mostly making all the sprites and working on the first dungeon.
right now I'm working on an Iron Knuckle enemy seem to be having issues getting him to play his sleeping animation while not active.

This command doesn't seem to do anything for some reason am I doing something wrong?

sprite:set_animation("sleeping")

Thanks in advance!
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 11, 2018, 02:39:16 pm
I can also never get this command to work

enemy:is_pushed_back_when_hurt(false)

its supposed to make it so they can't get knocked back but it never does anything for me really annoying cause it makes my mini bosses and bosses feel weak.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Max on September 11, 2018, 06:04:14 pm
It could be a few things- post your whole code and use the code=Lua tag in square brackets to format it.

A couple things that come to mind for the sleeping animation thing are that your variable "Sprite" doesn't contain the data of this enemy's sprite, or perhaps there is another function that's almost immediately changing his animation back from sleeping to walking or something.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 11, 2018, 07:26:11 pm
Okay so I managed to figure it out for some reason you can't use

enemy:set_pushed_back_when_hurt(false)

it has to be

self:set_pushed_back_when_hurt(false)

there is one more issue I'm having with my mini boss I'm trying to make him spawn bats every 3 seconds but its not working mind taking a look at the code?

here is the first bit

function enemy:on_created()
  self:set_pushed_back_when_hurt(false)
  self:set_hurt_style("boss")
  sprite = enemy:create_sprite("enemies/Ghomess")
  enemy:set_life(100)
  enemy:set_damage(9)
  enemy:check_hero()

end

I used   enemy:check_hero() to make it run the next part

function enemy:check_hero()
enemy:create_enemy{
name = "BadBat",
     breed = "BadBat",
}

sol.timer.start(self, 3000, function() enemy:check_hero() end)
end

it seems to be an issue with the timer it doesn't work for some reason not sure why do you notice anything wrong?

Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Max on September 11, 2018, 08:13:12 pm
Using the tag code = lua inside square brackets is super helpful is people are looking over your code, so you might do that next time. Have you used BBC formatting like that before? You can just copy and paste the whole enemy script so someone helping you can see how things are related.

One thing it looks like in your create-a-bat code is that enemy:create_enemy() needs x and y coordinates specified, or else you're creating it up at 0,0: the top left corner of the map. Perhaps they're being created but you can't see them up there for some reason?

Also, when are you calling your timer? You should probably call the timer in the enemy:on_restarted() event, or enemy:on_created()
It doesn't look like you're ever calling the timer?
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 11, 2018, 08:55:48 pm
"Using the tag code = lua inside square brackets is super helpful is people are looking over your code, so you might do that next time. Have you used BBC formatting like that before? You can just copy and paste the whole enemy script so someone helping you can see how things are related.

One thing it looks like in your create-a-bat code is that enemy:create_enemy() needs x and y coordinates specified, or else you're creating it up at 0,0: the top left corner of the map. Perhaps they're being created but you can't see them up there for some reason?

Also, when are you calling your timer? You should probably call the timer in the enemy:on_restarted() event, or enemy:on_created()
It doesn't look like you're ever calling the timer?"

Actually I have it set to create the bat's on self and sorry I had no idea you could use brackets  ??? what I was doing in my code doesn't work it seems what I tried to do was when the enemy was created make it run a check_hero command then under the function check hero make it spawn the bat and set a timer to check the hero again seems that doesn't work though.

I just tested out trying to set the timer under enemy:on_restarted() and it worked!
Thanks for the help!

Sorry, for my ignorance.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Diarandor on September 11, 2018, 10:23:01 pm
Tip: you can also quote with the quote button.

But the annoying thing is that with more than 1000 posts I'm still a Hero Member and not a Ninja Member or a Cat-lover Member.  :'(

PS: don't be sorry for your ignorance. Be proud of your knowledge, because we are all ignorant (except my cats).
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Max on September 11, 2018, 10:49:50 pm
Ignorance when you start learning is inevitable.
If you imagine I'm using [square brakets] instead of <> signs:
<Quote> quoted text goes here </quote>
<Code=Lua> your code goes here </code>
(And I'm just talking about on this website, not in your files, in case that wasn't clear).
Also giving your whole code is often helpful in case your problem isn't where you think it is, which is  more common when you're starting out.

Enemy:on_restarted is often a good place to set timers, because all timers with the context "enemy" are destroyed when the enemy restarts. So if you want a timer to restart when you restart the enemy (when it gets hit, when it is created, etc) create the timer there.

Keep in mind though, this might mean he'll create bats every time you hit him. If you don't want that, you'll want the context of the timer to be outside the enemy- set to the map for instance. I have the Solarus API open 24/7 on like two devices at least because I check it so much when I'm working, lol. Definitely reference it frequently while learning and trying new things.


I'm still wondering why enemy:set_pushed_when_hurt(false) didn't work though. Do you have your line declaring what the enemy variable refers to? Usually enemy=...(the dots mean, this instance of the code)
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 11, 2018, 10:54:14 pm
Yeah,

I'm not sure either I did have local enemy = ... I honestly have no idea why but when I changed it to self instead of enemy it worked I can send you the whole code if you want to take a look maybe I did something wrong?

Honestly I'm much better at making sprites then coding so far so I really need to work on that is their a way for me to get in touch with you guys like steam or discord maybe?

I don't want to bother you with to many questions but you guys seem nice and I could use your advice on how things look and act if that's fine with you of course.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Max on September 12, 2018, 12:32:06 am
Quote from: max
Also giving your whole code is often helpful in case your problem isn't where you think it is
Quote from: max
You can just copy and paste the whole enemy script so someone helping you can see how things are related.

I've low key been trying to say that the whole code in this case is probably more useful for people trying to help you. If you're an experienced coder and you've been testing things and you know where the issue is, maybe you don't need to send the whole thing but if you haven't coded many enemies and you're aware there's a problem somewhere, it isn't too hard for us to take a look over the whole thing.

As far as I know, there isn't a discord or anything for chatting, but I think posting your code on the forum is a pretty good way to get help fairly quickly. I check the forum at least five or six times a day unless I'm on vacation, and we're pretty nice around here. While we aren't going to code your whole game for you, if you've tried a bit yourself, most everyone is more than happy to point you in the right direction. For example, "Can someone show me how to make a custom sword that shoots lasers" might not get many replies, but being like "I tried this code to make a custom sword that shoots lasers, can someone help show me where I've gone wrong" is more likely to get assistance.

One way to get much better at coding is just to keep trying. Figure out what steps are necessary to what you're trying to do, and then think about how a computer might be able to do those steps. Keep breaking it down into more steps, keep looking over the API for methods that do what you want, use the search function there, and when you've tried a couple things and things aren't working, ask. Make sure to watch Christopho's tutorials on youtube, and look at the Solarus team's code on GitHub. If there are things there you don't understand, feel free to ask.

With all that said, I just started taking a coding course at a school in my city. In two weeks, I've learned almost as much as I could teach myself over six months trying things myself. It's worth it to buy or borrow a book about coding. Even if the language the book is about isn't Lua, many concepts will be transferable.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 12, 2018, 12:53:47 am

Here is the code.


Code: [Select]


local enemy = ...
local game = enemy:get_game()
local map = enemy:get_map()
local hero = map:get_hero()
local sprite
local movement
local sprite = enemy:create_sprite("enemies/" .. enemy:get_breed())

-- Event called when the enemy is initialized.
function enemy:on_created()
if game:get_value("Sleeping") == nil
then game:set_value("Sleeping",1)
end

  enemy:set_life(25)
  enemy:set_damage(12)
enemy:get_damage()
self:set_pushed_back_when_hurt(false)
end

function enemy:get_damage()
enemy:set_hurt_style("monster")
self:set_animation("sleeping")
end


function enemy:on_hurt()
if game:get_value("Sleeping") == 1
then game:set_value("Sleeping",2)
end
sol.audio.play_sound("IronKnuckle/Iron_KnuckleHit")
sol.audio.play_music("MiniBossTheme")
end

function enemy:on_dead()
enemy:create_enemy{
name = "UnarmoredIronKnuckle",
      breed = "IronKnuckle Early Unarmored",
}
sol.audio.play_sound("IronKnuckle/Iron_KnuckleLoseArmor")
end

function enemy:on_restarted()
if game:get_value("Sleeping") == 2
then movement = sol.movement.create("target")
end
if game:get_value("Sleeping") == 2
then movement:set_target(hero)
end
if game:get_value("Sleeping") == 2
then movement:set_speed(15)
end
if game:get_value("Sleeping") == 2
then movement:start(enemy)
end
if game:get_value("Sleeping") == 2
then sprite:set_animation("walking")
end
end
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Max on September 12, 2018, 01:40:15 am
Make sure you start you code with <code=lua>, not just <code> (square brackets, not <> signs.) This adds line numbers, which is SUPER helpful if I want to tell you there's an issue on line 19. Which there is. At least, I think it's line 19, but there aren't any line numbers, so....

Also, preface. You're clearly just leaning, and trying to take other people's code and make it work and don't know 100% what's going on yet, and that's okay. This actually seems like a pretty great code, especially for a beginner. You've just made a few beginner mistakes. But I think the ideas behind the code, that there should be an enemy that wakes up and starts playing miniboss music when he's first hit, and that once he takes some damage, he is replaced by an unarmored version, is a good concept. I assume the code for this basically works? It seems like it mostly should.

But, there's a couple issues and I'm going to give you a lot of information, hopefully it will help you learn and the next script you make, will be better because you'll know why you're making certain choices (not just "because it works").



So,
I don't think "sleeping" should be a savegame value- for one thing, right now every Iron Knuckle in the game shares the same value if they're sleeping or not so they'd all wake up at once XD. That's just a mess. What you want is a local variable.

For example, "local sprite" and "local movement" are two local variables called sprite and movement. They're declared at the top of the script, but they don't have any information in them yet. Some code will put some information in this variable later in the script, and it will affect only this script. Local variables are local to the "scope" of wherever you create them. So, since they're declared just in the enemy script, they're only a part of the enemy script. Every enemy can have a local variable called "number_of_pineapples" and if you give a specific enemy six pineapples when he bumps into a pineapple tree, that will just give him six pineapples. If you have an enemy with code like
Code: Lua
  1. enemy:on_bumping_into_tree()
  2.   game:set_value("number_of_pineapples", 6)
  3. end
  4.  
Then EVERY enemy of that breed would get six pineapples. You'd want:
Code: Lua
  1. local pineapples
  2. enemy:on_bumping_into_tree()
  3.   pineapples = pineapples+6
  4. end
  5.  

Then the pineapples variable is just accessible by this script, not ANY script looking at game:get_value("pineapples")
So I think you'd want "sleeping" to be a similar way, where each instance of the script running has a local sleeping variable. Does that all make sense?


And speaking of local variables, you have these lines:
local sprite
local sprite = enemy:create_sprite("enemies/" .. enemy:get_breed())
This is redundant. It's like saying "I'm going to create a local variable, and it's going to be called sprite. I'm going to create a local variable, and it's going to be called sprite, and it's going to contain [the sprite of this enemy breed]". You definitely shouldn't be declaring variables of any type twice.

Better than that would be:
local sprite
sprite = enemy:create_sprite("enemies/" .. enemy:get_breed())
But that's still redundant.

The best option would be
local sprite = enemy:create_sprite("enemies/" .. enemy:get_breed())



Moving on down, your line "enemy:get_damage()" is getting the value you just set with "enemy:set_damage()", but... it's not doing anything at all with that value? You just get it and then ignore it and move on. It's like if in the middle of a paragraph I just wrote something unrelated. 12. And then kept going and never talked about it again.

I still can't figure out why self:set_pushed_back_when_hurt(false) needs to be self and not enemy. Maybe this is a bug? Someone smarter than me will have to help you there : /


Now, tell me if I'm wrong, but does sleeping = 1 mean it's asleep and sleeping = 2 mean it's awake?
If that's the case, you should use a boolean variable. Booleans can only be true or false (or in lua, nil, which acts a lot like false but basically means nobody ever bothered assigning it a value).
Basically, instead of saying something like
Code: Lua
  1. local sleeping = 1
  2.  
You would say
Code: Lua
  1. local sleeping = true
  2.  

Then you could have statements like
Code: Lua
  1. if sleeping == true then
  2.   movement = sol.movement.create("target")
  3. end
  4.  

True/False is a LOT easier to understand than 1 or 2 for something that can only be true or false, like "is this enemy asleep?"



Finally, you have this mess here:
Code: Lua
  1. if game:get_value("Sleeping") == 2
  2. then movement = sol.movement.create("target")
  3. end
  4. if game:get_value("Sleeping") == 2
  5. then movement:set_target(hero)
  6. end
  7. if game:get_value("Sleeping") == 2
  8. then movement:set_speed(15)
  9. end
  10. if game:get_value("Sleeping") == 2
  11. then movement:start(enemy)
  12. end
  13. if game:get_value("Sleeping") == 2
  14. then sprite:set_animation("walking")
  15. end
  16.  

pleasepleasepleasepleaseplease write that like this:
Code: Lua
  1. if game:get_value("Sleeping") == 2 then
  2.   movement = sol.movement.create("target")
  3.   movement:set_target(hero)
  4.   movement:set_speed(15)
  5.   movement:start(enemy)
  6.   sprite:set_animation("walking")
  7. end
  8.  

Your way technically isn't wrong, but... it's very wrong.




I happen to have just started taking a computer coding course and the importance of writing code other people can understand is something we covered today. So we were encouraged to share our code and read other people's code, so this is practically studying for me, lol.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 12, 2018, 02:10:46 am
Okay,

Thank you so much for your help the reason I wrote

Code: Lua
  1. if game:get_value("Sleeping") == 2

for each one is because for whatever reason it was giving me errors if I tried to group them under one .

no clue why it did this for me maybe I just did it wrong not 100% sure

either way thanks for the tips I learned coding on other engines but I have not really messed with lua before so it's still kind of new to me.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 12, 2018, 02:27:56 am
ah I figured out why it was giving errors I kind of feel dumb now I was putting code like this

Code: Lua
  1. if game:get_value("Sleeping") == 2
  2. then movement:set_target(hero)
  3. then movement:set_target(hero)
  4. then movement:set_target(hero)
  5. end

I actually had no idea how to use the local function this is basically the same thing as a reference from elder scrolls engine's I was wondering if their was a way to use this type of feature but I just didn't understand how to declare it this helps me out VERY much seriously thanks for explaining this will make things much smoother  :D
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Max on September 12, 2018, 04:05:23 am
Yeah, most of my mistakes are me being like, why won't this work, I don't understand anything! And it's some simple syntax error like that.

I googled the elder scrolls engine, did you use their creation kit thing to make mods with their papyrus language?
Papyrus Introduction (https://www.creationkit.com/index.php?title=Papyrus_Introduction)

If so, from my brief glance over this page, I bet you'll find a lot of ideas to be pretty familiar in Solarus, just worded differently.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 12, 2018, 02:38:45 pm
Yes, that's exactly what I did
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Diarandor on September 12, 2018, 03:07:08 pm
Tip: you should improve the indentation of your code, to make it more readable. And read the scripts of finished projects to learn the basics.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 12, 2018, 04:48:41 pm
I've been doing that since I started.
I'm going to put my redead code here just in case somebody is looking for one and since you guys helped me it's only fair

I cleaned it up last night and made it look nicer your welcome to look over it and point anything out that may have been done wrong or could have been done better but it works like it should doesn't mean it couldn't be improved.

Code: Lua
  1. local enemy = ...
  2. local game = enemy:get_game()
  3. local map = enemy:get_map()
  4. local hero = map:get_hero()
  5. local sprite = enemy:create_sprite("enemies/Redead2")
  6. local movement
  7. local IsPlayerFrozen = false
  8.  
  9.  
  10. function enemy:on_created()
  11. movement = sol.movement.create("target")
  12.   enemy:set_life(8)
  13.   enemy:set_damage(10)
  14. end
  15.  
  16.  
  17.  
  18.  
  19.  
  20. function enemy:on_restarted()
  21.   sol.timer.start(self, 3000, function() sol.audio.play_sound("Redead/RedeadMoan") end)
  22.   self:get_sprite():set_animation("immobilized")
  23.   enemy:check_hero()
  24. if self:get_distance(hero) <= 80 then
  25. if IsPlayerFrozen == false then
  26.   sol.timer.start(self, 3000, function() hero:freeze() end)
  27.   IsPlayerFrozen = true
  28.   sol.audio.play_sound("Redead/RedeadScream")
  29. end
  30. end
  31.   if self:get_distance(hero) <= 80 then
  32.   if IsPlayerFrozen == true then
  33.   sol.timer.start(self, 5000, function() hero:unfreeze() end)
  34.   IsPlayerFrozen = false
  35. end
  36. end
  37. end
  38.  
  39.  
  40.  
  41. function enemy:check_hero()
  42.   if self:get_distance(hero) <= 80 then
  43.   movement = sol.movement.create("target")
  44.   self:get_sprite():set_animation("walking")
  45.   movement:set_speed(28)
  46.   movement:start(enemy)
  47. end
  48. sol.timer.start(self, 1000, function() self:check_hero() end)
  49. end
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58. function enemy:on_dying()
  59. sol.audio.play_sound("Redead/RedeadDie")
  60. end
  61.  
  62.  
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Max on September 12, 2018, 06:38:37 pm
I'm going to reformat your code a little bit, like Diarandor suggested.

I also added some comments into your code. One big this is don't do something like:
if rupees <5 then
  some code
end
if rupees > 5 then
  some code
end

You should be using an if/then/else/end construction.
https://www.lua.org/pil/4.3.1.html (https://www.lua.org/pil/4.3.1.html)
Look over that page. Also, elseif conditions are very useful.

Code: Lua
  1. local enemy = ...
  2. local game = enemy:get_game()
  3. local map = enemy:get_map()
  4. local hero = map:get_hero()
  5. local sprite = enemy:create_sprite("enemies/Redead2")
  6. local movement
  7. local IsPlayerFrozen = false
  8.  
  9.  
  10. function enemy:on_created()
  11.   movement = sol.movement.create("target")
  12.   enemy:set_life(8)
  13.   enemy:set_damage(10)
  14. end
  15.  
  16.  
  17.  
  18. function enemy:on_restarted()
  19.   sol.timer.start(self, 3000, function() sol.audio.play_sound("Redead/RedeadMoan") end)
  20. --do you really want every redead on the map to moan 3 seconds after you enter the map?
  21.   self:get_sprite():set_animation("immobilized")
  22.   enemy:check_hero()
  23. --you will probably want your check_hero() method to freeze the player. As it is, if the hero is more than 80px away, the redead will not
  24. --freeze the hero, but then it doesn't loop. It won't try to freeze the hero again until you damage it. I think you probably want to
  25. --check if the hero is close enough to freeze constantly, or every second or so, which is what your check_hero() method is doing anyway.
  26.  
  27.   if self:get_distance(hero) <= 80 then
  28.     if IsPlayerFrozen == false then
  29.       sol.timer.start(self, 3000, function() hero:freeze() end)
  30.       IsPlayerFrozen = true
  31.       sol.audio.play_sound("Redead/RedeadScream")
  32.     end
  33.   else --instead of checking a condition multiple times, do an "if player isn't close", then "ELSE", which mean, if the play IS close in this case.
  34.       sol.timer.start(self, 5000, function() hero:unfreeze() end)
  35.       IsPlayerFrozen = false
  36.     end
  37.   end
  38. end
  39.  
  40.  
  41.  
  42. function enemy:check_hero()
  43.   if self:get_distance(hero) <= 80 then
  44.     movement = sol.movement.create("target")
  45.     self:get_sprite():set_animation("walking")
  46.     movement:set_speed(28)
  47.     movement:start(enemy)
  48.   end
  49.   sol.timer.start(self, 1000, function() self:check_hero() end)
  50. end
  51.  
  52.  
  53.  
  54. function enemy:on_dying()
  55.   sol.audio.play_sound("Redead/RedeadDie")
  56. end
  57.  
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 13, 2018, 01:56:07 am
can you explain a bit more for some reason if I make it else the code doesn't work anymore it just runs it once instead of looping it for some reason.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Diarandor on September 13, 2018, 08:33:39 am
It is a bit risky to put the unfreezing timer on the enemy (the enemy could be killed when hero is frozen, for instance, by a boomerang, or other things). I recommend to put that timer (and maybe others) on the map, and get the frozen state with: hero:get_state() == "frozen".
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Max on September 13, 2018, 02:01:36 pm
I'm not sure which part of your code was looping? The only part that should have looped was the check_hero() method, which loops every 1sec. That's why I suggested putting the freezing function in there.

On their own, if/else branches don't loop. They have to be inside a loop for that.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Diarandor on September 13, 2018, 02:28:01 pm
Briefly: explain, this: "the code doesn't work anymore it just runs it once".
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 13, 2018, 04:16:39 pm
Not, sure what their is to explain?

if I use the else feature instead of making another if statement it no longer loops like it does before I changed it.

Basically the hero no longer gets unfrozen and frozen more then once.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Diarandor on September 13, 2018, 11:26:13 pm
You are right that the code is not ok. And there are a few more things wrong with the last code of Max, but if you read carefully, you can find them (exercise!). You will need to move/rewrite a few things to fix it. I challenge you, Akamatsu, to fix it!

[insert samurai emoticon here]

Edit: I think Max had in mind a different behavior for the Zombi thing, without restarting the freezing feature, or he wrote it too fast.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 13, 2018, 11:57:05 pm
it was already fixed before I tried to change it  :D I just changed it back although I kind of have a rough idea of what was wrong with it.

so enemies do not play walking left and right animations by default?
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Diarandor on September 14, 2018, 12:11:48 am
Could you post the last code, so that it can be reviewed for new possible advices? That will help beginners who read your code too.

EDIT: and I forgot: congrats! you completed the challenge! XD
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 14, 2018, 12:39:38 am
Code: Lua
  1. local enemy = ...
  2. local game = enemy:get_game()
  3. local map = enemy:get_map()
  4. local hero = map:get_hero()
  5. local sprite = enemy:create_sprite("enemies/Redead2")
  6. local movement
  7. local IsPlayerFrozen = false
  8.  
  9.  
  10. function enemy:on_created()
  11.  
  12. movement = sol.movement.create("target")
  13.  
  14.   enemy:set_life(8)
  15.  
  16.   enemy:set_damage(10)
  17.  
  18. end
  19.  
  20.  
  21.  
  22.  
  23.  
  24. function enemy:on_restarted()
  25.  
  26. sol.timer.start(self, 3000, function() sol.audio.play_sound("Redead/RedeadMoan") end)
  27.  
  28. self:get_sprite():set_animation("immobilized")
  29.  
  30. enemy:check_hero()
  31.  
  32. end
  33.  
  34.  
  35.  
  36. function enemy:check_hero()
  37.  
  38.    if self:get_distance(hero) <= 80 then
  39.  
  40.    movement = sol.movement.create("target")
  41.  
  42.    self:get_sprite():set_animation("walking")
  43.  
  44.    movement:set_speed(28)
  45.  
  46.    movement:start(enemy)
  47.  
  48. end
  49. sol.timer.start(self, 1000, function() self:check_hero() end)
  50.  
  51. if self:get_distance(hero) <= 80 then
  52.  
  53. if IsPlayerFrozen == false then
  54.  
  55.    sol.timer.start(self, 3000, function() hero:freeze() end)
  56.  
  57.    IsPlayerFrozen = true
  58.  
  59. end
  60.  
  61. end
  62.  
  63. if self:get_distance(hero) <= 80 then
  64.  
  65. if IsPlayerFrozen == true then
  66.  
  67.    sol.timer.start(self, 5000, function() hero:unfreeze() end)
  68.  
  69.     IsPlayerFrozen = false
  70. end
  71. end
  72. end
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81. function enemy:on_dying()
  82.  
  83. sol.audio.play_sound("Redead/RedeadDie")
  84.  
  85. end
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 14, 2018, 12:51:23 am
Also I'm always looking for help with my project if anyone is interested it's quite a large scale for one person i'll be showing off screenshots and such at a later point once I feel things are up to my standards I could always use another person on the project no matter what you can do.

I'll be sure to give a special thank you to Diarandor and Max
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Diarandor on September 14, 2018, 01:52:36 am
I think that lines 57 and 69 should go inside their timers above. Otherwise, if the enemy is restarted (and therefore all timers stopped), your enemy will break its behavior, as you can check if I'm not wrong. (Even if the hero is frozen, the enemy could be hurt by the boomerang or other thing, and so restarted too.)
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 14, 2018, 02:43:19 am
That's a good idea never thought about that.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Max on September 14, 2018, 04:43:22 am
Also I'm always looking for help with my project if anyone is interested it's quite a large scale for one person.

Just a little more unsolicited advice- if your game is large for one person, it's probably too large for you to finish. Just speaking for the experience of seeing many projects fail. If you're okay with not finishing, great, keep going as long as you can. But if you want to continue learning and developing more games, make a smaller one first. You'll learn WAY more doing a few small games that you would one big one.

Either way, good luck.
Title: Re: Need help making a Redead AI that acts similar to Ocarina of time
Post by: Akamatsu on September 14, 2018, 08:22:43 pm
I've always done projects by myself for the most part I just spend 1-2 years working on it.

there is only 1 game I have worked on with a team and that's SCP containment Breach

I normally pick things up pretty fast so I'm not to worried but if somebody has the free time to help I will not complain.