Paste #48746: Actually God, don't save me

Date: 2018/07/29 14:51:45 UTC-07:00
Type: Denizen Script

View Raw Paste Download This Paste
Copy Link


random_dungeon_sys_initializer:
  type: task
  debug: false
  speed: 0
  definitions: x|y|preset
  script:
  - define x <def[x].as_decimal.round_down.max[20]||20>
  - define y <def[y].as_decimal.round_down.max[20]||20>
  - define id <util.random.uuid.replace[-]>
  - yaml create id:random_dungeon_sys_d<def[id]>
  - yaml set width:<def[x]> id:random_dungeon_sys_d<def[id]>
  - yaml set length:<def[y]> id:random_dungeon_sys_d<def[id]>
  - yaml set preset:<def[preset]> id:random_dungeon_sys_d<def[id]>
  - repeat <def[x]> {
    - define data_x <def[value]>
    - repeat <def[y]> {
      - yaml set tiles.<def[data_x]>_<def[value]>:wall id:random_dungeon_sys_d<def[id]>
    }
  }

random_dungeon_sys_room_gen:
  type: task
  debug: false
  speed: 0
  definitions: id
  script:
  - define area '<custom@random_dungeon_object[id=<def[id]>].width.mul[<custom@random_dungeon_object[id=<def[id]>].length>]>'
  - define room_centers li@

  ###### Try rooms
  - define tries <def[area].div[125].round_down.max[1]>
  - define giveup 0
  - while <def[tries]> > 0 && <def[giveup]> < 50 {
    - define ext_x <util.random.int[4].to[<custom@random_dungeon_object[id=<def[id]>].width.div[3]>]>
    - define ext_y <util.random.int[4].to[<custom@random_dungeon_object[id=<def[id]>].length.div[3]>]>
    - define start_x '<util.random.int[1].to[<custom@random_dungeon_object[id=<def[id]>].width.sub[<def[ext_x].add[2]>]>]>'
    - define start_y '<util.random.int[1].to[<custom@random_dungeon_object[id=<def[id]>].length.sub[<def[ext_y].add[2]>]>]>'
    - foreach <yaml[random_dungeon_sys_d<def[id]>].read[rooms]||li@> {
      - if <def[start_x]> <= <def[value].before[_].add[<def[value].after[/].before[_]>].add[1]>
        && <def[start_y]> <= <def[value].after[_].before[/].add[<def[value].after_last[_]>].add[1]>
        && <def[start_x].add[<def[ext_x]>]> >= <def[value].before[_].sub[1]>
        && <def[start_y].add[<def[ext_y]>]> >= <def[value].after[_].before[/].sub[1]> {
        - define giveup <def[giveup].add[1]>
        - while next
      }
    }
    - yaml set rooms:->:<def[start_x]>_<def[start_y]>/<def[ext_x]>_<def[ext_y]> id:random_dungeon_sys_d<def[id]>
    - repeat <def[ext_x]> {
      - define tiledata_x <def[value].sub[1]>
      - repeat <def[ext_y]> {
        - yaml set tiles.<def[start_x].add[<def[tiledata_x]>]>_<def[start_y].add[<def[value].sub[1]>]>:floor_room id:random_dungeon_sys_d<def[id]>
      }
    }
    - define room_centers <def[room_centers].include[<def[start_x].add[<def[ext_x].div[2].round_down>]>_<def[start_y].add[<def[ext_y].div[2].round_down>]>]>
    - define giveup 0
    - define tries <def[tries].sub[1]>
  }
  - foreach <def[room_centers]> {
    - yaml set extra.room_centers:->:<def[value]> id:random_dungeon_sys_d<def[id]>
  }
  - yaml set tiles.<def[room_centers].last>:floor_exit id:random_dungeon_sys_d<def[id]>
  - yaml set floor_exit:<def[room_centers].last> id:random_dungeon_sys_d<def[id]>

