Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delayed combat executions can result in wrong damage values #2600

Open
2 tasks done
Erza opened this issue May 29, 2019 · 1 comment
Open
2 tasks done

Delayed combat executions can result in wrong damage values #2600

Erza opened this issue May 29, 2019 · 1 comment

Comments

@Erza
Copy link
Contributor

Erza commented May 29, 2019

Before creating an issue, please ensure:

  • This is a bug in the software that resides in this repository, and not a
    support matter (use https://otland.net/forums/support.16/ for support)
  • This issue is reproducible without changes to the code in this repository

Steps to reproduce (include any configuration/script required to reproduce)

  1. Replace any monster's attacks and defenses with these
<attacks>
	<attack name="energy ue" interval="2000" chance="50" min="-3000" max="-5000"/>
</attacks>
<defenses armor="55" defense="65">
	<defense name="healing" interval="3000" chance="35" min="2500" max="3500">
		<attribute key="areaEffect" value="blueshimmer" />
	</defense>
	<defense name="speed" interval="4000" chance="80" speedchange="700" duration="6000">
		<attribute key="areaEffect" value="redshimmer" />
	</defense>
</defenses>
  1. Add the spell to spells.xml
<instant name="energy ue" words="###54" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/energy ue.lua" />
  1. Create the file energy ue.lua in data/spells/monster with the following content
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT)
combat:setArea(createCombatArea(AREA_CIRCLE6X6))

local function executeUE(cid, var)
	local creature = Creature(cid)
	if creature then
		combat:execute(creature, var)
	end
end

function onCastSpell(creature, var)
	addEvent(executeUE, 5000, creature:getId(), var)
	return true
end
  1. Summon a dummy monster (e.g. /summon training monk) that your wild monster (e.g. /m gaz'haragoth) can attack and observe for a while

Expected behaviour

The damage is applied as it was intended

Actual behaviour

If another spell is cast before combat:execute() is fired, the damage values will be wrong, which can result in no damage, wrong damage or even healing the target
Here's a video

Technical explanation

The damage values are set here once the spell is casted, and then later fetched again here when combat:execute() is ran. If another spell is cast in the time frame of the addEvent delay, these values will be overwritten and result in an attack with incorrect damage values.

@Zbizu
Copy link
Contributor

Zbizu commented Dec 4, 2020

The fundamental problem of addEvent is that the stored objects point to places in memory, but after 5 seconds the memory is different so it points to another thing than you meant. This is why addEvent either returns random values (in this case) or even crashes the server (if you try to addEvent with Creature/Player object).

The solution here is creating the combat object inside the delayed function and include min/max values in lua.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants