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.


Messages - Max

Pages: [1] 2 3 ... 13
1
Quote
Is there any way I can share my whole data folder?
You could use something like gitlab or GitHub, they're designed for sharing exactly that kind of thing.

I don't know what might be causing that error- but maybe think about that you recently did before you got it.

The other day, for example, I was trying to call "hero:start_attack()", before the hero had the attack ability. The error I got was "Error: Cannot find sound file 'sounds/.ogg'

So it might be like, your code is looking for
"sprites/"..[a variable]
  but the variable is nil or equal to "", so it's trying to just use "sprites/" as a sprite, when in fact it's a directory.

Actually, thinking about those 2 errors, I think this explanation is pretty likely. Without seeing your code I couldn't tell you where, but probably somewhere in main, game_manager, or somewhere like that if it's being called as soon as the Solarus logo menu finishes.

2
Bugs & Feature requests / Re: Having Trouble with Quest simulation
« on: January 09, 2019, 06:08:49 am »
So, if you post your code like this:
Code: [Select]
[code=Lua]
Paste your code here
[\code]
(Except use a forward slash, not a backslash!)
It'll make it much easier to read for us : )

If you haven't changed anything in the game manager yourself on purpose, you should be able to copy the scripts from the 1.6 new quest into your current project. Or copy your current project's files into a new quest.

It looks like the problem is your main is calling game_manager:start_game(), which is not a function that the game manager you posted has. It looks like you might want to instead call game_manager:create("put the file name here")

For example, here's a couple lines in my main:
Code: [Select]
local game = game_manager:create"save1.dat"
  sol.main:start_savegame(game)

It sends a string, "save1.dat" to the game manager script to make a new game, or load one if it already exists, which the game_manager sends back as "game". Then we start that game with Sol.main.start_savegame

3
Development / Re: NPC disappears during walking animation?
« on: January 09, 2019, 05:58:23 am »
Yeah, when you apply a movement to an NPC, the engine knows you probably want the NPC to be walking, so it sets the walking animation, then automatically calls the stopped animation when the movement is finished.

4
Your scripts / Ball and Chain
« on: January 08, 2019, 06:45:15 pm »
I made this weapon last night, and thought you guys might want to put one together too. Basically, it's an item that when you use it, it creates a custom entity that can damage enemies, then creates a circular movement to swing it around your hero. I looked at how Christopho made arrows as a custom entity in his games to learn how to do this. I've started using this custom entity for a few new weapons I made because it's very versatile to have an entity that is basically just a weapon you can move.

For this recipe, you'll also need a hero animation called "charging", which is just the wind up before the hero swings the weapon. A useful animation to have for many weapons. Then it also uses the "hookshot" animation, which at least used to be required by the engine, for once you've swung the flail. You can change these to any animations you want, obviously.

Feel free to use this as you see fit! : )

Here's the custom entity script:
Code: (lua) [Select]
local sparkle = ...
local game = sparkle:get_game()
local map = sparkle:get_map() --actually, looking back over this, I don't think this line does anything

local damage = 10
local attack_type = "sword"

sparkle:set_can_traverse("crystal_block", true)
sparkle:set_can_traverse("hero", true)
sparkle:set_can_traverse("stairs", true)
sparkle:set_can_traverse("stream", true)
sparkle:set_can_traverse("switch", true)
sparkle:set_can_traverse("teletransporter", true)
sparkle:set_can_traverse_ground("deep_water", true)
sparkle:set_can_traverse_ground("shallow_water", true)
sparkle:set_can_traverse_ground("hole", true)
sparkle:set_can_traverse_ground("lava", true)
sparkle:set_can_traverse_ground("prickles", true)
sparkle:set_can_traverse_ground("low_wall", true)
sparkle:set_drawn_in_y_order(true)

function sparkle:on_created()
  --if you want to like, set the damage of this to your sword's damage, you can do that here
end

