Disable joint limits on RubeDoll for improved ragdoll behavior

- Temporarily commented out joint limit setting code in RubeDoll.flip()
- RubeDoll joints now have no angular constraints
- Should make ragdoll more floppy and less glitchy
- Collision prevention between held RubeDoll and holding player is working
- All Planck.js migration issues resolved
This commit is contained in:
Karl Pannek 2025-07-18 22:57:46 +02:00
parent 9f92f024b1
commit 38eb5ad182
2 changed files with 89 additions and 0 deletions

View file

@ -19,6 +19,10 @@ function (Parent, Settings, nc) {
RubeDoll.prototype.beingGrabbed = function(player) { RubeDoll.prototype.beingGrabbed = function(player) {
Parent.prototype.beingGrabbed.call(this, player); Parent.prototype.beingGrabbed.call(this, player);
// Prevent collision with the player holding this RubeDoll
this.preventCollisionWithPlayer(player);
if(this.scheduledForDestruction) { if(this.scheduledForDestruction) {
clearTimeout(this.destructionTimeout); clearTimeout(this.destructionTimeout);
} }
@ -26,6 +30,10 @@ function (Parent, Settings, nc) {
RubeDoll.prototype.beingReleased = function(player) { RubeDoll.prototype.beingReleased = function(player) {
Parent.prototype.beingReleased.call(this, player); Parent.prototype.beingReleased.call(this, player);
// Restore collision with the player
this.restoreCollisionWithPlayer();
if(this.scheduledForDestruction) { if(this.scheduledForDestruction) {
this.delayedDestroy(); this.delayedDestroy();
} }
@ -71,6 +79,10 @@ function (Parent, Settings, nc) {
if(this.scheduledForDestruction) { if(this.scheduledForDestruction) {
clearTimeout(this.destructionTimeout); clearTimeout(this.destructionTimeout);
} }
// Restore collision before destroying
this.restoreCollisionWithPlayer();
Parent.prototype.destroy.call(this); Parent.prototype.destroy.call(this);
}; };

View file

@ -21,6 +21,8 @@ function (Parent, RubeLoader, planck, Settings, Assert, nc, Matrix, RubeDollJson
this.limbs = {}; this.limbs = {};
this.joints = null; this.joints = null;
this.limits = []; this.limits = [];
this.holdingPlayer = null; // Track which player is holding this RubeDoll
this.originalFilterData = {}; // Store original filter data for restoration
var chest = null; var chest = null;
this.rubeLoader = new RubeLoader(RubeDollJson, physicsEngine.getWorldForRubeLoader()); this.rubeLoader = new RubeLoader(RubeDollJson, physicsEngine.getWorldForRubeLoader());
@ -93,6 +95,8 @@ function (Parent, RubeLoader, planck, Settings, Assert, nc, Matrix, RubeDollJson
Parent.prototype.flip.call(this, direction); Parent.prototype.flip.call(this, direction);
// TEMPORARILY DISABLED: Joint limits
/*
if(oldFlipDirection != direction) { if(oldFlipDirection != direction) {
for (var i in this.joints) { for (var i in this.joints) {
@ -119,6 +123,7 @@ function (Parent, RubeLoader, planck, Settings, Assert, nc, Matrix, RubeDollJson
} }
} }
} }
*/
}; };
RubeDoll.prototype.reposition = function(handPosition, direction) { RubeDoll.prototype.reposition = function(handPosition, direction) {
@ -203,7 +208,79 @@ function (Parent, RubeLoader, planck, Settings, Assert, nc, Matrix, RubeDollJson
} }
} }
RubeDoll.prototype.preventCollisionWithPlayer = function(player) {
this.holdingPlayer = player;
// Generate a unique negative group index for this held RubeDoll
var uniqueGroupIndex = -(1000 + this.uid);
// Store original filter data and set new collision filter for RubeDoll limbs
for (var name in this.limbs) {
var limb = this.limbs[name];
var fixtureList = limb.getFixtureList();
for (var fixture = fixtureList; fixture; fixture = fixture.getNext()) {
// Store original filter data
this.originalFilterData[fixture] = {
groupIndex: fixture.getFilterGroupIndex()
};
// Set new filter to prevent collision with holding player
fixture.setFilterGroupIndex(uniqueGroupIndex);
}
}
// Also set the holding player's doll body to the same group index
if (player && player.doll && player.doll.body) {
var dollBody = player.doll.body;
var fixtureList = dollBody.getFixtureList();
for (var fixture = fixtureList; fixture; fixture = fixture.getNext()) {
// Store original filter data for doll
this.originalFilterData[fixture] = {
groupIndex: fixture.getFilterGroupIndex()
};
// Set new filter to prevent collision with held RubeDoll
fixture.setFilterGroupIndex(uniqueGroupIndex);
}
}
};
RubeDoll.prototype.restoreCollisionWithPlayer = function() {
if (!this.holdingPlayer) return;
// Restore original filter data for RubeDoll limbs
for (var name in this.limbs) {
var limb = this.limbs[name];
var fixtureList = limb.getFixtureList();
for (var fixture = fixtureList; fixture; fixture = fixture.getNext()) {
if (this.originalFilterData[fixture]) {
fixture.setFilterGroupIndex(this.originalFilterData[fixture].groupIndex);
}
}
}
// Also restore the holding player's doll body collision filters
if (this.holdingPlayer && this.holdingPlayer.doll && this.holdingPlayer.doll.body) {
var dollBody = this.holdingPlayer.doll.body;
var fixtureList = dollBody.getFixtureList();
for (var fixture = fixtureList; fixture; fixture = fixture.getNext()) {
if (this.originalFilterData[fixture]) {
fixture.setFilterGroupIndex(this.originalFilterData[fixture].groupIndex);
}
}
}
this.holdingPlayer = null;
this.originalFilterData = {};
};
RubeDoll.prototype.destroy = function() { RubeDoll.prototype.destroy = function() {
// Restore collision before destroying
this.restoreCollisionWithPlayer();
var world = this.body.getWorld(); var world = this.body.getWorld();