Page 1 of 1

Speed Multiplier

Posted: Wed Mar 22, 2017 8:49 pm
by Gangrenous
Maybe I am off base with this, but I notice spells that are supposed to slow speed do some weird things. Digging into the source maybe this is it? I have not tried anything yet, too close to bedtime.

I notice GetSpeed multiplies by the speed_multiplier

Code: Select all

float Entity::GetSpeed() {
	float ret = speed;

	if (IsStealthed() || IsInvis())
		ret += stats[ITEM_STAT_STEALTHINVISSPEEDMOD];
	else if (EngagedInCombat())
		ret += stats[ITEM_STAT_OFFENSIVESPEED];
	else
		ret += max(stats[ITEM_STAT_SPEED], stats[ITEM_STAT_MOUNTSPEED]);

	ret *= speed_multiplier;
	return ret;
}
But there are lines that call this function and then set things by it.

Code: Select all

packet->setDataByName("pos_speed", GetSpeed()*((float)speed_multiplier / speed_ratio));
So you are setting the position speed and multiplying by the speed_multiplier which is doing it again when it gets speed in the same function. Whether this is what is causing it, it is definitely messed up. Peak had already noticed it and when working on spells tonight I notice the mobs start at one speed when snared and then come to a crawl and eventually stop.

Normally if your speed multiplier is 1.0f, hey no issues, it will never diminish. But when it is lets say .9 and then does it every tick....isn't it going to go into nothingness?

Re: Speed Multiplier

Posted: Thu Mar 23, 2017 6:17 am
by Gangrenous
Hmm, not as much as I thought. I think we are just doing that calculation based off the current walking / running speed in GetSpeed(). Instead it should be based on max_speed. My source has max_speed, but I seem to remember that is a change I made months ago, I could be wrong though. So changing it like this fixed mine. On a mob that is running at 6.0, it drops it down to 4.18 when the spell reduces it down 30.4%, a quick calculation shows that right. Also when the spell is removed the mob speeds back up like it should.

Code: Select all

float Entity::GetSpeed() {
	float ret = max_speed;

	if (IsStealthed() || IsInvis())
		ret += stats[ITEM_STAT_STEALTHINVISSPEEDMOD];
	else if (EngagedInCombat())
		ret += stats[ITEM_STAT_OFFENSIVESPEED];
	else
		ret += max(stats[ITEM_STAT_SPEED], stats[ITEM_STAT_MOUNTSPEED]);

	ret *= speed_multiplier;
	return ret;
}

Re: Speed Multiplier

Posted: Thu Mar 23, 2017 6:38 am
by Gangrenous
Oh, and pretty sure in the spells it need to be multiplied by .01

Instead of

Code: Select all

(100.0 - SnareAmount) 
Like this.

Code: Select all

(100.0 - SnareAmount) * .01

Re: Speed Multiplier

Posted: Thu Mar 23, 2017 2:45 pm
by Jabantiz
speed_multiplier and speed_ratio I believe are special values we pulled from packets that ended up as rules because they were randomly changing between client versions. Changing those values could result in a spawn desync between the client and server. There was also something else about speed the was important but a quick search and I can't find it and I don't have the time to go digging for it, I will have to get back to you on this subject as it has been a long time since I worked on anything speed related.

Re: Speed Multiplier

Posted: Thu Mar 23, 2017 4:31 pm
by Gangrenous
Well I found my previous assumption was wrong, but I did figure it out a bit better. I had to use a Get and pull the speed_multiplier, not the actual rule. And yes I am getting a spawn desync, something strange. The mob does indeed slow down but it gets strange, even at a 99% reduction, it kind of jerks around and does move. It definitely moves slower, but goes jerky and the legs quit moving.

Re: Speed Multiplier

Posted: Thu Mar 23, 2017 6:47 pm
by Gangrenous
Okay, I figured it out. It took me several attempts at looking at the code to figure out where it was getting multiplied out. The mob slows to a crawl but the latency jerky action is now gone. On a side note, not a huge deal but I notice if the spell is resisted, the speed effect still hits. The damage does not, but speed does. That will eventually need to get figured out.

Re: Speed Multiplier

Posted: Thu Mar 23, 2017 7:58 pm
by Gangrenous
I noticed that EQ2Emu_lua_SetSpeeedMultiplier is actually mispelled, maybe intentional? Anyway, this should stop the issue where a resist lets it work.

Just needed a return 0;

LuaFunctions.cpp

Code: Select all

int EQ2Emu_lua_SetSpeedMultiplier(lua_State* state) {
	if (!lua_interface)
		return 0;

	Spawn* target = lua_interface->GetSpawn(state);
	float val = lua_interface->GetFloatValue(state, 2);
	LuaSpell* spell = lua_interface->GetCurrentSpell(state);
	
	if (spell && spell->resisted)
		return 0;