function sparkle:set_damage(amount) --this will let you adjust the damage it does for various weapons
  damage = amount
end

function sparkle:set_attack_type(type) --this is sword by default, but you could set it to arrows or something custom
  attack_type = type
end


-- Hurt enemies.
sparkle:add_collision_test("sprite", function(sparkle, entity)
  if entity:get_type() == "enemy" then
    local enemy = entity
    local reaction = enemy:get_attack_consequence(attack_type)
    if reaction ~= "protected" or reaction ~= "ignored" then
     enemy:hurt(damage)
    end
  end
end)



So that's the custom entity, then here's the ball and chain item. The code is a liiiittle messy, sorry.

Code: (lua) [Select]
local item = ...
local game = item:get_game()

-- Event called when the game is initialized.
function item:on_started()
  item:set_savegame_variable("possession_ball_and_chain")
  item:set_assignable(true)
end

-- Event called when the hero is using this item.
function item:on_using()
  local map = item:get_map()
  local hero = map:get_hero()
  local hero_dir = hero:get_direction()
  hero:freeze()
  local x, y, layer = hero:get_position()

  local MIN_RADIUS = 2 --leave this one
  local RADIUS = 64 --you can adjust this one to make the flail swing wider or narrower
 
  --now move x or y depending on hero facing direction
  local start_x = x
  local start_y = y
  if hero_dir == 0 then start_x = x - 16 elseif hero_dir == 1 then start_y = y + 16 elseif hero_dir == 2 then start_x = x + 16 elseif hero_dir == 3 then start_y = y - 16 end

  --create the spike ball
  local spike_ball = map:create_custom_entity{
    name = "spike_ball",
    direction = 0,
    layer = layer,
    x = start_x,
    y = start_y,
    width = 16,
    height = 16,
    sprite = "entities/spike_ball",
    model = "damaging_sparkle"
  }
  --I want the flail to do 1.5 times the damage of my sword, but you'll need to adjust this if that's not how your sword works!
  spike_ball:set_damage(game:get_value("sword_damage") + game:get_value("sword_damage")/2)

  local flail_x = x
  local flail_y = y
  local start_angle = 0
  if hero_dir == 0 then flail_x = x + 16 start_angle = 0
  elseif hero_dir == 1 then flail_y = y - 16 start_angle = math.pi / 2
  elseif hero_dir == 2 then flail_x = x - 16 start_angle = math.pi
  elseif hero_dir == 3 then flail_y = y + 16 end start_angle = 3 * math.pi / 2

  --create a movement for the flail
  local m = sol.movement.create("circle")
  m:set_center(flail_x, flail_y)
--  m:set_angle_from_center(start_angle)
  m:set_radius(MIN_RADIUS)
  m:set_radius_speed(100)
  m:set_max_rotations(2)
  m:set_angular_speed(13)
  if hero_dir == 0 or hero_dir == 3 then m:set_clockwise() end


  --START CHARGING (because this is too powerful to not charge)
  hero:set_animation("charging")
  sol.timer.start(game, 500, function()
    --AND GO! ATTACK!
    --Start the movements and change the hero's animation
    hero:set_animation("hookshot")
    sol.audio.play_sound("boomerang")
    m:start(spike_ball, function() spike_ball:remove() end)
    m:set_radius(RADIUS)
    --you have to set the radius after the movement is started, or else the flair will start fully extended,
    --and we want a growing and shrinking circle
  end)


  --end the movement if it doesn't collide with something
  function m:on_finished()
    hero:unfreeze()
    spike_ball:remove()
    item:set_finished()
  end

  --if the movement collides with something
  function m:on_obstacle_reached()
    sol.audio.play_sound("sword_tapping")

    --these commented out lines would cause an explosion if the flail contacts something.
    --it's kind of cool, but will definitely kill the hero along with all the enemies. It's wild. Don't use indoors.
