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 - xavius

#16
Renkineko

For the set_speed(0), you could also use stop(). I did not see a difference. Maybe one is fat than the other in time processing?
For the go_random(), I only use it to change the animation of the enemy. I could put this in the check_hero().
For the alternating move, I think it is happening because movement:set_ignore_obstacles() is not set. The second time I enter the room, it is set via enemy:on_restarted(). Maybe there is no default value for this movement? I did not see the source code yet.


Christopho

I would really appreciate if you could. I do not have an environment set yet. I know how hard it can be since I am often cross compiling ARM kernels at work. If I do not mistake, the bug is when entering the room from south. I noticed that event after separator transition, I still was in the room below.


Thank you all.
#17
By the way, do you have a compiled version of solarus 1.2.1 for windows? Unless I do not have the right git address, it does not seems to have binaries.

Thank you!
#18
I think I found out the problem. I forgot to set the movement:set_ignore_obstacles() after creating the movement. I had in the past have a problem related to this.

Here is a cleaned up code of my enemy:
local enemy = ...
local going_hero = false
local m

function enemy:on_created()
  self:set_life(1)
  self:set_damage(2)
  self:create_sprite("enemies/fire_bat")
 
  self:set_size(16, 8)
  self:set_origin(8, 0)
  self:set_obstacle_behavior("flying")
  m = sol.movement.create("target")
  m:set_ignore_obstacles(false)
  m:set_speed(0)
  m:start(self)
end

function enemy:on_restarted()
  local sprite = self:get_sprite()
  sprite:set_animation("stopped")
  m:set_speed(0)
  going_hero = false

  self:go_random()
  self:check_hero()
end

function enemy:check_hero()
  local hero = self:get_map():get_entity("hero")
  local _, _, layer = self:get_position()
  local _, _, hero_layer = hero:get_position()
  local near_hero = layer == hero_layer
    and self:get_distance(hero) < 150

  if near_hero and not going_hero then
    self:go_hero()
sol.audio.play_sound("bat")

  elseif not near_hero and going_hero then
    self:go_random()
  end
sol.timer.stop_all(self)
sol.timer.start(self, 100, function() self:check_hero() end)
end

function enemy:go_random()
  going_hero = false
  local sprite = self:get_sprite()
  sprite:set_animation("stopped")
  m:set_speed(0)
end

function enemy:go_hero()
  going_hero = true
  local sprite = self:get_sprite()
  sprite:set_animation("walking")
  m:set_speed(88)
end
#19
Both ideas fromRenkineko and Christopho are good. I focused more on Christopho script because it better suits my needs.

I tweaked Christopho scprit a little because I was indeed seeing the enemies resetting to their place. I simply disable enemies when entering the separator (separator.on_activating) and reset their position then call separator.on_activated to enable only enemies in current region:

-- This script manages enemies when there are separators in a map.
-- Enemies that are prefixed by "auto_enemy" are automatically
-- reset at their initial position when taking separators prefixed by "auto_separator".

local separator_manager = {}

function separator_manager:manage_map(map)

  local enemy_places = {}

  -- Store the position and properties of enemies.
  for enemy in map:get_entities("auto_enemy") do
    local x, y, layer = enemy:get_position()
    enemy_places[#enemy_places + 1] = {
      x = x,
      y = y,
      layer = layer,
      direction = enemy:get_sprite():get_direction(),
      enemy = enemy,
    }
    enemy:set_enabled(false)
  end

  -- Function called when a separator was just taken.
  local function separator_on_activating(separator)
 
    local hero = map:get_hero()
    for _, enemy_place in ipairs(enemy_places) do
      local enemy = enemy_place.enemy

      if enemy:exists() then
        if enemy:is_in_same_region(hero) then
  enemy:set_position(enemy_place.x, enemy_place.y, enemy_place.layer)
  enemy:get_sprite():set_direction(enemy_place.direction)
  enemy:set_enabled(false)
end
      end
    end
  end
 
  -- Function called after a separator was just taken.
  local function separator_on_activated(separator)
    local hero = map:get_hero()
    for _, enemy_place in ipairs(enemy_places) do
      local enemy = enemy_place.enemy

      if enemy:exists() then
        if enemy:is_in_same_region(hero) then
  enemy:set_enabled(true)
  enemy:restart()
end
      end
    end
  end

  for separator in map:get_entities("auto_separator") do
    separator.on_activating = separator_on_activating
    separator.on_activated = separator_on_activated
  end

end

return separator_manager



Still, I have a weird problem. I created a simple bat enemy that run toward you when it sees you. We entering the region for the first time, the enemy is alternating between stopping and moving. This only happens on the first time. If I reenter the region later, everything will work as usual. Here is the enemy script. I can provide a video if needed.

local enemy = ...
local going_hero = false
local m

function enemy:on_created()

  self:set_life(1)
  self:set_damage(2)
  self:create_sprite("enemies/fire_bat")
 
  self:set_size(16, 8)
  self:set_origin(8, 0)
  self:set_obstacle_behavior("flying")
  m = sol.movement.create("target")
end

function enemy:stopping()
  local sprite = self:get_sprite()
  sprite:set_animation("stopped")
  --m:stop()
  m:set_speed(0)
  going_hero = false
end



function enemy:on_restarted()
  local sprite = self:get_sprite()
  sprite:set_animation("stopped")
  --m:stop()
  m:set_speed(0)
  going_hero = false

  self:go_random()
  self:check_hero()
end

function enemy:check_hero()
  local hero = self:get_map():get_entity("hero")
  local _, _, layer = self:get_position()
  local _, _, hero_layer = hero:get_position()
  local near_hero = layer == hero_layer
    and self:get_distance(hero) < 150

  if near_hero and not going_hero then
    self:go_hero()
--self:set_speed(40)
sol.audio.play_sound("bat")

  elseif not near_hero and going_hero then
--self:set_speed(32)
    self:go_random()
  end

  sol.timer.stop_all(self)
  sol.timer.start(self, 100, function() self:check_hero() end)
end

function enemy:go_random()
  going_hero = false
  local sprite = self:get_sprite()
  sprite:set_animation("stopped")
  m:set_speed(0)
end

function enemy:go_hero()
  going_hero = true
  local sprite = self:get_sprite()
  sprite:set_animation("walking")
  m:set_speed(88)
  m:set_ignore_obstacles(false)
  m:start(self)
end


Thank you again for all your help!
#20
Hi,

I was wondering if it is possible to reset the enemies position when changing region in a map, when crossing a separator.

What I actually do is put a sensor at the start of each region of the map and reset the not already killed enemies position of the region. Is there an easier way?

I do the same trick instead of using enemy:set_optimization_distance() to stop the enemies of next rooms.

Thank you!
#21
Ok, nice, thank you!
#22
Hi, I am trying to port my data from V1.1 to V1.2. I checked the porting guide but there is no mention of this problem.

When I start the game I get:
Fatal: Cannot load font from file 'text/fixed8.fon': Couldn't set font size

There is a fixed8.fon that exist in /text in my data folder after I updated the files with the V1.2 editor. I am not sure of what the problem means. Could it be simply that the engine is trying to find the file in ./text instead of ./data/text?

hank you for your help.

Best regards.