Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
Skins
  • Light
  • 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 352 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
        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