“苏泽学习笔记”的版本间的差异

来自星际争霸重制版地图研究所
跳到导航 跳到搜索
 
(未显示同一用户的9个中间版本)
第3行: 第3行:
== epScript、eudplib、euddraft 的关系 ==
== epScript、eudplib、euddraft 的关系 ==


[https://raw.githubusercontent.com/armoha/eudplib/master/docs/funclist.txt epScript] 是由 [https://github.com/phu54321 TriggerKing] 创造的脚本语言,用于利用星际争霸的触发器的 EUD 漏洞编写复杂的触发器逻辑
[https://raw.githubusercontent.com/armoha/eudplib/master/docs/funclist.txt epScript] 是由 [https://github.com/phu54321 TriggerKing] 创造的脚本语言,用于利用星际争霸的触发器的 [[EUD]] 漏洞编写复杂的触发器逻辑


[https://github.com/armoha/eudplib eudplib] 是一个 Python 库,它提供了一系列可读性较好的编写触发器逻辑的 API,并且运行这些 Python 脚本(<code>*.py</code>)将会生成对应的星际争霸的触发器字节码
[https://github.com/armoha/eudplib eudplib] 是一个 Python 库,它提供了一系列可读性较好的编写触发器逻辑的 API,并且运行这些 Python 脚本(<code>*.py</code>)将会生成对应的星际争霸的触发器字节码
第24行: 第24行:


[[SCMD]]
[[SCMD]]
这里假设你已经知道 EUD 是什么意思,如果还不知道,请先参考:
[[EUD]]


=== 环境准备 ===
=== 环境准备 ===
第31行: 第35行:
准备好 SCMD,如果还没准备,往回看几行
准备好 SCMD,如果还没准备,往回看几行


下载 [https://github.com/armoha/euddraft/releases/download/v0.9.9.7/euddraft0.9.9.7.7z euddraft0.9.9.7.7z]
==== 下载 [https://github.com/armoha/euddraft/releases/download/v0.9.9.7/euddraft0.9.9.7.7z euddraft0.9.9.7.7z] ====
 
将 euddraft 解压缩到一个纯英文没有空格的路径中,例如 D:\SCRMapDevTools\euddraft0.9.9.7


*将 euddraft 解压缩到一个纯英文没有空格的路径中,例如 D:\SCRMapDevTools\euddraft0.9.9.7
==== 下载 [https://code.visualstudio.com/Download VSCode] ====


下载 [https://code.visualstudio.com/Download VSCode]
安装它,随便怎么安装都行


*安装它,随便怎么安装都行
从 VSCode 插件商店中安装 eps-server 这款插件


*从 VSCode 插件商店中安装 eps-server 这款插件
=== 地图准备 ===
=== 地图准备 ===


准备一个普通的地图文件,可以用 SCMD 新建,然后保存成 Starcraft: Remastered Broodwar Map (*.scx) 格式的文件
准备一个普通的地图文件,可以用 SCMD 新建,然后保存成 Starcraft: Remastered Broodwar Map (*.scx) 格式的文件


依然保存到一个纯英文没有空格的路径中,例如 D:\Projects\test\basemap.scx
依然保存到一个纯英文没有空格的路径中,例如 <code>D:\Projects\test\basemap.scx</code>
 
=== 建立工程 ===
=== 建立工程 ===


新建一个文本文档,并将它的扩展名改为 edd ,例如 D:\Projects\test\test.edd
新建一个文本文档,并将它的扩展名改为 edd ,例如 <code>D:\Projects\test\test.edd</code>


*使用 VSCode 打开这个 edd 文件(直接将文件往打开的 VSCode 界面中一拖就行),然后把它的内容改为
使用 VSCode 打开这个 edd 文件(直接将文件往打开的 VSCode 界面中一拖就行),然后把它的内容改为


<source lang="js" line>
<source lang="js" line>
第59行: 第65行:
</source>
</source>


*以上代码用相对路径做例子,实际它是支持绝对路径的
以上代码用相对路径做例子,实际它是支持绝对路径的


*新建一个文本文档,并将它的扩展名改为 eps ,例如 D:\Projects\test\main.eps
新建一个文本文档,并将它的扩展名改为 eps ,例如 <code>D:\Projects\test\main.eps</code>


*使用 VSCode 打开这个 eps 文件,然后把它的内容改为
使用 VSCode 打开这个 eps 文件,然后把它的内容改为


<source lang="js" line>
<source lang="js" line>
第78行: 第84行:
}
}
</source>
</source>
新建一个文本文档,并将它的扩展名改为 bat ,例如 D:\Projects\test\build.bat
新建一个文本文档,并将它的扩展名改为 bat ,例如 <code>D:\Projects\test\build.bat</code>


使用 VSCode 打开这个 bat 文件,然后把它的内容改为
使用 VSCode 打开这个 bat 文件,然后把它的内容改为
第86行: 第92行:
</source>
</source>


*以上代码假设你将 euddraft 解压到了 D:\SCRMapDevTools\euddraft0.9.9.7 这个位置,如果它不在这儿,你应该替换它
* 以上代码假设你将 euddraft 解压到了 <code>D:\SCRMapDevTools\euddraft0.9.9.7</code> 这个位置,如果它不在这儿,你应该替换它


*至此,工程就已经建立好了,直接双击运行 build.bat 就可以生成 test.scx,将这个地图放入星际重制版的地图目录中,然后进游戏就能看到它在屏幕上输出的 Hello World
至此,工程就已经建立好了,直接双击运行 build.bat 就可以生成 test.scx,将这个地图放入星际重制版的地图目录中,然后进游戏就能看到它在屏幕上输出的 Hello World


== 运行模式 ==
== 运行模式 ==


是游戏开始后,执行一次 onPluginStart(),然后`每帧`在所有玩家的机器上都执行 beforeTriggerExec()、触发器、afterTriggerExec()
是游戏开始后,执行一次 onPluginStart(),然后在所有玩家的机器上都循环执行 beforeTriggerExec()、触发器、afterTriggerExec()


例如有如下配置 main.edd:
例如有如下配置 main.edd:
第121行: 第127行:
     a.afterTriggerExec()
     a.afterTriggerExec()
</source>
</source>
[[基本语法]]
[[使用变量]]
[[使用函数]]
[[使用对象]]
[[内置基本对象类型]]
[[内置扩展对象类型]]
[[内置函数库]]


== 数据同步说明 ==
== 数据同步说明 ==


如果将`非同步数据`(例如玩家鼠标位置)赋值给变量,该变量对于每个玩家都不一样,若以此判断做出更改`需要同步的数据`的动作,将会导致多人游戏中玩家`需要同步的数据`不同步而引发掉线
如果将<code>非同步数据</code>(例如玩家鼠标位置)赋值给变量,该变量对于每个玩家都不一样,若以此判断做出更改<code>需要同步的数据</code>的动作,将会导致多人游戏中玩家<code>需要同步的数据</code>不同步而引发掉线


该类任务通常可以使用 MSQC 插件来辅助解决
该类任务通常可以使用 MSQC 插件来辅助解决
第148行: 第140行:
=== 当前玩家 ===
=== 当前玩家 ===


即 CurrentPlayer ,是一个全局变量,有一些函数内部会使用它
是一个全局变量,有一些函数内部会使用它,<code>当前玩家</code>甚至可能根本不是指一个玩家,可能存储任何数值


setcurpl 是设置使用 CurrentPlayer 这个全局变量值的函数
setcurpl 是设置<code>当前玩家</code>这个全局变量值的函数


getcurpl 是获取 CurrentPlayer 这个全局变量现在是什么值的函数
getcurpl 是获取<code>当前玩家</code>这个全局变量现在是什么值的函数


无论你将 CurrentPlayer 设置为什么值,所有的代码都会在所有玩家的机器上执行
无论你将<code>当前玩家</code>设置为什么值,所有的代码都会在所有玩家的机器上执行


示例
示例
第165行: 第157行:
setcurpl(P3);
setcurpl(P3);
StringBuffer(64).printf(&quot;给玩家 3 打印的内容&quot;);
StringBuffer(64).printf(&quot;给玩家 3 打印的内容&quot;);
// CurrentPlayer 是常量数字 13,它可以使一些与玩家相关的条件或动作去访问 当前玩家 的值
// CurrentPlayer != getcurpl()
// 将 Fastest 游戏速度 x2
setcurpl(-122787 + 6);
SetDeaths(CurrentPlayer, SetTo, 21, 0);
</source>
</source>


第181行: 第180行:
setcurpl(P3); StringBuffer(64).printf(&quot;当前玩家编号:{}&quot;, getuserplayerid());
setcurpl(P3); StringBuffer(64).printf(&quot;当前玩家编号:{}&quot;, getuserplayerid());
</source>
</source>
=== edd 和 eds 的区别 ===
euddraft 对这两种扩展名的处理方式不一样
==== 对 edd 格式 ====
它会在顺利编译生成地图完成后保持等待,如果项目目录中文件发生了变化,则它会自动再次编译生成地图
如果不顺利,则输出错误信息,你可以按 R 键让它再次编译生成
==== 对 eds 格式 ====
它会在顺利编译生成地图完成后退出
如果不顺利,会输出错误信息并等待你按回车键退出
== epScript 文档 ==
[https://flowus.cn/share/1f8c26a6-90d3-49bb-ac03-091ae87d1fa1 基本语法]
[https://flowus.cn/share/7102c106-a67a-47e7-90fd-0433925cd0b3 使用变量]
[https://flowus.cn/share/1e5bcb2f-7833-42ab-bd30-08be29df9f3d 使用函数]
[https://flowus.cn/share/c3ebeebd-908a-4532-a319-f2dd6dde5391 使用对象]
[https://flowus.cn/share/fc3421f7-a8a6-484b-b415-6808634710d2 内置基本对象类型]
[https://flowus.cn/share/1644c29f-4a0a-4ae2-9ae7-af079b8d061e 内置扩展对象类型]
[https://flowus.cn/share/97e2df11-2d33-4e67-b915-40874d8428a7 常量对照表]
[https://flowus.cn/share/8cbb3629-3733-4e0e-91fb-bd965df03795 内置函数库]

2023年5月15日 (一) 15:27的最新版本

个人学习的理解

epScript、eudplib、euddraft 的关系

epScript 是由 TriggerKing 创造的脚本语言,用于利用星际争霸的触发器的 EUD 漏洞编写复杂的触发器逻辑

eudplib 是一个 Python 库,它提供了一系列可读性较好的编写触发器逻辑的 API,并且运行这些 Python 脚本(*.py)将会生成对应的星际争霸的触发器字节码

euddraft 先将编写好的 epScript 脚本(*.eps)编译成调用 eudplib 功能的 Python 脚本(*.py

然后 euddraft 会按照一定顺序运行这些 Python 脚本(*.py),它们将会调用 eudplib 来生成与编写好的 epScript 脚本(*.eps)等效的实际的触发器字节码

最终 euddraft 再将这些触发器字节码插入地图中,在地图加载时生效,实现逻辑并产生效果

更多细节可参考

epScript 实现原理

如何开始

以下操作,假如有遇到看不懂的地方,可以尝试搜索引擎解决

这里假设你已经会使用 SCMD 进行基本的地形设计,如果还不会,请先参考:

SCMD

这里假设你已经知道 EUD 是什么意思,如果还不知道,请先参考:

EUD

环境准备

准备一台 Windows 10 以上的 PC,或者虚拟机

准备好 SCMD,如果还没准备,往回看几行

下载 euddraft0.9.9.7.7z

将 euddraft 解压缩到一个纯英文没有空格的路径中,例如 D:\SCRMapDevTools\euddraft0.9.9.7

下载 VSCode

安装它,随便怎么安装都行

从 VSCode 插件商店中安装 eps-server 这款插件

地图准备

准备一个普通的地图文件,可以用 SCMD 新建,然后保存成 Starcraft: Remastered Broodwar Map (*.scx) 格式的文件

依然保存到一个纯英文没有空格的路径中,例如 D:\Projects\test\basemap.scx

建立工程

新建一个文本文档,并将它的扩展名改为 edd ,例如 D:\Projects\test\test.edd

使用 VSCode 打开这个 edd 文件(直接将文件往打开的 VSCode 界面中一拖就行),然后把它的内容改为

[main]
input: basemap.scx
output: test.scx

[main.eps]

以上代码用相对路径做例子,实际它是支持绝对路径的

新建一个文本文档,并将它的扩展名改为 eps ,例如 D:\Projects\test\main.eps

使用 VSCode 打开这个 eps 文件,然后把它的内容改为

function onPluginStart() { // 游戏开始将会执行一次这个函数
    DisplayTextAll("Hello World");
}

function beforeTriggerExec() { // 游戏每一帧会先执行一次这个,然后执行传统触发器

}

function afterTriggerExec() { // 游戏每一帧在执行完传统触发器后,会执行一次这个函数

}

新建一个文本文档,并将它的扩展名改为 bat ,例如 D:\Projects\test\build.bat

使用 VSCode 打开这个 bat 文件,然后把它的内容改为

D:\SCRMapDevTools\euddraft0.9.9.7\euddraft.exe test.edd
  • 以上代码假设你将 euddraft 解压到了 D:\SCRMapDevTools\euddraft0.9.9.7 这个位置,如果它不在这儿,你应该替换它

至此,工程就已经建立好了,直接双击运行 build.bat 就可以生成 test.scx,将这个地图放入星际重制版的地图目录中,然后进游戏就能看到它在屏幕上输出的 Hello World

运行模式

是游戏开始后,执行一次 onPluginStart(),然后在所有玩家的机器上都循环执行 beforeTriggerExec()、触发器、afterTriggerExec()

例如有如下配置 main.edd:

[main]
input: in.scx
output: out.scx

[a.eps]
[b.eps]
[c.eps]

游戏开始后的执行顺序为:

a.onPluginStart()
b.onPluginStart()
c.onPluginStart()
    每帧循环执行:
    a.beforeTriggerExec()
    b.beforeTriggerExec()
    c.beforeTriggerExec()
    SCMD 触发器
    c.afterTriggerExec()
    b.afterTriggerExec()
    a.afterTriggerExec()

数据同步说明

如果将非同步数据(例如玩家鼠标位置)赋值给变量,该变量对于每个玩家都不一样,若以此判断做出更改需要同步的数据的动作,将会导致多人游戏中玩家需要同步的数据不同步而引发掉线

该类任务通常可以使用 MSQC 插件来辅助解决


当前玩家与本机玩家

当前玩家本机玩家 是两个不同的概念

当前玩家

是一个全局变量,有一些函数内部会使用它,当前玩家甚至可能根本不是指一个玩家,可能存储任何数值

setcurpl 是设置当前玩家这个全局变量值的函数

getcurpl 是获取当前玩家这个全局变量现在是什么值的函数

无论你将当前玩家设置为什么值,所有的代码都会在所有玩家的机器上执行

示例

setcurpl(P1);
StringBuffer(64).printf("给玩家 1 打印的内容");
setcurpl(P2);
StringBuffer(64).printf("给玩家 2 打印的内容");
setcurpl(P3);
StringBuffer(64).printf("给玩家 3 打印的内容");

// CurrentPlayer 是常量数字 13,它可以使一些与玩家相关的条件或动作去访问 当前玩家 的值
// CurrentPlayer != getcurpl()

// 将 Fastest 游戏速度 x2
setcurpl(-122787 + 6);
SetDeaths(CurrentPlayer, SetTo, 21, 0);

本机玩家

getuserplayerid() 可以获取 本机玩家编号,它对每个机器都返回不同的值,与 setcurpl 函数设置的值毫无关联

可以使用 getuserplayerid() 来获取本机玩家的编号意味着你可以决定是否在本机执行或者不执行某些代码,当然你需要小心,千万不要试图以此直接或者间接污染`需要同步的数据`,它可能导致数据不同步而引发掉线

示例

setcurpl(P1);
StringBuffer(64).printf("当前玩家编号:{}", getuserplayerid());
setcurpl(P2); StringBuffer(64).printf("当前玩家编号:{}", getuserplayerid());
setcurpl(P3); StringBuffer(64).printf("当前玩家编号:{}", getuserplayerid());

edd 和 eds 的区别

euddraft 对这两种扩展名的处理方式不一样

对 edd 格式

它会在顺利编译生成地图完成后保持等待,如果项目目录中文件发生了变化,则它会自动再次编译生成地图

如果不顺利,则输出错误信息,你可以按 R 键让它再次编译生成

对 eds 格式

它会在顺利编译生成地图完成后退出

如果不顺利,会输出错误信息并等待你按回车键退出


epScript 文档

基本语法

使用变量

使用函数

使用对象

内置基本对象类型

内置扩展对象类型

常量对照表

内置函数库