https://linen.dev logo
乗車座標の動的処理
# forum
h
RTM電車モデルのサーバースクリプトを用いて座席位置を動的に変化させることは可能でしょうか。 速度に応じて座席位置が変動するようにしたいため、ご存知の方がいらっしゃいましたらご教授いただきたいです。 宜しくお願いします。
r
座席位置ってプレイヤー座るところのことですか?
オブジェクトならなんとなく分かりますが
h
ですです
jsonのslotPos,seatPosFとplayerPosで指定した値のことです
ソースが公開されているkaizPatchXで代用しますが、運転台部分の座席位置の処理がおそらくここで
EntityFloor(seatPosなどで指定するやつ)がここで処理されていると思うのでこの辺に何らかの手段で干渉できればなんとかならないかなとは思ってます
h
リプだと文字数制限でかけなかったのでこちらに書きます 車両Entity側にはentity.vehicleFloorsにList型で保存されているのですが、protectedのためリフレクションを通してアクセスする必要があります(動作は未検証
Copy code
js
importPackage(Packages.jp.ngt.ngtlib.util);//NGTUtil
importPackage(Packages.jp.ngt.rtm.entity.vehicle);//EntityVehicleBase
importPackage(Packages.jp.ngt.rtm.entity.train);//EntityTrainBase

︙

var floors = NGTUtil.getField(EntityTrainBase.class, entity, ["vehicleFloors"]);

for (var i = 0; i < floors.size(); i++){
  var entityFloor = floors.get(i);

  var floorVec = entityFloor.getPartVec();
  floorVec.func_72446_c(NGTMath.toRadians(-entity.rotationRoll));
  floorVec.func_72440_a(NGTMath.toRadians(entity.field_70125_A));
  floorVec.func_72442_b(NGTMath.toRadians(entity.field_70177_z));
  var x = entity.field_70165_t + floorVec.field_72450_a;
  var y = entity.field_70163_u + floorVec.field_72448_b;
  var z = entity.field_70161_v + floorVec.field_72449_c;
  entityFloor.func_70107_b(x, y, z);//entityFloor.setPosition(x, y, z)
  entityFloor.func_70101_b(entity.field_70177_z, entity.field_70125_A)//entityFloor.setRotation(entity.rotationYaw, entity.rotationPitch)
}
もし NGTUtil.getField(EntityTrainBase.class, entity, ["vehicleFloors"]); がダメそうなら NGTUtil.getField(EntityVehicleBase.class, entity, ["vehicleFloors"]); も試してみてください
h
情報ありがとうございます!試してみます
h
(座標操作の部分を編集で付け足しました)
ただ、RTM側も同じように処理をしているので動かせるかどうかはわからないです
h
なるほど
entity.vehicleFloorsはソースだとどこにありますかね
EntityTrainBase.javaなど読み漁っているところでして
h
EntityTrainBaseはEntityVehicleBaseを拡張したものなのですが、EntityVehicleBaseの方にvehicleFloorsがあります
h
なるほど(言った手前もしやと思い探したらありました)
h
ついでにplayerPosで設定される運転手の座標について調べてみました 運転手はEntityTrainBaseの方に直接乗ってるっぽい感じで、
Copy code
js
entity.field_70153_n.func_70107_b(x, y, z);//長いので省略  entity.riddenByEntity.setPosition(x, y, z)
entity.field_70153_n.field_70177_z -= MathHelper.func_76142_g(entity.field_70177_z - entity.field_70126_B);//entity.riddenByEntity.rotationYaw
となっているようです EntityTrainBase.updateRiderPosition (EntityTrainBase.func_70043_V) でその記述が見れます
h
これsetPosition()≠座席位置指定処理っぽい?
updateRiderPositionの処理を見てもそのエンティティの上に乗っているentityに対してこの処理が発生してて座席位置そのものを指定するものが存在しなさそう
以下Entity.classより抜粋
Copy code
java
    public void updateRiderPosition()
    {
        if (this.riddenByEntity != null)
        {
            this.riddenByEntity.setPosition(this.posX, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ);
        }
    }
h
Entity.func_70107_b(x, y, z) (Entity.setPosition(x, y, z)) はMinecraft側に実装されている処理で、対象のEntityの座標を直接操作する処理です。Minecraft側の処理のため難読化後の名称で呼び出す必要があります。
h
それは重々承知しております
h
これと同じ処理+オフセット分の値を入れてサーバースクリプトで実行してみて、それでもダメそうならスクリプトよりRTM側の処理のほうが優先されてるかもですね
あーjsonで設定した座標をスクリプトで動的に変えたいって感じでしたかね・・・ おそらくですが読み込み時に値が決まってしまうので、あとからjsonを動的に変えたり割り込み処理をいれるというのは無理かなと思います。 代替案として、RTMと同じ処理+移動分を付加した値をスクリプト側で実行して、うまく行けばスクリプト側の処理が通るかなという感じで提案させてもらいました。
h
了解です。ありがとうございます
これで取ってくるfloorsの値をNGTLogに出してみてみたんですが空っぽですね...
本来ならば座席2つ配置してるのでそれが出力されているはずなんですけども
完全な独り言になりますがEntityHorse.class(内部処理)だと
Copy code
java
 public void updateRiderPosition()
    {
        super.updateRiderPosition();

        if (this.prevRearingAmount > 0.0F)
        {
            float f = MathHelper.sin(this.renderYawOffset * (float)Math.PI / 180.0F);
            float f1 = MathHelper.cos(this.renderYawOffset * (float)Math.PI / 180.0F);
            float f2 = 0.7F * this.prevRearingAmount;
            float f3 = 0.15F * this.prevRearingAmount;
            this.riddenByEntity.setPosition(this.posX + (double)(f2 * f), this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset() + (double)f3, this.posZ - (double)(f2 * f1));

            if (this.riddenByEntity instanceof EntityLivingBase)
            {
                ((EntityLivingBase)this.riddenByEntity).renderYawOffset = this.renderYawOffset;
            }
        }
    }
で馬が跳ね馬の姿勢になった時に座席位置の変動があったのでもしかしたらscriptからもできるのではと思った次第であります
逆にjsonで座席を指定せずにserverscriptのほうからEntityFloorを召喚してそれを操作とかで対処できたりするのだろうか
その場合EntityFloorの座標同期処理とかを自前で用意する必要はありそうではある
とりあえずspawnEntityInWorld使って召喚してみたら勝手に座標同期してくれてますねこれ。(毎Tick呼び出されるので大量にスポーンする&列車entityを撤去しても一緒に消えてくれない) ---------------------------------- 追記(2024/04/28-00:11):jsonのseatPosやslotPosと同じように動作するようにできました。 (spawnEntityInWorld関連の処理を1回だけ実行されるようにし、その際にEntityFloorをEntityTrainに紐づける処理を追加した)
いろいろ試している最中でございますが、進捗として ・運転席の位置はEntityTrainで常時jsonのplayerPosになるように実行されているため干渉不可能 ・EntityFloorは近くにいるEntityTrainについていこうとする動作をする(相対距離をnbtで保存している)のでそこに干渉すればワンチャンあるかもしれない って感じですね
なのでserverScript側でEntityFloorを任意の場所に召喚し、召喚したEntityFloorを取得して配列に入れておいてそのEntityFloorのnbtタグをscriptからいじることでなんとかならないかと
nbtタグの数値をscriptから書き換えることでEntityFloorについては座標干渉できました
EntityFloorにはnbtタグのvecX,vecY,vecZでEntityTrainとの相対距離を保存してあるのでそこに干渉した形になります。