烁灵 发表于 2024-6-2 23:15:38

【汉化】距离与直线视野检查

本帖最后由 烁灵 于 2024-6-20 17:46 编辑

可判断事件与玩家是否接近,包含直线视野。


原地址:Proximity Sensor (RMMZ) | RPG Maker Forums (rpgmakerweb.com)

设置预览:



脚本:命名为 r88_ProximitySensor.js
/*:
@target MZ
@plugindesc 距离检测与直线视线.
汉化 by 烁灵 更多脚本请访问 www.hknmtt.com
@author reflector88
@url https://reflector88.itch.io/
@help

"Proximity Sensor 1.2"
本脚本将可在事件接近玩家时开启 开关或独立开关
可用来制作巡逻敌人、隐身物品、陷阱等,同时提供直线视线功能

Update
-V1.1 Added "Facing in a Line"
-V1.2 Switches now toggle; improved compatibility
____________________________________________________________________________
设置
1. 在事件指令中选择 "插件指令"

2. 选择你想用的距离检测类型:
    "所有" - 在所有方向上检测.
    "面对" - 只检查事件面对的方向.
    "十字线" - 在十字线上检测.
    "面对线" - 在事件面对的方向,并且与事件在同一条线上

3. 设置对象和距离
    (比如 "小于等于 3" 检查玩家是否与事件距离 3 格以内)

4. 设置要开启的开关/独立开关

5. 设置区域ID或地形标识来表示视野障碍
____________________________________________________________________________

TERMS OF USE
This plugin is free to use in both commercial and non-commercial projects,
though please credit me.


@param Obstacle Region ID
@text 障碍物区域ID
@type number
@desc 阻挡视线的区域ID
@default 1

@param Obstacle Terrain Tag
@text 障碍物地形标识
@type number
@desc 阻挡视线的地形标识
@default 1

@command Basic
@text 所有方向
@desc 检查事件是否接近玩家

    @arg Operator
    @text 计算方式
    @type select
    @option 小于
    @value less than
    @option 小于等于
    @value less than or equal to
    @option 等于
    @value equals
    @option 大于等于
    @value greater than or equal to
    @option 大于
    @value greater than
    @default less than or equal to
    @desc 计算方式.

    @arg Distance
    @text 距离
    @type number
    @default 3
    @desc 比较与玩家的距离

    @arg Self-Switch
    @text 独立开关
    @type select
    @option 0 @option A @option B @option C @option D
    @default A
    @desc 开启的独立开关

    @arg Switch
    @text 开关
    @type switch
    @default 0
    @desc 开启的开关

@command Facing
@text 面对
@desc 检查事件是否在事件面向的方向上接近玩家

    @arg Operator
    @text 计算方式
    @type select
    @option 小于
    @value less than
    @option 小于等于
    @value less than or equal to
    @option 等于
    @value equals
    @option 大于等于
    @value greater than or equal to
    @option 大于
    @value greater than
    @default less than or equal to
    @desc 计算方式.

    @arg Distance
    @text 距离
    @type number
    @default 3
    @desc 比较与玩家的距离

    @arg Self-Switch
    @text 独立开关
    @type select
    @option 0 @option A @option B @option C @option D
    @default A
    @desc 开启的独立开关

    @arg Switch
    @text 开关
    @type switch
    @default 0
    @desc 开启的开关

@command Orthogonal
@text 十字线
@desc 检查事件在所在的十字线上是否接近玩家

    @arg Operator
    @text 计算方式
    @type select
    @option 小于
    @value less than
    @option 小于等于
    @value less than or equal to
    @option 等于
    @value equals
    @option 大于等于
    @value greater than or equal to
    @option 大于
    @value greater than
    @default less than or equal to
    @desc 计算方式.

    @arg Distance
    @text 距离
    @type number
    @default 3
    @desc 比较与玩家的距离

    @arg Self-Switch
    @text 独立开关
    @type select
    @option 0 @option A @option B @option C @option D
    @default A
    @desc 开启的独立开关

    @arg Switch
    @text 开关
    @type switch
    @default 0
    @desc 开启的开关

@command FacingLine
@text 面对线
@desc 检查事件在事件面对的线上是否接近玩家.

    @arg Operator
    @text 计算方式
    @type select
    @option 小于
    @value less than
    @option 小于等于
    @value less than or equal to
    @option 等于
    @value equals
    @option 大于等于
    @value greater than or equal to
    @option 大于
    @value greater than
    @default less than or equal to
    @desc 计算方式.

    @arg Distance
    @text 距离
    @type number
    @default 3
    @desc 比较与玩家的距离

    @arg Self-Switch
    @text 独立开关
    @type select
    @option 0 @option A @option B @option C @option D
    @default A
    @desc 开启的独立开关

    @arg Switch
    @text 开关
    @type switch
    @default 0
    @desc 开启的开关
*/