--    if item:get_variant() >= 2 then
--      local spike_x, spike_y, spike_layer = spike_ball:get_position()
--      map:create_explosion{layer = spike_layer, x = spike_x, y = spike_y}
--    end
  end
end


5
Bugs & Feature requests / Re: Having Trouble with Quest simulation
« on: January 08, 2019, 06:20:14 pm »
What's in your game manager script? The problems you're having sound like ones that come from not having the basic files set up properly.

A bit of overview that might help you figure this stuff out- the only thing that the "run quest" button runs is main.lua. There, most likely, there's a like something like:
Code: [Select]
local game_manager = require("scripts/game_manager")Which means, now, in the main.lua script, whenever "game_manager" is written, it's referring to whatever the "scripts/game_manager" returns. Probably there ought to be a "start_game" function in your game manager, which would create or load a game.

What are you trying to run? A game you made yourself? Someone else's game? The default quest that is created when you go to file>new quest?

6
Bugs & Feature requests / Re: Having Trouble with Quest simulation
« on: January 06, 2019, 09:03:20 pm »
So, the whole "register event" stuff is from this "multi events" script that most everyone uses- have you added that, and if so, have you called it in the appropriate places?

I might not be understanding your whole problem if the multi-events system is working fine elsewhere though. Maybe post your whole game_manager script.

Also, are you trying to run your own quest? Someone else's? The default quest that is created when you make a new project?

7
Development / Re: Weird Stairs Issue
« on: January 02, 2019, 03:21:04 am »
I tried it, and unfortunately, although you can resize stairs to whatever size you want, they only activate when the hero is exactly lined up with the position of the 16x16 entity. The rest of the large stairs entity just operates as an invisible wall.

8
Development / Re: Weird Stairs Issue
« on: January 01, 2019, 03:58:40 pm »
What's a good idea, Alex! It could get the width for the stairs from it's own width, then create the sensors and invisible platform at it's coordinates. Good thinking.


Anyway, I was looking at the change log for 1.6 on the website's blog about the release, and saw this line:
Quote
Fix stairs activating when the hero is not exactly aligned.

And realized that's exactly what changed. Is there any way to un-fix this so I can make the behavior of my stairs back how it was?

9
Development / Re: Weird Stairs Issue
« on: December 31, 2018, 03:45:22 pm »
Thanks guys. I followed Christopho's tutorials, and now I've got it so I only need five tiles which I can copy from my debug map each time and the event is handled with metatables, which isn't too bad. However it still feels a little hacked together, since a function as basic as changing layers needs such a complex solution when I could just use stairs before, haha.

But I never liked how the automatic stairs took control away from the player so that's nice that it addresses that too! Now to just do this for dozens of stairs in my game, hahaha........

10
Development / Re: Weird Stairs Issue
« on: December 25, 2018, 05:23:41 pm »
Here's the results of using a sensor that does
Code: [Select]
for sensor in map:get_entities("stair_sensor") do
  function sensor:on_activated()
    hero:set_layer(hero:get_layer() + 1)
  end
end



Has anyone used sensors to move up layers and not had an issue with tiles on the upper layer overlapping the hero? How did you overcome that?

Also, just an observation from experimenting with the way stair entities work between 1.5 and 1.6- even if you just put a stair in the middle of an empty field in 1.5, you don't have to be perfectly aligned with it for the stair action to work. But in 1.6 even if a stair in the middle of a field, you have to be perfectly lined up with the tile for the stairs to do their thing.

11
Development / Re: Weird Stairs Issue
« on: December 23, 2018, 12:31:05 am »
It  actually is new to 1.6. I just opened up an old version of my game in 1.5 and there's no issues, tried the same staircase. I wonder what changed that it stopped working?

I'll figure out sensors then. What is the behavior of stairs besides some code like:
Code: (Lua) [Select]
function stair_sensor:on_activated()
 Hero:set_layer(hero:get_layer() +1)
end

Is forcing movement on the hero important, or if you don't make the hero move also will they just fall right back down immediately. Well, I guess I'll try it after I make some dinner and figure that out, lol

