There won't be a way to make water in the future... at least not water that you can swim in. It'll just be a water shader on the ground most likely, and if y ou wanted water dripping, you'll have to use a transulcent particle entity.
<!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->There won't be a way to make water in the future... at least not water that you can swim in.<!--QuoteEnd--></div><!--QuoteEEnd--> wut? sadface <!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->Btw you making a freezer/cooling system?<!--QuoteEnd--></div><!--QuoteEEnd--> Was going to make a flooded area
There was custom map in NS1 which had this and a kind of Alien4 vibe where they swim through the water I liked Been ages since I played it so I cant remember the name of the map
InsaneAnomalyJoin Date: 2002-05-13Member: 605Members, Super Administrators, Forum Admins, NS1 Playtester, Forum Moderators, NS2 Developer, Constellation, NS2 Playtester, Squad Five Blue, NS2 Map Tester, Subnautica Developer, Pistachionauts, Future Perfect Developer
Water is very low on the list at the moment. For the maps we're working on at the moment, which fall within the "Refinery" art set, there's no real requirement for volumes of water. With all of the various effects requirements we do have in order to pull off the Refinery look, water isn't a priority.
There was custom map in NS1 which had this and a kind of Alien4 vibe where they swim through the water I liked Been ages since I played it so I cant remember the name of the map<!--QuoteEnd--></div><!--QuoteEEnd--> ns_oasis (or perhaps my map ns_achio with weldable water drain :P) or ns_bast...
ns_bast was for a moment a custom map (right after the remake), but it does tick off two criteria. Aliens and water :P
Well here's hoping that when they move beyond the Refinery and start working on the Biosphere map they will realise the need for large bodies of water in pools, tanks, hydroponics and water recycling what not. Plus that map will almost certainly require a glass shader to be made.
So best case scenario: Biosphere map -> Swimmable water shader + Glass shader
Either that or we will have to settle with a water shader to have on flat polyguns just above the ground for some splashing pools and sewer and drain pipe like areas.
Kouji_SanSr. Hινε UÏкεεÏεг - EUPT DeputyThe NetherlandsJoin Date: 2003-05-13Member: 16271Members, NS2 Playtester, Squad Five Blue
<!--quoteo(post=1772554:date=May 28 2010, 01:12 AM:name=Skyforger2)--><div class='quotetop'>QUOTE (Skyforger2 @ May 28 2010, 01:12 AM) <a href="index.php?act=findpost&pid=1772554"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->Water and glass is a must i don't understand how they can release something without them. I can wait for 2 months more just for water and glass.<!--QuoteEnd--></div><!--QuoteEEnd--> Max said something along the lines of it being to hard on the engine's real-time lighting system, to make transparent textures look good
It's not a simple task to add glass, given the current rendering and lighting system, but it is something that is high on the priority list, and scheduled to be addressed soon. Several of our maps need glass, as well as many of the alien structures (well, not glass, but rather the same transparency effect that will also be used for glass)
As mentioned here, dripping water will be able to be done with the particle system, and most likely we'll have the ability to make puddles of water, but creating deep areas of water is not in the scope for now. It comes with a whole host of other technical issues, and having swimmable areas in maps are also problematic for gameplay.
About swimmable water, thats something we <i>could </i>code in lua. Place a map entity which the code picks up, then it play a cinematic fx to make it look like water around it, detect objects inside, lower gravity and max z vel (thats caused by pure gravity), let w&s be used to move on z axis aswell, voila, you made water.
Hm, I think I might actually try my hand at this (well not the cinematic part, but something that simulates water like it is done in source engine). Altough I am about 50% sure I wont suceed, 70% that I wont suceed until water is out anyway. And thats if I actually do try to do it.
I only know about non-lua games with water, where the most is C. Altough source engine released its sourcecode if I understood it right, it would probably be possible to read it and then code similar stuff in lua.
Who cares about rendering? I was msotly thinking filling an area with particles and the problem would be figuring out what functions to use to change some physics on the objects inside it (hm, do ns2 have applyforce or such?).
WoW uses Lua for UI customization, not the whole game. There's no Lua water in WoW. NS2 uses Lua for it's gameplay code, the interface exposed is simply not intended for a viable implementation of water (or glass). Max and Kurt will be doing this in C++.
To put it in a nutshell: From Lua, you can only control what to render; which lights, models; where, when. The actual rendering is handled by the Spark engine and is not easily modified.
Using only Lua, the closest you could get to water would probably be "Strange low-grav area with blue-ish smoke in it".
<!--coloro:#C0C0C0--><span style="color:#C0C0C0"><!--/coloro--><!--sizeo:1--><span style="font-size:8pt;line-height:100%"><!--/sizeo-->Edit: Spelling and wording.<!--sizec--></span><!--/sizec--><!--colorc--></span><!--/colorc-->
<!--quoteo(post=1772776:date=May 29 2010, 09:17 AM:name=Private)--><div class='quotetop'>QUOTE (Private @ May 29 2010, 09:17 AM) <a href="index.php?act=findpost&pid=1772776"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->Using only Lua, the closest you could get to water would probably be "Strange low-grav area with blue-ish smoke in it".<!--QuoteEnd--></div><!--QuoteEEnd-->
Yeah, I think it would definitely be possible to do this in Lua. The only problem that might exist would be the Speed at which it runs. Making actual water you can swim in would require some somewhat intense calculations if you were going to do anything other than a Lower Gravity environment (which most water is, at least in the somewhat older video games, NS1 included). Doing this calculations would be a lot faster in C/C++ than in Lua, and I haven't tried implement Low G in NS2 yet, but I doubt it would be worth it, so long as they implement it into the Spark Editor eventually.
GISPBattle GorgeDenmarkJoin Date: 2004-03-20Member: 27460Members, Playtest Lead, Forum Moderators, Constellation, NS2 Playtester, Squad Five Blue, Squad Five Silver, Squad Five Gold, NS2 Map Tester, Reinforced - Onos, WC 2013 - Gold, Subnautica Playtester, Forum staff
<a href="http://freespace.virgin.net/hugo.elias/graphics/x_water.htm" target="_blank">2D Water</a> to be used in creating puddles and raindrop thingies?
<!--quoteo(post=1772825:date=May 29 2010, 08:58 PM:name=GISP)--><div class='quotetop'>QUOTE (GISP @ May 29 2010, 08:58 PM) <a href="index.php?act=findpost&pid=1772825"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec--><a href="http://freespace.virgin.net/hugo.elias/graphics/x_water.htm" target="_blank">2D Water</a> to be used in creating puddles and raindrop thingies?<!--QuoteEnd--></div><!--QuoteEEnd-->
Something like that could be created using a Particle Emitter much faster and easier (a more complicated one one with perfect timing, etc. could be created if we were able to create Entities in Lua, which AFAIK, we can't create and place via the Editor). The problem is more along the lines of water that can be displaced by players (which will be sort of easy to make given Lua Entities and Particle Emitters - but it won't look realistic at all) and how to implement swimming underwater, in Lua.
IE. For a simple ripple effect, you have a circular ripple texture that expands until it dies. I could be very wrong (I haven't messed with the cinematic editor very much) but I don't think Scalling over time (or any effect over time, other than movement) is implemented yet.
Well I decided to code some water, and its done, atm I am tweaking some stuff so swimming goes better. Ofc there is not graphics for it, just a 10 units radius field with some interesting effects to your movement.
However, looking at jumping I noticed something odd. it seem to scale the strength by the gravity! self.velocity.y = math.sqrt(-2 * Player.jumpHeight * Player.gravity) Remember gravity is a negative number or it might look very odd.
EDIT: I think I put code here. it is pretty bad looking to swim with it tbh, and its easy to get stuck in roof, but its closer to water then normal air.
// Collide with everything except group 1. That group is reserved // for things we don't want to collide with. self.moveGroupMask = 0xFFFFFFFD
if (Server) then
// Create the view model entity which is used to display our current weapon. local viewModel = Server.CreateEntity(ViewModel.mapName, self:GetOrigin()) viewModel:SetParent(self) self.viewModelId = viewModel:GetId()
// Give ourself a weapon. //self:GiveWeapon("weapon_rifle") //self:GiveWeapon("weapon_physgun") self:GiveWeapon("weapon_spawngun")
end
if (Client) then
self:SetHud("ui/hud.swf")
self.horizontalSwing = 0 self.verticalSwing = 0
end
self:SetBaseAnimation("run")
end
/** * Sets the view angles for the player. Note that setting the yaw of the * view will also adjust the player's yaw. */ function Player:SetViewAngles(viewAngles)
local angles = Angles(self:GetAngles()) angles.yaw = viewAngles.yaw
self:SetAngles(angles)
end
/** * Gets the view angles for the player. */ function Player:GetViewAngles(viewAngles) return Angles(self.viewPitch, self:GetAngles().yaw, self.viewRoll) end
/** * Sets the animation which is played on top of the base animation for the player. * The overlay animation is typically used to combine an animation like an attack * animation with the base movement animation. */ function Player:SetOverlayAnimation( animationName )
if ( animationName ~= nil ) then
local animationSequence = self:GetAnimationIndex( animationName )
if (self.overlayAnimationSequence ~= animationSequence) then self.overlayAnimationSequence = animationSequence self.overlayAnimationStart = Shared.GetTime() end
else self.overlayAnimationSequence = Model.invalidSequence end
end
/** * Sets the activity the player is currently performing. */ function Player:SetBaseAnimation(activity)
local animationPrefix = "" local weapon = self:GetActiveWeapon()
if (weapon) then animationPrefix = weapon:GetAnimationPrefix() .. "_" weapon:SetAnimation( activity ) end
self:SetAnimation(animationPrefix .. activity)
end
/** * Called by the engine to construct the pose of the bones for the player's model. */ function Player:BuildPose(poses)
Actor.BuildPose(self, poses)
// Apply the overlay animation if we have one. if (self.overlayAnimationSequence ~= Model.invalidSequence) then self:AccumulateAnimation(poses, self.overlayAnimationSequence, self.overlayAnimationStart) end
end
/** * Called to handle user input for the player. */ function Player:OnProcessMove(input)
if (Client) then
self:UpdateWeaponSwing(input)
if (Client.GetIsRunningPrediction()) then
// When exit hit, bring up menu if(bit.band(input.commands, Move.Exit) ~= 0) then ShowInGameMenu() end
end
end
local canMove = self:GetCanMove()
// Update the view angles based on the input. local angles = Angles(input.pitch, input.yaw, 0.0) self:SetViewAngles(angles)
local viewCoords = angles:GetCoords()
local ground, groundNormal = self:GetIsOnGround() local water = self:GetIsInWater()
local fowardAxis = nil local sideAxis = nil
// Handle jumpping if (canMove and bit.band(input.commands, Move.Jump) ~= 0) then if (ground) then // Compute the initial velocity to give us the desired jump // height under the force of gravity. self.velocity.y = math.sqrt(-2 * Player.jumpHeight * Player.gravity) ground = false elseif (water) then // Float if in water and pressign space self.velocity.y = 15 * Player.jumpHeight end end
if (ground) then // Since we're standing on the ground, remove any downward velocity. self.velocity.y = 0 else // Apply the gravitational acceleration. if (water) then self.velocity.y = self.velocity.y + (Player.gravity / Player.buoyancy) * input.time else self.velocity.y = self.velocity.y + Player.gravity * input.time end end
// Compute the forward and side axis aligned with the world xz plane. if (water) then forwardAxis = Vector(viewCoords.zAxis.x, viewCoords.zAxis.y, viewCoords.zAxis.z) sideAxis = Vector(viewCoords.xAxis.x, 0, viewCoords.xAxis.z) else forwardAxis = Vector(viewCoords.zAxis.x, 0, viewCoords.zAxis.z) sideAxis = Vector(viewCoords.xAxis.x, 0, viewCoords.xAxis.z) end
forwardAxis:Normalize() sideAxis:Normalize()
self:ApplyFriction(input, ground)
if (canMove) then
// Compute the desired movement direction based on the input. local wishDirection = forwardAxis * input.move.z + sideAxis * input.move.x local wishSpeed = math.min(wishDirection:Normalize(), 1) * Player.moveSpeed
// Accelerate in the desired direction, ala Quake/Half-Life
local currentSpeed = Math.DotProduct(self.velocity, wishDirection) local addSpeed = wishSpeed - currentSpeed
if (addSpeed > 0) then local accelSpeed = math.min(addSpeed, Player.moveAcceleration * input.time * wishSpeed) self.velocity = self.velocity + wishDirection * accelSpeed end
local offset = nil
if (ground) then // First move the character upwards to allow them to go up stairs and // over small obstacles. local start = Vector(self:GetOrigin()) offset = self:PerformMovement( Vector(0, Player.stepHeight, 0), 1 ) - start end
// Move the player with collision detection. self:PerformMovement( self.velocity * input.time, 5 )
if (ground) then // Finally, move the player back down to compensate for moving them up. // We add in an additional step height for moving down steps/ramps. offset.y = offset.y + Player.stepHeight self:PerformMovement( -offset, 1 ) end
// Handle the buttons.
if (bit.band(input.commands, Move.Reload) ~= 0) then
if (self.activity == Player.Activity.Shooting) then self:StopPrimaryAttack() elseif (self.activity == Player.Activity.AltShooting) then self:StopSecondaryAttack() end
self:Reload()
else
// Process attack if (bit.band(input.commands, Move.PrimaryAttack) ~= 0) then self:PrimaryAttack() elseif (self.activity == Player.Activity.Shooting) then self:StopPrimaryAttack() end
if (bit.band(input.commands, Move.SecondaryAttack) ~= 0) then self:SecondaryAttack() elseif (self.activity == Player.Activity.AltShooting) then self:StopSecondaryAttack() end
end
end
// Transition to the idle animation if the current activity has finished.
local time = Shared.GetTime()
if (time > self.activityEnd and self.activity ~= Player.Activity.None) then self:Idle() end
if (not Shared.GetIsRunningPrediction()) then self:UpdatePoseParameters() end
end
function Player:ApplyFriction(input, ground)
local velocity = Vector(self.velocity)
if (ground) then velocity.y = 0 end
local speed = velocity:GetLength()
if (speed > 0) then
local drop = speed * Player.friction * input.time local speedScalar = math.max(speed - drop, 0) / speed
// Only apply friction in the movement plane. self.velocity.x = self.velocity.x * speedScalar self.velocity.z = self.velocity.z * speedScalar
end
end
/** * Returns true if the player is allowed to move (this doesn't affect moving * the view). */ function Player:GetCanMove() return Game.instance:GetHasGameStarted() end
/** * Returns true if the player is standing on the ground. */ function Player:GetIsOnGround()
if (self.velocity.y > 0) then // If we are moving away from the ground, don't treat // us as standing on it. return false, nil end
local capsuleRadius = self.extents.x local capsuleHeight = (self.extents.y - capsuleRadius) * 2
local center = Vector(0, capsuleHeight * 0.5 + capsuleRadius, 0) local origin = self:GetOrigin()
local offset = Vector(0, -0.1, 0)
local traceStart = origin + center local traceEnd = traceStart + offset
local trace = Shared.TraceCapsule(traceStart, traceEnd, capsuleRadius, capsuleHeight, self.moveGroupMask)
if (trace.fraction < 1 and trace.normal.y < Player.maxWalkableNormal) then return false, nil end
return trace.fraction < 1, trace.normal
end
/** * Returns true if the player is in water. */ function Player:GetIsInWater()
pos = self:GetOrigin() local entities = GetEntitiesWithClassname("water")
for k,v in pairs(entities) do
local dir = v:GetOrigin()-pos local radius = v.radius
if (dir:GetLength() < radius) then return true end
end
end
/** * Moves by the player by the specified offset, colliding and sliding with the world. */ function Player:PerformMovement(offset, maxTraces)
local capsuleRadius = self.extents.x local capsuleHeight = (self.extents.y - capsuleRadius) * 2
local center = Vector(0, capsuleHeight * 0.5 + capsuleRadius, 0) local origin = Vector(self:GetOrigin())
local tracesPerformed = 0
while (offset:GetLengthSquared() > 0.0 and tracesPerformed < maxTraces) do
local traceStart = origin + center local traceEnd = traceStart + offset
local trace = Shared.TraceCapsule(traceStart, traceEnd, capsuleRadius, capsuleHeight, self.moveGroupMask)
if (trace.fraction < 1) then
// Remove the amount of the offset we've already moved. offset = offset * (1 - trace.fraction)
// Make the motion perpendicular to the surface we collided with so we slide. offset = offset - offset:GetProjection(trace.normal)
completedSweep = false capsuleSweepHit = true
else offset = Vector(0, 0, 0) end
origin = trace.endPoint - center tracesPerformed = tracesPerformed + 1
end
self:SetOrigin(origin) return origin
end
/** * Returns the view model entity. */ function Player:GetViewModelEntity() return Shared.GetEntity(self.viewModelId) end
/** * Sets the model currently displayed on the view model. */ function Player:SetViewModel(viewModelName) local viewModel = self:GetViewModelEntity() viewModel:SetModel(viewModelName) end
/** * Returns the currently selected weapon if there is one. If there isn't, * returns nil. */ function Player:GetActiveWeapon()
if (self.activeWeaponId > 0) then return Shared.GetEntity(self.activeWeaponId) end
return nil
end
/** * Unholsters the active weapon. */ function Player:DrawWeapon()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
// Apply the weapon's view model. self:SetViewModel(weapon:GetViewModelName()) weapon:Draw(self)
/** * Reloads the current weapon. */ function Player:Reload()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
local time = Shared.GetTime()
if (time > self.activityEnd and weapon:Reload(self)) then self:SetOverlayAnimation( weapon:GetAnimationPrefix() .. "_reload" ) self.activityEnd = time + weapon:GetReloadTime() self.activity = Player.Activity.Reloading end
end
end
/** * Performs the primary attack for the current weapon */ function Player:PrimaryAttack()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
local time = Shared.GetTime()
if (time > self.activityEnd) then
if (weapon:FireBullets(self)) then self:SetOverlayAnimation( weapon:GetAnimationPrefix() .. "_fire" ) self.activityEnd = time + weapon:GetFireDelay() self.activity = Player.Activity.Shooting else // The weapon can't fire anymore (out of bullets, etc.) if (self.activity == Player.Activity.Shooting) then self:StopPrimaryAttack() end self:Idle() end end
end
end
function Player:StopPrimaryAttack()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then weapon:StopPrimaryAttack(self) end
self.activity = Player.Activity.None
end
function Player:SecondaryAttack() local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
local time = Shared.GetTime()
if (time > self.activityEnd) then
if (weapon:FireAlt(self)) then self.activityEnd = time + weapon:GetAltDelay() self.activity = Player.Activity.AltShooting else // The weapon can't fire anymore (out of bullets, etc.) if (self.activity == Player.Activity.AltShooting) then self:StopSecondaryAttack() end self:Idle() end end
end
end
function Player:StopSecondaryAttack()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then weapon:StopSecondaryAttack(self) end
/** * Returns true if the player is currently being viewed in 3rd person mode. */ function Player:GetIsThirdPerson() return self.thirdPerson end
/** * Sets whether or not the player is being viewed in 3rd person mode. */ function Player:SetIsThirdPerson(thirdPerson)
self.thirdPerson = thirdPerson
// Hide the view model when we're in third person mode. local viewModel = self:GetViewModelEntity() if (viewModel ~= nil) then viewModel:SetIsVisible( not self.thirdPerson ) end
end
/** * Called by the engine to get the object to world space transformation * for the camera. */ function Player:GetCameraViewCoords()
local viewCoords = self:GetViewAngles():GetCoords()
/** * Creates an effect at an attachment point for the active weapon. */ function Player:CreateWeaponEffect(playerAttachPointName, entityAttachPointName, cinematicName)
local viewEffect = Client and (Client.GetLocalPlayer() == self) and not self:GetIsThirdPerson()
if (viewEffect) then
// Create the effect on the view model entity. local viewModel = self:GetViewModelEntity() Shared.CreateAttachedEffect(self, cinematicName, viewModel, Coords.GetTranslation(self:GetViewOffset()), entityAttachPointName, true)
else
// Create the effect on the weapon entity.
local attachPoint = self:GetAttachPointIndex(playerAttachPointName) local coords = Coords.GetIdentity();
if (attachPoint ~= -1) then coords = self:GetCoords():GetInverse() * self:GetAttachPointCoords(attachPoint) end
local weapon = self:GetActiveWeapon() Shared.CreateAttachedEffect(self, cinematicName, weapon, coords, entityAttachPointName, false)
end
end
if (Client) then
/** * Sets the Flash movie that's displayed for the HUD. */ function Player:SetHud(hudFileName)
local flashPlayer = Client.CreateFlashPlayer() Client.AddFlashPlayerToDisplay(flashPlayer)
function Player:GetRenderFov() return Math.Radians(90.0) end
function Player:UpdateClientEffects(deltaTime)
Actor.UpdateClientEffects(self, deltaTime)
// Show or hide the local player model depending on whether or not // we're in third person mode for the local player. local showModel = Client.GetLocalPlayer() ~= self or self:GetIsThirdPerson() self:ShowModel( showModel )
local activeWeapon = self:GetActiveWeapon() if (activeWeapon ~= nil) then activeWeapon:ShowModel( showModel ) end
self:UpdatePoseParameters()
end
function Player:UpdateWeaponSwing(input)
// Look at difference between previous and current angles to add "swing" to view model local kSwingSensitivity = .5 local yawDiff = GetAnglesDifference(self:GetViewAngles().yaw, input.yaw) self.horizontalSwing = self.horizontalSwing + yawDiff*kSwingSensitivity
local pitchDiff = GetAnglesDifference(self:GetViewAngles().pitch, input.pitch) self.verticalSwing = self.verticalSwing - pitchDiff*kSwingSensitivity
// Decrease it non-linearly over time (the farther off center it is the faster it will return) local horizontalSwingDampening = 100*input.time*math.sin((math.abs(self.horizontalSwing)/45)*math.pi/2) local verticalSwingDampening = 100*input.time*math.sin((math.abs(self.verticalSwing)/45)*math.pi/2)
if (self.horizontalSwing < 0) then self.horizontalSwing = Math.Clamp(self.horizontalSwing + horizontalSwingDampening, -1, 0) elseif (self.horizontalSwing > 0) then self.horizontalSwing = Math.Clamp(self.horizontalSwing - horizontalSwingDampening, 0, 1) end
if (self.verticalSwing < 0) then self.verticalSwing = Math.Clamp(self.verticalSwing + verticalSwingDampening, -1, 0) elseif (self.verticalSwing > 0) then self.verticalSwing = Math.Clamp(self.verticalSwing - verticalSwingDampening, 0, 1) end
local viewModel = self:GetViewModelEntity()
if (viewModel ~= nil) then
local weapon = self:GetActiveWeapon() local swingAmount = 0
if (weapon ~= nil) then swingAmount = weapon:GetSwingAmount() end
viewModel:SetPoseParam("swing_yaw", self.horizontalSwing * swingAmount) viewModel:SetPoseParam("swing_pitch", self.verticalSwing * swingAmount) end
Gravity changing areas is easy to do. Atleast for players. Check in start of Player.lua for "Player.gravity = 9.81", change it to change gravity. To make an entity for changing gravity in an area, just do something similar to what I did with water (a check function and an entity with radius and gravity str), and if inside gravity field change to that gravity, and if not, change back to default.
<!--quoteo(post=1772826:date=May 29 2010, 09:23 PM:name=Dalin Seivewright)--><div class='quotetop'>QUOTE (Dalin Seivewright @ May 29 2010, 09:23 PM) <a href="index.php?act=findpost&pid=1772826"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->Something like that could be created using a Particle Emitter much faster and easier (a more complicated one one with perfect timing, etc. could be created if we were able to create Entities in Lua, which AFAIK, we can't create and place via the Editor). The problem is more along the lines of water that can be displaced by players (which will be sort of easy to make given Lua Entities and Particle Emitters - but it won't look realistic at all) and how to implement swimming underwater, in Lua.
IE. For a simple ripple effect, you have a circular ripple texture that expands until it dies. I could be very wrong (I haven't messed with the cinematic editor very much) but I don't think Scalling over time (or any effect over time, other than movement) is implemented yet.<!--QuoteEnd--></div><!--QuoteEEnd-->
This might be more for the "modding" section, however, poking around the ns2 folder, I noticed a file called <i>editor.xml</i>. I haven't fully tested this yet but it seems you would add your custom entity information here and then you could place your own entities within the Spark editor. I'm not certain the exact specifications, but it shouldn't be too hard to figure out based on what's in there already.
<!--quoteo(post=1773036:date=Jun 1 2010, 02:26 PM:name=Xuaxinodal)--><div class='quotetop'>QUOTE (Xuaxinodal @ Jun 1 2010, 02:26 PM) <a href="index.php?act=findpost&pid=1773036"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->This might be more for the "modding" section, however, poking around the ns2 folder, I noticed a file called <i>editor.xml</i>. I haven't fully tested this yet but it seems you would add your custom entity information here and then you could place your own entities within the Spark editor. I'm not certain the exact specifications, but it shouldn't be too hard to figure out based on what's in there already.<!--QuoteEnd--></div><!--QuoteEEnd-->
Forgot about that file (everytime I see it, I keep thinking its for the Builder setup). Definitely going to have to fiddle with this after work :)
Comments
Water and Glass are two things that will be added in the future.
Unless you want to fill a basin with blue particles thats the most you could possibly do for now.
Btw you making a freezer/cooling system?
It'll just be a water shader on the ground most likely, and if y ou wanted water dripping, you'll have to use a transulcent particle entity.
wut? sadface
<!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->Btw you making a freezer/cooling system?<!--QuoteEnd--></div><!--QuoteEEnd-->
Was going to make a flooded area
There was custom map in NS1 which had this and a kind of Alien4 vibe where they swim through the water I liked
Been ages since I played it so I cant remember the name of the map
And I would be suprised if there is not going the exist water :S. Altough I would also be suprised if it was anything but a very low priority.
Was going to make a flooded area
There was custom map in NS1 which had this and a kind of Alien4 vibe where they swim through the water I liked
Been ages since I played it so I cant remember the name of the map<!--QuoteEnd--></div><!--QuoteEEnd-->
ns_oasis (or perhaps my map ns_achio with weldable water drain :P) or ns_bast...
ns_bast was for a moment a custom map (right after the remake), but it does tick off two criteria. Aliens and water :P
So best case scenario: Biosphere map -> Swimmable water shader + Glass shader
Either that or we will have to settle with a water shader to have on flat polyguns just above the ground for some splashing pools and sewer and drain pipe like areas.
Max said something along the lines of it being to hard on the engine's real-time lighting system, to make transparent textures look good
As mentioned here, dripping water will be able to be done with the particle system, and most likely we'll have the ability to make puddles of water, but creating deep areas of water is not in the scope for now. It comes with a whole host of other technical issues, and having swimmable areas in maps are also problematic for gameplay.
--Cory
Hm, I think I might actually try my hand at this (well not the cinematic part, but something that simulates water like it is done in source engine). Altough I am about 50% sure I wont suceed, 70% that I wont suceed until water is out anyway.
And thats if I actually do try to do it.
Altough source engine released its sourcecode if I understood it right, it would probably be possible to read it and then code similar stuff in lua.
Im sure thers alot of other games using lua has water aswell.
<img src="http://www.worldofwarcraft.com/downloads/ssotd/images/screens/ss1321.jpg" border="0" class="linked-image" /><img src="http://www.worldofwarcraft.com/downloads/ssotd/images/screens/ss1309.jpg" border="0" class="linked-image" />
NS2 uses Lua for it's gameplay code, the interface exposed is simply not intended for a viable implementation of water (or glass).
Max and Kurt will be doing this in C++.
To put it in a nutshell: From Lua, you can only control what to render; which lights, models; where, when. The actual rendering is handled by the Spark engine and is not easily modified.
Using only Lua, the closest you could get to water would probably be "Strange low-grav area with blue-ish smoke in it".
<!--coloro:#C0C0C0--><span style="color:#C0C0C0"><!--/coloro--><!--sizeo:1--><span style="font-size:8pt;line-height:100%"><!--/sizeo-->Edit: Spelling and wording.<!--sizec--></span><!--/sizec--><!--colorc--></span><!--/colorc-->
Yeah, I think it would definitely be possible to do this in Lua. The only problem that might exist would be the Speed at which it runs. Making actual water you can swim in would require some somewhat intense calculations if you were going to do anything other than a Lower Gravity environment (which most water is, at least in the somewhat older video games, NS1 included). Doing this calculations would be a lot faster in C/C++ than in Lua, and I haven't tried implement Low G in NS2 yet, but I doubt it would be worth it, so long as they implement it into the Spark Editor eventually.
Something like that could be created using a Particle Emitter much faster and easier (a more complicated one one with perfect timing, etc. could be created if we were able to create Entities in Lua, which AFAIK, we can't create and place via the Editor). The problem is more along the lines of water that can be displaced by players (which will be sort of easy to make given Lua Entities and Particle Emitters - but it won't look realistic at all) and how to implement swimming underwater, in Lua.
IE. For a simple ripple effect, you have a circular ripple texture that expands until it dies. I could be very wrong (I haven't messed with the cinematic editor very much) but I don't think Scalling over time (or any effect over time, other than movement) is implemented yet.
However, looking at jumping I noticed something odd. it seem to scale the strength by the gravity!
self.velocity.y = math.sqrt(-2 * Player.jumpHeight * Player.gravity)
Remember gravity is a negative number or it might look very odd.
EDIT:
I think I put code here. it is pretty bad looking to swim with it tbh, and its easy to get stuck in roof, but its closer to water then normal air.
Water.lua
<div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>//=============================================================================
//
// Sandbox/Water.lua
//
//=============================================================================
class 'Water' (Entity)
function Water:OnCreate()
self:SetIsVisible(false)
self.radius = 5
end
Shared.LinkClassToMap("Water", "water", {} )</div>
Player.lua
<div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>//=============================================================================
//
// RifleRange/Player.lua
//
// Created by Max McGuire (max@unknownworlds.com)
// Copyright © 2010, Unknown Worlds Entertainment, Inc.
//
//=============================================================================
Script.Load("lua/Utility.lua")
Script.Load("lua/Game.lua")
class 'Player' (Actor)
Player.networkVars =
{
viewPitch = "interpolated predicted angle",
viewRoll = "interpolated predicted angle",
viewModelId = "entityid",
viewOffset = "vector",
velocity = "predicted vector",
activeWeaponId = "entityid",
overlayAnimationSequence = "integer (-1 to 60)",
overlayAnimationStart = "float",
thirdPerson = "boolean",
activity = "predicted integer (1 to 5)",
activityEnd = "predicted float",
score = "integer"
}
Player.modelName = "models/marine/male/male.model"
Player.extents = Vector(0.4064, 0.7874, 0.4064)
Player.moveSpeed = 7
Player.moveAcceleration = 4
Player.gravity = -9.81
Player.buoyancy = 2
Player.stepHeight = 0.2
Player.jumpHeight = 1
Player.friction = 6
Player.maxWalkableNormal = math.cos( math.pi/2 - math.rad(45) )
Player.Activity = enum { 'None', 'Drawing', 'Reloading', 'Shooting', 'AltShooting' }
Shared.PrecacheModel(Player.modelName)
function Player:OnCreate()
Actor.OnCreate(self)
self:SetModel(Player.modelName)
self.viewPitch = 0
self.viewRoll = 0
self.velocity = Vector(0, 0, 0)
self.activeWeaponId = 0
self.activity = Player.Activity.None
self.activityEnd = 0
self.viewOffset = Vector(0, 1.6256, 0)
self.thirdPerson = false
self.overlayAnimationSequence = Model.invalidSequence
self.overlayAnimationStart = 0
self.score = 0
// Collide with everything except group 1. That group is reserved
// for things we don't want to collide with.
self.moveGroupMask = 0xFFFFFFFD
if (Server) then
// Create the view model entity which is used to display our current weapon.
local viewModel = Server.CreateEntity(ViewModel.mapName, self:GetOrigin())
viewModel:SetParent(self)
self.viewModelId = viewModel:GetId()
// Give ourself a weapon.
//self:GiveWeapon("weapon_rifle")
//self:GiveWeapon("weapon_physgun")
self:GiveWeapon("weapon_spawngun")
end
if (Client) then
self:SetHud("ui/hud.swf")
self.horizontalSwing = 0
self.verticalSwing = 0
end
self:SetBaseAnimation("run")
end
/**
* Sets the view angles for the player. Note that setting the yaw of the
* view will also adjust the player's yaw.
*/
function Player:SetViewAngles(viewAngles)
self.viewPitch = viewAngles.pitch
self.viewRoll = viewAngles.roll
local angles = Angles(self:GetAngles())
angles.yaw = viewAngles.yaw
self:SetAngles(angles)
end
/**
* Gets the view angles for the player.
*/
function Player:GetViewAngles(viewAngles)
return Angles(self.viewPitch, self:GetAngles().yaw, self.viewRoll)
end
/**
* Sets the animation which is played on top of the base animation for the player.
* The overlay animation is typically used to combine an animation like an attack
* animation with the base movement animation.
*/
function Player:SetOverlayAnimation( animationName )
if ( animationName ~= nil ) then
local animationSequence = self:GetAnimationIndex( animationName )
if (self.overlayAnimationSequence ~= animationSequence) then
self.overlayAnimationSequence = animationSequence
self.overlayAnimationStart = Shared.GetTime()
end
else
self.overlayAnimationSequence = Model.invalidSequence
end
end
/**
* Sets the activity the player is currently performing.
*/
function Player:SetBaseAnimation(activity)
local animationPrefix = ""
local weapon = self:GetActiveWeapon()
if (weapon) then
animationPrefix = weapon:GetAnimationPrefix() .. "_"
weapon:SetAnimation( activity )
end
self:SetAnimation(animationPrefix .. activity)
end
/**
* Called by the engine to construct the pose of the bones for the player's model.
*/
function Player:BuildPose(poses)
Actor.BuildPose(self, poses)
// Apply the overlay animation if we have one.
if (self.overlayAnimationSequence ~= Model.invalidSequence) then
self:AccumulateAnimation(poses, self.overlayAnimationSequence, self.overlayAnimationStart)
end
end
/**
* Called to handle user input for the player.
*/
function Player:OnProcessMove(input)
if (Client) then
self:UpdateWeaponSwing(input)
if (Client.GetIsRunningPrediction()) then
// When exit hit, bring up menu
if(bit.band(input.commands, Move.Exit) ~= 0) then
ShowInGameMenu()
end
end
end
local canMove = self:GetCanMove()
// Update the view angles based on the input.
local angles = Angles(input.pitch, input.yaw, 0.0)
self:SetViewAngles(angles)
local viewCoords = angles:GetCoords()
local ground, groundNormal = self:GetIsOnGround()
local water = self:GetIsInWater()
local fowardAxis = nil
local sideAxis = nil
// Handle jumpping
if (canMove and bit.band(input.commands, Move.Jump) ~= 0) then
if (ground) then
// Compute the initial velocity to give us the desired jump
// height under the force of gravity.
self.velocity.y = math.sqrt(-2 * Player.jumpHeight * Player.gravity)
ground = false
elseif (water) then
// Float if in water and pressign space
self.velocity.y = 15 * Player.jumpHeight
end
end
if (ground) then
// Since we're standing on the ground, remove any downward velocity.
self.velocity.y = 0
else
// Apply the gravitational acceleration.
if (water) then
self.velocity.y = self.velocity.y + (Player.gravity / Player.buoyancy) * input.time
else
self.velocity.y = self.velocity.y + Player.gravity * input.time
end
end
// Compute the forward and side axis aligned with the world xz plane.
if (water) then
forwardAxis = Vector(viewCoords.zAxis.x, viewCoords.zAxis.y, viewCoords.zAxis.z)
sideAxis = Vector(viewCoords.xAxis.x, 0, viewCoords.xAxis.z)
else
forwardAxis = Vector(viewCoords.zAxis.x, 0, viewCoords.zAxis.z)
sideAxis = Vector(viewCoords.xAxis.x, 0, viewCoords.xAxis.z)
end
forwardAxis:Normalize()
sideAxis:Normalize()
self:ApplyFriction(input, ground)
if (canMove) then
// Compute the desired movement direction based on the input.
local wishDirection = forwardAxis * input.move.z + sideAxis * input.move.x
local wishSpeed = math.min(wishDirection:Normalize(), 1) * Player.moveSpeed
// Accelerate in the desired direction, ala Quake/Half-Life
local currentSpeed = Math.DotProduct(self.velocity, wishDirection)
local addSpeed = wishSpeed - currentSpeed
if (addSpeed > 0) then
local accelSpeed = math.min(addSpeed, Player.moveAcceleration * input.time * wishSpeed)
self.velocity = self.velocity + wishDirection * accelSpeed
end
local offset = nil
if (ground) then
// First move the character upwards to allow them to go up stairs and
// over small obstacles.
local start = Vector(self:GetOrigin())
offset = self:PerformMovement( Vector(0, Player.stepHeight, 0), 1 ) - start
end
// Move the player with collision detection.
self:PerformMovement( self.velocity * input.time, 5 )
if (ground) then
// Finally, move the player back down to compensate for moving them up.
// We add in an additional step height for moving down steps/ramps.
offset.y = offset.y + Player.stepHeight
self:PerformMovement( -offset, 1 )
end
// Handle the buttons.
if (bit.band(input.commands, Move.Reload) ~= 0) then
if (self.activity == Player.Activity.Shooting) then
self:StopPrimaryAttack()
elseif (self.activity == Player.Activity.AltShooting) then
self:StopSecondaryAttack()
end
self:Reload()
else
// Process attack
if (bit.band(input.commands, Move.PrimaryAttack) ~= 0) then
self:PrimaryAttack()
elseif (self.activity == Player.Activity.Shooting) then
self:StopPrimaryAttack()
end
if (bit.band(input.commands, Move.SecondaryAttack) ~= 0) then
self:SecondaryAttack()
elseif (self.activity == Player.Activity.AltShooting) then
self:StopSecondaryAttack()
end
end
end
// Transition to the idle animation if the current activity has finished.
local time = Shared.GetTime()
if (time > self.activityEnd and self.activity ~= Player.Activity.None) then
self:Idle()
end
if (not Shared.GetIsRunningPrediction()) then
self:UpdatePoseParameters()
end
end
function Player:ApplyFriction(input, ground)
local velocity = Vector(self.velocity)
if (ground) then
velocity.y = 0
end
local speed = velocity:GetLength()
if (speed > 0) then
local drop = speed * Player.friction * input.time
local speedScalar = math.max(speed - drop, 0) / speed
// Only apply friction in the movement plane.
self.velocity.x = self.velocity.x * speedScalar
self.velocity.z = self.velocity.z * speedScalar
end
end
/**
* Returns true if the player is allowed to move (this doesn't affect moving
* the view).
*/
function Player:GetCanMove()
return Game.instance:GetHasGameStarted()
end
/**
* Returns true if the player is standing on the ground.
*/
function Player:GetIsOnGround()
if (self.velocity.y > 0) then
// If we are moving away from the ground, don't treat
// us as standing on it.
return false, nil
end
local capsuleRadius = self.extents.x
local capsuleHeight = (self.extents.y - capsuleRadius) * 2
local center = Vector(0, capsuleHeight * 0.5 + capsuleRadius, 0)
local origin = self:GetOrigin()
local offset = Vector(0, -0.1, 0)
local traceStart = origin + center
local traceEnd = traceStart + offset
local trace = Shared.TraceCapsule(traceStart, traceEnd, capsuleRadius, capsuleHeight, self.moveGroupMask)
if (trace.fraction < 1 and trace.normal.y < Player.maxWalkableNormal) then
return false, nil
end
return trace.fraction < 1, trace.normal
end
/**
* Returns true if the player is in water.
*/
function Player:GetIsInWater()
pos = self:GetOrigin()
local entities = GetEntitiesWithClassname("water")
for k,v in pairs(entities) do
local dir = v:GetOrigin()-pos
local radius = v.radius
if (dir:GetLength() < radius) then
return true
end
end
end
/**
* Moves by the player by the specified offset, colliding and sliding with the world.
*/
function Player:PerformMovement(offset, maxTraces)
local capsuleRadius = self.extents.x
local capsuleHeight = (self.extents.y - capsuleRadius) * 2
local center = Vector(0, capsuleHeight * 0.5 + capsuleRadius, 0)
local origin = Vector(self:GetOrigin())
local tracesPerformed = 0
while (offset:GetLengthSquared() > 0.0 and tracesPerformed < maxTraces) do
local traceStart = origin + center
local traceEnd = traceStart + offset
local trace = Shared.TraceCapsule(traceStart, traceEnd, capsuleRadius, capsuleHeight, self.moveGroupMask)
if (trace.fraction < 1) then
// Remove the amount of the offset we've already moved.
offset = offset * (1 - trace.fraction)
// Make the motion perpendicular to the surface we collided with so we slide.
offset = offset - offset:GetProjection(trace.normal)
completedSweep = false
capsuleSweepHit = true
else
offset = Vector(0, 0, 0)
end
origin = trace.endPoint - center
tracesPerformed = tracesPerformed + 1
end
self:SetOrigin(origin)
return origin
end
/**
* Returns the view model entity.
*/
function Player:GetViewModelEntity()
return Shared.GetEntity(self.viewModelId)
end
/**
* Sets the model currently displayed on the view model.
*/
function Player:SetViewModel(viewModelName)
local viewModel = self:GetViewModelEntity()
viewModel:SetModel(viewModelName)
end
/**
* Returns the currently selected weapon if there is one. If there isn't,
* returns nil.
*/
function Player:GetActiveWeapon()
if (self.activeWeaponId > 0) then
return Shared.GetEntity(self.activeWeaponId)
end
return nil
end
/**
* Unholsters the active weapon.
*/
function Player:DrawWeapon()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
// Apply the weapon's view model.
self:SetViewModel(weapon:GetViewModelName())
weapon:Draw(self)
self.activity = Player.Activity.Drawing
self.activityEnd = Shared.GetTime() + weapon:GetDrawTime()
end
end
/**
* Reloads the current weapon.
*/
function Player:Reload()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
local time = Shared.GetTime()
if (time > self.activityEnd and weapon:Reload(self)) then
self:SetOverlayAnimation( weapon:GetAnimationPrefix() .. "_reload" )
self.activityEnd = time + weapon:GetReloadTime()
self.activity = Player.Activity.Reloading
end
end
end
/**
* Performs the primary attack for the current weapon
*/
function Player:PrimaryAttack()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
local time = Shared.GetTime()
if (time > self.activityEnd) then
if (weapon:FireBullets(self)) then
self:SetOverlayAnimation( weapon:GetAnimationPrefix() .. "_fire" )
self.activityEnd = time + weapon:GetFireDelay()
self.activity = Player.Activity.Shooting
else
// The weapon can't fire anymore (out of bullets, etc.)
if (self.activity == Player.Activity.Shooting) then
self:StopPrimaryAttack()
end
self:Idle()
end
end
end
end
function Player:StopPrimaryAttack()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
weapon:StopPrimaryAttack(self)
end
self.activity = Player.Activity.None
end
function Player:SecondaryAttack()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
local time = Shared.GetTime()
if (time > self.activityEnd) then
if (weapon:FireAlt(self)) then
self.activityEnd = time + weapon:GetAltDelay()
self.activity = Player.Activity.AltShooting
else
// The weapon can't fire anymore (out of bullets, etc.)
if (self.activity == Player.Activity.AltShooting) then
self:StopSecondaryAttack()
end
self:Idle()
end
end
end
end
function Player:StopSecondaryAttack()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
weapon:StopSecondaryAttack(self)
end
self.activity = Player.Activity.None
end
function Player:Idle()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
weapon:Idle(self)
end
self:SetOverlayAnimation(nil)
self.activity = Player.Activity.None
end
function Player:GetViewOffset()
return self.viewOffset
end
/**
* Retursn the amount of ammo in the clip for the active weapon.
*/
function Player:GetWeaponClip()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
return weapon:GetClip()
end
return 0
end
/**
* Returns the total amount of ammo for the currently selected weapon.
*/
function Player:GetWeaponAmmo()
local weapon = self:GetActiveWeapon()
if (weapon ~= nil) then
return weapon:GetAmmo()
end
return 0
end
function Player:UpdatePoseParameters()
local viewAngles = self:GetViewAngles()
local pitch = -Math.Wrap( Math.Degrees(viewAngles.pitch), -180, 180 )
self:SetPoseParam("body_pitch", pitch)
local viewCoords = viewAngles:GetCoords()
local horizontalVelocity = Vector(self.velocity)
horizontalVelocity.y = 0
local x = Math.DotProduct(viewCoords.xAxis, horizontalVelocity)
local z = Math.DotProduct(viewCoords.zAxis, horizontalVelocity)
local moveYaw = math.atan2(z, x) * 180 / math.pi
self:SetPoseParam("move_yaw", moveYaw)
self:SetPoseParam("move_speed", horizontalVelocity:GetLength() * 0.25)
end
/**
* Returns true if the player is currently being viewed in 3rd person mode.
*/
function Player:GetIsThirdPerson()
return self.thirdPerson
end
/**
* Sets whether or not the player is being viewed in 3rd person mode.
*/
function Player:SetIsThirdPerson(thirdPerson)
self.thirdPerson = thirdPerson
// Hide the view model when we're in third person mode.
local viewModel = self:GetViewModelEntity()
if (viewModel ~= nil) then
viewModel:SetIsVisible( not self.thirdPerson )
end
end
/**
* Called by the engine to get the object to world space transformation
* for the camera.
*/
function Player:GetCameraViewCoords()
local viewCoords = self:GetViewAngles():GetCoords()
viewCoords.origin = self:GetOrigin() + self.viewOffset
if (self.thirdPerson) then
//viewCoords.origin = viewCoords.origin - viewCoords.zAxis * 0.4 - viewCoords.xAxis * 0.35 + viewCoords.yAxis * 0.1
viewCoords.origin = viewCoords.origin - viewCoords.zAxis * 2.5
end
return viewCoords
end
if (Server) then
function Player:GiveWeapon(className)
local weapon = Server.CreateEntity(className, self:GetOrigin())
weapon:SetParent(self)
weapon:SetAttachPoint("RHand_Weapon")
self.activeWeaponId = weapon:GetId()
self:DrawWeapon()
end
end
/**
* Creates an effect at an attachment point for the active weapon.
*/
function Player:CreateWeaponEffect(playerAttachPointName, entityAttachPointName, cinematicName)
local viewEffect = Client and (Client.GetLocalPlayer() == self) and not self:GetIsThirdPerson()
if (viewEffect) then
// Create the effect on the view model entity.
local viewModel = self:GetViewModelEntity()
Shared.CreateAttachedEffect(self, cinematicName, viewModel, Coords.GetTranslation(self:GetViewOffset()), entityAttachPointName, true)
else
// Create the effect on the weapon entity.
local attachPoint = self:GetAttachPointIndex(playerAttachPointName)
local coords = Coords.GetIdentity();
if (attachPoint ~= -1) then
coords = self:GetCoords():GetInverse() * self:GetAttachPointCoords(attachPoint)
end
local weapon = self:GetActiveWeapon()
Shared.CreateAttachedEffect(self, cinematicName, weapon, coords, entityAttachPointName, false)
end
end
if (Client) then
/**
* Sets the Flash movie that's displayed for the HUD.
*/
function Player:SetHud(hudFileName)
local flashPlayer = Client.CreateFlashPlayer()
Client.AddFlashPlayerToDisplay(flashPlayer)
flashPlayer:Load(hudFileName)
flashPlayer:SetBackgroundOpacity(0)
end
function Player:GetRenderFov()
return Math.Radians(90.0)
end
function Player:UpdateClientEffects(deltaTime)
Actor.UpdateClientEffects(self, deltaTime)
// Show or hide the local player model depending on whether or not
// we're in third person mode for the local player.
local showModel = Client.GetLocalPlayer() ~= self or self:GetIsThirdPerson()
self:ShowModel( showModel )
local activeWeapon = self:GetActiveWeapon()
if (activeWeapon ~= nil) then
activeWeapon:ShowModel( showModel )
end
self:UpdatePoseParameters()
end
function Player:UpdateWeaponSwing(input)
// Look at difference between previous and current angles to add "swing" to view model
local kSwingSensitivity = .5
local yawDiff = GetAnglesDifference(self:GetViewAngles().yaw, input.yaw)
self.horizontalSwing = self.horizontalSwing + yawDiff*kSwingSensitivity
local pitchDiff = GetAnglesDifference(self:GetViewAngles().pitch, input.pitch)
self.verticalSwing = self.verticalSwing - pitchDiff*kSwingSensitivity
// Decrease it non-linearly over time (the farther off center it is the faster it will return)
local horizontalSwingDampening = 100*input.time*math.sin((math.abs(self.horizontalSwing)/45)*math.pi/2)
local verticalSwingDampening = 100*input.time*math.sin((math.abs(self.verticalSwing)/45)*math.pi/2)
if (self.horizontalSwing < 0) then
self.horizontalSwing = Math.Clamp(self.horizontalSwing + horizontalSwingDampening, -1, 0)
elseif (self.horizontalSwing > 0) then
self.horizontalSwing = Math.Clamp(self.horizontalSwing - horizontalSwingDampening, 0, 1)
end
if (self.verticalSwing < 0) then
self.verticalSwing = Math.Clamp(self.verticalSwing + verticalSwingDampening, -1, 0)
elseif (self.verticalSwing > 0) then
self.verticalSwing = Math.Clamp(self.verticalSwing - verticalSwingDampening, 0, 1)
end
local viewModel = self:GetViewModelEntity()
if (viewModel ~= nil) then
local weapon = self:GetActiveWeapon()
local swingAmount = 0
if (weapon ~= nil) then
swingAmount = weapon:GetSwingAmount()
end
viewModel:SetPoseParam("swing_yaw", self.horizontalSwing * swingAmount)
viewModel:SetPoseParam("swing_pitch", self.verticalSwing * swingAmount)
end
end
end
Shared.LinkClassToMap("Player", "player", Player.networkVars )</div>
Myself I create it with a gun I coded (spawngun ftw!), but to use the lua function CreateEntity you will have to do script.load in server.lua
Or does the rules aply to the entire map?
edit gisp its a function, returning the gravity. if the engine fills in the gravity off the current location the player is in its possible.
they're setting upwards speed with that equation after all.
IE. For a simple ripple effect, you have a circular ripple texture that expands until it dies. I could be very wrong (I haven't messed with the cinematic editor very much) but I don't think Scalling over time (or any effect over time, other than movement) is implemented yet.<!--QuoteEnd--></div><!--QuoteEEnd-->
This might be more for the "modding" section, however, poking around the ns2 folder, I noticed a file called <i>editor.xml</i>. I haven't fully tested this yet but it seems you would add your custom entity information here and then you could place your own entities within the Spark editor. I'm not certain the exact specifications, but it shouldn't be too hard to figure out based on what's in there already.
Forgot about that file (everytime I see it, I keep thinking its for the Builder setup). Definitely going to have to fiddle with this after work :)