RMRK is retiring.
Registration is disabled. The site will remain online, but eventually become a read-only archive. More information.

RMRK.net has nothing to do with Blockchains, Cryptocurrency or NFTs. We have been around since the early 2000s, but there is a new group using the RMRK name that deals with those things. We have nothing to do with them.
NFTs are a scam, and if somebody is trying to persuade you to buy or invest in crypto/blockchain/NFT content, please turn them down and save your money. See this video for more information.
Calculate Movable Spaces Trouble

0 Members and 1 Guest are viewing this topic.

***
Rep:
Level 87
 I apologize in advance if this was supposed to be placed in the Scripts Support area, but I'm pretty sure help needed with others scripts goes here :P

 I have been working on a Tactical Turn-Based game. Unfortunately, I want to make it in VX, (I like RGSS2 alot better :),) and so far there are no TBSs out since GTBS, which is not compatible with VX. Not only this, but there are numerous kinks with GTBD I want to get out, and many components I don't need (isometric, etc) that just get in the way of what I want. I'm therefore attempting to just do my own coding entirely, which has so far been perfectly fine, seeing as I've avoided the most basic and daunting thing: the game system. :( (I've been messing around with custom inventory systems and the like)

 The biggest problem I am having is the very first thing to be done: moving... I first tried to find out logically the method behing moving, obstacles, terrain that "slows you down", etc (think: Fire Emblem) but I was at a loss for anything simple. So, I searched my folders and pulled out an old DL of Gubid's TBS, and took a look at what he did. I actually yelled out loud when I saw the 800 line method, calc_pos, the method for determining movable spaces. I took a long study of it, and after cropping out all the isometric and "ENCOUNTER MOVE METHOD" optional code found it the be only 400 lines. ;)
Nonetheless, this script is still proving disastrously hard to integrate into a fellow RMXP project, let alone VX. The even sadder part is, I haven't even addressed AI -_-...

 So, I have two questions:
