burgelkat Posted March 8, 2018 Share Posted March 8, 2018 Hi , i will share my solution for the Mortar. Mortar = a Pivot put there this script in (MortarTracking.lua) import "Scripts/Functions/ReleaseTableObjects.lua" import "Scripts/Functions/GetEntityNeighbors.lua" Script.enabled=true--bool "Enabled" Script.trackingrange = 10 Script.tracking=false function Script:Enable()--in if self.enabled==false then self.enabled=true self.component:CallOutputs("Enable") end end function Script:Disable()--in if self.enabled then self.enabled=false self.component:CallOutputs("Disable") end end function Script:UpdatePhysics() if self.enabled then -- load entities within range (5000) of self.entity into "entities", only load entities that have scripts attached local entities = GetEntityNeighbors(self.entity,5000,true) local k,entity -- loop thrrough the result of "entities". k = key, entity = result for k,entity in pairs(entities) do -- only select entities with teamid == 1 ("good") if entity.script.teamid == 1 then -- and if the entity has at least 1 health remaining if entity.script.health>0 then local d = self.entity:GetDistance(entity) self.target = entity end local pos = self.entity:GetPosition() local targetpos = self.target:GetPosition() --if math.abs(targetpos.y-pos.y)<1.5 then if pos:xz():DistanceToPoint(targetpos:xz())<self.trackingrange then self.tracking=false else self.tracking=true end end end if self.tracking==true then self.entity:Point(self.target,2,Time:GetSpeed()*1.5); end end end in Mortar Body = the Model put in the script (Mortar.lua) import "Scripts/Functions/ReleaseTableObjects.lua" import "Scripts/Functions/GetEntityNeighbors.lua" Script.enabled=true--bool "Enabled" --Public Script.target = nil--enemy to shoot Script.teamid=3--choice "Team" "Neutral,Good,Bad" Script.range = 5000 Script.health=100 Script.projectilepath = "Prefabs/projectiles/MortarAmmo.pfb" Script.shoot1sound=""--path "File" "All Supported Files:ogg,wav;Waveform Audio File Format (*.wav):wav;Ogg Vorbis (*.ogg):ogg|Sound" Script.shoot2sound=""--path "File" "All Supported Files:ogg,wav;Waveform Audio File Format (*.wav):wav;Ogg Vorbis (*.ogg):ogg|Sound" Script.shoot3sound=""--path "File" "All Supported Files:ogg,wav;Waveform Audio File Format (*.wav):wav;Ogg Vorbis (*.ogg):ogg|Sound" --Private Script.lastfiretime=0 Script.mode = "idle" Script.lastsearchtime = 0 Script.searchfrequency = 500 Script.firefrequency = 4000 Script.Force1 = Vec3(0,1500,0) Script.Force2 = Vec3(0,2500,0) Script.Force3 = Vec3(0,3000,0) Script.Force4 = Vec3(0,3500,0) Script.range0 = 20 Script.range1 = 30 Script.range2 = 60 Script.range3 = 90 Script.range4 = 110 function Script:Start() --Load sounds self.sound = {} self.sound.shoot = {} if self.shoot1sound~="" then self.sound.shoot[1] = Sound:Load(self.shoot1sound) end if self.shoot2sound~="" then self.sound.shoot[2] = Sound:Load(self.shoot2sound) end if self.shoot3sound~="" then self.sound.shoot[3] = Sound:Load(self.shoot3sound) end self.projectile = Prefab:Load(self.projectilepath) if self.projectile~=nil then self.projectile:Hide() end self.Mortar = self.entity:FindChild("Mortar") --Add muzzleflash to gun self.muzzle = self.entity:FindChild("muzzle") if self.muzzle~=nil then local mtl=Material:Create() mtl:SetBlendMode(5) self.muzzle:SetMaterial(mtl) mtl:Release() self.muzzleflash = Sprite:Create() self.muzzleflash:SetSize(0.35,0.35) local pos=self.muzzle:GetPosition(true) self.muzzleflash:SetPosition(pos,true) self.muzzleflash:SetParent(self.muzzle,true) mtl = Material:Load("Materials/Effects/muzzleflash.mat") if mtl then self.muzzleflash:SetMaterial(mtl) mtl:Release() mtl=nil end local light = PointLight:Create() light:SetRange(5) light:SetColor(1,0.75,0) light:SetParent(self.muzzleflash,flash) if light.world:GetLightQuality()<2 then light:SetShadowMode(0) end self.muzzleflash:Hide() end end function Script:Release() if self.projectile~=nil then self.projectile:Release() self.projectile = nil end end function MortarSearchHook(entity,extra) if entity~=extra then if entity.script~=nil then if entity.script.teamid == 1 then if type(entity.script.health)=="number" then if entity.script.health>0 then local d = extra:GetDistance(entity) if d<extra.script.range then if extra.script.target~=nil then if extra.script:GetDistance(extra.script.target)>d then if extra.script:GetTargetVisible(entity.script) then extra.script.target = entity.script end end else if extra.script:GetTargetVisible(entity.script) then extra.script.target = entity.script end end end end end end end end end function Script:GetTargetVisible(target) if target==nil then target = self.target end if target==nil then return false end local pickinfo = PickInfo() local p0 = self.entity:GetAABB().center local p1 = target.entity:GetAABB().center local pickmode0 = self.entity:GetPickMode() local pickmode1 = target.entity:GetPickMode() self.entity:SetPickMode(0) target.entity:SetPickMode(0) local result = not self.entity.world:Pick(p0,p1,pickinfo,0,false,Collision.LineOfSight) self.entity:SetPickMode(pickmode0) target.entity:SetPickMode(pickmode1) return result end function Script:UpdateWorld() if self.enabled==true then if self.health>=0 then self.component:CallOutputs("Online") local currenttime = Time:GetCurrent() --Stop shooting if target is dead if self.target~=nil then if self.target.health<=0 then self.component:CallOutputs("Idle") self.target = nil end end --Search for target if self.enabled==true then if self.target==nil then if currenttime - self.lastsearchtime > self.searchfrequency then self.lastsearchtime = currenttime local pos = self.entity:GetPosition(true) local aabb = AABB(pos - Vec3(self.range), pos + Vec3(self.range)) self.entity.world:ForEachEntityInAABBDo(aabb,"MortarSearchHook",self.entity) end end end ---------------------deactivated because the Mortar should fire if vegetation hides you----------------- --Continuous visibility test --[[ if self.target~=nil then if currenttime - self.lastsearchtime > self.searchfrequency then self.lastsearchtime = currenttime if self:GetTargetVisible(self.target)==false then self.target = nil return end end end]] ---------------------------------------------------------------------------------------------------------- if self.target~=nil then ---------------------------no need for this (i think)--------------------------------------------------------------- --[[Motion tracking if self.Mortar~=nil then local p0 = self.Mortar:GetPosition(true) local p1 = self.target.entity:GetAABB().center local yplane = p1 - p0 yplane.y=0 self.Mortar:AlignToVector(yplane,1,0.1 / Time:GetSpeed(),0) end]] ---------------------------------------------------------------------------------------------------------- --Shoot if self.muzzle~=nil and self.projectile~=nil then if currenttime - self.lastfiretime > self.firefrequency then self.lastfiretime = currenttime local bullet = self.projectile:Instance() self.muzzleflash:Show() self.muzzleflash:EmitSound(self.sound.shoot[#self.sound.shoot]) self.muzzleflash:SetAngle(math.random(0,360)) self.muzzleflashtime=currenttime if bullet~=nil then bullet:Show() bullet:SetFriction(1000,1000) bullet:SetCollisionType(Collision.Projectile) bullet:SetPosition(self.muzzle:GetPosition(true),true) bullet:SetRotation(self.muzzle:GetRotation(true),true) targetpos = self.target.entity:GetPosition() pos1 = self.entity:GetPosition(true) --if math.abs(targetpos.y-pos1.y)<1.5 then -------------------------------------------------Fire Range--------------------------------------------------------------------- if pos1:xz():DistanceToPoint(targetpos:xz())<self.range1 then System:Print("1") bullet:AddForce(self.Force1) else if pos1:xz():DistanceToPoint(targetpos:xz())<self.range2 then System:Print("2") bullet:AddForce(self.Force2) else if pos1:xz():DistanceToPoint(targetpos:xz())<self.range3 then System:Print("3") bullet:AddForce(self.Force4) else if pos1:xz():DistanceToPoint(targetpos:xz())<self.range4 then System:Print("4") bullet:AddForce(self.Force4) else return 100000 end end end end -------------------------------------------------------------------------------------------------------------------------------- bullet:SetMass(0.4) if bullet.script~=nil then bullet.script.owner = self if type(bullet.script.Enable)=="function" then bullet.script:Enable() end bullet:Turn(Math:Random(-4,4),Math:Random(-4,4),0) end end end end end end if self.health<=0 then self.component:CallOutputs("Offline") end self:UpdateMuzzleFlash() end end function Script:UpdateMuzzleFlash() if self.muzzleflashtime then if Time:GetCurrent()-self.muzzleflashtime<30 then self.muzzleflash:Show() else self.muzzleflash:Hide() end end end function Script:Online()--in if self.enabled==false then self.component:CallOutputs("Online") self.enabled=true end end function Script:Offline()--in if self.enabled==true then self.component:CallOutputs("Offline") self.enabled=false end end for the Ammo search a model like my on http://www.cadnav.com/3d-models/model-42383.html and put the script "MortarAmmo" in Script.movespeed=1000 Script.pickradius=0 Script.damage=10 Script.lifetime=20000 Script.enabled=false--bool "Enabled" function Script:Start() self.sound={} self.sound.ricochet={} self.sound.ricochet[1]=Sound:Load("Sound/Weapons/Explosion.wav") self.sound.ricochet[2]=Sound:Load("Sound/Weapons/Explosion.wav") self.sound.ricochet[3]=Sound:Load("Sound/Weapons/Explosion.wav") self.starttime=Time:GetCurrent() self.emitter={} --Debris emitter - This will throw chunks off of walls and make it look like they are breaking self.emitter[0]=Emitter:Create() self.emitter[0]:SetCollisionType(Collision.Prop)--Enables particle bouncing self.emitter[0]:SetMaterial("Materials/Effects/smoke.mat") self.emitter[0]:SetEmissionVolume(0.05,0.05,0.05) self.emitter[0]:SetColor(0.1,0.1,0.1,1) self.emitter[0]:SetVelocity(5.5,15,5.5,1) self.emitter[0]:SetParticleCount(20) self.emitter[0]:SetReleaseQuantity(20) self.emitter[0]:SetMaxScale(0.9) self.emitter[0]:SetDuration(1500) self.emitter[0]:SetAcceleration(0,-12,0) self.emitter[0]:SetLoopMode(false) self.emitter[0]:Hide() --Smoke emitter - This will provide a soft dust effect around bullet impacts self.emitter[1]=Emitter:Create() self.emitter[1]:SetColor(1,1,1,0.25) self.emitter[1]:SetMaterial("Materials/Effects/smoke.mat") self.emitter[1]:SetEmissionVolume(0.1,0.1,0.1) self.emitter[1]:SetVelocity(0.3,0.3,0.3,1) self.emitter[1]:SetParticleCount(8) self.emitter[1]:SetReleaseQuantity(3) self.emitter[1]:SetMaxScale(15) self.emitter[1]:SetDuration(3800) self.emitter[1]:AddScaleControlPoint(0,0.5) self.emitter[1]:AddScaleControlPoint(1,1) self.emitter[1]:SetRotationSpeed(10) self.emitter[1]:SetLoopMode(false) self.emitter[1]:Hide() --Smoke emitter - This will provide a soft dust effect around bullet impacts self.emitter[2]=Emitter:Create() self.emitter[2]:SetColor(1,1,1,0.25) self.emitter[2]:SetMaterial("Prefabs/Effects/Explosion/explosion.mat") self.emitter[2]:SetEmissionVolume(0.1,0.1,0.1) self.emitter[2]:SetVelocity(0.3,0.3,0.3,1) self.emitter[2]:SetParticleCount(1) self.emitter[2]:SetReleaseQuantity(1) self.emitter[2]:SetMaxScale(25) self.emitter[2]:SetDuration(2500) self.emitter[2]:AddScaleControlPoint(0,0.5) self.emitter[2]:AddScaleControlPoint(1,1) self.emitter[2]:SetRotationSpeed(10) self.emitter[2]:SetLoopMode(false) self.emitter[2]:Hide() end function Script:Enable() if self.enabled==false then self.enabled=true end end function Script:FindScriptedParent(entity,func) while entity~=nil do if entity.script then if type(entity.script[func])=="function" then return entity end end entity = entity:GetParent() end return nil end function Script:UpdateWorld() if self.enabled==false then return end if self.entity:Hidden() then return end local pickinfo=PickInfo() local pos = self.entity:GetPosition(true) local targetpos = Transform:Point(0,0,self.movespeed/60.0 * Time:GetSpeed(),self.entity,nil) local result = self.entity.world:Pick(pos,targetpos,pickinfo,self.pickradius,true,Collision.Projectile) if result then local enemy = self:FindScriptedParent(pickinfo.entity,"Hurt") if enemy then if self.owner then --if self.owner.teamid==enemy.script.teamid then -- result=false --end end if result then if enemy.script.health>0 then enemy.script:Hurt(self.damage,self.owner) end end end if result then self:Explode() --Bullet mark decal local mtl local scale = 2 if enemy~=nil then mtl = Material:Load("Materials/Decals/wound.mat") scale = 0.1 else if pickinfo.surface~=nil then local pickedmaterial = pickinfo.surface:GetMaterial() if pickedmaterial~=nil then rendermode = pickedmaterial:GetDecalMode() end end mtl = Material:Load("Materials/Decals/BombCrater.mat") end local decal = Decal:Create(mtl) decal:AlignToVector(pickinfo.normal,2) decal:Turn(0,0,Math:Random(0,360)) decal:SetScript("Scripts/Objects/Effects/BulletMark.lua") if mtl~=nil then mtl:Release() end decal:SetPosition(pickinfo.position) decal:SetParent(pickinfo.entity) --Apply global scaling local mat = decal:GetMatrix() mat[0] = mat[0]:Normalize() * scale mat[1] = mat[1]:Normalize() * scale mat[2] = mat[2]:Normalize() * scale decal:SetMatrix(mat) decal:EmitSound(self.sound.ricochet[math.random(#self.sound.ricochet)],30) self.entity:Release() else self.entity:SetPosition(targetpos) end else self.entity:SetPosition(targetpos) end if Time:GetCurrent()-self.starttime>self.lifetime then self.entity:Release() end end function Script:Explode() self.entity:EmitSound(self.sound.ricochet[math.random(#self.sound.ricochet)],30) self.emitter[0]:Show() self.emitter[0]:SetPosition(self.entity:GetPosition(true)) self.emitter[0]:Reset() self.emitter[0]:Play() self.emitter[1]:Show() self.emitter[1]:Reset() self.emitter[1]:SetPosition(self.entity:GetPosition(true)) self.emitter[1]:Play() self.emitter[2]:Show() self.emitter[2]:Reset() self.emitter[2]:SetPosition(self.entity:GetPosition(true)) self.emitter[2]:Play() end function Script:Collision(entity, position, normal, speed) self:Explode() end ok so far so good i hope you have fun. at the moment i think the scripts can be better written... for sure the Ammo script because it use the raycast to detect impact. i build in a collision line additional but this is not a perfect solution because the decal works only on pick ok changes from you are welcome in this post 2 Quote Link to comment Share on other sites More sharing options...
burgelkat Posted March 8, 2018 Author Share Posted March 8, 2018 i read this post https://www.leadwerks.com/community/topic/9862-small-entities-fall-through-terrain/ buit if i use force i have to add a Mass so rey cast for this not work Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.