Wizy
有什么办法能在一个没有参数的重写方法内让ICommandsender类的对象适配为entity或者entityplayer的对象, 或者说在没有参数的重写方法中怎么检测指令输入者, 来执行另一个套在这个方法里面的有参方法(比如像图片里面这种)
感谢!


Thehrz
你这是覆写了什么类?

Wizy
Thehrz 发表于 2022-8-20 10:08
你这是覆写了什么类?

重写了EntityMob里面的onkillCommand

Thehrz
Wizy 发表于 2022-8-20 10:12
重写了EntityMob里面的onkillCommand

那执行者不就是 this 吗?

Wizy
Thehrz 发表于 2022-8-20 10:18
那执行者不就是 this 吗?

但是这样执行没有用,是不是什么地方写错了
  1. protected void execute(ICommandSender sender) throws CommandException {

  2.             EntityPlayer entityplayer = getCommandSenderAsPlayer(sender);
  3.         if (sender instanceof EntityPlayer) {
  4.             ProcedureBigBroOnKillCommand.executeProcedure(entityplayer);
  5.         }
  6.     }

  7.     @Override
  8.     public void onKillCommand() {
  9.         MinecraftServer server = this.getServer();
  10.         World worldIn = this.getEntityWorld();
  11.         try {
  12.             EntityPlayer entityPlayer = getCommandSenderAsPlayer(this);
  13.         } catch (PlayerNotFoundException e) {
  14.             e.printStackTrace();
  15.         }
  16.         try {
  17.             execute(this);
  18.         } catch (CommandException e) {
  19.             e.printStackTrace();
  20.         }
  21.     }
复制代码



另一个类:
  1.     public static void executeProcedure(EntityPlayer player) {
  2.         player.setDead();
  3.     }
复制代码

Thehrz
Wizy 发表于 2022-8-20 10:25
但是这样执行没有用,是不是什么地方写错了

我没仔细看代码 Sorry 这个 this 其实是被 Kill 的实体

不能从这里获取到 Sender

这个 onKillCommand 就是直接杀死实体

Entity
  1. public void onKillCommand() {
  2.     this.remove();
  3. }
复制代码


只能从 CommandKill#processCommand() 获取执行Kill命令的执行者

Wizy
本帖最后由 Wizy 于 2022-8-20 10:37 编辑
Thehrz 发表于 2022-8-20 10:30
我没仔细看代码 Sorry 这个 this 其实是被 Kill 的实体

不能从这里获取到 Sender

