Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* text=auto eol=lf

31 changes: 30 additions & 1 deletion scripts/MaxYari/LuaPhysics/PhysicsEngineGlobal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,35 @@ return {
[D.e.DetectCulpritResult] = function(...)
if not crimeSystemActive then return end
PhysAiSystem.onDetectCulpritResult(...)
end,
["DropItem"] = function(data)
local newObject = data.object
print("Initializing physics for dropped item", newObject.recordId, "at position", newObject.position)
local mat = PhysMatSystem.getMaterialFromObject(newObject)
print("Material:", mat)
newObject:sendEvent(D.e.SetMaterial, { material = mat})
newObject:sendEvent(D.e.SetPhysicsProperties, {
drag = 0.08,
bounce = 1.2,
isSleeping = false,
culprit = data.culprit,
mass = 1.2,
buoyancy = 0.3,
lockRotation = false,
angularDrag = 0.20,
resetOnLoad = false,
ignoreWorldCollisions = false,
collisionMode = "sphere",
realignWhenRested = false
})
newObject:sendEvent(D.e.SetPositionUnadjusted, {position = newObject.position})
local randomHorizontal = util.vector3(
(math.random() - 0.5) * 16,
(math.random() - 0.5) * 16,
-200
)
newObject:sendEvent(D.e.ApplyImpulse, {impulse = randomHorizontal, culprit = data.culprit})
print("Applied impulse, physics initialized")
end
},
interfaceName = "LuaPhysics",
Expand All @@ -260,4 +289,4 @@ return {
getMaterialFromObject = PhysMatSystem.getMaterialFromObject,
removeObject = removeObject
},
}
}
42 changes: 41 additions & 1 deletion scripts/MaxYari/LuaPhysics/PhysicsEngineLocal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ local vfs = require('openmw.vfs')
local nearby = require('openmw.nearby')

local omwself = require('openmw.self')
local types = require('openmw.types')

local PhysicsObject = require(mp..'PhysicsObject')

Expand Down Expand Up @@ -126,8 +127,48 @@ local function checkOutOfBounds()
end


local function projectileCollisionFilter(hit)
if not hit or not hit.hitObject then return true end

local obj = hit.hitObject
if obj.type == types.NPC or obj.type == types.Creature then
local health = types.Actor.stats.dynamic.health(obj).current
if health <= 0 then
-- Dead actor. Check height.
local relZ = hit.hitPos.z - obj.position.z
if relZ > 20 then
-- TOO HIGH. Ignore collision with the ghost upright capsule.
return false
end
end
end
return true
end

physicsObject.collisionFilter = projectileCollisionFilter


local function onCollision(hitResult)
tryPlayCollisionSounds(hitResult)

-- [[ CUSTOM LUA PROJECTILE PHYSICS HOOK ]] --
if omwself.type == types.Weapon then
local record = types.Weapon.record(omwself)
if record and (record.type == types.Weapon.TYPE.Arrow or
record.type == types.Weapon.TYPE.Bolt or
record.type == types.Weapon.TYPE.MarksmanThrown) then

core.sendGlobalEvent('LuaProjectilePhysics_ProjectileHit', {
projectile = omwself,
hitObject = hitResult.hitObject,
hitPos = hitResult.hitPos,
hitNormal = hitResult.hitNormal or hitResult.normal,
velocity = physicsObject.velocity
})
end
end
-- [[ END CUSTOM HOOK ]] --

if physicsObject.velocity:length() >= fenagledMinSpeed then
core.sendGlobalEvent(D.e.ObjectFenagled, {
object = omwself,
Expand Down Expand Up @@ -271,4 +312,3 @@ return {




2 changes: 1 addition & 1 deletion scripts/MaxYari/LuaPhysics/PhysicsEnginePlayer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,4 @@ return {
},
interfaceName = "LuaPhysics",
interface = interface
}
}
33 changes: 24 additions & 9 deletions scripts/MaxYari/LuaPhysics/PhysicsObject.lua
Original file line number Diff line number Diff line change
Expand Up @@ -405,18 +405,34 @@ function PhysicsObject:update(dt)

if not self.ignoreWorldCollisions then
if self.collisionMode == "sphere" then
hitResult = nearby.castRay(rayStart, rayEnd, { radius = self.radius })
-- Use numeric bitmask 63 (AnyPhysical: World+Door+Actor+HeightMap+Projectile+Water)
hitResult = nearby.castRay(rayStart, rayEnd, {
radius = self.radius,
collisionType = 63
})
elseif self.collisionMode == "aabb" then
hitResult = phUtils.customRaycastAABB(rayStart, rayEnd, self.radius, self.object:getBoundingBox(), self.rotation, { ignore = self.object })
hitResult = phUtils.customRaycastAABB(rayStart, rayEnd, self.radius, self.object:getBoundingBox(), self.rotation, { ignore = self.object, collisionType = 63 })
end

if hitResult and hitResult.hit then
collided = self:handleCollision(hitResult)
if self.collisionMode == "sphere" then
-- Update position on collision to get close to a surface without penetrating
if collided then self.position = phUtils.calcSpherePosAtHit(self.position, displacement, hitResult.hitPos, self.radius) end
elseif self.collisionMode == "aabb" then
-- Dont update position on collision, to ensure no penetration
local isHitValid = true
if self.collisionFilter then
isHitValid = self.collisionFilter(hitResult)
end

if isHitValid then
collided = self:handleCollision(hitResult)
if self.collisionMode == "sphere" then
-- Update position on collision to get close to a surface without penetrating
if collided then self.position = phUtils.calcSpherePosAtHit(self.position, displacement, hitResult.hitPos, self.radius) end
elseif self.collisionMode == "aabb" then
-- Dont update position on collision, to ensure no penetration
end
else
-- Filter rejected this hit (e.g. ghost air above dead actor)
-- We act as if no hit occurred so displacement can continue.
hitResult = nil
collided = false
end
end
end
Expand Down Expand Up @@ -486,4 +502,3 @@ return PhysicsObject