random_dungeon_sys_corridor_gen:
  type: task
  debug: false
  speed: 0
  definitions: id
  script:
  - while true {
    - define rnd_pt <util.random.int[1].to[<custom@random_dungeon_object[id=<def[id]>].width.sub[1]>]>_<util.random.int[1].to[<custom@random_dungeon_object[id=<def[id]>].length.sub[1]>]>
    - if <custom@random_dungeon_object[id=<def[id]>].is_isolated[<def[rnd_pt]>]> {
      - yaml set tiles.<def[value]>:floor_corridor id:random_dungeon_sys_d<def[id]>
      - while stop
    }
  }
  - define points li@<def[rnd_pt]>
  - while !<def[points].is_empty> {
    - while stop
  }

random_dungeon_sys_visualizer:
  type: task
  debug: false
  speed: 0
  definitions: id|loc
  script:
  - define flatboard cu@<def[loc]>|<def[loc].add[<yaml[random_dungeon_sys_d<def[id]>].read[width].sub[1]>,0,<yaml[random_dungeon_sys_d<def[id]>].read[length].sub[1]>]>
  - modifyblock <def[flatboard]> m@black_concrete
  - foreach <yaml[random_dungeon_sys_d<def[id]>].list_keys[tiles]> {
    - if <yaml[random_dungeon_sys_d<def[id]>].read[tiles.<def[value]>]> == floor_room {
      - modifyblock <def[loc].add[<def[value].before[_]>,0,<def[value].after[_]>]> m@lime_concrete
    }
    - if <yaml[random_dungeon_sys_d<def[id]>].read[tiles.<def[value]>]> == floor_corridor {
      - modifyblock <def[loc].add[<def[value].before[_]>,0,<def[value].after[_]>]> m@blue_concrete
    }
  }

  # Extra data visualized for debugging purposes
  - foreach <yaml[random_dungeon_sys_d<def[id]>].read[extra.room_centers]||li@> {
    - modifyblock <def[loc].add[<def[value].before[_]>,0,<def[value].after[_]>]> m@purple_concrete
  }
  - modifyblock <def[loc].add[<yaml[random_dungeon_sys_d<def[id]>].read[floor_exit].before[_]>,0,<yaml[random_dungeon_sys_d<def[id]>].read[floor_exit].after[_]>]> m@red_concrete

random_dungeon_sys_objectvalidate:
  type: task
  debug: false
  speed: 0
  script:
  - debug ERROR 'Invalid validation path!'
  - determine null
  cell:
  - if !<context.value.matches[[0-9]+,[0-9]+]>
    || <context.value.before[,]> > <context.this.width>
    || <context.value.after[,]> > <context.this.length>
    || <context.value.before[,]> < 0
    || <context.value.after[,]> < 0 {
    - debug ERROR 'Invalid cell!'
    - determine null
  }
  id:
  - if !<context.this.list_dungeon_ids.contains[<def[1]>]> {
    - debug ERROR 'Invalid dungeon ID!'
    - determine null
  }

