Jump to content

How to exclude entities inside player inventory in check for entities


Recommended Posts

Hello, I'm stuck with this and if someone can help me out that'd be so nice!

So I'm using some code to check what is closest creature near me..

local target = GLOBAL.GetClosestInstWithTag({"_health", "_combat"}, inst, 3)

		if target ~= nil and not target.components.health:IsDead() and not target:HasTag("playerghost") then
				inst.components.combat:SetTarget(target)
				inst.components.combat:StartAttack()
		end

..but the problem is if the player is holding on to a rabbit, bee, ect.. It makes player target the entity in their inventory! Is there a way to prevent this?

Thanks for checking out my problem, have a great time :wilson_laugh:!

Link to comment
Share on other sites

I'll take a guess on this one:

local function smallanimal(item)
    return item:HasTag("smallcreature") --things that can be captured
end

local target = GLOBAL.GetClosestInstWithTag({"_health", "_combat"}, inst, 3)

if target ~= nil and not target.components.health:IsDead() and not target:HasTag("playerghost") and not inst.components.inventory:FindItem(smallanimal) then

inst.components.combat:SetTarget(target)

inst.components.combat:StartAttack()

end

not sure if it works.

Edited by K1NGT1GER609
Link to comment
Share on other sites

--simutil.lua line ~136 
function GetClosestInstWithTag(tag, inst, radius)
    local x, y, z = inst.Transform:GetWorldPosition()
    local ents = TheSim:FindEntities(x, y, z, radius, type(tag) == "string" and { tag } or tag)
    return ents[1] ~= inst and ents[1] or ents[2]
