Juryiel's Forum Posts

  • Update again:

    I put NonPlayers overlaps Players check in the LOS function under a "Players: Pick by Players.Value('ClassID') Equal 2"

    When I do that even if the player with ClassID=1 goes into LOS the NonPlayers will 'see' the player with ClassID=2. To me this suggests that the condition: NonPlayers overlaps Players does not respect picking (since I'm picking Player with CLassID=2 specifically right before I call it, yet it still triggers when Player with ClassID=1 goes into LOS)

    Grumble grumble grumble, now what?

    EDIT: Replaced the NonPlayers overlaps Players check with:

    Players overlaps NonPlayers (offset is now Players.X-NonPlayers.X-global('LOS_X'), etc). This seems to work. I expected the Player to be picked correctly but expected the NonPlayers to all agro when only one was in LOS since my guess of what was going on was that the second family in teh overlap comparison ignored picking. So now I'm totally confused.

  • LOS Sprite is not flexible enough for what I want to do. I want to be able to fully control which points are checked for LOS specifically, including Max radius, min radius, max angle, min angle (min angle not implemented yet but will be), and even specific points.

    Also, the NonPlayers are picked correctly. It's the players who are not, so a container of NonPlayers with LOS Sprites wouldn't likely solve this issue.

  • Update:

    If I put the text where it says Function.Return Equal 1, it still returns both ClassIDs, (in fact it always returns both, right now I have 2 players, and the order it returns them in is 2,1, which is why I was getting 1 all the time before, since it always came last).

    So it looks like regardless of which player goes into LOS, the LOS function returns 1 for both Players the moment only one of them goes into LOS. Hmmm.

  • Just to add, the idea of the loops is:

    I want to have every NonPlayer check LOS with every player. So I thought the straightforward way to do that is to Loop through each NonPlayer and each of them checks every player for LOS. Don't get confused by the Super loop, it's just storing data and checking data structures, but the data it's storing is not yet being used (since it is not hte correct data)

  • Here's the idea of what I"m trying to do (not necessarily what I'm actually doing).

    I only want to check LOS every X milliseconds. I want each individual NonPlayer to have its own check Every X + Random(200) milliseconds so that they don't all happen at the same frame. Temporal resolution is unimportant for these types of LOS checks (the player will not move out of LOS in less than 1 second unless he's teetering on the edge of the cone, and if he is that's fine). On the other hand I plan to have many enemies at once, up to 30-40+ in some instances so I want the checks to be staggered in time and not cause lag. Right now the way it's set up it's not quite doing that, instead it picks a random NonPlayer and does LOS on that NonPlayer. I tried deactivating the Every X event just now and it didn't fix the problem, but it did make the game unplayably laggy. I also tried disabling the superloop and moving the text as you described and yes, it shows all of the Player ClassIDs

    As for the Super loop, that checks to see if a player has already been added to the Hatelist of an enemy. When a NonPlayer sees a Player, that Player is added to the NonPlayer's Hatelist. This is because even if the player tries to move out of LOS, the NonPlayer has already seen him and begins to look for him outside of his LOS range. The thing is, players can build aggro, which is stored in that Super. THere are 6 players, and they can build aggro / hate with their actions, which is then used by the AI to determine its actions. If an enemy has already seen a player, I do not want to reset his aggro levels at every LOS check, so I loop through the Super that stores HateSlots, which are number arrays containing the Player.Value('ClassID') and the Player aggro levels. If a HateSlot with a ClassID matching the current Players.Value('ClassID') is found, then nothing is done since the enemy has already seen that player and now other code runs.

    In short I don't think I can get away with disabling the Super Loop. Also I don't think that it's the problem since that's not really doing anything to picking, it's just storing data that isn't used until another part of the code.

    I could PM you a cap if you woudl like but it is super complicated. Those are the only parts of the code that are relevant to this behavior, I think, but I could be wrong.

  • Right, I am also using my own LOS system, as you can see by the function I posted above :) I stole it from the thread I linked above and the basic idea is that I check if player and enemy overlap certain offsets. Those offsets are placed along a cone that defines the LOS.

    The function itself can be quite demanding if you have many enemies checking LOS. As such, I made one change from the function in tulamide's linked post which, although I don't think are relevant to the issue I'm having, I might as well explain so people can see what the code is doing. You have 3 parameters to balance to get LOS working as you want, and those are spatial resolution, temporal resolution, and performance. You can trade performance to increase temporal and spatial resolution (check LOS more frequently or add more points along the cone where you check). The noise parameters in teh function are a way to trade temporal resolution to improve spatial resolution instead of trading performance for it. That is, instead of checking many points at specific locations along the LOS cone, you check a few randomly and uniformly distributed points, and run a few tests so that the cone is covered entirely after X tests. The idea is that you can take yoru time running the tests so that not all points are checked in the same frame, thus not sacrificing performance, but instead sacrificing temporal resolution in order to eventually cover the whole cone. So that's what teh noise parameters are doing, and everything else is explained in the linked tulamide's thread (but again, just check for overlap at offsets arranged in an LOS cone).

  • I have the following events:

    <img src="https://dl.dropbox.com/u/30864403/constructcode.jpg" border="0" />

    And the LOS function that is called is the one found in the third post by tulamide here:

    scirra.com/forum/solved-custom-lineofsight-issue_topic43661.html

    Here's an image of its code

    <img src="https://dl.dropbox.com/u/30864403/constructcode2.jpg" border="0" />

    The LOS checks if a member of the family NonPlayers has LOS on a member of the family called Players.

    The issue is that if I move a Player with ClassID=2 into LOS of a NonPlayer, it still acts as if I moved the Player with ClassID=1 into LOS (The toggled off Debug Text also reports 1 for ClassID when I turn it on), as if picking isn't working with the For Each. Why is that?

    Thanks for any help, and let me know if you need any more info. Sorry I'm not sure how to post bigger images, but if you copy the image url and paste it in a new tab you should be able to see it better.

  • Is it possible to sort things in S? Specifically, I have the following setup:

    {"SuperArray","SubSuperArray","NumberArray"} and each "NumberArray" has 2 values. I want to take the second one of those values (at index 1) and use it to sort the various NumberArrays. Is that possible without writing some sort of sorting algorithm and a separate structure to hold the values? (I want to basically access value 1 in each NumberArray" in the order determined by value 2)

  • Ah great, thanks. Is it possible to resize the tiled background texture? I want to use the images in a couple of places with different sizes and I'd rather not make copies just for that. If not I can try the Unique sprite plugin.

    HMM seems like the image scale changes the image size but it seems unintuitive how I have to offset it. At 0 0 offset the image is off center regardless if I set hotspot and image point to 0, 0 or to the center of the image.

    Edit: Ahh figured out to offset by the amount I'm resizing and it works good, thanks :)

  • I think I asked a similar question about this and forgot the answer, and can't find it in the forums so here it is, possibly again.

    I'm using Create Object at runtime to create some sprites from the same object and using the Load Frame from file to set their picture. This sets teh same picture (the last one loaded) to all sprites. I'm sure this has to do with the fact that they're all instances (I remember this being the reason from my prior post anyway) but I forgot what to do about it. Do I just not use sprites and use a different object?

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I see, thanks for the input, sounds like I need to use a variable as you mentioned because I do need to see how much time is left. Thanks!

  • I'm making a game which runs in real-time and not turn-based. With the help of this community and the S plugin I've managed to finish the guts of a semi-complicated ability system (yay, thanks!) but ran into an issue in putting finishing touches on it. I need to create a cast time for each ability. Each character and NPC can use one ability at a time that takes some pre-set time to use. I was wondering what the most accurate way to implement this would be.

    I've read about issues with frame-rate and timers, which I would like to avoid. In addition, I read that using the timer behavior can cause issues when dealing with multiple instances of an object, or something of that nature, and that "Every X" command botches picking.

    Not sure what other issues there are, but what would be the best way to implement a cast-time when an ability is used so that:

    1. The timer is as accurate as possible since it will be necessary for balancing issues

    2. The timer avoids known bugs

    3. The timer preserves the real-time nature of the game so that other events can run freely while the timer counts down.

    4. The timer works with instances of the same object.

    Thanks for your input :)

  • Hmm ran into another problem:

    Make Super Array {""}: "NPCDebuffs" with default 0

    For Each NonPlayers (this is a family)

    ->S: insert super "default" to {"NPCDebuffs"}

    ->S: Make Super Array {"NPCDebuffs", S.sule({"NPCDebuffs"})}: str(NonPlayers.UID)

    ->DebugText: Set text to DebugText.Text & str(S.sule({NPCDebuffs",str(NonPlayers.UID)})) & " "

    This will cause a crash. But if I put in the UID of the lowest NonPlayers object ("290" in this case), it works correctly. If I put in any of the other ones ("293", "296", "299" in this case), it will crash.

    However, if I check the Size-1 of the "NPCDebuffs" super, it is actually 3, which is correct. So I guess the arrays are not being named correctly for whatever reason. Is there some way I can check the names ?

    if I change ->S: Make Super Array {"NPCDebuffs", S.sule({"NPCDebuffs"})} to remove the S.sule, then it works. So I guess I'm still missing how this works conceptually speaking.

    One other issue, is that if I try to get the size-1 of an array that's empty, I get a very large number. Is there some other way to determine if an array is empty?

  • Ok I figured out how to do what I want. I didn't realize that array names and indices are not interchangeable (e.g. that if you want Value 3, in Array2, located in Array1, you don't do {"Array1",0,2} but you do {"Array1",0,"Array2",2}) but instead you specify the name of the array, and then the index you want. That was a bit confusing to me but I see why it was done the way it was and it is clearly the best way to do it even if unintuitive to noobs like me at first.

    However, it seems that "end" doesn't work in the {""} address method. Instead, I have to do something like {"Array1",0,"Array2",S.sule({"Array1","Array2"})) to get the last element in Array2 or to add elements to the last structure in Array2 (note that this is different from adding to the last element in Array2 in which case you can add to "end")

    Well it works, yay. If there's a better method to refer to the last element in {""} notation that would be great, I tried to parse the tutorials for the 50th time in figuring out my issues, but I seem to lose track and get confused of how this works :)

  • Hmm, how to reference the specific string array then?

    So I have a Super "ASDF"

    String array "stringasdf1"

    String array "stringasdf2"

    ...

    String array "stringasdfN"

    Each has 3 strings in it.

    I want to loop through the string arrays in "ASDF" (so not through the actual strings, but the arrays 1 to N themselves). However, I don't actually know the names ahead of time and there can be a wide variety of names, so I want some numerical or loop-based (e.g. current array in loop, loopindex, etc) way to access them. however, if I do:

    {"ASDF","stringasdf1",1} this works but

    {"ASDF",0,1} this doesn't work (or also loopindex instead of 0 doesn't work). How do i go about doing this?

    I also tried using "l" but it's also crashing so I must be doing something wrong. I did this:

    For Each Super in "ASDF"

    S.s({"ASDF","stringasdf1",0}) ####This works

    S.s({"l","loopname",0}) ####This crashes.