Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Max

#196
Your projects / Re: Ocean's Heart
May 04, 2018, 09:13:45 AM
Small update to the current demo! Watching Christopho's let's play, as well as my wife test-playing last night, alerted me to a small handful of bugs that I've dealt with.

I've also tweaked some of the damage and life for enemies in the second half of the demo to make them a bit tougher. I might need to go in and make a bit more armor available, but if you play, let me know what you think about the enemy difficulty!

Latest Build (google drive download)
#197
Your scripts / Re: Deku/Turret Type Enemy
May 04, 2018, 06:20:06 AM
Hey, thanks for showing me! Those look great, they work really well in narrow corridors. It might be a nice scenario to have where there's a narrow corridor with little cubbies on the side you have to duck into the avoid the projectiles and time your dashes in between them. Your deku looks like you can pretty reliably hit him right before he ducks, I don't know if you experimented with the min_range property, but if you want them to duck a bit sooner, you can increase that. Or maybe you have it right where you want it, I don't know : )

For making the enemy non traversable, try experimenting with enemy:set_traversable(false), maybe just when it's "asleep" in case you'd want it to be able to damage the player when it's awake. That might work better than a wall.

I was also having problems with showing a waking up animation. I think tying it to a timer might have been a bad idea, probably something using the event sprite:on_animation_finished() somewhere within function enemy:wake_up() would be better. Probably within the conditional branch "if properties.waking_animation ~= nil then"... Maybe something like this:

Code (lua) Select

if properties.waking_animation ~= nil then
  function sprite:on_animation_finished()
    self:finish_waking_up()
  end
else
  self:finish_waking_up()
end


I thiiiiiink that might work but I literally just wrote that here instead of doing any testing whatsoever, so...


Also, I kind of have a demo out now, check out my game's topic in the forum, there should be a link in the top post. I suppose it's a bit more like an open beta than a demo, because I keep uploading patches. But anyway! I'm planning on putting a new version of the demo out tonight or tomorrow morning that addresses a handful of bugs that I saw in Christopho's let's play, as well as a playtest my wife did last night instead of sleeping, haha.
#198
Quote from: CrookiNari on May 04, 2018, 05:16:16 AM
The strange thing is, when I first did it, it worked fine. After moving the map into a different folder, it stopped working. There's nothing else wrong with the script, it doesn't throw out any errors or anything, it just doesn't give the proper response.

One thing I noticed looking at your github is that your maps seem to be organized really different from mine. In my "data" folder, I have a "maps" folder (also "enemies", "entities", "fonts", etc...), and every map is in there. It seems like yours are in folders scattered throughout your "data" folder? I don't know how the engine reads maps, but I'm pretty sure when I specify a map in code, the engine assumes they're in a folder called "maps", because I don't think I usually specify that.
#199
What's the text of the NPCs? If you aren't using the right syntax within your dialogs, the choices don't work with their ALTTP dialog script. For example, here's a sample dialog:

_npcs.sample_guy.1

Did you like your dinner?
$? Yes
$? No

_npcs.sample_guy.2

I'm glad it was tasty... NOW PREPARE TO DIE!
I poisoned it!!

_npcs.sample_guy.3

Oh no, was it because it was POISONED!?


So your map script would have:

Code (Lua) Select


function sample_guy:on_interaction()

game:start_dialog("_npcs.sample_guy.1", function (answer)

if answer == 2 then
game:start_dialog("_npcs.sample_guy.2")

else

game:start_dialog("_npcs.s.sample_guy.3")

end)

end



Don't copy/paste that without checking for typos, I typed this on mobile and autocorrect is zealous.


I don't think you would ever have something like if answer == 6 because the answer is relative to the choice's line in the box, not in the whole text string. So it'll always be 1-4.



It looks like you're using the whole pause system from the Solarus team's games, which I don't understand fully, so I can't help there : /
#200
Okay, that makes sense. Do you know how I can get the staircase teleporters to notify my script? The only way I can think of it map:get_entities by type, getting spiral staircase types, and comparing all their coordinates to the hero's coordinate, and if any are the same, having a conditional branch that set the respawn x-value to +-16.

But that seems like an inordinately difficult way to do it, but is that the only way?
#201
Hey! So I thought this script was working out all great and fine, but I've encountered an issue. If you use any of the "spiral staircase" modifiers to your teleports, you can get stuck in a wall if you respawn.

The problem is this- the spiral staircase things work like this I think: they change the behavior of your teleport, so that instead of going right to the destination, the put you 16px to the right or left of your destination (in a wall), then the engine automatically moves the hero into the destination then down 16px while playing an animation to simulate the staircase thing.