end
--TheSim:FindEntities(x,y,z, radius, musttags and #musttags or 0, canttags and #canttags or 0, mustoneoftags and #mustoneoftags or 0)

We could just make a modified version of the GetClosestInstWithTag

local function ReturnEntityWithSpecificTagsAndNotInInventory(inst, radius, musttags, canttags, mustoneoftags)
    local x, y, z = inst.Transform:GetWorldPosition()
    local ents = TheSim:FindEntities(x, y, z, radius, musttags, canttags, mustoneoftags)
    for i, v in ipairs(ents) do
		if v ~= inst and v.entity:IsVisible()  and not (v.components.inventoryitem ~= nil and v.components.inventoryitem:IsHeld() ~= nil) then
				return v
		end
    end
end

Too be honest though you should probably be using FindEntity instead of ClosestInst as the difference seems negible when they are returning the first or second thing in the array anyways.

Checking out the simutil.lua file is a pretty good way to understand how to find stuff in the world.

Edited by IronHunter
Not Tested
Link to comment
Share on other sites

Hey, so I tried using your code but I probably did it real wrong it crashes saying "attempt to index field 'Transform' (a nil value)"

Spoiler

local function ReturnEntityWithSpecificTagsAndNotInInventory(inst, radius, musttags, canttags, mustoneoftags)
    local x, y, z = inst.Transform:GetWorldPosition() -- Crashes here
    local ents = TheSim:FindEntities(x, y, z, radius, musttags, canttags, mustoneoftags)
    for i, v in ipairs(ents) do
		if v ~= inst and v.entity:IsVisible()  and not (v.components.inventoryitem ~= nil and v.components.inventoryitem:IsHeld() ~= nil) then
				return v
		end
    end
end

local target = ReturnEntityWithSpecificTagsAndNotInInventory({"_health", "_combat"}, inst, 3)

		if target ~= nil and not target.components.health:IsDead() and not target:HasTag("playerghost") then
				inst.components.combat:SetTarget(target)
				inst.components.combat:StartAttack()
		end

 

 

The reason I don't use find entity is because I think that will apply code to multiple entities that are found within that range? I'm using this code for an attack function and I want it only to attack what is closest to the player..

Though, Ideally I'd like instead of attacking what is closest to the player the attack hits whatever is in front of the player for a certain range which can be changed based on different things like long weapon, short weapon, ect.. maybe like an "attack_range" value which is increased/lowered when player equips something. Though I don't know if there's a code which can make such a thing possible :wilson_dorky:.

And thanks for your help!

Link to comment
Share on other sites

1 hour ago, IronHunter said:

I don't remember if the whip does this, but I do remember it had a passification effect that affected enemies in a radius nearby.

Yes it seems to be this code

local x,y,z = inst.Transform:GetWorldPosition()
local ents = TheSim:FindEntities(x,y,z, TUNING.WHIP_SUPERCRACK_RANGE, { "_combat" }, { "player", "epic", "shadow", "shadowminion", "shadowchesspiece" })

but it makes entities in a close range from all direction get effect not entities in certain direction or something (like only entities in front of player), I will see if simutil.lua will give me any hints but probably won't understanding anything lol

anyways.. thanks :D!

Link to comment
Share on other sites

After you get the entities first then use some math to get an arc in front of you so you only affect those enemies. Like atan2 or something. I think we did something like that for a earlier piece of code that was used to knock items out of your characters hand.

I'll look into it more when I have access to my computer.

Edit: assuming there is no prebuilt function in simutil that is. I'll look into making a global function for anybody to use.

Edited by IronHunter
See notes
Link to comment
Share on other sites

Spoiler

---------------------------
----<  Arcing Sweeps  >----
----< By: Iron_Hunter >----
---------------------------
AddComponentPostInit("combat", function(self)
	function self:SetConicalAreaAttack(angle) --inputs angle e.g 90 when divided by 2 is 45 left and 45 right of your target
		self.conicalareaattack = angle
	end
	self.OldDoAreaAttack = self.DoAreaAttack
	function self:DoAreaAttack(target, range, weapon, validfn, stimuli, excludetags)
		if self.conicalareaattack ~= nil then
			local hitcount = 0
			local targetangle = self.inst:GetAngleToPoint(target.Transform:GetWorldPosition())+ 360--returns math.atan2 in radians = PI/180 * degrees
			local angle = math.deg(self.conicalareaattack/2 * PI/180)
			local targetdist = math.sqrt(self.inst:GetDistanceSqToInst(target))
			local maxdist = math.floor(math.max(range, targetdist))+1
			local x, y, z = self.inst.Transform:GetWorldPosition()
			local ents = TheSim:FindEntities(x, y, z, maxdist, { "_combat" }, excludetags)--the good news we don't need to worry about radius as we got all entities in radius already.
			for i, ent in ipairs(ents) do
				if ent ~= target and ent ~= self.inst and self:IsValidTarget(ent) and (validfn == nil or validfn(ent)) then
					local entangle = self.inst:GetAngleToPoint(ent.Transform:GetWorldPosition())+ 360 --prevents negative numbers
					print(targetangle + angle .. " >= " .. entangle .." , "..  targetangle - angle .. " <= " .. entangle)
					if targetangle + angle >= entangle and targetangle - angle <= entangle then
						self.inst:PushEvent("onareaattackother", { target = ent, weapon = weapon, stimuli = stimuli })
						ent.components.combat:GetAttacked(self.inst, self:CalcDamage(ent, weapon, self.areahitdamagepercent), weapon, stimuli)
						hitcount = hitcount + 1
					end
				end
			end
			return hitcount
		else
			self:OldDoAreaAttack(target, range, weapon, validfn, stimuli, excludetags)
		end
	end
end)

 

I am not sure if this is what you are looking for, but I feel like sharing it anyways, I created a custom area attack that attacks in a customizable angle infront of the attacker. Think sword slash in front of the user.

It piggybacks off the normal area attack function so you must have that normally before utilizing this feature.

Link to comment
Share on other sites

10 hours ago, IronHunter said:

I am not sure if this is what you are looking for, but I feel like sharing it anyways, I created a custom area attack that attacks in a customizable angle infront of the attacker. Think sword slash in front of the user.

It piggybacks off the normal area attack function so you must have that normally before utilizing this feature.

Thanks! I hate to be stupid but uhh how to I use this code :wilson_dorky:? I do force attack on entities and it seems it still only hits 1 entity (I put code in modmain), sorry for my stupidness :wilson_ecstatic:!

Edited by SuperDavid
Link to comment
Share on other sites

4 minutes ago, SuperDavid said:

Thanks! I hate to be stupid but uhh how to I use this code :wilson_dorky:? I do force attack on entities and it seems it still only hits 1 entity (I put code in modmain), sorry I'm stupidness :wilson_ecstatic:!

It was designed to piggyback off of the normal area of effect, I built it to use for custom mobs. But it was also fun fooling around with characters

--set up a normal area damage attack, but make it a sector of a circle rather than a whole circle
inst.components.combat:SetAreaDamage(3)
inst.components.combat:SetConicalAreaAttack(180) --alternatively inst.components.combat.conicalareaattack = 180
--e.g. 180 = 180 degrees or half a circle in front of you.

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...