random_dungeon_cell_object:
  type: custom
  debug: false
  dungeon: custom@random_dungeon_object[id=null]
  x: 0
  y: 0
  tags:
    is_valid:
    - define 1 <context.this.dungeon.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - if <context.this.x> < 0 || <context.this.x> > <context.this.dungeon.width.sub[1]>
      || <context.this.y> < 0 || <context.this.y> > <context.this.dungeon.length.sub[1]> {
      - determine false
    }
    - determine true
    # Read types are:
    # 
    # WALL
    # FLOOR_CORRIDOR
    # FLOOR_ROOM
    read:
    - define 1 <context.this.dungeon.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - determine <yaml[random_dungeon_sys_d<context.this.id>].read[tiles.<context.this.x>_<context.this.y>]>
    # Property types are:
    # 
    # door/DIRECTION/IS_LOCKED(Boolean)
    # exit/IS_LOCKED(Boolean)
    # false_wall/FALSE_WALL_ID/CAN_FORCE_OPEN(Boolean)
    # switch/FALSE_WALL_ID
    # trap/TYPE/IS_PERMANENT(Boolean)
    # treasure/LEVEL/IS_LOCKED(Boolean)/HAS_EXIT_KEY(Boolean)
    property:
    - define 1 <context.this.dungeon.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - if !<context.this.read.starts_with[floor]> {
      - determine null
    }
    - determine <yaml[random_dungeon_sys_d<context.this.id>].read[prop.<context.this.x>_<context.this.y>]||none>
    # Ordered N, S, E, W
    # Relies on the Cartesian coordinate plane. May not be accurate to Minecraft's coordinate
    # system.
    adjacent_cells:
    - define 1 <context.this.dungeon.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - determine <li@custom@random_dungeon_cell_object[dungeon=<context.this.dungeon>;x=<context.this.x>;y=<context.this.y.add[1]>]|custom@random_dungeon_cell_object[dungeon=<context.this.dungeon>;x=<context.this.x>;y=<context.this.y.sub[1]>]|custom@random_dungeon_cell_object[dungeon=<context.this.dungeon>;x=<context.this.x.add[1]>;y=<context.this.y>]|custom@random_dungeon_cell_object[dungeon=<context.this.dungeon>;x=<context.this.x.sub[1]>_<context.this.y>].filter[is_valid]>
    # Ordered NE, NW, SW, SE
    # Relies on the Cartesian coordinate plane, and is ordered by quadrant number. May not be
    # accurate to Minecraft's coordinate system.
    diagonal_cells:
    - define 1 <context.this.dungeon.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - determine <li@custom@random_dungeon_cell_object[dungeon=<context.this.dungeon>;x=<context.this.x.add[1]>;y=<context.this.y.add[1]>]|custom@random_dungeon_cell_object[dungeon=<context.this.dungeon>;x=<context.this.x.sub[1]>;y=<context.this.y.add[1]>]|custom@random_dungeon_cell_object[dungeon=<context.this.dungeon.sub[1]>;x=<context.this.x>;y=<context.this.y.sub[1]>]|custom@random_dungeon_cell_object[dungeon=<context.this.dungeon>;x=<context.this.x.add[1]>;y=<context.this.y.sub[1]>].filter[is_valid]>
    above:
    - define 1 <context.this.dungeon.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - adjust <context.this> y:<context.this.y.add[1]> save:n
    - if <entry[n].result.is_valid> {
      - determine <entry[n].result>
    }
    - determine null
    below:
    - define 1 <context.this.dungeon.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - adjust <context.this> y:<context.this.y.sub[1]> save:n
    - if <entry[n].result.is_valid> {
      - determine <entry[n].result>
    }
    - determine null
    to_right:
    - define 1 <context.this.dungeon.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - adjust <context.this> x:<context.this.x.add[1]> save:n
    - if <entry[n].result.is_valid> {
      - determine <entry[n].result>
    }
    - determine null
    to_left:
    - define 1 <context.this.dungeon.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - adjust <context.this> x:<context.this.x.sub[1]> save:n
    - if <entry[n].result.is_valid> {
      - determine <entry[n].result>
    }
    - determine null
    is_isolated:
    - define 1 <context.this.dungeon.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - foreach <context.this.adjacent_cells.include[<context.this.diagonal_cells>]> {
      - if <def[value].read||null> != wall {
        - determine false
      }
    }
    - determine true

  mechanisms:
    x:
    - if !<context.value.matches[[0-9]+]> {
      - debug ERROR 'Invalid x coordinate!'
      - determine <context.this>
    }
    - adjust <context.this> x:<context.value> save:n
    - determine <entry[n].result>
    y:
    - if !<context.value.matches[[0-9]+]> {
      - debug ERROR 'Invalid y coordinate!'
      - determine <context.this>
    }
    - adjust <context.this> y:<context.value> save:n
    - determine <entry[n].result>
    dungeon:
    - define 1 <context.value.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - adjust <context.this> dungeon:<context.value>
    - determine <entry[n].result>
    floor_property:
    #         exit - none
    #     treasure - 1, 2, 3, 4, 5
    #         trap - poison, slow, treasure, monster
    set_tile:
    # FLOOR - room, corridor
    # WALL
    - if <li@floor_room|floor_corridor|floor_exit|door_n

