Lin-JN 發表於 2024-3-30 08:12

极限节省物件id之R版暴击特效(附加媒介召唤方法)

本帖最後由 Lin-JN 於 2024-4-19 15:49 編輯


    /**
   * R版暴击特效处理<br>
   * 极限继承物件id by 圣子默默<br>
   * 全网搜索 圣子默默 观看更多视频及天堂一教程<br>
   * 放 L1PcInstance 或 L1Character 任意位置<br>
   * 建议后者 可通用 给NPC(虚拟人物)使用
   *
   * @param target 受攻击对象
   * @param gfx_id 特效动画
   */
    public void sendFollowEffect(L1Character target, int gfx_id) {

      L1NpcInstance followEffect;

      if (this.getFollowEffect() != null) { // 特效物件已经存在
            followEffect = this.getFollowEffect();
            followEffect.setLocation(target.getLocation());
            followEffect.setHeading(this.getHeading());

      } else { // 召唤一次特效物件媒介 然后锁定在主人身上
            followEffect = L1SpawnUtil.spawnS(target.getLocation(),
                  this.get_showId(), 0, this.getHeading());
            this.setFollowEffect(followEffect);
      }

      // 这段用于测试打印物件id 实装时请删除
      Optional.ofNullable(followEffect).ifPresent(u ->
                _log.info("followEffect: " + followEffect.getId()));

      // 送出物件封包 通知所有对象位置、面向的变化
      Optional.ofNullable(followEffect).ifPresent(u -> followEffect
                .broadcastPacketAll(new S_NPCPack(followEffect)));
      // 送出特效动画
      Optional.ofNullable(followEffect).ifPresent(u -> followEffect
                .broadcastPacketAll(new S_SkillSound(followEffect.getId(), gfx_id)));
    }



   // 双手剑R版暴击特效举例 L1Attack (L1AttackPc / L1AttackNpc)
    _pc.sendFollowEffect(_target, 13410);



    /**
   * 召唤的特效物件媒介
   */
    private L1NpcInstance _followEffect;

    private void setFollowEffect(L1NpcInstance followEffect) {
      _followEffect = followEffect;
    }

    public L1NpcInstance getFollowEffect() {
      return _followEffect;
    }



      // 玩家离线或NPC死亡删除时执行
      if (getFollowEffect() != null) {
            getFollowEffect().deleteMe();
      }



    /**
   * 依LOC位置召唤指定NPC (R版变身攻击特效媒介)
   *
   * @param loc   LOC
   * @param showId副本编号
   * @param time    存在时间(秒) 小于等于0不限制
   * @param heading 面向
   */
    public static L1NpcInstance spawnS(final L1Location loc, final int showId, final int time,
                                       final int heading, final int objId) {
      try {
            final L1NpcInstance npc = NpcTable.get().newNpcInstance(56168);

            if (npc == null) {
                return null;
            }

            npc.setId(objId);
            npc.setMap(loc.getMap());
            npc.getLocation().set(loc);

            npc.setHomeX(npc.getX());
            npc.setHomeY(npc.getY());
            npc.setHeading(heading);

            npc.set_showId(showId);

            World.get().storeObject(npc); // 不需要 addVisibleObject

            if (0 < time) {
                npc.set_spawnTime(time);
            }

            return npc;

      } catch (final Exception e) {
            _log.error("依LOC位置召唤指定NPC(传回NPC讯息)发生异常: 56168", e);
      }
      return null;
    }

和正常的R版暴击特效写法相比,试想一个角色在24小时内(我的服好几天才会重启一次……)要挥刀多少次?会触发多少次特效?原版的写法里,每一次触发都需要消耗掉一个物件id,如此修改,在物件主人消失(离线)之前,不论何时攻击触发,都只会用到一个物件id。

代码不作隐藏,欢迎取用。

keiggoo 發表於 2024-3-30 11:35

謝謝大大分享
新手學習
目前功力還不到那邊
看看學習

Java大神 發表於 2024-3-30 15:29

疑 爆擊特效 為什麼不用 S_SkillSound 還是R版沒這個封包

Lin-JN 發表於 2024-3-30 17:47

Java大神 發表於 2024-3-30 15:29
疑 爆擊特效 為什麼不用 S_SkillSound 還是R版沒這個封包

天堂1的特效动画各不一样,一般分为四种。

1:无向特效,比如极道落雷、流星雨、究极光裂之类,这种特效不区分方向,不管哪个位置都是同样方向的动画。
2:有向特效,比如黑妖双刀双击、钢爪重击,特征为触发在当前的物件身上,显示的方向和当前物件一致。
3:R版暴击特效,特征为触发在被攻击者身上,但显示位置会在被攻击者前一格的位置,而显示的方向和攻击发起者一致,所以是不可以使用S_SkillSound封包的,那样看起来会很诡异。
4:飞行特效,弓箭,飞刀,沙哈魔法箭矢类

这里指的就是第3种。
第1种,建议使用S_EffectLocation封包。
第2种,建议使用S_SKillSound封包。
第3种,建议用我上面写的。
第4种,只有一种封包,封包名字各人写法不同,我用的是S_UseArrowFlySkill

