• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!
  • New resources must be posted under Resources tab. A discussion thread will be created automatically, you can't open threads manually anymore.

NPC Do you want an auto-attacker npc? check here

Joined
Apr 17, 2008
Messages
1,922
Solutions
1
Reaction score
188
Location
Venezuela
I made this because i was bored :D!

Go to your npc-lua file and replace
LUA:
function onThink()                                      npcHandler:onThink() end

With
LUA:
local damaged = {}
local times = {}
local combat =
{
	type = COMBAT_FIREDAMAGE,
	min = -20,
	max = -80,
	effect = CONST_ME_FIRE,
	disteffect = CONST_ANI_FIRE
}
local rangex, rangey = 4, 4
local timeBetweenAttack = 5 --seconds
function onThink()

	local list = getSpectators(getCreaturePosition(getNpcCid()), rangex, rangey)
	if list and #list > 0 then
		for _, uid in ipairs(list) do
			if isPlayer(uid) and getCreatureSkullType(uid) > 2 then
				if not damaged[uid] then
					damaged[uid] = os.time(t)
					times[uid] = 1
					doTargetCombatHealth(getNpcCid(), uid, combat.type, combat.min * times[uid], combat.max * times[uid], combat.effect)
					doCreatureSay(getNpcCid(), "Get out of here " .. getCreatureName(uid) .. "!", TALKTYPE_SAY)
					doSendDistanceShoot(getCreaturePosition(getNpcCid()), getCreaturePosition(uid), combat.disteffect)
					return npcHandler:onThink()
				else
					if os.time(t) - damaged[uid] > timeBetweenAttack then
						times[uid] = (os.time(t) - damaged[uid] > 20 and 1 or times[uid] + 1)
						damaged[uid] = os.time(t)
						doTargetCombatHealth(getNpcCid(), uid, combat.type, combat.min * times[uid], combat.max * times[uid], combat.effect)
						doCreatureSay(getNpcCid(), "You again " .. getCreatureName(uid) .. "?... Get out of here!", TALKTYPE_SAY)
						doSendDistanceShoot(getCreaturePosition(getNpcCid()), getCreaturePosition(uid), combat.disteffect)
						return npcHandler:onThink()
					end
				end
			end
		end
	end
	return npcHandler:onThink()
end

Every 5 seconds, the npc will attack players with white, red or black skull on a range of 5x5 (Configurable)
Each time npc attacks the same player, damage will be higher for that player.

:D
 
Last edited:
LUA:
local list = getSpectators(getCreaturePosition(getNpcCid()), rangex, rangey)
if list and #list > 0 then
can be changed to
LUA:
local list = getSpectators(getNpcPos(), rangex, rangey) or {}
your script will also cause memory leaks because you're not freeing the table values of tables damaged & times
 
freeing? this is not C/C++

It is a global table that allocates memory for each key used. The garbage collector for Lua will not free the memory unless the table goes out of scope or the key values are set to nil. The table is global so it won't go out of scope, and the script does not set them to nil when they no longer have to be used so they will stay there until the server restarts or the script environment is reloaded. Who has fooled you that you only can free allocated memory in C/C++?
 
It is a global table that allocates memory for each key used. The garbage collector for Lua will not free the memory unless the table goes out of scope or the key values are set to nil. The table is global so it won't go out of scope, and the script does not set them to nil when they no longer have to be used so they will stay there until the server restarts or the script environment is reloaded. Who has fooled you that you only can free allocated memory in C/C++?
lol, equalizing the variable to nil doesnt mean freeing, like in C/C++ when you equalize the variable to NULL doesnt mean freeing, about "running out of scope" i have to agree on that
 
lol, equalizing the variable to nil doesnt mean freeing, like in C/C++ when you equalize the variable to NULL doesnt mean freeing, about "running out of scope" i have to agree on that

I have not said that setting the variable to nil means freeing - and are you seriously comparing freeing in C/C++ to freeing in Lua?! The garbage collector in Lua will free the memory when it no longer is accessible (which it won't be if you set the table keys to nil).

Please read: Lua 5.1 Reference Manual.

I can also quote it for you: "Lua manages memory automatically by running a garbage collector from time to time to collect all dead objects (that is, objects that are no longer accessible from Lua).".
By setting the keys to nil, the data you previously allocated to these keys is no longer accessible and will be flagged as dead so that Lua's garbage collector can free them.
 
LUA:
local t = {}
local combat =
{
	type = COMBAT_PHYSICALDAMAGE,
	min = -20,
	max = -80,
	effect = CONST_ME_EXPLOSIONAREA,
	disteffect = CONST_ANI_EXPLOSION
}
local radX, radY = 4, 4
local timeBetweenAttack = 5 -- seconds

function onThink()
	local npc, _t = getNpcId(), {}
	local p, f = getThingPos(npc)
	for _, cid in ipairs(getSpectators(p, radX, radY) or {}) do
		if isPlayer(cid) and getCreatureSkullType(cid) > 2 then
			if not f then
				selfFocus(cid)
				f = true
			end
			local new = not t[cid]
			if new or os.clock() - t[cid][1] >= timeBetweenAttack then
				local _p = getThingPos(cid)
				if not getTileInfo(_p).protection and isSightClear(p, _p, false) then
					_t[cid] = {os.clock(), (new or os.clock() - t[cid][1] >= 20) and 1 or t[cid][2] + 1}
					doCreatureSay(npc, new and 'Get out of here ' .. getCreatureName(cid) .. '!' or 'You again, ' .. getCreatureName(cid) .. '?! Get out of here, criminal scum!', TALKTYPE_PRIVATE_NP, false, cid, p)
					doTargetCombatHealth(npc, cid, combat.type, combat.min * _t[cid][2], combat.max * _t[cid][2], combat.effect)
					doSendDistanceShoot(p, _p, combat.disteffect)
				end
			else
				_t[cid] = {t[cid][1], 1}
			end
		end
	end
	if not f then
		selfFocus(0)
	end
	t = _t
	npcHandler:onThink()
end
 
Back
Top