1) Should I just leave this and wait until someone makes a TBS? (I'm still a bit new to scripting anything beyond simple -_-, but it would make me sad to abandon this :()

2) Can someone take a look at this calc_pos method and try to make a friendlier version of it that I can integrate into VX or at least a new RMXP project? Even just explaining how this monster method works would be fine. (Just leave a comment for any variables I need to account for, such as base_move or an actor's x and y coords)
Also, for check_th, I haven't a clue what's going on there -_-.

Original GTBS

This is the watered down version of def calc_pos without the needless iso and ENCOUNTER METHOD branches
Spoiler for "Calculate Positions Method":
Code: [Select]
  #----------------------------------------------------------
  #Calc_Pos - calculates tiles to be highlighted for spells, move, attack
  #----------------------------------------------------------
  def calc_pos(actor, range_max = 0, range_min = 0, type = "all", override = false)
    positions = []
    unless range_max == nil
      if range_max > -1 and type == "all"
        if @move_positions.size > 1 and override == false
          range_max -= actor.base_move_range
          if range_min == actor.base_move_range + actor.attack_skill_range
            range_min -= actor.base_move_range
          end
        end
        case range_max
        when 0
          positions.push([actor.x, actor.y])       
        else
          positions.push([actor.x, actor.y]) #starting position
          th = check_th(actor.x, actor.y)
          for position in @move_positions
            x = position[0]
            y = position[1]
            #cross pattern add stuff
            #    #
            #   ###
            #    #
            for ox in (range_min+1)..(range_max)
              positions.push([x - ox, y]) unless !valid?(actor.x - ox, actor.y) or positions.include?([x - ox, y])
              positions.push([x + ox, y]) unless !valid?(actor.x + ox, actor.y) or positions.include?([x + ox, y])
              positions.push([x, y - ox]) unless !valid?(actor.x, actor.y - ox) or positions.include?([x, y - ox])
              positions.push([x, y + ox]) unless !valid?(actor.x, actor.y + ox) or positions.include?([x, y + ox])
            end
            #fill in gaps between cross for full fill
            #     #
            #    ###
            #   #####
            #    ###
            #     #
            for i in (range_min+1)..range_max-1
              it = range_max - i
              unless it < 0
                loop do
                  if $game_map.iso?
                    positions.push([x - it, y - (range_max - (it + i - 1))]) unless !valid?(x - it, y - (range_max - (it + i - 1))) or positions.include?([x - it, y - (range_max - (it + i - 1))]) or check_th(x - it, y - (range_max - (it + i - 1))) - 10 > th
                    positions.push([x - it, y + (range_max - (it + i - 1))]) unless !valid?(x - it, y + (range_max - (it + i - 1))) or positions.include?([x - it, y + (range_max - (it + i - 1))]) or check_th(x - it, y + (range_max - (it + i - 1))) - 10 > th
                    positions.push([x + it, y + (range_max - (it + i - 1))]) unless !valid?(x + it, y + (range_max - (it + i - 1))) or positions.include?([x + it, y + (range_max - (it + i - 1))]) or check_th(x + it, y + (range_max - (it + i - 1))) - 10 > th
                    positions.push([x + it, y - (range_max - (it + i - 1))]) unless !valid?(x + it, y - (range_max - (it + i - 1))) or positions.include?([x + it, y - (range_max - (it + i - 1))]) or check_th(x + it, y - (range_max - (it + i - 1))) - 10 > th
                  else
                    positions.push([x - it, y - (range_max - (it + i - 1))]) unless !valid?(x - it, y - (range_max - (it + i - 1))) or positions.include?([x - it, y - (range_max - (it + i - 1))])
                    positions.push([x - it, y + (range_max - (it + i - 1))]) unless !valid?(x - it, y + (range_max - (it + i - 1))) or positions.include?([x - it, y + (range_max - (it + i - 1))])
                    positions.push([x + it, y + (range_max - (it + i - 1))]) unless !valid?(x + it, y + (range_max - (it + i - 1))) or positions.include?([x + it, y + (range_max - (it + i - 1))])
                    positions.push([x + it, y - (range_max - (it + i - 1))]) unless !valid?(x + it, y - (range_max - (it + i - 1))) or positions.include?([x + it, y - (range_max - (it + i - 1))])
                  end
                  it -= 1
             
                  break if it == 0
                end
              end
            end
          end
        end
      elsif range_max > -1 and type == "move"
        case range_max
        when 0
          positions.push([actor.x, actor.y])
          return positions
        else
          positions.push([actor.x, actor.y])              #push starting position
          start_move = true
          route = [[]]                                    #initialize route
          cost = [0]                                      #start position cost = 0
          more_step = [0]                                 #initialize array
          for i in more_step                              #each step in position
            x = positions[i][0]                           #set x for index
            y = positions[i][1]                           #set y for index
            c = cost[i]                                   #set cost for current postion index
            th = check_th(x,y)                            #get current tile height
           
            if actor.passable?(x, y, 2)                   #if can pass down?
              tt = $game_map.terrain_tag(x, y + 1)         #get terrain tag
              if tt > 4                                   #is terrain tag less than 4?
                tt = 0                                    #else, tt = o
              end
              nth = check_th(x, y+1)                      #get new tile height
              if c+1+tt <= range_max                      #if current route cost + 1 + terrain tag value <= move_range
                if positions.include?([x, y + 1])         #if up already found? (yes)
                  index = positions.index([x, y + 1])     #set index for position
                  unless index == i
                    if cost[index] > c+1+tt                 #is new route found less costly?
                      route[index].clear                    #reset existing route
                      route[index] = route[i] + [2]         #set new route
                      cost[index] = c+1+tt                  #replace cost table for pos
                    elsif cost[index] == c+1+tt             #is new route just as costly?
                      if rand(2) == 0                       #randomly replace, 1/3 chance
                        route[index].clear
                        route[index] = route[i] + [2]       #replace route
                        cost[index] = c+1+tt                #replace cost table for pos
                      end
                    end
                  end
                else                                      #up not found..
                  positions.push([x, y + 1])              #add position to positions array
                  route.push(route[i] + [2])              #add route for position
                  cost.push(c+1+tt)                       #add cost required for position
                  if route[i].size + 1 < range_max         #can one more step?
                    more_step.push(route.index(route[i] + [2])) #push more step for position
                  end
                end
              end
            end
             
            #comments repeat for each direction
            if actor.passable?(x, y, 4) #left
              tt = $game_map.terrain_tag(x - 1,y)
              if tt > 4
                tt = 0
              end
              nth = check_th(x, y+1)                      #get new tile height
              if c+1+tt <= range_max               
                if positions.include?([x - 1, y])
                  index = positions.index([x - 1, y])
                  if cost[index] > c+1+tt
                    route[index].clear
                    route[index] = route[i] + [4]
                    cost[index] = c+1+tt
                  elsif cost[index] == c+1+tt
                    if rand(2) == 0
                      route[index].clear
                      route[index] = route[i] + [4]
                      cost[index] = c+1+tt
                    end
                  end
                else
                  positions.push([x - 1, y])
                  route.push(route[i] + [4])
                  cost.push(c+1+tt)
                  if c+1+tt < range_max
                    more_step.push(route.index(route[i] + [4]))
                  end
                end     
              end
            end
           
            if actor.passable?(x, y, 6) #right
              tt = $game_map.terrain_tag(x + 1,y)
              if tt > 4
                tt = 0
              end
              nth = check_th(x, y+1)                      #get new tile height
              if c+1+tt <= range_max
                if positions.include?([x + 1, y])
                  index = positions.index([x + 1, y])
                  if cost[index] > c+1+tt
                    route[index].clear
                    route[index] = route[i] + [6]
                    cost[index] = c+1+tt
                  elsif cost[index] == c+1+tt
                    if rand(2) == 0
                      route[index].clear
                      route[index] = route[i] + [6]
                      cost[index] = c+1+tt
                    end
                  end
                else
                  positions.push([x + 1, y])
                  route.push(route[i] + [6])
                  cost.push(c+1+tt)
                  if c+1+tt < range_max
                    more_step.push(route.index(route[i] + [6]))
                  end
                end
              end
            end
           
            if actor.passable?(x, y, 8) #Up
              tt = $game_map.terrain_tag(x,y - 1) #get terrain tag
              if tt > 4 #is terrain tag less than 4?
                tt = 0 #else, tt = o
              end
              nth = check_th(x, y-1)                      #get new tile height
              if c+1+tt <= range_max #if current route cost + 1 + terrain tag value <= move_range
                if positions.include?([x, y - 1]) #if up already found? (yes)
                  index = positions.index([x, y - 1])
                  if cost[index] > c+1+tt #is new route found less costly?
                    route[index].clear
                    route[index] = route[i] + [8] #replace route
                    cost[index] = c+1+tt       #update cost table for pos
                  elsif cost[index] == c+1+tt #is new route just as costly?
                    if rand(3) == 0 #randomly replace, 1/3 chance
                      route[index].clear
                      route[index] = route[i] + [8] #replace route
                      cost[index] = c+1+tt     #replace cost table for pos
                    end
                  end
                else    #up not found..
                  positions.push([x, y - 1]) #add position to positions array
                  route.push(route[i] + [8]) #add route for position
                  cost.push(c+1+tt) #add cost required for position
                  if c+1+tt < range_max #can one more step?
                    more_step.push(route.index(route[i] + [8])) #push more step for position
                  end
                end
              end
            end
            if start_move
              start_move = false
            end
            #--------------------------------------------------------------
            # Old path finding method
            #--------------------------------------------------------------
            #if actor.passable?(x, y, 8) #!positions.include?([x, y - 1]) and
            #  positions.push([x, y - 1])
            #  route.push(route[i] + [8])
            #  if route[i].size + 1 < range_max
            #    more_step.push(route.index(route[i] + [8]))
            #  end
            #end
          end
        end
        need_del = [] #initialize need_del array
        for pos in positions #check all positions
          if occupied?(pos[0], pos[1]) #position occupied?
            r = route[positions.index(pos)] #read route for position
            need_del.push([pos, r]) #add position and route to array for deletion
          end         
        end
        if need_del.size > 0 #if array size > 0
          loop do #run loop
            p = need_del[0][0] #read path
            r = need_del[0][1] #read route
            route.delete(r) #delete route
            positions.delete(p) #delete path
            need_del.delete([p,r]) #update need_del array
            if need_del.size == 0 #if need_del == 0
              break  #break loop
            end
          end
        end
        @route = route #set route as instance variable instead of local only.
      elsif range_max > -1 and type == "attack"
        if @move_positions.nil?
          @move_positions = [[actor.x, actor.y]]
        end
        if @move_positions.size > 1
          range_max -= actor.base_move_range if override == false
        end
        for position in @move_positions
          x = position[0]
          y = position[1]
          if range_max == 0 and range_min == 0
            positions.push([x, y])
          end
          for ox in (range_min+1)..(range_max)           
            positions.push([x - ox, y]) unless positions.include?([x - ox, y]) or !valid?(x - ox, y)
            positions.push([x + ox, y]) unless positions.include?([x + ox, y]) or !valid?(x + ox, y)
            positions.push([x, y - ox]) unless positions.include?([x, y - ox]) or !valid?(x, y - ox)
            positions.push([x, y + ox]) unless positions.include?([x, y + ox]) or !valid?(x, y + ox)
          end
        end
      elsif range_max > -1 and type == "spell"
        case range_max
        when 0
          positions.push([actor.x, actor.y])       
        else
          positions.push([actor.x, actor.y])
          for ox in (range_min+1)..(range_max)           
            positions.push([actor.x - ox, actor.y]) unless !valid?(actor.x - ox, actor.y) or positions.include?([actor.x - ox, actor.y])
            positions.push([actor.x + ox, actor.y]) unless !valid?(actor.x + ox, actor.y) or positions.include?([actor.x + ox, actor.y])
            positions.push([actor.x, actor.y - ox]) unless !valid?(actor.x, actor.y - ox) or positions.include?([actor.x, actor.y - ox])
            positions.push([actor.x, actor.y + ox]) unless !valid?(actor.x, actor.y + ox) or positions.include?([actor.x, actor.y + ox])
          end
          for i in (range_min+1)..range_max-1
            it = range_max - i
            unless it < 0
              loop do               
                positions.push([actor.x - it, actor.y - (range_max - (it + i - 1))]) unless !valid?(actor.x - it, actor.y - (range_max - (it + i - 1))) or positions.include?([actor.x - it, actor.y - (range_max - (it + i - 1))])
                positions.push([actor.x - it, actor.y + (range_max - (it + i - 1))]) unless !valid?(actor.x - it, actor.y + (range_max - (it + i - 1))) or positions.include?([actor.x - it, actor.y + (range_max - (it + i - 1))])
                positions.push([actor.x + it, actor.y + (range_max - (it + i - 1))]) unless !valid?(actor.x + it, actor.y + (range_max - (it + i - 1))) or positions.include?([actor.x + it, actor.y + (range_max - (it + i - 1))])
                positions.push([actor.x + it, actor.y - (range_max - (it + i - 1))]) unless !valid?(actor.x + it, actor.y - (range_max - (it + i - 1))) or positions.include?([actor.x + it, actor.y - (range_max - (it + i - 1))])
               
                it -= 1
                break if it == 0
              end
            end
          end
        end
      elsif range_max > -1 and type == "bow"
        #if range_max == actor.weapon_range[0] + actor.base_move_range
        #  range_max -= actor.base_move_range
        #  range_min -= actor.base_move_range
        #end
        #p range_max
        case range_max
        when 0
          positions.push([actor.x, actor.y])
        else
          all_pos = []
          for position in @move_positions
            ox = position[0]
            oy = position[1]
            if range_max == 0 and range_min == 0
              positions.push([ox, oy])
            end
            positions = []
            positions2 = []
            positions.push([ox, oy])
            route = [[]]
            more_step = [0]
            for i in more_step
              x = positions[i][0]
              y = positions[i][1]
              th = check_th(ox,oy)
              if !positions.include?([x, y + 1]) and $game_map.valid?(x, y + 1)
                positions.push([x, y + 1])
                route.push(route[i] + [2])
                if route[i].size + 1 < range_max
                  more_step.push(route.index(route[i] + [2]))
                end
              end
              if !positions.include?([x - 1, y]) and $game_map.valid?(x - 1, y)               
                positions.push([x - 1, y])
                route.push(route[i] + [4])
                if route[i].size + 1 < range_max
                  more_step.push(route.index(route[i] + [4]))
                end
              end
              if !positions.include?([x + 1, y]) and $game_map.valid?(x + 1, y)
                positions.push([x + 1, y])
                route.push(route[i] + [6])
                if route[i].size + 1 < range_max
                  more_step.push(route.index(route[i] + [6]))
                end
              end
              if !positions.include?([x, y - 1]) and $game_map.valid?(x, y - 1)
                positions.push([x, y - 1])
                route.push(route[i] + [8])
                if route[i].size + 1 < range_max
                  more_step.push(route.index(route[i] + [8]))
                end
              end
            end
            positions2.push([ox, oy])
            route2 = [[]]
            more_step2 = [0]
            if range_min != 0
            for i in more_step2
              x = positions2[i][0]
              y = positions2[i][1]
              if !positions2.include?([x, y + 1]) and $game_map.valid?(x, y + 1)
                positions2.push([x, y + 1])
                route2.push(route2[i] + [2])
                if route2[i].size + 1 < range_min
                  more_step2.push(route2.index(route2[i] + [2]))
                end
              end
              if !positions2.include?([x - 1, y]) and $game_map.valid?(x - 1, y )
                positions2.push([x - 1, y])
                route2.push(route2[i] + [4])
                if route2[i].size + 1 < range_min
                  more_step2.push(route2.index(route2[i] + [4]))
                end
              end
              if !positions2.include?([x + 1, y]) and $game_map.valid?(x + 1, y )
                positions2.push([x + 1, y])
                route2.push(route2[i] + [6])
                if route2[i].size + 1 < range_min
                  more_step2.push(route2.index(route2[i] + [6]))
                end
              end
              if !positions2.include?([x, y - 1]) and $game_map.valid?(x, y - 1)
                positions2.push([x, y - 1])
                route2.push(route2[i] + [8])
                if route2[i].size + 1 < range_min
                  more_step2.push(route2.index(route2[i] + [8]))
                end
              end
            end
            end#end range min 0 check
            for pos in positions2
              if positions.include?(pos)
                positions.delete(pos)
              end
            end
            for pos in positions
              if !all_pos.include?(pos)
                all_pos.push(pos)
              end
            end
          end
          positions = all_pos
        end
      end
    end
    return positions
  end
« Last Edit: May 02, 2009, 08:15:58 AM by da good king »

********
Resource Artist
Rep:
Level 94
\\\\\
Project of the Month winner for June 2009
so far there are no TBSs out since GTBS,

yes there is. by the same guy. He made it for VX too. I had it for a while, but i got rid of it since I didn't have the resources for it and i didn't feel like making the resource for it. it worked fine. it was also isometric.

also, even tho this is a complicated script for probably yourself (as you said you are fairly new), i wouldn't give up on this, but i also wouldn't make this your priority. Just make other scripts and learn more while making this in the background adding new things you've learned. never the less, a non isometric TBS would be pretty cool so good luck on making this :)

*
Rep:
Level 97
2014 Most Unsung Member2014 Best RPG Maker User - Engine2013 Best RPG Maker User (Scripting)2012 Most Mature Member2012 Favorite Staff Member2012 Best RPG Maker User (Scripting)2012 Best MemberSecret Santa 2012 ParticipantProject of the Month winner for July 20092011 Best Use of Avatar and Signature Space2011 Best RPG Maker User (Scripting)2011 Most Mature Member2011 Favourite Staff Member2011 Best Veteran2010 Most Mature Member2010 Favourite Staff Member
Yeah, I don't know if I would want to start out with a TBS. I'm kind of thinking of making a TBS for VX, but I probably wouldn't release it publicly. As for calculating that, I don't see why it should be a 400 line method. Well, I sort of do, but you can use other scripts to help you out. A) My pathfinding script could be adapted for this purpose, and B) I think KGC made a terrain tag script which could be used for slowdown and stuff. Anyway, good luck.

***
Rep:
Level 87
 Thanks for all the good advice :) I'll search that pathfinding script as I too was skeptical of calc_pos's length (I starting reading the whole thing to rap my mind around the logic, but there were too many unrecognized variables that I somehow couldn't find their definition in his 20+ scripts...

 If I wasn't so sure I wanted a TBS, I'd probably change up :P After playing a certain Wii Fire Emblem however, I'm certain I want to make one soon if not now. Alot of things lacked in that game.) I'm still working out a few decisions, but I think leaving this for now and coming back later will be the best course to take, as I'll soon have summer break to get some free time for this :d