1. Post #1
    Gold Member
    Ronon Dex's Avatar
    February 2009
    1,861 Posts
    Objective: I need my Puddle Jumper to roll but AddAngleVelocity just makes it spin out of control
    Error: No errors but spins out of control
    Code:
    /*
    	Puddle Jumper for GarrysMod10
    	Copyright (C) 2009 RononDex
    
    	This program is free software: you can redistribute it and/or modify
    	it under the terms of the GNU General Public License as published by
    	the Free Software Foundation, either version 3 of the License, or
    	(at your option) any later version.
    
    	This program is distributed in the hope that it will be useful,
    	but WITHOUT ANY WARRANTY; without even the implied warranty of
    	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    	GNU General Public License for more details.
    
    	You should have received a copy of the GNU General Public License
    	along with this program.  If not, see <http://www.gnu.org/licenses/>.
    */
    --################# HEADER #################
    AddCSLuaFile("cl_init.lua");
    AddCSLuaFile("shared.lua");
    include("shared.lua");
    
    ENT.Sounds={
    	Fail={Sound("buttons/button19.wav"),Sound("buttons/combine_button2.wav")},
    	Cloak=Sound("npc/strider/striderx_alert4.wav"),
    	Uncloak=Sound("npc/turret_floor/die.wav"),
    };
    
    --############### Makes it spawn
    function ENT:SpawnFunction(pl, tr)
    	if (!tr.HitWorld) then return end;
    	local e = ents.Create("puddle_jumper");
    	e:SetPos(tr.HitPos + Vector(0, 10, 50));
    	e:Spawn();
    	e:Activate();
    	return e;
    end
    
    --################# Init 
    function ENT:Initialize()
    	
    	self.Jumper = {}
    	self.Jumper.RotorWash = {}
    	self.Entity:SetUseType( SIMPLE_USE )
    	self.Rotorwash = false
    	
    	self.Inflight=false
    	self.Pilot=false
    	self.Entity:SetModel("models/Votekick/jumper/jumper_v3.mdl");
    	self.Entity:PhysicsInit(SOLID_VPHYSICS);
    	self.Entity:SetMoveType(MOVETYPE_VPHYSICS);
    	self.Entity:SetSolid(SOLID_VPHYSICS);
    	self.Entity:StartMotionController()
    	self.Accel=0
    	self.reloadtime = (4);
    	self.Hover = true;
    	self.Entity:Health( 500 )
    	self.Target = Vector(0,0,0);
    	self.DroneMaxSpeed = (8000);
    	self.AllowAutoTrack = (true);
    	self.AllowEyeTrack = (false);
    	self.TrackTime = 1000000;
    	self.Drones = {};
    	self.DroneCount = 0;
    	self.MaxDrones = (10);
    	self.Track = false;
    	self.Launched = false;
    	self.sequence2 = self.Entity:LookupSequence("door_o");
    	self.door = true	
    	self.Entity:SetSequence(self.sequence2);
    	self.Entity:SetPlaybackRate(2.0);
    
    	local phys = self.Entity:GetPhysicsObject();
    	if(phys:IsValid()) then
    		phys:Wake();
    		phys:SetMass(10000);
    	end
    end
    
    
    
    function ENT:OnRemove()
    if self.Inflight then
    	self.Pilot:Spawn(self.Entity:GetPos())
    	self.Inflight=false
    	self.Rotorwashent:Remove()
    	self.Rotorwash = false
    else
    	return end
    end
    
    function ENT:Think()
    
    		if self.Pilot and self.Inflight and self.Pilot:IsValid() then
    			if self.Pilot:KeyDown(IN_SPEED) then
    			
    		if(not self.epodo) then
    			self.sequence = self.Entity:LookupSequence("open");
    				self.epodo = true
    				self.Entity:EmitSound("jumper/Drivepods1.mp3", 100, 100 )
    			else
    				self.sequence = self.Entity:LookupSequence("close")
    				self.epodo = false
    				self.Entity:EmitSound("jumper/Drivepods2.mp3", 100, 100 )
    	end
    		self.Entity:SetSequence(self.sequence);
    	end
    
    
    if self.Pilot and self.Inflight and self.Pilot:IsValid() then
    
    	if self.Pilot:KeyDown(IN_SCORE) then
    		if(not self.door) then
    			self.sequence2 = self.Entity:LookupSequence("door_o");
    			self.door = true
    		else
    			self.sequence2 = self.Entity:LookupSequence("door_c");
    			self.door = false
    		end
    		self.Entity:SetSequence(self.sequence2);
    	end
    
    	if self.Pilot:KeyDown(IN_RELOAD) then
    	if(not ValidEntity(p)) then return end;
    	local e = self:FindGate(3000);
    	if(not ValidEntity(e)) then return end;
    	if(hook.Call("StarGate.Player.CanDialGate",GAMEMODE,p,e) == false) then return end;
    	umsg.Start("StarGate.OpenDialMenuDHD",p);
    	umsg.Entity(e);
    	umsg.End();
    end
    
    
    
    	if self.Pilot:KeyDown(IN_WALK) then
    	self:Status(true);
    		else
    	self:Status(false);
    end
    
    
    	
    //if !self.Pilot then return end
    
    if self.Inflight and self.Pilot and self.Pilot:IsValid() then
    
    		self.Pilot:SetPos(self.Entity:GetPos())
    
    
    if self.Pilot:KeyDown(IN_USE) then
    			
    		self.Entity:NextThink(CurTime())
    		
    		else
    		
    		self.Entity:NextThink(CurTime() +1)
    
    	end
    end
    
    local enabled = self:Enabled();
    
    return true;
    	end
    end
    		if self.Inflight == false then
    		self.Rotorwash = false
    end
    end
    
    
    
    function ENT:Use(ply,caller,ent)
    
    	if self.Inflight then
    	
    	self.Pilot:UnSpectate()
    			self.Pilot:DrawViewModel(true)
    			self.Pilot:DrawWorldModel(true)
    			self.Pilot:Spawn()
    			self.Pilot:SetNetworkedBool("isDrivePJ",false)
    			self.Pilot:SetPos(self.Entity:GetPos()+Vector(0,0,-30))
    			self.sequence2 = self.Entity:LookupSequence("door_o");
    			self.door = true
    			self.sequence = self.Entity:LookupSequence("close");
    			self.epodo = false
    
    			self.Entity:SetSequence(self.sequence)
    			self.Entity:SetSequence(self.sequence2);
    
    			self.Accel=0
    			self.Inflight=false
    			self.Rotorwash = false
    			self.Rotorwashent:Remove()
    	
    	else
    
    		self.Entity:GetPhysicsObject():Wake()
    		self.Entity:GetPhysicsObject():EnableMotion(true)
    		self.Inflight=true
    		self.Pilot=ply
    		
    		local rotorent = ents.Create("env_rotorwash_emitter")
    		rotorent:SetPos(self.Entity:GetPos())
    		rotorent:Spawn()
    		rotorent:Activate()
    		rotorent:SetParent(self.Entity)
    		self.Rotorwashent = rotorent
    		self.Rotorwash = true
    		
    		ply:Spectate( OBS_MODE_CHASE )
    		ply:DrawViewModel(false)
    		ply:DrawWorldModel(false)
    		ply:StripWeapons()
    		ply:SetNetworkedBool("isDrivePJ",true)
    		ply:SetNetworkedEntity("PJ",self.Entity)
    		if( self.door == true ) then
    		self.sequence2 = self.Entity:LookupSequence("door_c");
    		self.door = false
    	else
    		return end		
    		self.Entity:SetSequence(self.sequence2);
    	end
    end
    
    function ENT:PhysicsSimulate( phys, deltatime )
    	
    	
    	if self.Pilot and self.Pilot:IsValid() then
    
    		if self.Inflight then
    		local num=0
    		
    		if( self.epodo == true ) and self.Pilot:KeyDown(IN_FORWARD) then
    			num=1500
    		elseif self.Pilot:KeyDown(IN_FORWARD) then
    			num=1000
    		elseif self.epodo == false and self.Pilot:KeyDown(IN_MOVELEFT) then
    			num=500
    		elseif self.epodo == false and self.Pilot:KeyDown(IN_MOVERIGHT) then
    			num=500
    		elseif self.Pilot:KeyDown(IN_BACK) then
    			num=-500
    	end
    
    	
    		phys:Wake()
    			self.Accel=math.Approach(self.Accel,num,10)
    			if not self.Hover then
    			if self.Accel>-200 and self.Accel < 200 then return end --with out this you float
    			end
    				if self.epodo == true and self.Pilot:KeyDown(IN_MOVELEFT) then
    	phys:AddAngleVelocity(phys:GetAngleVelocity()+Angle(0,0,-1))
    	
    	elseif self.epodo == true and self.Pilot:KeyDown(IN_MOVERIGHT) then
    	phys:AddAngleVelocity(phys:GetAngleVelocity()+Angle(0,0,1))
    	end
    		local pr={}
    			pr.secondstoarrive	= 1
    			if  self.Pilot:KeyDown( IN_DUCK ) then 
    				pr.pos = self.Entity:GetPos()+self.Entity:GetUp()*-200
    			elseif  self.Pilot:KeyDown( IN_JUMP ) then 
    				pr.pos = self.Entity:GetPos()+self.Entity:GetUp()*300
    			elseif self.Pilot:KeyDown( IN_MOVERIGHT ) then 
    				pr.pos = self.Entity:GetPos()+self.Entity:GetRight()*400
    			elseif self.Pilot:KeyDown( IN_MOVELEFT ) then 
    				pr.pos = self.Entity:GetPos()+self.Entity:GetRight()*-400
    			else 
    				pr.pos = self.Entity:GetPos()+self.Entity:GetForward()*self.Accel
    			end
    			pr.maxangular		= 5000
    			pr.maxangulardamp	= 10000
    			pr.maxspeed			= 1000000
    			pr.maxspeeddamp		= 10000
    			pr.dampfactor		= 0.8
    			pr.teleportdistance	= 5000
    			pr.angle		= self.Pilot:GetAimVector():Angle()
    			
    			pr.deltatime		= deltatime
    		phys:ComputeShadowControl(pr)
    			end
    	
    	
    
    	local pos = self.Entity:GetPos();
    	
    	if self.epodo == true then
    	if (self.Inflight and self.DroneCount < 10) then
    	
    			if self.Pilot:KeyDown(IN_ATTACK) then 
    				local vel = self.Entity:GetVelocity();
    				local up = self.Entity:GetUp();
    				-- calculate the drone's position offset. Otherwise it might collide with the launcher
    				local offset = StarGate.VelocityOffset({Velocity=vel,Direction=up,BoundingMax=self.Entity:OBBMaxs().z});
    				local e = ents.Create("drone");
    				e.Parent = self.Entity;
    				e:SetPos(pos+offset);
    				e:SetAngles(self.Entity:GetForward():Angle()+Angle(math.random(-2,2),math.random(-2,2),math.random(-2,2)));
    				e:SetOwner(self.Entity); -- Don't collide with this thing here please
    				e.Owner = self.Entity.Owner;
    				e:Spawn();
    				e:SetVelocity(vel);
    				self.DroneCount = self.DroneCount + 1;
    				self.Drones[e] = true;
    				-- This is necessary to make the drone not collide and explode with the cannon when it's moving
    				e.CurrentVelocity = math.Clamp(vel:Length(),0,self.DroneMaxSpeed-500)+500;
    				e.CannonVeloctiy = vel;
    			end
    	end
    	
    	if self.Inflight then
    		self.Track = false
    			if self.Pilot:KeyDown(IN_ATTACK2) then
    			self.Track = true
    			end 
    		end
    	end
    end
    end
    	
    
    	
    function ENT:ShowOutput()
    
    end
    
    
    function ENT:StargateCheck() --Check if we are near a dialing stargate.
    	local gate = self:FindGate(800)
    	self.NearValidStargate = false
    	if ValidEntity(gate) then
    		if gate.IsStargate then
    			if gate.Outbound then
    				self.NearValidStargate = true
    			end
    		end
    	end
    end
    
    function ENT:OpenDHD(p) --thank you avon
    	if(not ValidEntity(p)) then return end;
    	local e = self:FindGate(3000);
    	if(not ValidEntity(e)) then return end;
    	if(hook.Call("StarGate.Player.CanDialGate",GAMEMODE,p,e) == false) then return end;
    	umsg.Start("StarGate.OpenDialMenuDHD",p);
    	umsg.Entity(e);
    	umsg.End();
    end
    
    function ENT:FindGate(dist)
    	local gate;
    	local pos = self.Entity:GetPos();
    	for _,v in pairs(ents.FindByClass("stargate_*")) do
    		local sg_dist = (pos - v:GetPos()):Length();
    		if(dist >= sg_dist) then
    			dist = sg_dist;
    			gate = v;
    		end
    	end
    	return gate;
    end
    
    function ENT:Status(b,nosound)
    	if(b) then
    		if(not self:Enabled()) then
    				local e = ents.Create("cloaking");
    				e.Size = 200;
    				e:SetPos(self.Entity:GetPos());
    				e:SetAngles(self.Entity:GetAngles());
    				e:SetParent(self.Entity);
    				e:Spawn();
    				if(not nosound) then
    					self:EmitSound(self.Sounds.Cloak,80,math.random(80,100));
    				end
    				if(e and e:IsValid() and not e.Disable) then -- When our new cloak mentioned, that there is already a cloak
    					self.Cloak = e;
    					
    					return;
    				end
    			
    		end
    	else
    		if(self:Enabled()) then
    			self.Cloak:Remove();
    			self.Cloak = nil;
    			-- Give back the energy, we took when it was enagaged
    			if(not nosound) then
    				self:EmitSound(self.Sounds.Uncloak,80,math.random(90,110));
    			end
    		end
    		return;
    	end
    
    	-- Fail animation
    
    end
    
    function ENT:Enabled()
    	return (self.Cloak and self.Cloak:IsValid());
    end
    
    --Add explosions
    function ENT:Health()
    
    if self.Entity:Health() < 1 then
    	local explode = ents.Create( "env_explosion" )
    	explode:Spawn()
    	explode:SetKeyValue( "iMagnitude", "220" )
    	explode:Fire( "Explode", 0, 0 )
    	explode:EmitSound( "weapon_AWP.Single", 400, 400 )
    	end
    end
    
    Any help would be brilliant

    Thanks
    Reply With Quote Edit / Delete Reply Show Events Friendly Friendly x 1 (list)

  2. Post #2
    Gold Member
    thomasfn's Avatar
    July 2008
    2,960 Posts
    Can we see your code?

  3. Post #3
    Gold Member
    Ronon Dex's Avatar
    February 2009
    1,861 Posts
    Added to OP

  4. Post #4
    Gold Member
    conman420's Avatar
    January 2007
    1,794 Posts
    Do this instead:

    self.lin = Vector(0,0,0)
    self.ang = Vector(0,0,0)
    local forcelinear, forceangular = phys:CalculateForceOffset(self:GetUp() * 20, self:GetPos() + self:GetRight() * 20) //First arguement is the vector force, second is the origin of the force.
    
    //self.lin = forcelinear + self.lin Dont apply linear you just want it to roll
    self.ang = forceangular + self.ang
    
    return self.ang, self.lin, SIM_GLOBAL_ACCELERATION
    

    If you want to make the ship move forwards with this method then do this:

    local forcelinear, forceangular = phys:CalculateForceOffset(self:GetForwawrd() * 20, self:GetPos())
    
    self.lin = forcelinear + self.lin
    //self.ang = forceangular + self.ang On this occasion we DO want to apply linear force but not turn.
    

    Inside your physics simulate function where you want to make it roll left. To make it roll right change the origin to the left and do the same without returning the angular and linear vectors.

  5. Post #5
    Gold Member
    Ronon Dex's Avatar
    February 2009
    1,861 Posts
    Yeah i don't understand what your doing there

    Edited:

    I've fixed it now, now rolls perfectly