(() => {
    'use strict';
    var r88 = r88 || {};
    r88.PS = r88.PS || {};
    r88.PS.parameters = PluginManager.parameters('r88_ProximitySensor');
    r88.PS.regionId = r88.PS.parameters["Obstacle Region ID"];
    r88.PS.terrainTag = r88.PS.parameters["Obstacle Terrain Tag"];

    function r88_isProx(args) {
      const playerX = $gamePlayer.x;
      const playerY = $gamePlayer.y;
      const eventX = $gameMap.event(this._eventId).x;
      const eventY = $gameMap.event(this._eventId).y;
      const operator = args['Operator'];
      const distance = args['Distance'];
      const proximity = (Math.sqrt(Math.pow(eventX - playerX, 2) +
            Math.pow(eventY - playerY, 2)));

      switch (operator) {
            case 'less than': return proximity < distance;
            case 'less than or equal to': return proximity <= distance;
            case 'equals': return proximity === distance;
            case 'greater than or equal to': return proximity >= distance;
            case 'greater than': return proximity > distance;
            default: return false;
      }
    }

    function r88_isFacing() {
      const dir = $gameMap.event(this._eventId).direction();
      const playerX = $gamePlayer.x;
      const playerY = $gamePlayer.y;
      const eventX = $gameMap.event(this._eventId).x;
      const eventY = $gameMap.event(this._eventId).y;

      if (dir == 2 && eventY < playerY || dir == 8 && eventY > playerY
            || dir == 4 && eventX > playerX || dir == 6 && eventX < playerX) {
            return true;
      } else {
            return false;
      }
    }

    function r88_isOrthogonal() {
      const playerX = $gamePlayer.x;
      const playerY = $gamePlayer.y;
      const eventX = $gameMap.event(this._eventId).x;
      const eventY = $gameMap.event(this._eventId).y;

      return playerX === eventX || playerY === eventY;
    }

    // Bresenham Algorithm for line of sight calculation
    function r88_inLineOfSight() {
      const tileCoords = [];
      const playerX = $gamePlayer.x;
      const playerY = $gamePlayer.y;
      const eventX = $gameMap.event(this._eventId).x;
      const eventY = $gameMap.event(this._eventId).y;
      const distanceX = Math.abs(playerX - eventX);
      const distanceY = Math.abs(playerY - eventY);
      const incrementX = (eventX < playerX) ? 1 : -1;
      const incrementY = (eventY < playerY) ? 1 : -1;
      let tileX = eventX;
      let tileY = eventY;
      let error = distanceX - distanceY;

      while (tileX !== playerX || tileY !== playerY) {
            tileCoords.push();

            const error2 = 2 * error;
            if (error2 > -distanceY) {
                error -= distanceY;
                tileX += incrementX;
            }
            if (error2 < distanceX) {
                error += distanceX;
                tileY += incrementY;
            }
      }

      for (let i = 0; i < tileCoords.length; i++) {
            if ($gameMap.regionId(tileCoords, tileCoords) == r88.PS.regionId ||
                $gameMap.terrainTag(tileCoords, tileCoords) == r88.PS.terrainTag)
                return false;
      }
      return true;

    }

    function r88_FlipSwitch(args) {
      if (r88_inLineOfSight.call(this)) {

            if (args['Self-Switch'] !== '0') {
                $gameSelfSwitches.setValue([this._mapId, this._eventId,
                args['Self-Switch']], !$gameSelfSwitches.value([this._mapId, this._eventId,
                args['Self-Switch']]));
            }
            $gameSwitches.setValue(args['Switch'], !$gameSwitches.value(args['Switch']));
      }
    }

    // User-defined plugin commands
    function r88_basicProx(args) {
      if (r88_isProx.call(this, args)) {
            r88_FlipSwitch.call(this, args);
      }
    }

    function r88_facingProx(args) {
      if (r88_isProx.call(this, args) && r88_isFacing.call(this)) {
            r88_FlipSwitch.call(this, args);
      }
    }

    function r88_orthogonalProx(args) {
      if (r88_isProx.call(this, args) && r88_isOrthogonal.call(this)) {
            r88_FlipSwitch.call(this, args);
      }
    }

    function r88_facingLineProx(args) {
      if (r88_isProx.call(this, args) && r88_isFacing.call(this) && r88_isOrthogonal.call(this)) {
            r88_FlipSwitch.call(this, args);
      }
    }


    PluginManager.registerCommand("r88_ProximitySensor", "Basic", r88_basicProx);
    PluginManager.registerCommand("r88_ProximitySensor", "Facing", r88_facingProx);
    PluginManager.registerCommand("r88_ProximitySensor", "Orthogonal", r88_orthogonalProx);
    PluginManager.registerCommand("r88_ProximitySensor", "FacingLine", r88_facingLineProx);

})();

页: [1]
查看完整版本: 【汉化】距离与直线视野检查