不能类似写传送指令的方法来获取指令执行者吗(      貌似需要通过execute方法里面的ICommandSender参数

Thehrz
Wizy 发表于 2022-8-20 10:35
不能类似写传送指令的方法来获取指令执行者吗(      貌似需要通过execute方法里面的ICommandSender参数
...

? 那是怎样的

总之就是不能通过onKillCommand 来获取执行者

在后来的MCP名中

这个 onKillCommand 直接变成了 kill 所以说它和命令其实关系不大


Wizy
本帖最后由 Wizy 于 2022-8-20 10:44 编辑
Thehrz 发表于 2022-8-20 10:41
? 那是怎样的

总之就是不能通过onKillCommand 来获取执行者

哦哦, 我意思其实是被onkill的时候执行另一个动作, 而不是被杀死, 直接作用在实体身上的是可以实现的, 但是我想实现反过来作用在玩家身上, 或者能获取范围玩家也行

Thehrz
Wizy 发表于 2022-8-20 10:43
哦哦, 我意思其实是被onkill的时候执行另一个动作, 而不是被杀死, 直接作用在实体身上的是可以实现的, 但 ...

那为什么不监听 LivingDeathEvent 事件?

Wizy
Thehrz 发表于 2022-8-20 11:21
那为什么不监听 LivingDeathEvent 事件?

这个条件需要对象死亡吗

Thehrz
Wizy 发表于 2022-8-20 11:50
这个条件需要对象死亡吗



事件可以 setCancelled

最简单就是监听事件 或者写 CoreMod 注入到 processCommand

Wizy
Thehrz 发表于 2022-8-20 12:09


事件可以 setCancelled

监听LivingDeath的话怎么套用到onkill方法里面呢, onkill里面没有参数而且不能在里面获取玩家的话LivingDeath事件还是不能适用于onkill里面阿

Thehrz
Wizy 发表于 2022-8-20 17:19
监听LivingDeath的话怎么套用到onkill方法里面呢, onkill里面没有参数而且不能在里面获取玩家的话LivingD ...

为什么一定要使用onKillCommand

这个就是直接杀死实体 不一定是命令调用它 Mod如果要杀死实体也可以使用这个

不要因为它的 MCP名 误导了

LivingDeathEvent 确实不能监听到Kill命令

那这种情况下 只能从 CommandKill#processCommand 来达到你想要的

Wizy
Thehrz 发表于 2022-8-20 17:53
为什么一定要使用onKillCommand

这个就是直接杀死实体 不一定是命令调用它 Mod如果要杀死实体也可以使用 ...

已经解决了,之前this对象搞错了,直接get了附近玩家,还是要多看看源码......直接监听有个问题,就和重写setdead方法一样会出问题,直接规避死亡的话会导致实体被刷掉的时候游戏崩溃,不知道是源码的小bug还是啥

Thehrz
Wizy 发表于 2022-8-24 14:14
已经解决了,之前this对象搞错了,直接get了附近玩家,还是要多看看源码......直接监听有个问题,就和重写setd ...

上传游戏崩溃报告看看

Wizy
本帖最后由 Wizy 于 2022-8-25 12:56 编辑
Thehrz 发表于 2022-8-24 17:45
上传游戏崩溃报告看看

应该是这个, 编译器抛了个空指针异常, 但是不知道是哪的问题

Thehrz
Wizy 发表于 2022-8-25 12:51
应该是这个, 编译器抛了个空指针异常, 但是不知道是哪的问题

上传 com.wizy.wizymod.objects.entity.BigBro 类 完整代码

Wizy
本帖最后由 Wizy 于 2022-8-25 13:18 编辑
Thehrz 发表于 2022-8-25 13:06
上传 com.wizy.wizymod.objects.entity.BigBro 类 完整代码

已经改掉了...忘了之前怎么写的了,现在重写setdead没有报错了,但是不能实现isdead=false...........哦不对,重写setdead不对.................还是会报错,我把实体传送到虚空,然后实体死亡,玩家接近虚空就会崩溃

Wizy
Thehrz 发表于 2022-8-25 13:06
上传 com.wizy.wizymod.objects.entity.BigBro 类 完整代码

这是类代码,

Thehrz
  1. EntityPlayer entityPlayer = this.world.getClosestPlayerToEntity(this, 1000.00);
复制代码


entityPlayer 可能是null 但没有判空

Wizy
Thehrz 发表于 2022-8-25 14:46
entityPlayer 可能是null 但没有判空

哦....确实,一般这种对象定义都最好判空一下吗

Thehrz
Wizy 发表于 2022-8-25 17:40
哦....确实,一般这种对象定义都最好判空一下吗

是的 在使用它的成员方法之前 应该要判空 除非已说明NotNull 即非空

但我还是不理解一些东西

你能上传完整项目代码吗? 站内PM也行 我总感觉你的实现方式很怪 越来越偏离这个帖子的标题了

Wizy
本帖最后由 Wizy 于 2022-8-25 18:06 编辑
Thehrz 发表于 2022-8-25 17:47
是的 在使用它的成员方法之前 应该要判空 除非已说明NotNull 即非空

但我还是不理解一些东西

其实就是想在检测到kill指令的时候执行对玩家某种效果,之前的问题是kill指令里面没有参数而且不知道什么方法来获取玩家,后来发现是this对象搞错了,现在执行的是获取附近玩家.  其实感觉有很多地方能精简的,主要是想先实现再说,现在大概是这样

Thehrz
Wizy 发表于 2022-8-25 18:03
其实就是想在检测到kill指令的时候执行对玩家某种效果,之前的问题是kill指令里面没有参数而且不知道什么方 ...

可是啊 有些 Mod 会使用 onKillCommand() 来杀死一个实体 而且你还在 setDead() 写了

这些代码不一定通过Kill命令触发 我之前忘了这些 你可以监听 CommandEvent

Wizy
本帖最后由 Wizy 于 2022-8-26 08:52 编辑
Thehrz 发表于 2022-8-25 21:23
可是啊 有些 Mod 会使用 onKillCommand() 来杀死一个实体 而且你还在 setDead() 写了

这些代码不一定通 ...

阿...现在是需要对实体isdead的手段,监听dead事件然后取消就无敌了吧(............还是说再添加判断排除某个条件吗.........再一个就是我没找到什么触发方式来触发livingdeathevent,这个是不是能不在bigbro类里面触发阿,或者说livingdeathevent方法自己就能当触发器?

Thehrz
Wizy 发表于 2022-8-26 08:23
阿...现在是需要对实体isdead的手段,监听dead事件然后取消就无敌了吧(............还是说再添加判断排除某 ...

我仔细看了源代码

最好的办法应该是 CommandKill#processCommand()

你可以注入修改 RETURN

这里就可以获取 Sender 和 Killer

  1. @Override
  2. public void processCommand(ICommandSender sender, String[] args) throws CommandException {
  3.     if (args.length == 0) {
  4.         EntityPlayerMP entityplayer = CommandKill.getCommandSenderAsPlayer(sender);
  5.         entityplayer.onKillCommand();
  6.         CommandKill.notifyOperators(sender, (ICommand)this, "commands.kill.successful", entityplayer.getDisplayName());
  7.         return;
  8.     }
  9.     Entity entity = CommandKill.func_175768_b(sender, args[0]);
  10.     entity.onKillCommand();
  11.     CommandKill.notifyOperators(sender, (ICommand)this, "commands.kill.successful", entity.getDisplayName());
  12. }
复制代码

Wizy
Thehrz 发表于 2022-8-26 09:54
我仔细看了源代码

最好的办法应该是 CommandKill#processCommand()

这个方法我之前看到了,我这个是叫execute,但是由于继承不同的父类,所以我找不到办法把两个类的方法合起来
  1.     public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException
  2.     {
  3.         if (args.length == 0)
  4.         {
  5.             EntityPlayer entityplayer = getCommandSenderAsPlayer(sender);
  6.             entityplayer.onKillCommand();
  7.             notifyCommandListener(sender, this, "commands.kill.successful", new Object[] {entityplayer.getDisplayName()});
  8.         }
  9.         else
  10.         {
  11.             Entity entity = getEntity(server, sender, args[0]);
  12.             entity.onKillCommand();
  13.             notifyCommandListener(sender, this, "commands.kill.successful", new Object[] {entity.getDisplayName()});
  14.         }
  15.     }
复制代码



Thehrz
Wizy 发表于 2022-8-26 12:04
这个方法我之前看到了,我这个是叫execute,但是由于继承不同的父类,所以我找不到办法把两个类的方法合起来
...

啊 之前你都是这样的方法的吗

使用 Mixin 来修改字节码

简单的办法 还是监听 CommandEvent

Wizy
Thehrz 发表于 2022-8-26 12:27
啊 之前你都是这样的方法的吗

使用 Mixin 来修改字节码

那这个监听怎么触发阿,监听器也是继承的不同的父类,不能直接在bigbro类里面触发.............Mixin这个确实不会,我去看看(

Thehrz
Wizy 发表于 2022-8-26 17:58
那这个监听怎么触发阿,监听器也是继承的不同的父类,不能直接在bigbro类里面触发.............Mixin这个确 ...

啊? 监听器为什么要继承别的类?如果要自定义事件才会需要继承事件类

  1. @SubscribeEvent
  2. public void onCommand(CommandEvent event) {
  3.     if (event.command.getCommandName().equals("kill")) {
  4.             ...
  5.     }
  6. }
复制代码

Wizy
本帖最后由 Wizy 于 2022-8-27 09:37 编辑
Thehrz 发表于 2022-8-26 19:35
啊? 监听器为什么要继承别的类?如果要自定义事件才会需要继承事件类

...

监听器不用继承Livingdeathevent吗.......哦,等一下,好像不用

Wizy
本帖最后由 Wizy 于 2022-8-29 11:17 编辑
Thehrz 发表于 2022-8-26 19:35
啊? 监听器为什么要继承别的类?如果要自定义事件才会需要继承事件类

...

这样写没用阿,我不知道怎么get到我当前的bigbro对象....
  1.     public void LivingDeathEvent(ProcedureBigBroOnkill procedureBigBroOnkill){
  2.         BigBro bigBro = new BigBro(getEntityWorld());
  3.         if(bigBro.isDead == true){
  4.             procedureBigBroOnkill.setCanceled(true);
  5.         }else {
  6.             return;
  7.         }
  8.     }
复制代码
那个对象定义现在是乱写的,像这种应该怎么获取啊,现在到获取对象那一步是触发不了的

Thehrz
Wizy 发表于 2022-8-29 11:16
这样写没用阿,我不知道怎么get到我当前的bigbro对象....
那个对象定义现在是乱写的,像这种应该怎么获取啊, ...

啊? 你这是一个监听器吗? 我完全不理解为什么要这样写?

  1. @SubscribeEvent
  2. public void livingDeathEvent(LivingDeathEvent event) {
  3. }
复制代码

Wizy
本帖最后由 Wizy 于 2022-8-29 14:58 编辑
Thehrz 发表于 2022-8-29 11:51
啊? 你这是一个监听器吗? 我完全不理解为什么要这样写?

这个就只是写了个方法,然后调用了事件livingdeathevent里面的setcanceled方法,但是不知道怎么检测当前对象,所以就这样写了..........哦不对,这个方法根本就没执行()

Wizy
Thehrz 发表于 2022-8-29 11:51
啊? 你这是一个监听器吗? 我完全不理解为什么要这样写?

这个监听死亡应该怎么触发啊,确实找不到啥方法了...

秦千久
Entity 不是实现了 ICommandsender 了吗,直接强转不可以吗

Wizy
秦千久 发表于 2022-9-4 11:41
Entity 不是实现了 ICommandsender 了吗,直接强转不可以吗

不行,获取不了的,而且这两个继承的不是一个父类

秦千久
本帖最后由 秦千久 于 2022-9-4 12:57 编辑
Wizy 发表于 2022-9-4 12:18
不行,获取不了的,而且这两个继承的不是一个父类

你这是 1.12 对吧?有个比较黑的办法:
CommandBase 里有个 commandListener,用来监听指令执行的。你可以替换掉原本的 commandListener,如果是 kill 指令就能获取 sender,使用 CommandBase 里的 getCommandSenderAsPlayer 就可以获取到玩家了。然后再调用原本的 commandListener 的 notifyListener 就可以了。


Wizy
秦千久 发表于 2022-9-4 12:47
你这是 1.12 对吧?有个比较黑的办法:
CommandBase 里有个 commandListener,用来监听指令执行的。你可以 ...

get获取玩家没问题,问题在于在继承entity类的onkill方法里面这个办法就行不通了,我现在是用获取附近玩家来代替的

秦千久
Wizy 发表于 2022-9-5 10:40
get获取玩家没问题,问题在于在继承entity类的onkill方法里面这个办法就行不通了,我现在是用获取附近玩家 ...

当然,onKill 没有 ICommandSender,在这个地方尝试获取指令执行者肯定不行,要不你就 mixin / asm 插到 kill 指令执行的地方新增一个带 sender 的 onKill 方法

Wizy
秦千久 发表于 2022-9-5 17:31
当然,onKill 没有 ICommandSender,在这个地方尝试获取指令执行者肯定不行,要不你就 mixin / asm 插到  ...

草, mixin就算了,那个方法太麻烦了, 只是实现一个简单功能完全没必要(

秦千久
Wizy 发表于 2022-9-6 14:12
草, mixin就算了,那个方法太麻烦了, 只是实现一个简单功能完全没必要(

你想要实现什么功能呢?最终目的

Wizy
秦千久 发表于 2022-9-6 16:25
你想要实现什么功能呢?最终目的

刚开始是实体被kill指令,然后触发对玩家的某种效果,现在直接重写了setdead来实现了对附近玩家的效果. 这样比kill指令更全面, 也就是说其实大体上已经没问题了(

第一页 上一页 下一页 最后一页