The problem comes if you die in the room you entered by staircase. Since that's your respawn map, this script will send you back to wherever you entered the map. However, if you entered via spiral staircase, you technically entered the map 16px to the right or left of where the stairs (and your destination entity) are. So you'll respawn trapped in the wall, since the respawn script doesn't know if you came into the room via staircase.


So I'm wondering, is there any way to let the script know that you entered the map via spiral staircase?
#202
You could also use a metaevent for on_map_changed, or on world changed, that resets the hero's stats (walking speed and abilities) to savegames variables, besides doing this whenever the game is loaded up. This could be figured out and perhaps exploited by the player, but would help safeguard against potential bugs.

I've given this a little thought because I was thinking about potential temporary-stat-boosting potions, but it does open up a lot of bugs. I can't think of a way to have like something like "this boosts your attack for 15 minutes" carry over if the game is paused and restarted, all effects would need to be reset upon quitting the game. And perhaps upon dying, too, I'm not sure if timers with the context "game" are destroyed or not when you die and are reset. Probably depends on how death is handled by your game.
#203
I think there's an event called enemy:on_attacking_hero(). You could call some code here that sets the hero's speed to something lower, then removes the attack ability of the hero. Then you could set a timer that after 5 seconds sets the hero's speed back and gives the track ability back.

There's probably a better way to do this. I also have no idea what would happen if the player saved or reset the game or died in this state, you'd need some way to reset the hero's abilities since in these cases, the timer that would give the hero's abilities back would get destroyed.
#204
Your scripts / Re: Deku/Turret Type Enemy
May 02, 2018, 06:12:26 PM
Oh shoot, I should also have included the script of a projectile for example, too. I'll put them down here as well as in the first post.

Also llamazing, that makes things hella concise, I love it. I don't know if I'll update every enemy I've done so far, but I will likely use that format in my next game : )

Here's a projectile that goes in orthogonal directions, borrowed from Solarus DX:

Code (lua) Select

-- Stone shot by Octorok.

local enemy = ...

function enemy:on_created()

  enemy:set_life(1)
  enemy:set_damage(2)
  enemy:create_sprite("enemies/" .. enemy:get_breed())
  enemy:set_size(8, 8)
  enemy:set_origin(4, 4)
  enemy:set_invincible()
  enemy:set_obstacle_behavior("flying")
  enemy:set_attack_consequence("sword", "custom")
end

function enemy:on_obstacle_reached()

  enemy:remove()
end

function enemy:go(direction4)

  local angle = direction4 * math.pi / 2
  local movement = sol.movement.create("straight")
  movement:set_speed(150)
  movement:set_angle(angle)
  movement:set_smooth(false)
  movement:start(enemy)

  enemy:get_sprite():set_direction(direction4)
end

--destroy if hit with sword
--
function enemy:on_custom_attack_received(attack, sprite)

  if attack == "sword" then
  enemy:remove_life(1)
  end
end
--]]



And here's one that will go in any direction, also adapted from Solarus DX:

Code (lua) Select

-- 3 fireballs shot by enemies like Zora and that go toward the hero.
-- They can be hit with the sword, this changes their direction.
local enemy = ...

local sprites = {}

function enemy:on_created()

  enemy:set_life(1)
  enemy:set_damage(2)
  enemy:set_size(8, 8)
  enemy:set_origin(4, 4)
  enemy:set_obstacle_behavior("flying")
  enemy:set_can_hurt_hero_running(true)
  enemy:set_invincible()
  enemy:set_attack_consequence("sword", "custom")

  sprites[1] = enemy:create_sprite("enemies/" .. enemy:get_breed())
  -- Sprites 2 and 3 do not belong to the enemy to avoid testing collisions with them.
  sprites[2] = sol.sprite.create("enemies/" .. enemy:get_breed())
  sprites[3] = sol.sprite.create("enemies/" .. enemy:get_breed())
end

local function go(angle)

  local movement = sol.movement.create("straight")
  movement:set_speed(175)
  movement:set_angle(angle)
  movement:set_smooth(false)

  function movement:on_obstacle_reached()
    enemy:remove()
  end

  -- Compute the coordinate offset of follower sprites.
  local x = math.cos(angle) * 10
  local y = -math.sin(angle) * 10
  sprites[1]:set_xy(2 * x, 2 * y)
  sprites[2]:set_xy(x, y)

  sprites[1]:set_animation("walking")
  sprites[2]:set_animation("following_1")
  sprites[3]:set_animation("following_2")

  movement:start(enemy)
end

function enemy:on_restarted()

  local hero = enemy:get_map():get_hero()
  local angle = enemy:get_angle(hero:get_center_position())
  go(angle)
end

