Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse

LiquidBounce Forum

  1. Home
  2. Chinese
  3. [Script] PathAlgorithm 0.3(寻路算法动画)

[Script] PathAlgorithm 0.3(寻路算法动画)

Scheduled Pinned Locked Moved Chinese
3 Posts 3 Posters 1.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • CookieChineseC Offline
    CookieChineseC Offline
    CookieChinese
    wrote on last edited by
    #1

    作者:mumy
    B站:https://space.bilibili.com/363239963

    这是个教学性脚本,可用于学习如何编写寻路

    import Color = JVM.java$.awt$.Color;
    import JavaBoolean = JVM.java$.lang$.Boolean;
    import JavaFloat = JVM.java$.lang$.Float;
    import JavaInteger = JVM.java$.lang$.Integer;
    import JavaString = JVM.java$.lang$.String;
    import AttackEvent = JVM.net$.ccbluex$.liquidbounce$.event$.AttackEvent;
    import ClickBlockEvent = JVM.net$.ccbluex$.liquidbounce$.event$.ClickBlockEvent;
    import JumpEvent = JVM.net$.ccbluex$.liquidbounce$.event$.JumpEvent;
    import KeyEvent = JVM.net$.ccbluex$.liquidbounce$.event$.KeyEvent;
    import MotionEvent = JVM.net$.ccbluex$.liquidbounce$.event$.MotionEvent;
    import MoveEvent = JVM.net$.ccbluex$.liquidbounce$.event$.MoveEvent;
    import PacketEvent = JVM.net$.ccbluex$.liquidbounce$.event$.PacketEvent;
    import Render2DEvent = JVM.net$.ccbluex$.liquidbounce$.event$.Render2DEvent;
    import Render3DEvent = JVM.net$.ccbluex$.liquidbounce$.event$.Render3DEvent;
    import SlowDownEvent = JVM.net$.ccbluex$.liquidbounce$.event$.SlowDownEvent;
    import StepEvent = JVM.net$.ccbluex$.liquidbounce$.event$.StepEvent;
    import StrafeEvent = JVM.net$.ccbluex$.liquidbounce$.event$.StrafeEvent;
    import UpdateEvent = JVM.net$.ccbluex$.liquidbounce$.event$.UpdateEvent;
    import WorldEvent = JVM.net$.ccbluex$.liquidbounce$.event$.WorldEvent;
    import RenderUtils = JVM.net$.ccbluex$.liquidbounce$.utils$.render$.RenderUtils;
    import BlockValue = JVM.net$.ccbluex$.liquidbounce$.value$.BlockValue;
    import BoolValue = JVM.net$.ccbluex$.liquidbounce$.value$.BoolValue;
    import FloatValue = JVM.net$.ccbluex$.liquidbounce$.value$.FloatValue;
    import IntegerValue = JVM.net$.ccbluex$.liquidbounce$.value$.IntegerValue;
    import ListValue = JVM.net$.ccbluex$.liquidbounce$.value$.ListValue;
    import TextValue = JVM.net$.ccbluex$.liquidbounce$.value$.TextValue;
    import BlockSnow = JVM.net$.minecraft$.block$.BlockSnow;
    import BlockWeb = JVM.net$.minecraft$.block$.BlockWeb;
    import GlStateManager = JVM.net$.minecraft$.client$.renderer$.GlStateManager;
    import AxisAlignedBB = JVM.net$.minecraft$.util$.AxisAlignedBB;
    import BlockPos = JVM.net$.minecraft$.util$.BlockPos;
    import GL11 = JVM.org$.lwjgl$.opengl$.GL11;
    
    const scriptName = "PathAlgorithm";
    const scriptVersion = 0.3;
    const scriptAuthor = "mumy++";
    
    class PathAlgorithm {
    
        private readonly setting = {
            float: (name: string, def: number, min: number, max: number, object: object = {}) => {
                return new _AdaptedValue<number, JavaFloat>(new (Java.extend(FloatValue, object))(name, def, min, max));
            },
            integer: (name: string, def: number, min: number, max: number, object: object = {}) => {
                return new _AdaptedValue<number, JavaInteger>(new (Java.extend(IntegerValue, object))(name, def, min, max));
            },
            boolean: (name: string, def: boolean, object: object = {}) => {
                return new _AdaptedValue<boolean, JavaBoolean>(new (Java.extend(BoolValue, object))(name, def));
            },
            list: (name: string, values: string[], def: string, object: object = {}) => {
                return new _AdaptedValue<string, JavaString>(new (Java.extend(ListValue, object))(name, values, def));
            },
            text: (name: string, def: string, object: object = {}) => {
                return new _AdaptedValue<string, JavaString>(new (Java.extend(TextValue, object))(name, def));
            },
            block: (name: string, def: number, object: object = {}) => {
                return new _AdaptedValue<number, JavaInteger>(new (Java.extend(BlockValue, object))(name, def));
            }
        };
    
        private readonly settings = {
            setStart: this.setting.boolean("SetStart", false, {
                onChanged: (oldValue: boolean, newValue: boolean) => {
                    if (!newValue) {
                        return;
                    }
                    const player = mc.thePlayer!;
                    this.start = new PathAlgorithm.Pos(Math.floor(player.posX), Math.floor(player.posY), Math.floor(player.posZ));
                    this.aStarAlgorithm = null;
                    this.settings.setStart.set(false);
                }
            }),
            setEnd: this.setting.boolean("SetEnd", false, {
                onChanged: (oldValue: boolean, newValue: boolean) => {
                    if (!newValue) {
                        return;
                    }
                    const player = mc.thePlayer!;
                    this.end = new PathAlgorithm.Pos(Math.floor(player.posX), Math.floor(player.posY), Math.floor(player.posZ));
                    this.aStarAlgorithm = null;
                    this.settings.setEnd.set(false);
                }
            }),
            gWeight: this.setting.float("GWeight", 1.00005, 0, 2),
            hWeight: this.setting.float("HWeight", 1, 0, 2),
            speed: this.setting.integer("Speed", 1, 1, 50),
            reset: this.setting.boolean("Reset", false, {
                onChanged: (oldValue: boolean, newValue: boolean) => {
                    if (!newValue) {
                        return;
                    }
                    this.start = null;
                    this.end = null;
                    this.aStarAlgorithm = null;
                    this.settings.reset.set(false);
                }
            })
        };
    
        private start = <typeof PathAlgorithm.Pos.prototype | null>null;
        private end = <typeof PathAlgorithm.Pos.prototype | null>null;
    
        private aStarAlgorithm = <typeof PathAlgorithm.AStarAlgorithm.prototype | null>null;
    
        private readonly openColor = new Color(200, 200, 200);
        private readonly closeColor = new Color(127, 127, 127);
        private readonly pathColor = new Color(0, 220, 220);
    
        public getName() {
            return "PathAlgorithm";
        }
    
        public getDescription() {
            return "PathAlgorithm-Module, By-mumy";
        }
    
        public getCategory() {
            return "Misc";
        }
    
        public onEnable() {
            this.start = null;
            this.end = null;
            this.aStarAlgorithm = null;
        }
    
        public onDisable() {
            this.onEnable();
        }
    
        public onUpdate() {
            if (this.start != null && this.end != null) {
                if (this.aStarAlgorithm == null) {
                    this.aStarAlgorithm = new PathAlgorithm.AStarAlgorithm(this.start, this.end, this.settings.hWeight.get(), this.settings.gWeight.get());
                }
                this.aStarAlgorithm.update(this.settings.speed.get());
            }
        }
    
        public onRender3D(event: Render3DEvent) {
            if (this.start != null && this.aStarAlgorithm == null) {
                const { x, y, z } = this.start;
                this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.openColor);
            } if (this.end != null && this.aStarAlgorithm?.path == null) {
                const { x, y, z } = this.end;
                this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.openColor);
            } if (this.aStarAlgorithm != null) {
                if (this.aStarAlgorithm.path != null) {
                    for (let pos of this.aStarAlgorithm.path) {
                        const { x, y, z } = pos;
                        this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.pathColor);
                    }
                } else {
                    for (let pos of this.aStarAlgorithm.openList) {
                        const { x, y, z } = pos;
                        this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.openColor);
                    } for (let pos of this.aStarAlgorithm.closeList) {
                        const { x, y, z } = pos;
                        this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.closeColor);
                    }
                }
            }
        }
    
        public onWorld(event: WorldEvent) {
            moduleManager.getModule(this.getName())!.setState(false);
        }
    
        public addValues(values: _ValueAdapter) {
            const settings = <{ [ket: string]: _AdaptedValue<unknown, unknown> }>this.settings;
            for (let key in settings) {
                values.add(settings[key]);
            }
        }
    
        private drawEntityBox(entityBox: AxisAlignedBB, color: Color) {
            const renderManager = mc.getRenderManager()!;
            GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
            RenderUtils.enableGlCap(GL11.GL_BLEND);
            RenderUtils.disableGlCap(GL11.GL_TEXTURE_2D, GL11.GL_DEPTH_TEST);
            GL11.glDepthMask(false);
            RenderUtils.glColor(color.getRed(), color.getGreen(), color.getBlue(), 26);
            const axisAlignedBB = new AxisAlignedBB(entityBox.minX - renderManager.renderPosX,
                entityBox.minY - renderManager.renderPosY,
                entityBox.minZ - renderManager.renderPosZ,
                entityBox.maxX - renderManager.renderPosX,
                entityBox.maxY - renderManager.renderPosY,
                entityBox.maxZ - renderManager.renderPosZ);
            RenderUtils.drawFilledBox(axisAlignedBB);
            GL11.glLineWidth(1);
            RenderUtils.enableGlCap(GL11.GL_LINE_SMOOTH);
            RenderUtils.glColor(color.getRed(), color.getGreen(), color.getBlue(), 95);
            RenderUtils.drawSelectionBoundingBox(axisAlignedBB);
            GlStateManager.resetColor();
            GL11.glDepthMask(true);
            RenderUtils.resetCaps();
        }
    
        public static Pos = class Pos {
    
            public constructor(public x: number, public y: number, public z: number) {}
    
            public equals(pos: Pos) {
                return pos.x === this.x && pos.y === this.y && pos.z === this.z;
            }
    
        }
    
        public static Node = class Node extends PathAlgorithm.Pos {
    
            public cost = 0;
            public hCost = 0;
    
            public constructor(public x: number, public y: number, public z: number, public parent: Node | null) {
                super(x, y, z);
                this.hCost = (parent?.hCost ?? -1) + 1;
            }
    
        }
    
        private static AStarAlgorithm = class AStarAlgorithm {
    
            private readonly start: typeof PathAlgorithm.Pos.prototype;
            private readonly end: typeof PathAlgorithm.Pos.prototype;
            public readonly openList = <typeof PathAlgorithm.Node.prototype[]>[];
            public readonly closeList = <typeof PathAlgorithm.Pos.prototype[]>[];
            private readonly hWeight: number;
            private readonly gWeight: number;
            public path = <typeof PathAlgorithm.Pos.prototype[] | null>null;
    
            public constructor(start: typeof PathAlgorithm.Pos.prototype, end: typeof PathAlgorithm.Pos.prototype, hWeight: number, gWeight: number) {
                this.start = start;
                this.end = end;
                this.hWeight = hWeight;
                this.gWeight = gWeight;
                this.openList.push(new PathAlgorithm.Node(start.x, start.y, start.z, null));
            }
    
            public update(loops: number) {
                if (this.path != null) {
                    return false;
                }
                top: while (loops-- > 0) {
                    if (this.openList.length === 0) {
                        return false;
                    }
                    const node = this.getNode()!;
                    for (let pos of this.closeList) {
                        if (node.equals(pos)) {
                            continue top;
                        }
                    } if (!this.canPassable(new BlockPos(node.x, node.y, node.z))) {
                        continue;
                    } if (node.equals(this.end)) {
                        this.path = [];
                        let temp = <typeof PathAlgorithm.Node.prototype | null>node;
                        do {
                            this.path.push(temp!);
                            temp = temp!.parent;
                        } while (temp != null);
                        this.path.reverse();
                        return false;
                    }
                    this.closeList.push(node);
                    const { x, y, z } = node;
                    this.createNodeToOpenList(x + 1, y, z, node);
                    this.createNodeToOpenList(x, y + 1, z, node);
                    this.createNodeToOpenList(x, y, z + 1, node);
                    this.createNodeToOpenList(x - 1, y, z, node);
                    this.createNodeToOpenList(x, y - 1, z, node);
                    this.createNodeToOpenList(x, y, z - 1, node);
                }
                return true;
            }
    
            private createNodeToOpenList(x: number, y: number, z: number, parent: typeof PathAlgorithm.Node.prototype | null) {
                const node = new PathAlgorithm.Node(x, y, z, parent);
                const [ xDist, yDist, zDist ] = [Math.abs(node.x - this.end.x), Math.abs(node.y - this.end.y), Math.abs(node.z - this.end.z)];
                node.cost = node.hCost * this.gWeight + (xDist + yDist + zDist) * this.hWeight;
                this.openList.push(node);
            }
    
            private getNode() {
                let finalIndex = -1;
                let finalCost = -1;
                let finalNode = <typeof PathAlgorithm.Node.prototype | null>null;
                for (let i = this.openList.length - 1; !(i < 0); --i) {
                    const node = this.openList[i];
                    const cost = node.cost;
                    if (finalNode == null || cost < finalCost) {
                        finalNode = node;
                        finalCost = cost;
                        finalIndex = i;
                    } if (i === 0) {
                        this.openList.splice(finalIndex, 1);
                    }
                }
                return finalNode;
            }
    
            private canPassable(blockPos: BlockPos) {
                const world = mc.theWorld!;
                const iBlockState = world.getBlockState(blockPos)!;
                const block = iBlockState.getBlock()!;
                return block.getCollisionBoundingBox(world, blockPos, iBlockState) == null ? !(block instanceof BlockWeb) : block instanceof BlockSnow && block.isReplaceable(world, blockPos);
            }
    
        }
    
    }
    
    let scriptModule: any;
    
    function onLoad() {}
    
    function onEnable() {
        scriptModule = moduleManager.registerModule(new PathAlgorithm());
    }
    
    function onDisable() {
        moduleManager.unregisterModule(scriptModule);
    }
    
    kawaiinekololisK ybyyby_ awaY 2 Replies Last reply
    1
    • CookieChineseC CookieChinese

      作者:mumy
      B站:https://space.bilibili.com/363239963

      这是个教学性脚本,可用于学习如何编写寻路

      import Color = JVM.java$.awt$.Color;
      import JavaBoolean = JVM.java$.lang$.Boolean;
      import JavaFloat = JVM.java$.lang$.Float;
      import JavaInteger = JVM.java$.lang$.Integer;
      import JavaString = JVM.java$.lang$.String;
      import AttackEvent = JVM.net$.ccbluex$.liquidbounce$.event$.AttackEvent;
      import ClickBlockEvent = JVM.net$.ccbluex$.liquidbounce$.event$.ClickBlockEvent;
      import JumpEvent = JVM.net$.ccbluex$.liquidbounce$.event$.JumpEvent;
      import KeyEvent = JVM.net$.ccbluex$.liquidbounce$.event$.KeyEvent;
      import MotionEvent = JVM.net$.ccbluex$.liquidbounce$.event$.MotionEvent;
      import MoveEvent = JVM.net$.ccbluex$.liquidbounce$.event$.MoveEvent;
      import PacketEvent = JVM.net$.ccbluex$.liquidbounce$.event$.PacketEvent;
      import Render2DEvent = JVM.net$.ccbluex$.liquidbounce$.event$.Render2DEvent;
      import Render3DEvent = JVM.net$.ccbluex$.liquidbounce$.event$.Render3DEvent;
      import SlowDownEvent = JVM.net$.ccbluex$.liquidbounce$.event$.SlowDownEvent;
      import StepEvent = JVM.net$.ccbluex$.liquidbounce$.event$.StepEvent;
      import StrafeEvent = JVM.net$.ccbluex$.liquidbounce$.event$.StrafeEvent;
      import UpdateEvent = JVM.net$.ccbluex$.liquidbounce$.event$.UpdateEvent;
      import WorldEvent = JVM.net$.ccbluex$.liquidbounce$.event$.WorldEvent;
      import RenderUtils = JVM.net$.ccbluex$.liquidbounce$.utils$.render$.RenderUtils;
      import BlockValue = JVM.net$.ccbluex$.liquidbounce$.value$.BlockValue;
      import BoolValue = JVM.net$.ccbluex$.liquidbounce$.value$.BoolValue;
      import FloatValue = JVM.net$.ccbluex$.liquidbounce$.value$.FloatValue;
      import IntegerValue = JVM.net$.ccbluex$.liquidbounce$.value$.IntegerValue;
      import ListValue = JVM.net$.ccbluex$.liquidbounce$.value$.ListValue;
      import TextValue = JVM.net$.ccbluex$.liquidbounce$.value$.TextValue;
      import BlockSnow = JVM.net$.minecraft$.block$.BlockSnow;
      import BlockWeb = JVM.net$.minecraft$.block$.BlockWeb;
      import GlStateManager = JVM.net$.minecraft$.client$.renderer$.GlStateManager;
      import AxisAlignedBB = JVM.net$.minecraft$.util$.AxisAlignedBB;
      import BlockPos = JVM.net$.minecraft$.util$.BlockPos;
      import GL11 = JVM.org$.lwjgl$.opengl$.GL11;
      
      const scriptName = "PathAlgorithm";
      const scriptVersion = 0.3;
      const scriptAuthor = "mumy++";
      
      class PathAlgorithm {
      
          private readonly setting = {
              float: (name: string, def: number, min: number, max: number, object: object = {}) => {
                  return new _AdaptedValue<number, JavaFloat>(new (Java.extend(FloatValue, object))(name, def, min, max));
              },
              integer: (name: string, def: number, min: number, max: number, object: object = {}) => {
                  return new _AdaptedValue<number, JavaInteger>(new (Java.extend(IntegerValue, object))(name, def, min, max));
              },
              boolean: (name: string, def: boolean, object: object = {}) => {
                  return new _AdaptedValue<boolean, JavaBoolean>(new (Java.extend(BoolValue, object))(name, def));
              },
              list: (name: string, values: string[], def: string, object: object = {}) => {
                  return new _AdaptedValue<string, JavaString>(new (Java.extend(ListValue, object))(name, values, def));
              },
              text: (name: string, def: string, object: object = {}) => {
                  return new _AdaptedValue<string, JavaString>(new (Java.extend(TextValue, object))(name, def));
              },
              block: (name: string, def: number, object: object = {}) => {
                  return new _AdaptedValue<number, JavaInteger>(new (Java.extend(BlockValue, object))(name, def));
              }
          };
      
          private readonly settings = {
              setStart: this.setting.boolean("SetStart", false, {
                  onChanged: (oldValue: boolean, newValue: boolean) => {
                      if (!newValue) {
                          return;
                      }
                      const player = mc.thePlayer!;
                      this.start = new PathAlgorithm.Pos(Math.floor(player.posX), Math.floor(player.posY), Math.floor(player.posZ));
                      this.aStarAlgorithm = null;
                      this.settings.setStart.set(false);
                  }
              }),
              setEnd: this.setting.boolean("SetEnd", false, {
                  onChanged: (oldValue: boolean, newValue: boolean) => {
                      if (!newValue) {
                          return;
                      }
                      const player = mc.thePlayer!;
                      this.end = new PathAlgorithm.Pos(Math.floor(player.posX), Math.floor(player.posY), Math.floor(player.posZ));
                      this.aStarAlgorithm = null;
                      this.settings.setEnd.set(false);
                  }
              }),
              gWeight: this.setting.float("GWeight", 1.00005, 0, 2),
              hWeight: this.setting.float("HWeight", 1, 0, 2),
              speed: this.setting.integer("Speed", 1, 1, 50),
              reset: this.setting.boolean("Reset", false, {
                  onChanged: (oldValue: boolean, newValue: boolean) => {
                      if (!newValue) {
                          return;
                      }
                      this.start = null;
                      this.end = null;
                      this.aStarAlgorithm = null;
                      this.settings.reset.set(false);
                  }
              })
          };
      
          private start = <typeof PathAlgorithm.Pos.prototype | null>null;
          private end = <typeof PathAlgorithm.Pos.prototype | null>null;
      
          private aStarAlgorithm = <typeof PathAlgorithm.AStarAlgorithm.prototype | null>null;
      
          private readonly openColor = new Color(200, 200, 200);
          private readonly closeColor = new Color(127, 127, 127);
          private readonly pathColor = new Color(0, 220, 220);
      
          public getName() {
              return "PathAlgorithm";
          }
      
          public getDescription() {
              return "PathAlgorithm-Module, By-mumy";
          }
      
          public getCategory() {
              return "Misc";
          }
      
          public onEnable() {
              this.start = null;
              this.end = null;
              this.aStarAlgorithm = null;
          }
      
          public onDisable() {
              this.onEnable();
          }
      
          public onUpdate() {
              if (this.start != null && this.end != null) {
                  if (this.aStarAlgorithm == null) {
                      this.aStarAlgorithm = new PathAlgorithm.AStarAlgorithm(this.start, this.end, this.settings.hWeight.get(), this.settings.gWeight.get());
                  }
                  this.aStarAlgorithm.update(this.settings.speed.get());
              }
          }
      
          public onRender3D(event: Render3DEvent) {
              if (this.start != null && this.aStarAlgorithm == null) {
                  const { x, y, z } = this.start;
                  this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.openColor);
              } if (this.end != null && this.aStarAlgorithm?.path == null) {
                  const { x, y, z } = this.end;
                  this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.openColor);
              } if (this.aStarAlgorithm != null) {
                  if (this.aStarAlgorithm.path != null) {
                      for (let pos of this.aStarAlgorithm.path) {
                          const { x, y, z } = pos;
                          this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.pathColor);
                      }
                  } else {
                      for (let pos of this.aStarAlgorithm.openList) {
                          const { x, y, z } = pos;
                          this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.openColor);
                      } for (let pos of this.aStarAlgorithm.closeList) {
                          const { x, y, z } = pos;
                          this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.closeColor);
                      }
                  }
              }
          }
      
          public onWorld(event: WorldEvent) {
              moduleManager.getModule(this.getName())!.setState(false);
          }
      
          public addValues(values: _ValueAdapter) {
              const settings = <{ [ket: string]: _AdaptedValue<unknown, unknown> }>this.settings;
              for (let key in settings) {
                  values.add(settings[key]);
              }
          }
      
          private drawEntityBox(entityBox: AxisAlignedBB, color: Color) {
              const renderManager = mc.getRenderManager()!;
              GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
              RenderUtils.enableGlCap(GL11.GL_BLEND);
              RenderUtils.disableGlCap(GL11.GL_TEXTURE_2D, GL11.GL_DEPTH_TEST);
              GL11.glDepthMask(false);
              RenderUtils.glColor(color.getRed(), color.getGreen(), color.getBlue(), 26);
              const axisAlignedBB = new AxisAlignedBB(entityBox.minX - renderManager.renderPosX,
                  entityBox.minY - renderManager.renderPosY,
                  entityBox.minZ - renderManager.renderPosZ,
                  entityBox.maxX - renderManager.renderPosX,
                  entityBox.maxY - renderManager.renderPosY,
                  entityBox.maxZ - renderManager.renderPosZ);
              RenderUtils.drawFilledBox(axisAlignedBB);
              GL11.glLineWidth(1);
              RenderUtils.enableGlCap(GL11.GL_LINE_SMOOTH);
              RenderUtils.glColor(color.getRed(), color.getGreen(), color.getBlue(), 95);
              RenderUtils.drawSelectionBoundingBox(axisAlignedBB);
              GlStateManager.resetColor();
              GL11.glDepthMask(true);
              RenderUtils.resetCaps();
          }
      
          public static Pos = class Pos {
      
              public constructor(public x: number, public y: number, public z: number) {}
      
              public equals(pos: Pos) {
                  return pos.x === this.x && pos.y === this.y && pos.z === this.z;
              }
      
          }
      
          public static Node = class Node extends PathAlgorithm.Pos {
      
              public cost = 0;
              public hCost = 0;
      
              public constructor(public x: number, public y: number, public z: number, public parent: Node | null) {
                  super(x, y, z);
                  this.hCost = (parent?.hCost ?? -1) + 1;
              }
      
          }
      
          private static AStarAlgorithm = class AStarAlgorithm {
      
              private readonly start: typeof PathAlgorithm.Pos.prototype;
              private readonly end: typeof PathAlgorithm.Pos.prototype;
              public readonly openList = <typeof PathAlgorithm.Node.prototype[]>[];
              public readonly closeList = <typeof PathAlgorithm.Pos.prototype[]>[];
              private readonly hWeight: number;
              private readonly gWeight: number;
              public path = <typeof PathAlgorithm.Pos.prototype[] | null>null;
      
              public constructor(start: typeof PathAlgorithm.Pos.prototype, end: typeof PathAlgorithm.Pos.prototype, hWeight: number, gWeight: number) {
                  this.start = start;
                  this.end = end;
                  this.hWeight = hWeight;
                  this.gWeight = gWeight;
                  this.openList.push(new PathAlgorithm.Node(start.x, start.y, start.z, null));
              }
      
              public update(loops: number) {
                  if (this.path != null) {
                      return false;
                  }
                  top: while (loops-- > 0) {
                      if (this.openList.length === 0) {
                          return false;
                      }
                      const node = this.getNode()!;
                      for (let pos of this.closeList) {
                          if (node.equals(pos)) {
                              continue top;
                          }
                      } if (!this.canPassable(new BlockPos(node.x, node.y, node.z))) {
                          continue;
                      } if (node.equals(this.end)) {
                          this.path = [];
                          let temp = <typeof PathAlgorithm.Node.prototype | null>node;
                          do {
                              this.path.push(temp!);
                              temp = temp!.parent;
                          } while (temp != null);
                          this.path.reverse();
                          return false;
                      }
                      this.closeList.push(node);
                      const { x, y, z } = node;
                      this.createNodeToOpenList(x + 1, y, z, node);
                      this.createNodeToOpenList(x, y + 1, z, node);
                      this.createNodeToOpenList(x, y, z + 1, node);
                      this.createNodeToOpenList(x - 1, y, z, node);
                      this.createNodeToOpenList(x, y - 1, z, node);
                      this.createNodeToOpenList(x, y, z - 1, node);
                  }
                  return true;
              }
      
              private createNodeToOpenList(x: number, y: number, z: number, parent: typeof PathAlgorithm.Node.prototype | null) {
                  const node = new PathAlgorithm.Node(x, y, z, parent);
                  const [ xDist, yDist, zDist ] = [Math.abs(node.x - this.end.x), Math.abs(node.y - this.end.y), Math.abs(node.z - this.end.z)];
                  node.cost = node.hCost * this.gWeight + (xDist + yDist + zDist) * this.hWeight;
                  this.openList.push(node);
              }
      
              private getNode() {
                  let finalIndex = -1;
                  let finalCost = -1;
                  let finalNode = <typeof PathAlgorithm.Node.prototype | null>null;
                  for (let i = this.openList.length - 1; !(i < 0); --i) {
                      const node = this.openList[i];
                      const cost = node.cost;
                      if (finalNode == null || cost < finalCost) {
                          finalNode = node;
                          finalCost = cost;
                          finalIndex = i;
                      } if (i === 0) {
                          this.openList.splice(finalIndex, 1);
                      }
                  }
                  return finalNode;
              }
      
              private canPassable(blockPos: BlockPos) {
                  const world = mc.theWorld!;
                  const iBlockState = world.getBlockState(blockPos)!;
                  const block = iBlockState.getBlock()!;
                  return block.getCollisionBoundingBox(world, blockPos, iBlockState) == null ? !(block instanceof BlockWeb) : block instanceof BlockSnow && block.isReplaceable(world, blockPos);
              }
      
          }
      
      }
      
      let scriptModule: any;
      
      function onLoad() {}
      
      function onEnable() {
          scriptModule = moduleManager.registerModule(new PathAlgorithm());
      }
      
      function onDisable() {
          moduleManager.unregisterModule(scriptModule);
      }
      
      kawaiinekololisK Offline
      kawaiinekololisK Offline
      kawaiinekololis
      Admin
      wrote on last edited by
      #2

      @CookieChinese Very cool.

      1 Reply Last reply
      0
      • CookieChineseC CookieChinese

        作者:mumy
        B站:https://space.bilibili.com/363239963

        这是个教学性脚本,可用于学习如何编写寻路

        import Color = JVM.java$.awt$.Color;
        import JavaBoolean = JVM.java$.lang$.Boolean;
        import JavaFloat = JVM.java$.lang$.Float;
        import JavaInteger = JVM.java$.lang$.Integer;
        import JavaString = JVM.java$.lang$.String;
        import AttackEvent = JVM.net$.ccbluex$.liquidbounce$.event$.AttackEvent;
        import ClickBlockEvent = JVM.net$.ccbluex$.liquidbounce$.event$.ClickBlockEvent;
        import JumpEvent = JVM.net$.ccbluex$.liquidbounce$.event$.JumpEvent;
        import KeyEvent = JVM.net$.ccbluex$.liquidbounce$.event$.KeyEvent;
        import MotionEvent = JVM.net$.ccbluex$.liquidbounce$.event$.MotionEvent;
        import MoveEvent = JVM.net$.ccbluex$.liquidbounce$.event$.MoveEvent;
        import PacketEvent = JVM.net$.ccbluex$.liquidbounce$.event$.PacketEvent;
        import Render2DEvent = JVM.net$.ccbluex$.liquidbounce$.event$.Render2DEvent;
        import Render3DEvent = JVM.net$.ccbluex$.liquidbounce$.event$.Render3DEvent;
        import SlowDownEvent = JVM.net$.ccbluex$.liquidbounce$.event$.SlowDownEvent;
        import StepEvent = JVM.net$.ccbluex$.liquidbounce$.event$.StepEvent;
        import StrafeEvent = JVM.net$.ccbluex$.liquidbounce$.event$.StrafeEvent;
        import UpdateEvent = JVM.net$.ccbluex$.liquidbounce$.event$.UpdateEvent;
        import WorldEvent = JVM.net$.ccbluex$.liquidbounce$.event$.WorldEvent;
        import RenderUtils = JVM.net$.ccbluex$.liquidbounce$.utils$.render$.RenderUtils;
        import BlockValue = JVM.net$.ccbluex$.liquidbounce$.value$.BlockValue;
        import BoolValue = JVM.net$.ccbluex$.liquidbounce$.value$.BoolValue;
        import FloatValue = JVM.net$.ccbluex$.liquidbounce$.value$.FloatValue;
        import IntegerValue = JVM.net$.ccbluex$.liquidbounce$.value$.IntegerValue;
        import ListValue = JVM.net$.ccbluex$.liquidbounce$.value$.ListValue;
        import TextValue = JVM.net$.ccbluex$.liquidbounce$.value$.TextValue;
        import BlockSnow = JVM.net$.minecraft$.block$.BlockSnow;
        import BlockWeb = JVM.net$.minecraft$.block$.BlockWeb;
        import GlStateManager = JVM.net$.minecraft$.client$.renderer$.GlStateManager;
        import AxisAlignedBB = JVM.net$.minecraft$.util$.AxisAlignedBB;
        import BlockPos = JVM.net$.minecraft$.util$.BlockPos;
        import GL11 = JVM.org$.lwjgl$.opengl$.GL11;
        
        const scriptName = "PathAlgorithm";
        const scriptVersion = 0.3;
        const scriptAuthor = "mumy++";
        
        class PathAlgorithm {
        
            private readonly setting = {
                float: (name: string, def: number, min: number, max: number, object: object = {}) => {
                    return new _AdaptedValue<number, JavaFloat>(new (Java.extend(FloatValue, object))(name, def, min, max));
                },
                integer: (name: string, def: number, min: number, max: number, object: object = {}) => {
                    return new _AdaptedValue<number, JavaInteger>(new (Java.extend(IntegerValue, object))(name, def, min, max));
                },
                boolean: (name: string, def: boolean, object: object = {}) => {
                    return new _AdaptedValue<boolean, JavaBoolean>(new (Java.extend(BoolValue, object))(name, def));
                },
                list: (name: string, values: string[], def: string, object: object = {}) => {
                    return new _AdaptedValue<string, JavaString>(new (Java.extend(ListValue, object))(name, values, def));
                },
                text: (name: string, def: string, object: object = {}) => {
                    return new _AdaptedValue<string, JavaString>(new (Java.extend(TextValue, object))(name, def));
                },
                block: (name: string, def: number, object: object = {}) => {
                    return new _AdaptedValue<number, JavaInteger>(new (Java.extend(BlockValue, object))(name, def));
                }
            };
        
            private readonly settings = {
                setStart: this.setting.boolean("SetStart", false, {
                    onChanged: (oldValue: boolean, newValue: boolean) => {
                        if (!newValue) {
                            return;
                        }
                        const player = mc.thePlayer!;
                        this.start = new PathAlgorithm.Pos(Math.floor(player.posX), Math.floor(player.posY), Math.floor(player.posZ));
                        this.aStarAlgorithm = null;
                        this.settings.setStart.set(false);
                    }
                }),
                setEnd: this.setting.boolean("SetEnd", false, {
                    onChanged: (oldValue: boolean, newValue: boolean) => {
                        if (!newValue) {
                            return;
                        }
                        const player = mc.thePlayer!;
                        this.end = new PathAlgorithm.Pos(Math.floor(player.posX), Math.floor(player.posY), Math.floor(player.posZ));
                        this.aStarAlgorithm = null;
                        this.settings.setEnd.set(false);
                    }
                }),
                gWeight: this.setting.float("GWeight", 1.00005, 0, 2),
                hWeight: this.setting.float("HWeight", 1, 0, 2),
                speed: this.setting.integer("Speed", 1, 1, 50),
                reset: this.setting.boolean("Reset", false, {
                    onChanged: (oldValue: boolean, newValue: boolean) => {
                        if (!newValue) {
                            return;
                        }
                        this.start = null;
                        this.end = null;
                        this.aStarAlgorithm = null;
                        this.settings.reset.set(false);
                    }
                })
            };
        
            private start = <typeof PathAlgorithm.Pos.prototype | null>null;
            private end = <typeof PathAlgorithm.Pos.prototype | null>null;
        
            private aStarAlgorithm = <typeof PathAlgorithm.AStarAlgorithm.prototype | null>null;
        
            private readonly openColor = new Color(200, 200, 200);
            private readonly closeColor = new Color(127, 127, 127);
            private readonly pathColor = new Color(0, 220, 220);
        
            public getName() {
                return "PathAlgorithm";
            }
        
            public getDescription() {
                return "PathAlgorithm-Module, By-mumy";
            }
        
            public getCategory() {
                return "Misc";
            }
        
            public onEnable() {
                this.start = null;
                this.end = null;
                this.aStarAlgorithm = null;
            }
        
            public onDisable() {
                this.onEnable();
            }
        
            public onUpdate() {
                if (this.start != null && this.end != null) {
                    if (this.aStarAlgorithm == null) {
                        this.aStarAlgorithm = new PathAlgorithm.AStarAlgorithm(this.start, this.end, this.settings.hWeight.get(), this.settings.gWeight.get());
                    }
                    this.aStarAlgorithm.update(this.settings.speed.get());
                }
            }
        
            public onRender3D(event: Render3DEvent) {
                if (this.start != null && this.aStarAlgorithm == null) {
                    const { x, y, z } = this.start;
                    this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.openColor);
                } if (this.end != null && this.aStarAlgorithm?.path == null) {
                    const { x, y, z } = this.end;
                    this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.openColor);
                } if (this.aStarAlgorithm != null) {
                    if (this.aStarAlgorithm.path != null) {
                        for (let pos of this.aStarAlgorithm.path) {
                            const { x, y, z } = pos;
                            this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.pathColor);
                        }
                    } else {
                        for (let pos of this.aStarAlgorithm.openList) {
                            const { x, y, z } = pos;
                            this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.openColor);
                        } for (let pos of this.aStarAlgorithm.closeList) {
                            const { x, y, z } = pos;
                            this.drawEntityBox(new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1), this.closeColor);
                        }
                    }
                }
            }
        
            public onWorld(event: WorldEvent) {
                moduleManager.getModule(this.getName())!.setState(false);
            }
        
            public addValues(values: _ValueAdapter) {
                const settings = <{ [ket: string]: _AdaptedValue<unknown, unknown> }>this.settings;
                for (let key in settings) {
                    values.add(settings[key]);
                }
            }
        
            private drawEntityBox(entityBox: AxisAlignedBB, color: Color) {
                const renderManager = mc.getRenderManager()!;
                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
                RenderUtils.enableGlCap(GL11.GL_BLEND);
                RenderUtils.disableGlCap(GL11.GL_TEXTURE_2D, GL11.GL_DEPTH_TEST);
                GL11.glDepthMask(false);
                RenderUtils.glColor(color.getRed(), color.getGreen(), color.getBlue(), 26);
                const axisAlignedBB = new AxisAlignedBB(entityBox.minX - renderManager.renderPosX,
                    entityBox.minY - renderManager.renderPosY,
                    entityBox.minZ - renderManager.renderPosZ,
                    entityBox.maxX - renderManager.renderPosX,
                    entityBox.maxY - renderManager.renderPosY,
                    entityBox.maxZ - renderManager.renderPosZ);
                RenderUtils.drawFilledBox(axisAlignedBB);
                GL11.glLineWidth(1);
                RenderUtils.enableGlCap(GL11.GL_LINE_SMOOTH);
                RenderUtils.glColor(color.getRed(), color.getGreen(), color.getBlue(), 95);
                RenderUtils.drawSelectionBoundingBox(axisAlignedBB);
                GlStateManager.resetColor();
                GL11.glDepthMask(true);
                RenderUtils.resetCaps();
            }
        
            public static Pos = class Pos {
        
                public constructor(public x: number, public y: number, public z: number) {}
        
                public equals(pos: Pos) {
                    return pos.x === this.x && pos.y === this.y && pos.z === this.z;
                }
        
            }
        
            public static Node = class Node extends PathAlgorithm.Pos {
        
                public cost = 0;
                public hCost = 0;
        
                public constructor(public x: number, public y: number, public z: number, public parent: Node | null) {
                    super(x, y, z);
                    this.hCost = (parent?.hCost ?? -1) + 1;
                }
        
            }
        
            private static AStarAlgorithm = class AStarAlgorithm {
        
                private readonly start: typeof PathAlgorithm.Pos.prototype;
                private readonly end: typeof PathAlgorithm.Pos.prototype;
                public readonly openList = <typeof PathAlgorithm.Node.prototype[]>[];
                public readonly closeList = <typeof PathAlgorithm.Pos.prototype[]>[];
                private readonly hWeight: number;
                private readonly gWeight: number;
                public path = <typeof PathAlgorithm.Pos.prototype[] | null>null;
        
                public constructor(start: typeof PathAlgorithm.Pos.prototype, end: typeof PathAlgorithm.Pos.prototype, hWeight: number, gWeight: number) {
                    this.start = start;
                    this.end = end;
                    this.hWeight = hWeight;
                    this.gWeight = gWeight;
                    this.openList.push(new PathAlgorithm.Node(start.x, start.y, start.z, null));
                }
        
                public update(loops: number) {
                    if (this.path != null) {
                        return false;
                    }
                    top: while (loops-- > 0) {
                        if (this.openList.length === 0) {
                            return false;
                        }
                        const node = this.getNode()!;
                        for (let pos of this.closeList) {
                            if (node.equals(pos)) {
                                continue top;
                            }
                        } if (!this.canPassable(new BlockPos(node.x, node.y, node.z))) {
                            continue;
                        } if (node.equals(this.end)) {
                            this.path = [];
                            let temp = <typeof PathAlgorithm.Node.prototype | null>node;
                            do {
                                this.path.push(temp!);
                                temp = temp!.parent;
                            } while (temp != null);
                            this.path.reverse();
                            return false;
                        }
                        this.closeList.push(node);
                        const { x, y, z } = node;
                        this.createNodeToOpenList(x + 1, y, z, node);
                        this.createNodeToOpenList(x, y + 1, z, node);
                        this.createNodeToOpenList(x, y, z + 1, node);
                        this.createNodeToOpenList(x - 1, y, z, node);
                        this.createNodeToOpenList(x, y - 1, z, node);
                        this.createNodeToOpenList(x, y, z - 1, node);
                    }
                    return true;
                }
        
                private createNodeToOpenList(x: number, y: number, z: number, parent: typeof PathAlgorithm.Node.prototype | null) {
                    const node = new PathAlgorithm.Node(x, y, z, parent);
                    const [ xDist, yDist, zDist ] = [Math.abs(node.x - this.end.x), Math.abs(node.y - this.end.y), Math.abs(node.z - this.end.z)];
                    node.cost = node.hCost * this.gWeight + (xDist + yDist + zDist) * this.hWeight;
                    this.openList.push(node);
                }
        
                private getNode() {
                    let finalIndex = -1;
                    let finalCost = -1;
                    let finalNode = <typeof PathAlgorithm.Node.prototype | null>null;
                    for (let i = this.openList.length - 1; !(i < 0); --i) {
                        const node = this.openList[i];
                        const cost = node.cost;
                        if (finalNode == null || cost < finalCost) {
                            finalNode = node;
                            finalCost = cost;
                            finalIndex = i;
                        } if (i === 0) {
                            this.openList.splice(finalIndex, 1);
                        }
                    }
                    return finalNode;
                }
        
                private canPassable(blockPos: BlockPos) {
                    const world = mc.theWorld!;
                    const iBlockState = world.getBlockState(blockPos)!;
                    const block = iBlockState.getBlock()!;
                    return block.getCollisionBoundingBox(world, blockPos, iBlockState) == null ? !(block instanceof BlockWeb) : block instanceof BlockSnow && block.isReplaceable(world, blockPos);
                }
        
            }
        
        }
        
        let scriptModule: any;
        
        function onLoad() {}
        
        function onEnable() {
            scriptModule = moduleManager.registerModule(new PathAlgorithm());
        }
        
        function onDisable() {
            moduleManager.unregisterModule(scriptModule);
        }
        
        ybyyby_ awaY Offline
        ybyyby_ awaY Offline
        ybyyby_ awa
        wrote on last edited by
        #3

        @CookieChinese 十分有趣

        1 Reply Last reply
        0

        Hello! It looks like you're interested in this conversation, but you don't have an account yet.

        Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

        With your input, this post could be even better 💗

        Register Login
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        About
        • Terms of Service
        • Privacy Policy
        • Status
        • Contact Us
        Downloads
        • Releases
        • Source code
        • License
        Docs
        • Tutorials
        • CustomHUD
        • AutoSettings
        • ScriptAPI
        Community
        • Forum
        • Guilded
        • YouTube
        • Twitter
        • D.Tube
        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups