>此篇幅可能较大,我尽可能的讲的直白一点
导航:
[TOC]
<br><br><br>
*****
# 浅尝代码(必读)
## 在pr4.3.0以下版本时,公式是这样的
```
#启用伤害节点
damage-types:
#攻击mob时所选
mob:
#左键攻击
damage:
#自定义伤害类型
伤害: true
#战斗公式节点
formula:
fight:
mob:
damage:
伤害:
damage:
hit: true
value: 'Math.max({a.攻击}-{v,防御},1)'
```
*****
<br><br><br>
## 因此转换后得到:
```
#启用伤害节点
damage-types:
#攻击mob时所选
mob:
#左键攻击
damage:
#自定义伤害类型
伤害: true
#战斗公式节点
formula:
fight:
mob:
damage:
伤害:
damage:
hit: true
value: |-
UMap a = data.get("attacker");
Att a_att = a.get("att");
UMap v = data.get("victim");
Att v_att = v.get("att");
double a_攻击 = a_att.get("攻击");
double v_防御 = v_att.get("防御");
return Math.max(a_攻击-v_防御,1);
```
*****
<br><br><br>
## UMap类型
```
UMap a = data.get("attacker");
//类型 变量名 = 变量名.方法名(参数1[,参数2...]);
```
**UMap** 是一个java类 ~~(类似于HashMap)~~ ,内含了 **get(String key)** 等方法供用户去获取里面的内容
>用白话来讲就`UMap`相当于一个柜子,柜子有很多格子,pr在传过来的会在格子里面塞满了东西
你要拿柜子上 **第三排第四格(假如是 attacker)** 的东西
只需要使用 **data.get("attacker");** 即可拿到
*****
<br><br><br>
## 获取双方相关属性对象:
```
UMap a = data.get("attacker");
//先拿到攻击方的相关数据,并命名变量名为 a(供下方代码使用), 攻击方的相关数据也是一个 UMap
```
```
Att a_att = a.get("att");
//再从 a 里面拿到 攻击方的相关属性对象 类型 Att 并命名变量为: a_att(供下面代码使用)
```
**[`Att`](../%E5%B8%B8%E7%94%A8%E5%B7%A5%E5%85%B7%E7%B1%BB/%5B%E5%B1%9E%E6%80%A7%E5%AF%B9%E8%B1%A1%5DAtt.md)** 是pr封装的一个属性类
```
//拿到 攻击方 的 "攻击" 总属性:
double a_攻击 = a_att.get("攻击"); // (注意如果是 String 字符串类型常量,需要前后加上双引号)
//注意这里是 double 类型, 也就小数, 整数类型一般用 int
```
```
//再拿到 被攻击方 的 "防御" 属性
UMap v = data.get("victim"); // 被攻击方的相关数据
Att v_att = v.get("att"); //被攻击方的相关属性对象
double v_防御 = v_att.get("防御");
```
```
//最终将两者属性运用在想要的公式当中返回给pr
return Math.max(a_攻击 - v_防御, 1);
//这里的 Math.max(参数1,参数2) 是java的取最大值的静态方法,pr已将其自动导入环境,无需再导入可直接使用
```
<br><br><br>
## 总和起来的代码就是
```
UMap a = data.get("attacker");
UMap v = data.get("victim");
Att a_att = a.get("att");
Att v_att = v.get("att");
double a_攻击 = a_att.get("攻击");
double v_防御 = v_att.get("防御");
return Math.max(a_攻击 - v_防御, 1);
//注意代码的放置顺序, 在下面的代码可以调用到上面代码声明的变量,
//如: Att a_att = a.get("att"); 就必须放在 UMap a = data.get("attacker"); 的下面
//说白点就是:
//你得先告诉程序, 我声明了一个类型为 UMap ,名字为 a 的变量
//并且他拿着我给他的重要文件,我下面可能要用到,别给老子搞丢了
```
>[danger] Tip: 变量名不可以重复!!!, 支持 英文或下划线或中文/开头,后面还支持数字
> 变量在程序中是没有任何作用的, 只是给我们写代码的人看得懂不要出错就行
<br><br><br>
## 启用公式返回值和战斗公式中hit和value的返回值
```
#启用伤害节点
damage-types:
mob:
damage:
伤害: true //这里的返回值是boolea型(真假|对错), 其值只有2个 不是 true 就是 false
#战斗公式节点
fight-formula:
mob:
damage:
伤害:
damage:
hit: true //这里命中公式返回的是 boolean 型(真假), 其值只有2个 不是 true 就是 false
//这里如果写了多行代码,则需要写成 return true/false; 如果只有单个 true 或者 false 可以直接写 true/false
/* 如下
hit: |-
UMap a = data.get("attacker");
Att a_att = a.get("att");
UMap v = data.get("victim");
Att v_att = v.get("att");
double a_命中= a_att.get("命中");
double v_闪避 = v_att.get("闪避");
//这里的 Math.random() 是取随机数小数 范围 0~1
if(Math.random() <= a_命中 / (a_命中+v_闪避)){
return true;
} else {
return false;
}
*/
value: |-
UMap a = data.get("attacker");
Att a_att = a.get("att");
UMap v = data.get("victim");
Att v_att = v.get("att");
double a_攻击 = a_att.get("攻击");
double v_防御 = v_att.get("防御");
return Math.max(a_攻击-v_防御,1); //这里返回的是 double 型(小数),值的范围就大了
```
<br><br><br>
## 在公式中进行调试输出任意内容
```
#战斗公式节点
fight-formula:
mob:
damage:
伤害:
damage:
hit: true
value: |-
//使用java原生方法向服务端后台打印信息
double a_属性 = 15D;
System.out.println("这是调试信息, 打印攻击方属性: " + a_属性);
```
>可以使用 + 来连接各种变量或者字符串
<br><br><br>
# 深入一点(浅尝后)
>[danger] 请在学习浅尝后正确触发伤害公式再看
<br><br><br>
## 拿到双方的等级
```
UMap a = data.get("attacker");
UMap v = data.get("victim");
//既然 攻击方 也是个 UMap , 那里面应该也有不少东西
int a_level = a.get("level"); //除了能 获取 Att 属性, pr也将当前的主职业等级(或者是mob的当前等级) 也放进来了
int v_level = v.get("level"); //被攻击方也是一样
```
<br><br><br>
## 万能的 IF 表达式(用于流程控制)
```
//万能的if写法
if( 逻辑表达式 ){
//成立的代码块
}else{
//不成立的代码块
}
```
<br><br><br>
*****
### 逻辑表达式可以是啥:
>逻辑表达式一旦成立,就会返回 true
#### 比较两个数
```
比较两个数:
x == y
x != y
x >= y
x > y
x < y
x <= y
```
<br><br><br>
#### 比较两个字符串
```
String str = "我是SB";
//以下是原生java的方法
str.contains("SB") //str中包含 "SB" 时就会成立,
str.equals("SB") //str 完全等于 "SB" 时就会成立
str.equalsIgnoreCase("sb") //str 忽略大小写等于 "sb" 时就会成立
```
<br><br><br>
#### 比较逻辑类型
```
boolean 玩家等级是否大于10 = false;
if(玩家等级是否大于10 == true){ ... } else { ... } //注意判断符号不是 = 而是 ==
if(玩家等级是否大于10){ ... } else { ... } //当上面的代码判断 boolean 是否等于 true 时,可忽略后面的 等值判断代码
```
<br><br><br>
#### 取反
>前面加个叹号,使其逻辑意思相反,假的变真,真的变假
如果是多元表达式, 请前后加上括号
```
2>1 = true
!(2>1) = false
String str = "SB";
!str.equalsIgnoreCase("sb") //str 忽略大小写等于 "sb" 时会成立,但是取反, 就返回 false 了
```
<br><br><br>
#### 比较双方等级
```
UMap a = data.get("attacker");
UMap v = data.get("victim");
int a_level = a.get("level");
int v_level = v.get("level");
if(a_level > v_level){
//如果攻击方的等级 > 被攻击方的等级时, 执行的代码块
}else{
//如果攻击方的等级 <= 被攻击方的等级时, 执行的代码块
}
```
<br><br><br>
### 多个同级逻辑判断 && 和 ||
>&& = 而且
|| = 或者
例子1:
```
...
int a_level = 10;
int v_level = 5;
//攻击方等级> 9级 而且 攻击方等级 > 被攻击方等级 这个表达式成立
if(a_level > 9 && a_level > v_level){
//成立
}
...
```
例子2:
```
...
int a_level = 5;
int v_level = 3;
//攻击方等级> 9级 或者 攻击方等级 > 被攻击方等级 这个表达式成立
if(a_level > 9 || a_level > v_level){
//成立
}
...
```
例子3:
```
...
int a_level = 15;
int v_level = 3;
//在攻击方等级 >= 10 而且 <= 20 并且 > 被攻击方等级时成立
if(a_level >= 10 && a_level <= 20 && a_level > v_level){
//成立
}
...
```
<br><br><br>
### 简化if/三元运算
```
...
int a_level = 10;
int v_level = 5;
double 伤害倍率 = 1; //先声明一个变量,名字随便取,自己看得懂就行
if(a_level > v_level){
伤害倍率 = 1.5;
}else{
伤害倍率 = 0.5;
}
...
```
当if代码块里面只有一行代码时, 可以去掉花括号,结果如下:
```
...
int a_level = 10;
int v_level = 5;
double 伤害倍率 = 1; //先声明一个变量,名字随便取,自己看得懂就行
if(a_level > v_level)
伤害倍率 = 1.5;
else
伤害倍率 = 0.5;
//或者=> if(a_level > v_level) 伤害倍率 = 1.5; else 伤害倍率 = 0.5;
...
```
像上面这种代码还可以简化成三元运算
```
...
int a_level = 10;
int v_level = 5;
double 伤害倍率 = a_level > v_level ? 1.5 : 0.5; //跟上面的结果是一样的
...
```
逻辑型变量更简单:
```
...
int a_level = 10;
int v_level = 5;
boolean 伤害倍率开启 = a_level > v_level; //三元运算 问号 前面的是逻辑表达式
...
```
<br><br><br>
### if的注意事项
>[danger]在公式中或者具有返回值的方法体里面
所有if分支都需要具有一个明确的返回值
例如命中公式:
```
hit: |-
if( 逻辑表达式1 ){
if( 逻辑表达式2 ){
return true;
} else {
return false;
}
} else if( 逻辑表达式2 ){
return true;
} else {
return false;
}
```
<br><br><br>
## Math数学函数类
>[info] 该类是java自带的原生类: `java.lang.Math`
<br><br><br>
### 常用的方法
```
Math.max(x,y); //取2者较大值
Math.min(x,y); //取2者较小值
Math.round(x); //四舍五入, 返回 int 类型
Math.random(); //取0~1之间的随机小数, 返回 double 类型
Math.pow(x,y); //取 x 的 y 次方 , 返回 double 类型
Math.sqrt(x); //开平方 , 返回 double 类型
```
其他的方法可以查看: [java原生文档](https://docs.oracle.com/javase/8/docs/api/)
<br><br><br>
## Pr 往 UMap data 放了些什么?
### **UMap** 类的所有方法
```
boolean has(String key); //是否有 key 的内容
Object get(String key); //获取 key 的内容
Object get(String key, Object def); //获取 key 的内容,没找到时 返回 def
set(String key, Object obj); //设置 key 的内容为 obj
Set keys(); //返回所有 key
```
>这一段是给有点基础的人看的,不懂可以不深究
这里出现了 **Object** 类,这是java所有类的父类,也可以理解为 通用类型
```
UMap a = data.get("attacker"); //这里之所以不需要向下强转,是因为我在代码层面提供了运行时检查类型
UMap a = (UMap) data.get("attacker"); //实际上这才是java调用的正确方法
```
<br><br><br>
### for循环,遍历UMap的所有内容
```
for(int i = 0 ; i < 10; i++){
System.out.println(i); //这里会循环10次, 并输出在控制台当前的循环次数
}
```
```
int 循环次数= 10;
for(int i = 0 ; i < 循环次数; i++){
System.out.println("当前循环次数: " + i);
}
```
**UMap** 有个方法是:
```
Set keys(); //返回所有 key
```
可使用for循环来遍历里面的内容:
>[danger] 注意! 代码并不支持泛型,请勿使用泛型
```
Set set = data.keys();
for(String key : set){
Object obj = data.get(key);
System.out.println("data里面有: " + key + " ,它的java类型为: " + obj.getClass().getName());
}
```
<br><br><br>
*****
### 旧版暴击伤害内的 {this.damage.value} 怎么获取 [img]
![](https://img.kancloud.cn/89/04/8904b96b793c04fd76e9ab564aa81e80_851x274.png)
![](https://img.kancloud.cn/57/fc/57fc5b919f01fe33caecb181d3f4516f_757x75.png)
这个也是pr添加的,类型也是 UMap
这个里面的内容会在pr把一段代码执行完,添加对应的内容
下图是获取 **伤害**(自定义类型) 下 **damage**(普通伤害) 的 **value**(计算的值) 并对其做一些计算
![](https://img.kancloud.cn/f2/73/f273945f82876e344bb84390be1e7062_892x675.png)
<br><br><br>
*****
### 旧版上次数据列表
```
double total_damage = fight_data.get("total_damage",0);// 到此为止的总伤害
double last_伤害_total_damage = fight_data.get("last_伤害_total_damage",0); //上面 伤害 的总结果(包含crit等),可用于附加伤害
boolean last_伤害_damage_hit = fight_data.get("last_伤害_damage_hit",false); //上面 伤害.damage 的 命中结果 ,可用于附加伤害的命中结果
double last_伤害_damage_value = fight_data.get("last_伤害_damage_value",0); //上面 伤害.damage 的 计算结果 ,可用于附加伤害的比例结果
```
<br><br><br>
*****
## SkillAPI技能等级现在该怎么获取?
当战斗公式隶属于 **skillapi** 类型时
可使用以下代码获取当前释放技能的等级
```
int skill_level = fight_data.get("skill_level");
```
另外如果像做技能等级加成伤害时,可使用下列代码:
```
UMap a = data.get("attacker");//先获取 攻击方的 UMap
USkill a_skill = a.get("skillapi"); //获取 攻击方的 USkill 数据(必须安装skillapi才会存在)
int a_天雷斩_level = a_skill.level("天雷斩"); //获取 攻击方 "天雷斩" 的技能等级
//被攻击方同理
return [最终伤害...] * (1+a_天雷斩_level*0.05); //即可实现每级天雷斩提升 5% 的伤害
```
**USkill** 所有方法:
```
int level(String skill); //获取技能等级, 没有则返回0
boolean hasSkill(String skill); //是否有某个技能
```
### 技能等级加成伤害的完整例子:
```
UMap a = data.get("attacker");
UMap v = data.get("victim");
Att a_att = a.get("att");
Att v_att = v.get("att");
USkill a_skill = a.get("skillapi");
int a_天雷斩_level = a_skill.level("天雷斩"); //这里这里
double a_攻击 = a_att.get("攻击");
double v_防御 = v_att.get("防御");
return Math.max(a_攻击 - v_防御,1) * (1+a_天雷斩_level*0.05) * Math.random(0.8,1.2);
//最后可以加一个 80%到120% 的结果随机值以免每次伤害都是一样 QAQ
```
<br><br><br>
# 再深一点!!!
>[danger] 可能需要一些java基础才能理解,下面有一些已经封装好可以直接用的类
<br><br><br>
## 向java类添加的额外方法/新增自定义类及方法
在服务器目录 `plugins\PxRpg\Modules\Code\Cover` 文件夹下
可以创建自定义类文件(后缀名必须为: .java)
>*如果找到java类,会在原有的java类上添加新的方法,未找到则会新建一个java类(看看即可)*
![](https://img.kancloud.cn/b2/b4/b2b41a3dabb99904d0893c279a738052_659x108.png)
<br>
### :-: **pxrpg.工具.java**
```
import org.bukkit.entity.Player;
import me.clip.placeholderapi.PlaceholderAPI as 变量; //导入PAPI变量的api 并设置别名为 变量
class 工具{
static void 调试(String text){
System.out.println(text);
}
static double 到小数(String text){
return Double.parseDouble(text);
}
/**
此方法需要安装 PlaceholderAPI 插件
*/
static String 取变量(String text){
return 取变量((Player) null,text);
}
/**
此方法需要安装 PlaceholderAPI 插件
*/
static String 取变量(AdapterPlayer player,String text){
return 取变量((Player) player.getObject(),text);
}
/**
此方法需要安装 PlaceholderAPI 插件
*/
static String 取变量(Player player,String text){
switch (text){
case "%player_name%":
return player.getName();
case "%plauer_level%":
return player.getLevel()+"";
}
return 变量.setPlaceholders(player, text);
}
}
```
<br><br><br>
### 将自定义类/其他类导入到环境中
*****
>[danger]创建的自定义类不会自动导入到环境内,可以在 `plugins\PxRpg\Modules\Code\env-imports.yml`文件里面添加
![](https://img.kancloud.cn/0d/29/0d29b9b6fa140a97a072dc28a4d969c1_169x47.png)
这样就可以直接在pr任何地方直接调用 `工具.方法名()`了
#### 不导入环境可以在使用前使用 `import pxrpg.工具;` 语句来导入:
```
UMap a = data.get("attacker");
import pxrpg.工具;
AdapterLivingEntity a_lving = a.get("entity");
String a_name = 工具.取变量(a_lving, "%player_name%");
...
```
#### 或者直接使用全路径名`pxrpg.工具.方法名()` 来调用
```
UMap a = data.get("attacker");
AdapterLivingEntity a_lving = a.get("entity");
String a_name = pxrpg.工具.取变量(a_lving, "%player_name%");
...
```
#### 如果后台提示重名了, 可以使用 `as 别名` 来定义另外的名字
![](https://img.kancloud.cn/53/cd/53cdec86780a4f2e5a00a1aced9e233f_247x61.png) 这样可以用 `工具类别名.方法名()` 来调用
<br><br><br>
### :-: **java.lang.Math.java**
*****
```
import java.text.NumberFormat;
import java.math.RoundingMode;
/**
在 java.lang.Math 类添加扩展方法(类似于kotlin的扩展方法)
*/
class Math{
/**
取随机小数,含头含尾
min = 最小值
max = 最大值
*/
static double random(double min,double max){
/*
在当前类的静态方法体内是具有静态环境的
这种情况下,下列三种静态方法的调用都是等价的:
random()
Math.random()
java.lang.Math.random()
*/
return random() * (max-min)+min;
}
/**
取随机整数,含头含尾
min = 最小值
max = 最大值
*/
static int random(int min,int max){
//注意强转 int
return (int) round(random() * (max-min) + min);
}
/**
取随机整数,含头含尾
max = 最大值
*/
static int random(int max){
//注意强转 int
return random(0,max);
}
/**
兼容旧版randomint
*/
static int randomint(int min,int max){
return random(min,max);
}
//静态成员
static NumberFormat nf = NumberFormat.getNumberInstance();
/**
保留小数后的几位
value = 小数
retain = 保留位数
*/
static double decimals(double value,int retain){
nf.setMaximumFractionDigits(retain);
nf.setRoundingMode(RoundingMode.HALF_UP);
nf.setGroupingUsed(false);
return Double.parseDouble(nf.format(value));
}
/**
兼容旧版RandomWeight
*/
static String RandomWeight(int[] nums,String[] rets){
int max = 0;
for(int i = 0;i<nums.length;i++) max+=nums[i];
int next = random(max);
int c = 0;
for(int i = 0;i<nums.length;i++){
c += nums[i];
if(c >= next) return rets[i];
}
return rets[0];
}
}
```
<br><br><br>
## 现在可以利用 pxrpg.工具 在战斗公式获取双方的papi变量
### 例子:
```
UMap a = data.get("attacker");
UMap v = data.get("victim");
AdapterLivingEntity a_living = a.get("entity");//获取攻击方实体
AdapterLivingEntity v_living = v.get("entity");//获取被攻击方实体
double a_papi_level = 0;//先声明 a papi等级 为0
double v_papi_level = 0;//先声明 v papi等级 为0
//判断实体是不是 玩家类型, 加上这一步可以在所有战斗公式通用
//不加的话 player攻击mob里面的mob是没有papi的
if(a_living instanceof AdapterPlayer)
a_papi_level = 工具.到小数(工具.取变量(a_living ,"%player_level%"));
if(v_living instanceof AdapterPlayer)
v_papi_level = 工具.到小数(工具.取变量((AdapterPlayer) v_living ,"%player_level%"));//这里的强转其实可以省略
...
```
> **`instanceof`** 是java关键字,用于判断对象是不是某个类型,返回 **`boolean`** 型
<br><br><br>
### 利用三元运算简化例子:
```
UMap a = data.get("attacker");
UMap v = data.get("victim");
AdapterLivingEntity a_living = a.get("entity");//获取攻击方实体
AdapterLivingEntity v_living = v.get("entity");//获取被攻击方实体
double a_papi_level = a_living instanceof AdapterPlayer ? 工具.到小数(工具.取变量(a_living ,"%player_level%")) : 0;
double v_papi_level = v_living instanceof AdapterPlayer ? 工具.到小数(工具.取变量(v_living ,"%player_level%")): 0;
...
```
<br><br><br>
## 提取相同的代码到公用库类 **Code\Cover** [img]
上面讲了新建自定义类
可以新建一个自己看得懂的类
![](https://img.kancloud.cn/db/15/db15185a6b1718d115d8f603b3a713c1_682x121.png)
并且在 `Code/env-imports.yml` 里面添加到环境导入
![](https://img.kancloud.cn/b3/a7/b3a79f53662b2a2ce42dfd17128168b3_280x81.png)
![](https://img.kancloud.cn/b1/d1/b1d1f37c1c817fe7403ac2f42a542d8c_694x653.png)
打开职业文件找到普通攻击的公式内容改为以下内容即可
![](https://img.kancloud.cn/a1/da/a1da928fe07ae31129330b070933ba34_581x204.png)
当执行代码时,只有一行可以省略 **return**
这样可以将相同的代码简化成一个方法,并可在其他地方也这样调用
- 通用配置(使用px之前先看这里)
- 1分钟搭建数据库
- 1分钟搭建Redis环境教程
- 常见问题与报错
- [技能驱动]PxSkilldrive
- 介绍
- config配置
- 所有指令
- 单个技能完整配置
- MythisMobs技能配置
- 自带的技能系统[1.1.4+]
- 打开技能组
- PlaceHolderAPI变量
- 更新日志
- [商会]PxMerchant
- 介绍
- 配置文件
- 更新日志
- [帮派]PxGangs
- 介绍
- 用前必看
- 指令一览
- 职位/权限
- 帮派数据/建筑
- PlaceHolderAPI变量
- 兼容插件
- 更新日志
- [商店]PxShop
- 介绍
- 完整商店配置
- 货币/商品
- 更新日志
- [在线/成就奖励]PxLoginRewards
- 介绍
- 安装使用
- 完整配置
- 要求/奖励
- 更新日志
- [属性]PxRpg
- 介绍
- 安装使用
- 模块文件夹
- 指令
- 属性
- 属性是什么
- 如何创建属性
- 属性组
- 如何利用属性打出伤害(已过时)
- 词条
- 介绍
- 随机词条组列表[4.4.2+]
- 职业
- config[已过时]
- 创建一个职业[已过时]
- 职业[4.3.0+]
- config[4.3.0+]
- 怪物
- 天生属性[4.5.4+]
- 装备
- 装备配置文件
- 让装备获得属性
- 装备变量[已过时]
- 装备类型
- 手持武器[4.5.3+]
- 切换装备[4.5.3+]
- 物品显示模板(lore内容)
- 装备模板的使用
- 物品
- 普通物品
- 消耗品
- 回血道具[旧版]
- 代码回血/回蓝(4.3.0+)
- code代码执行(4.3.0+)
- 介绍
- 例子
- Buff相关
- 传送相关
- 执行3种指令
- 洗炼道具
- 强化类
- 强化道具
- 强化保护券
- 强化券
- 强化转移道具
- 解绑道具
- 宝石相关
- 打孔道具
- 摘除宝石
- 绑定系统
- 绑定类型
- 战斗系统
- 战斗公式变量(已弃用)
- 配置战斗公式[4.3.0+]
- 攻击类型列表
- 自定义伤害类型
- 伤害机制
- 伤害显示
- 掉落
- 掉落类型(已弃用)
- 配置怪物掉落包
- 掉落包[4.3.0+]
- Buff
- 介绍
- buff支持的词条
- 给予buff的方法
- 显示相关
- 萌芽显示
- 龙核相关
- 套装
- 介绍
- 技能[4.5.1+]
- 介绍
- 配置技能
- 技能词条介绍
- 钩子模块[4.5.1+]
- 介绍
- 监听器API
- [自身]Monitor.yml
- [装备容器]Equip Container.yml
- [鉴定]Appraisal.yml
- [绑定]Bind.yml
- [怪物]Mob.yml
- [Buff]Buff.yml
- [分解]Decompose.yml
- [战斗]Fight.yml
- [职业]Occupation.yml
- [玩家]Player Data.yml
- Mythicmobs
- 兼容mm技能(不推荐)
- 如何让MM打出伤害
- MM技能Buff(4.1.1新增)
- MM技能触发Pr伤害(4.2.1+)
- SkillAPI(4.3.0)
- 同步SkillAPI职业
- 战斗公式变量(已弃用)
- 个人变量(已弃用)
- 覆盖技能伤害
- Buff(4.1.1新增)
- 给Mob添加Buff(4.1.1新增)
- 治疗/回蓝组件(4.3.0+)
- PlaceholderAPI变量
- 统计(4.1.0更新)
- [附属]装备经验和升级
- 使用教程
- [附属]物品拓展功能
- 介绍
- [ExtendGui]窗口环境的所有方法
- [ExtendData]拓展数据所有方法
- 类方法
- [工具类]QuickTools
- [拓展数据]ExtendData
- [拓展属性]Attr
- [拓展技能]SkillLv
- 物品生成时添加
- 属性拓展
- 技能拓展[1.0.1+]
- 大量例子
- [福利]提交活动
- 作者发布
- 简单强化
- 界面锁定
- 延迟强化
- 菜单例子
- 吞噬物品永久保存
- 安笙
- 作者介绍
- 词条强化[暂无法使用 等待更新]
- 酒桶
- 作者介绍
- 更新日志
- [附属]萌芽装备容器
- 介绍
- 例子
- 常用工具类
- [数据容器]UMap
- [属性对象]Att
- [对象BUFF]BuffContainer
- [技能对象]USKill
- 接入PxRpg插件(开发者)
- 注册模块入口
- 接入属性
- 模块配置读取
- 接入物品
- 道具生成
- 道具数据获取
- 设置数据并渲染
- 自定义道具组件
- 具有生成参数的组件
- 集成模块介绍
- 更新日志
- 视频预览
- 4.3.0+新版公式教程
- 简介(内含旧版公式转换器)
- 教程(战斗公式篇)(必先学)
- 传递参数和类型的常用方法(重要)
- 单例属性教程(含战斗力变量教程)
- 道具消耗品(含属性加成)
- 装备/宝石/怪物的属性词条
- Buff新版词条(内含属性加成)
- Drop掉落物配置(内含属性掉落加成)
- [副本]PxInstance-Pro
- 介绍
- 世界规则
- 指令详解
- 副本规则(rule)
- 触发器(trigger)
- 触发器参数详解
- 条件(condition)
- 事件(event)
- 副本流程详解
- 根据难度初始化怪物
- 判定通关条件,发放通关奖励
- 副本倒计时/超时处理
- 动态创建倒计时
- 结算奖励
- 副本自带变量
- PlaceholderAPI变量
- 更新日志
- [副本]PxInstace(不再更新)
- 介绍
- 安装使用
- 配置教程
- PlaceholderAPI变量
- 流程配置
- [队伍]PxTeam-Pro
- 介绍
- HUD设置教程
- 变量大全
- 配置文件
- config.yml
- 开发者
- 调用API
- 更新日志
- [任务]BookQuest
- 介绍
- 完整任务配置
- 4种状态显示[4.2.1+]
- 要求/奖励
- 更新日志
- [对话]PxDialogue
- 介绍
- 完整的对话配置
- 一个住酒店的例子
- 更新日志
- [采集]PxCollect
- 介绍
- 作物配置
- 区域生成
- 种植配置
- 条件/事件
- 更新日志
- [技能快捷键]PxQuickSkill
- 介绍
- [仓库]PxWarehouse
- 介绍
- 更新日志
- [拍卖行]PxAuction
- 介绍
- [队伍]PxTeam(不再更新)
- 介绍
- [锻造]PxForging
- 介绍
- 材料/产物
- 完整的锻造配置
- 更新日志
- [邮箱]PxEmail
- 介绍
- PlaceHolderAPI变量
- 编辑邮件模板
- 编辑玩家群
- 编辑系统类型
- 编辑定时邮件
- 权限
- 更新日志
- [MM管理]PxMMSpawner
- 介绍
- 更新日志
- [前置]PxTools(通用部分)
- 介绍
- 掉落物显示[1.12.2+]
- 函数[弃用]
- abs
- ceil
- decimals
- floor
- format
- gradual
- if
- max
- min
- pow
- prd
- random
- randomint
- randomweight
- repeat
- round
- sum
- time
- 要求/奖励(1.9.0+)
- 时间要求(1.9.1+)
- 条件/事件
- 指令
- 事件组
- PlaceholderAPI变量
- 更新日志
- 一些通用的工具类
- 介绍[必看]
- [经济]Vault
- [点券]PlayerPoints
- PxTools相关
- [玩家变量]VarAPI
- [玩家标签]TagAPI
- [玩家计数器]CountAPI
- [时间相关]Date
- [数学函数]Math
- [变量API]PlaceholderAPI
- [自定义冷却]CooldownUtil
- [数字千分化]NumFormat
- [萌芽API]GermAPI
- 消息转发[1.12.3+]