random_dungeon_object:
  type: custom
  debug: false
  id: null
  tags:
    list_dungeon_ids:
    - determine <yaml.list.filter[starts_with[random_dungeon_sys_d]].parse[after[random_dungeon_sys_d]]>
    width:
    - define 1 <context.this.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - determine <yaml[random_dungeon_sys_d<context.this.id>].read[width]>
    length:
    - define 1 <context.this.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - determine <yaml[random_dungeon_sys_d<context.this.id>].read[length]>
    cell:
    - define 1 <context.this.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - if <custom@random_dungeon_cell_object[dungeon=<context.this>;x=<context.value.before[,]>;y=<context.value.after[,]>].is_valid> {
      - determine custom@random_dungeon_cell_object[dungeon=<context.this>;x=<context.value.before[,]>;y=<context.value.after[,]>]
    }
    - determine null
    #- determine <yaml[random_dungeon_sys_d<context.this.id>].read[tiles.<context.value>]>
    random_cell:
    - define 1 <context.this.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - determine custom@random_dungeon_cell_object[dungeon=<context.this>;x=<yaml[random_dungeon_sys_d<context.this.id>].list_keys[tiles].random.before[_]>;y=<yaml[random_dungeon_sys_d<context.this.id>].list_keys[tiles].random.after[_]>]
    #- determine <yaml[random_dungeon_sys_d<context.this.id>].list_keys[tiles].random>
    random_room:
    - define 1 <context.this.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - determine <yaml[random_dungeon_sys_d<context.this.id>].read[rooms].random>
    get_exit:
    - define 1 <context.this.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - determine custom@random_dungeon_cell_object[dungeon=<context.this>;x=<yaml[random_dungeon_sys_d<context.this.id>].read[floor_exit].before[_]>;y=<yaml[random_dungeon_sys_d<context.this.id>].read[floor_exit].after[_]>]
    #- determine <yaml[random_dungeon_sys_d<context.this.id>].read[floor_exit]>
    can_make_corridor:
    - define 1 <context.this.id>
    - inject random_dungeon_sys_objectvalidate path:id
    - if !<custom@random_dungeon_cell_object[dungeon=<context.this>;x=<context.value.before[,]>;y=<context.value.after[,]>].is_valid>
      || <custom@random_dungeon_cell_object[dungeon=<context.this>;x=<context.value.before[,]>;y=<context.value.after[,]>].read> != wall {
      - determine false
    }
    - if <yaml[random_dungeon_sys_d<context.this.id>].read[tiles.<context.value.before[_].add[1]>_<context.value.after[_].add[1]>]> == wall
      && <yaml[random_dungeon_sys_d<context.this.id>].read[tiles.<context.value.before[_].add[1]>_<context.value.after[_].sub[1]>]> == wall
      && <yaml[random_dungeon_sys_d<context.this.id>].read[tiles.<context.value.before[_].sub[1]>_<context.value.after[_].add[1]>]> == wall
      && <yaml[random_dungeon_sys_d<context.this.id>].read[tiles.<context.value.before[_].sub[1]>_<context.value.after[_].add[1]>]> == wall {
      - determine true
    }
    - determine false

  mechanisms:
    delete:
    - define 1 <context.value>
    - inject random_dungeon_sys_check_id
    - yaml unload id:random_dungeon_sys_d<context.value>
    - determine null
    set_id:
    - adjust <context.this> id:<context.value> save:n
    - determine <entry[n].result>