以上四种,就是天堂1常用的特效显示方式。
至于一些S_Attack之类的type 0x01 0x02 0x04 0x08之类的封包特效就不叙述了,那玩意有些主程式(客户端)下使用可能会有问题,而且局限性大,仅适用于双击、重击等几个有限的场合,极度不推荐。

19870922 發表於 2024-3-30 18:48

感謝分享

allen1210 發表於 2024-3-30 19:22

謝謝大大分享
新手學習

kevinsoin 發表於 2024-3-30 19:31

讓我們繼續看下去~

Java大神 發表於 2024-3-31 00:51

Lin-JN 發表於 2024-3-30 17:47
天堂1的特效动画各不一样,一般分为四种。

1:无向特效,比如极道落雷、流星雨、究极光裂之类,这种特效 ...

了解 謝謝解釋

diorlive 發表於 2024-4-11 22:09

請問你的 spawnS 是自訂方法嗎? 因為原始的 spawnS 是5個數值, 你提供的代碼中缺少了 npcid, 是否刻意移除?

ryan0703 發表於 2024-4-12 02:02

       
感謝分享-學習學習

紅藍天堂 發表於 2024-4-17 14:28

感謝有您的無私分享

Lin-JN 發表於 2024-4-18 00:41

diorlive 發表於 2024-4-11 22:09
請問你的 spawnS 是自訂方法嗎? 因為原始的 spawnS 是5個數值, 你提供的代碼中缺少了 npcid, 是否刻意移除 ...

自己修改,没有必要太多参数的,就自然不需要了。


我写的任何所谓“教学”,都是仅供参考的,一般直接搬运肯定是不行的,每个人版本不一样,参数也不同,主要是了解大致上的方法流程以及思路。

diorlive 發表於 2024-4-18 06:31

本帖最後由 diorlive 於 2024-4-18 06:34 編輯

Lin-JN 發表於 2024-4-18 00:41
自己修改,没有必要太多参数的,就自然不需要了。



瞭解 謝謝

diorlive 發表於 2024-4-18 21:34

請問如果碰到這樣召喚出來的特效不會消失的問題, 您的時間控制是怎麼做的呢..

tiantang2024 發表於 2024-4-18 21:43

               
       
謝謝大大分享
新手學習
目前功力還不到那邊
看看學習

       

Lin-JN 發表於 2024-4-19 15:38

diorlive 發表於 2024-4-18 21:34
請問如果碰到這樣召喚出來的特效不會消失的問題, 您的時間控制是怎麼做的呢.. ...

不需要时间控制的,玩家下线或者怪物死亡那里进行删除就可以了。

au03l729 發表於 2024-4-19 15:49

感恩大大無私分享

diorlive 發表於 2024-4-19 17:07

Lin-JN 發表於 2024-4-19 15:38
不需要时间控制的,玩家下线或者怪物死亡那里进行删除就可以了。

我碰到的問題是因為這個暴擊特效是機率產生的 他是隨著觸發暴擊而調用
但是暴擊時調用了特效 他播放一次後就呈現停止畫面留在畫面上了
換下一隻怪上一隻怪停在畫面上的特效才會消失 但是下一隻怪身上有觸發又會停一個.. 他不像單純用 skillsound 發送一樣播放完一次消失..

Lin-JN 發表於 2024-4-19 20:48

你是把暴击动画做成了npc类型吧,然后又使用了 addVisibleObject 世界可见类型。
你应该是完全没理解我写的代码,返回去好好看看我的全部代码。

56168 在资料库中设定 l1npc 类型,图档随便设置一个0或者任意小型NPC的外观就行。

diorlive 發表於 2024-4-20 03:18

本帖最後由 diorlive 於 2024-4-20 05:55 編輯

Lin-JN 發表於 2024-4-19 20:48
你是把暴击动画做成了npc类型吧,然后又使用了 addVisibleObject 世界可见类型。
你应该是完全没理解我写的 ...
老實說, 你之前沒有放上 spawnS 方法, 今天補上 我比對了一下跟我理解中所寫的一樣..
而且我也沒有 add . 只是 store 世界而已

其他都與你說的一樣
我反覆看了你補上的方法,
我應該是能理解你是創造一個 npc 套在目標身上而這 npc 的外型用 skillsound 的方式調用圖檔, 這樣只會消耗掉一個npc的世界id

如果要說沒有理解的部分.. 我想主要是因為你之前沒有給spawnS 方法, 又回復說是自訂的..
現在給了方法又與調用的結構不同.. 我能理解召喚時同時將調用時傳入的 gfx_id 套在召喚的npc 上
但是新增提供的方法方法內又變成取 objId... 並且還取消了向世界ID工廠遞增添加世界ID而是直接取 set objid..??
我相信你的能力跟邏輯.. 但一方面看你分享的代碼怎麼看都覺得有點詭異.. 所以有點拉扯罷了
當然, 我知道你只是提供一個觀念. 不一定是正確的代碼, 但是這樣對於前後不匹配的代碼還是容易造成混淆的..

by the way, 我已經完成了, 謝謝你提供的想法.





頁: [1] 2
查看完整版本: 极限节省物件id之R版暴击特效(附加媒介召唤方法)