--Description: resource_node script by smallg. --Description: player can only mine the resource_node when equipped with the [WeaponRequired$="any"] weapon. --Description: Drops [DamageQuantity=1] every time it loses [DamagePercent=10] % of health. --Description: Spawns the resources with a height of [YOffset=50]. --Description: and a maximum horizontal distance of [OffH=50]. --Description: If [MinScale=50] is set below <100> the entity reduces in size when hit - (too small objects could be hard to hit in game). --Description: [ScaleTime#=0.2] allows for some smoother scaling - i.e. takes longer to shrink when hit with higher values. --Description: after being destroyed the resource node will respawn after [RespawnTime=60] seconds (set to 0 to never respawn). --Description: if [ShowWeaponName!=0] is true the currently held weapon will be shown on screen. U = require "scriptbank\\utillib" g_resource_node = {} function resource_node_properties(e, weaponrequired, damagequantity, damagepercent, yoffset, offh, minscale, scaletime, respawntime, showweaponname) g_resource_node[e] = g_Entity[e] local r = g_resource_node[e] r.weaponrequired = string.lower(weaponrequired) r.damagequantity = damagequantity r.damagepercent = damagepercent / 100 r.yoffset = yoffset r.offh = offh r.minscale = minscale r.showweaponname = showweaponname r.scaletime = scaletime r.respawntime = respawntime r.resources = {} r.gotresources = false r.state = "init" end function resource_node_init(e) g_resource_node[e] = {} resource_node_properties(e, "any", 1, 10, 50, 50, 50, 0.2, 60, 0) end function resource_node_main(e) local r = g_resource_node[e] local currentPlayerWeapon = string.lower(g_PlayerGunName) if r.showweaponname == 1 then TextCenterOnX(50,90,3,"Player's current weapon : "..currentPlayerWeapon) end if r.state == "init" then if #r.resources == 0 then for a = 0, 9 do local c = GetEntityRelationshipID(e,a) if c > 0 and c ~= e then local collectable = GetEntityCollectable(c) if collectable > 0 then table.insert(r.resources, c) Hide(c) CollisionOff(c) SetActivated(c,0) end end end if #r.resources == 0 then SwitchScript(e,"") return end end r.respawntimer = 0 r.scaletimer = 0 r.oldhealth = r.health r.maxhealth = r.health r.damagestep = 1 r.damagerequiredperstep = r.health - r.health * (1 - r.damagepercent * r.damagestep) r.scalex, r.scaley, r.scalez = GetObjectScales(r.obj) r.oscalex, r.oscaley, r.oscalez = r.scalex, r.scaley, r.scalez r.drophealth = r.health - r.damagerequiredperstep r.oldCorrectWeapon = true r.droppedcount = 0 r.oldweaponname = "none" r.state = "active" elseif r.state == "active" then if currentPlayerWeapon ~= r.oldweaponname then r.weaponrange = GetWeaponRange(g_PlayerGunID, g_PlayerGunMode) if r.weaponrange < 1 then r.weaponrange = 85 end r.oldweaponname = currentPlayerWeapon end if r.weaponrequired == "any" or r.weaponrequired == currentPlayerWeapon then if not r.oldCorrectWeapon then r.oldCorrectWeapon = true end r.correctWeapon = true if r.health < r.oldhealth then -- when hit we should update our target scales for scaling over time later r.tscale = r.health / r.maxhealth r.tscale = r.minscale + (100 - r.minscale) * r.tscale r.sscalex = r.scalex * 100 r.sscaley = r.scaley * 100 r.sscalez = r.scalez * 100 r.tscalex = r.scalex * r.tscale r.tscaley = r.scaley * r.tscale r.tscalez = r.scalez * r.tscale -- ensures the target scale doesn't go below the desired minimum scale r.tscalex = math.max(r.oscalex * r.minscale, r.tscalex) r.tscaley = math.max(r.oscaley * r.minscale, r.tscaley) r.tscalez = math.max(r.oscalez * r.minscale, r.tscalez) r.oldhealth = r.health r.scaletimer = r.scaletime if r.health <= r.drophealth then r.damagestep = r.damagestep + 1 r.drophealth = r.maxhealth - (r.damagerequiredperstep * r.damagestep) -- should also drop when destroyed if r.drophealth < 1 then r.drophealth = 1 end r.droppedcount = r.droppedcount + r.damagequantity local x,y,z, ax,ay,az = GetEntityPosAng(e) r.tscale2 = r.tscale r.tscale2 = r.tscale2 / 100 for a = 1, r.damagequantity do for b,c in pairs (r.resources) do local ne = SpawnNewEntity(c) if ne == nil or ne == 0 then ne = CreateEntityIfNotPresent(ne) end g_Entity[ne] = g_Entity[c] g_EntityExtra[ne] = g_EntityExtra[c] local tyoff = r.yoffset * r.tscale2 local nay = math.random(0,360) local ox = math.cos(nay) * math.random(-r.offh * r.tscale2, r.offh * r.tscale2) local oz = math.sin(nay) * math.random(-r.offh * r.tscale2, r.offh * r.tscale2) SetPosition(ne, x+ox,y+tyoff,z+oz) ResetPosition(ne, x+ox,y+r.yoffset,z+oz) SetRotation(ne, ax,ay,az) end end end end else if r.oldCorrectWeapon then r.oldCorrectWeapon = false end r.correctWeapon = false -- prevent the entity from being destroyed while holding the wrong weapon SetEntityHealthSilent(e,r.oldhealth) r.health = r.oldhealth end -- scales over time for better transition / animation if r.scaletimer > 0 then CollisionOff(e) local perc = math.min(r.scaletimer / r.scaletime, 1) local tx = Lerp(r.sscalex, r.tscalex, 1-perc) local ty = Lerp(r.sscaley, r.tscaley, 1-perc) local tz = Lerp(r.sscalez, r.tscalez, 1-perc) ScaleObject(r.obj, tx,ty,tz) r.scalex, r.scaley, r.scalez = GetObjectScales(r.obj) r.scaletimer = r.scaletimer - GetElapsedTime() CollisionOn(e) --TextCenterOnX(50,40,3,"start scale y = "..r.sscaley.." , target scale y = "..r.tscaley.." , current y scale = "..ty) end if U.PlayerLookingAtObj(r.obj, r.weaponrange) then if r.correctWeapon then TextCenterOnXColor(50,50,3,"+",0,255,0) else TextCenterOnXColor(50,50,3,"+",255,0,0) end end if r.health < 1 then Hide(e) CollisionOff(e) r.respawntimer = r.respawntime r.state = "wait for respawn" end elseif r.state == "wait for respawn" then r.respawntimer = r.respawntimer - GetElapsedTime() if r.respawntimer <= 0 then SetEntityHealth(e, r.maxhealth) r.oldhealth = r.maxhealth r.health = r.oldhealth CollisionOff(e) ScaleObject(r.obj, r.oscalex * 100, r.oscaley * 100, r.oscalez * 100) Show(e) CollisionOn(e) r.state = "init" end end local tCorrectWeapon = "No" if r.correctWeapon then tCorrectWeapon = "Yes" end --PromptLocal(e,"health : "..r.health..", required weapon : "..r.weaponrequired.." - can be damaged : "..tCorrectWeapon..", has dropped : "..r.droppedcount.." times - next drop : "..r.drophealth.."hp, scaley : "..r.scaley) end -- Linear interpolation function function Lerp(a, b, t) return a + (b - a) * t end