-- Destroy the fireball when the hero is touched.
function enemy:on_attacking_hero(hero, enemy_sprite)

  hero:start_hurt(enemy, enemy_sprite, enemy:get_damage())
  enemy:remove()
end

-- Change the direction of the movement when hit with the sword.
function enemy:on_custom_attack_received(attack, sprite)

  if attack == "sword" and sprite == sprites[1] then
    local hero = enemy:get_map():get_hero()
    local movement = enemy:get_movement()
    if movement == nil then
      return
    end

    local old_angle = movement:get_angle()
    local angle
    local hero_direction = hero:get_direction()
    if hero_direction == 0 or hero_direction == 2 then
      angle = math.pi - old_angle
    else
      angle = 2 * math.pi - old_angle
    end

    go(angle)
    sol.audio.play_sound("enemy_hurt")

    -- The trailing fireballs are now on the hero: don't attack temporarily
    enemy:set_can_attack(false)
    sol.timer.start(enemy, 500, function()
      enemy:set_can_attack(true)
    end)
  end
end

function enemy:on_pre_draw()

  local map = enemy:get_map()
  local x, y = enemy:get_position()
  map:draw_visual(sprites[2], x, y)
  map:draw_visual(sprites[3], x, y)
end
#205
Development / Re: The dangerous escape key
May 02, 2018, 06:04:37 PM
Thanks, llamazing! This works great.
#206
So, I've seen that there is a "Door Manager" script in a few of the Solarus Team's projects, which seems to help with this instance as well as a few other things you might want to do with doors- I've tried it and it works great once you figure out what you're supposed to do to use it! However, I don't 100% understand everything in that code, so I don't like using it. Maybe once I'm smart enough to re-code it myself to understand it I will, but until then I'm stubbornly doing things poorly so I can learn.

So, one way I've achieved this effect is by having an event for every enemy that, when they're killed, checking if there aren't any other enemies left and if so, opening the door (or whatever). I know for a fact that this is not very good code, and it's repetitive and hard-codes the number of enemies, but it might be a good starting point for you to try to understand some of the code that you'll need.

Code (lua) Select

function mushroom_golem_1:on_dead()
  if map:get_entities_count("mushroom_golem") == 0 then --)this line counts the number of entities that are named starting with "mushroom_golem...")
    game:start_dialog("_yarrowmouth.observations.mushroom_spot.1")
    map:open_doors("gate")
  end
end

function mushroom_golem_2:on_dead()
  if map:get_entities_count("mushroom_golem") == 0 then
    game:start_dialog("_yarrowmouth.observations.mushroom_spot.1")
    map:open_doors("gate")
  end
end

--and so on, with function mushroom_golem_3:on_dead(), mushroom_golem_4, etc...
#207
Game art & music / Re: Oceansheart Graphics
May 02, 2018, 05:49:43 PM
Thanks Zefk, I guess v4 because that's the current one? So, I'm having a hard time understanding all this. I've been looking into it for about an hour now, and maybe you can tell me if my understanding is correct.

If something is CC-BY-SA 4.0, you (as a random person on the internet) can take that content and say hey, now this is licensed under GPLv3. Which, I thiiiiiink, doesn't carry the attribution requirement? But if you convert to GPL you'd need to at least link to the source code and provide indication of your changes, which seems basically like requiring attribution, because of that link.

This is also a weird thing becuase in the case of an image, I'm not sure what source code would be. I suppose the original image? This is a little confusing for me, but thank you for bringing it to my attention, Zefk : )
#208
Your projects / Re: Ocean's Heart
May 01, 2018, 11:23:18 PM
Thanks Christopho! That explains something I made a note of actually. This should all be easy to fix.

Most of them are just the errors for single-direction sprites that aren't facing their proper direction, which gives an error but doesn't result in any actual provlems, so I've just been ignoring them.

Thanks again for playing!
#209
Development / Re: The dangerous escape key
April 29, 2018, 02:26:20 AM
Oops, I retyped it on the forum, there isn't a typo in my real code. It's the same function that handles the map, which works fine, so that's not the issue. But it should override the quit function if it just plays a sound effect or something?
#210
Development / The dangerous escape key
April 28, 2018, 09:38:44 PM
Quick question- I saw a couple times in Christopho's let's play of my game, he accidentally pressed the ESC key and quit the game without saving. This is the default behavior of Solarus, but how would I change that so nobody else accidentally quits and loses progress?

I tried this:
Code (lua) Select

function game:on_ley_pressed(key, modifiers)
  if key == "esc" then (some random code that's not quitting the game) end
end


But the game still just quits when the esc key is pressed. It's nice when I'm testing things quickly but dangerous if you're actually playing.