12
Development / Weird Stairs Issue
« on: December 22, 2018, 08:02:41 pm »
Hey guys, just downloaded 1.6 and I've got a weird issue.

It seems like platform stairs won't push the hero up a level unless you hit them EXACTLY straight on. For a staircase only 16px wide, this is no problem, but if a staircase is wider, the player might be moving up the stairs straddling two tiles- in this situation it seems like the entities act like a wall.

I've attached a gif that hopefully shows that's going on better, and a couple screenshots of the way the tiles are laid out.

Hopefully I've just been putting stairs together incorrectly this whole time and it's not the first post-release 1.6 bug?


13
Development / Re: How do you organize your quest data files?
« on: December 07, 2018, 12:30:05 am »
Lol, that stresses me out. Personally, the only things I want in my maps folder are subfolders, more subfolders, and a debug room.

My world is broken up into islands, which helps. But for each island's folder, I've got 4-10 overworld maps, and each area has a unique name. Then any towns have folders for building interior maps, and there's a folder for any small caves in the overworld. Anything mini-dungeon to main dungeon has its own folder inside its region's folder. Every island has the same file structure. I also wish I was a bit better organized, haha, but I think everyone always will.


I do my dialogues similarly. Every island has a folder for NPCs, observations the protagonist makes to herself (or reading books and posters), and signs. Inside each of those folders, there's sub folders dividing the category geographically, so like, signs in the forest region of Goatshead Island. There's maybe only one or two in some subfolders when you divide down this much, but it's consistent and I know where to look for stuff.
I think a fairly typical structure is like:
oakhaven_island/npc/oakhaven_port/portside_shop/shopkeeper/3
For major characters, sometimes they'll have several subfolders for each time you encounter them or different phases of a quest they're involved in, or else sometimes there will be different folders for the same character in different regions. This inconsistency bothers me but it's too late at this point!


It seems to me like you need some paths like maps/forest/tree, or maps/beach/water_dungeon/3. I don't know if your overworld makes sense to divide into regions with areas in each region, but if it even makes sense for a few areas, you should do that before you get even more disorganized, if it's stressing you out. Good workflow and workspaces lead to better work! :D

14
General discussion / Re: Need Help With Enemy Scripting
« on: October 30, 2018, 01:10:46 am »
I've made a spike trap enemy, and just heads up, it's surprisingly difficult. My method was to make it so they would go in any of the 4 directions if the hero's x/y lined up with theirs +/- 16px.

I think having the enemy check on_update() might be overkill. I usually run check_hero methods every 100ms or more, which have never been a noticeable delay. Idk what Solarus' framerate is, but having a timer run a checking method every 100ms is at last half the processing, if not less.

What that might look like is this:
function Enemy:check_hero()
--some code that gets the hero's coordinates and maybe calls another function if the hero is close or lined up
so.timer.start(enemy, 100, enemy:check_hero())
end

Basically, after the timer, it calls the function, which after the timer calls the function, which after the timer calls the function, which after the timer........

Christopho or someone might know better than me, but I don't think movement:on_finished() is called for interrupted movements. I would, just in case something weird happens, set a call back function for when the movement completes, as well as defining an on_obstacle_reached event.

One thing that, until 1.6 comes out, you could do is use the enemy's initial facing direction as a property to set which direction it's capable of going, but if you're totally new to coding, I'd recommend working on some different enemies first.

15
Your projects / Re: Some Maps I've been working on...
« on: October 28, 2018, 03:28:06 am »
Welcome : )
I really like the village you've got at the top, it seems nicely laid out and uses various heights in an interesting way. I appreciate how everything is sectioned and compartmentalized, but also looks easy to navigate.

Some of the other ones share a trait of having long, open borders. It's usually better to have smaller "doors" between areas, but keep it up? Are you planning on making a game?

Pages: [1] 2 3 ... 13