Jump to content


Photo

Throwing Attribute


  • Please log in to reply
3 replies to this topic

#1 zizaniste

zizaniste

    Squaddie

  • Forum Members
  • PipPip
  • 1 posts

Posted 11 March 2008 - 09:40 AM

The "throwing" attribute has no effect - am I right?

I couldn't quite persuade myself to read all the relevant bits of the source, but this is how it looks to me. A test with a 50 thrower and an 80 thrower seems to confirm - the accuracy is always 100, whatever the item and whatever the stats.

#2 Emerald

Emerald

    Sergeant

  • Forum Members
  • PipPipPip
  • 14 posts

Posted 16 March 2008 - 05:29 PM

That's not exactly true. I often find that the thrown object might land a space or two off of the target space. However maybe it's more due to random chance, than the actual skill.


Still, what sort of comparison did you make? I mean, if a snap shot hits a target from 5 spaces, and an aimed shot hits a target from 5 spaces, you can't really say 'there's no difference in accuracy'

#3 Zyzyx

Zyzyx

    Squaddie

  • Forum Members
  • PipPip
  • 2 posts

Posted 10 January 2010 - 02:37 PM

I agree, thrown items seem to always land on the spot you select.
The 'problem' seems to be in Soldier::apply_throwing_accuracy(REAL &fi, REAL &te, int weight). The local variables TE_STEP and FI_STEP are too small to produce any noticable variation.

Basically, a random number is generated using target.accur and then multiplied by TE_STEP and FI_STEP. So if these numbers are bigger, it will increase the amount of variation in where the thrown item ends up. You can try playing around with them to get the desired effect. I found that I had to make them ~40 x (!!!) larger before I started noticing any change.

/**
 * Calculate random deviation for a grenade-throw 
 * based on throwing accuracy of soldier.
 */
void Soldier::apply_throwing_accuracy(REAL &fi, REAL &te, int weight)
{
	ASSERT(weight > 0);
	//REAL TE_STEP = (PI /  8 / 30.0);
	//REAL FI_STEP = (PI / 32 / 30.0);
	REAL TE_STEP = (PI /  8 / 0.65); //<-- some alternate values that I've found through trial and error - produces a more 'realistic' variation in where
	REAL FI_STEP = (PI / 32 / 0.65); // a thrown item lands.

	REAL rand_te, rand_fi, rand_range;
	rand_range = 100.0 - target.accur;
	if (rand_range < 1.0) rand_range = 1.0;
	rand_te = cur_random->getUniform(-rand_range * 0.5, rand_range * 0.5);
	rand_fi = cur_random->getUniform(0, rand_range) - rand_range / weight;
	te += TE_STEP * rand_te;
	fi += FI_STEP * rand_fi;
}

As for the throwing attribute, you are right, it doesn't have any effect. If you look around, you'll find that the variable target.accur is set by Soldier::assign_target(Action action, int iplace). For throwing actions, target.accur is fixed at 100. There is a case for something called AIMEDTHROW, but it does not seem to be used anywhere. You could try replacing target.accur = 100; with target.accur = TAccuracy(it->obdata_accuracy(ATHROW)); You may have to adjust the TE_STEP and FE_STEP to account for the accuracy not being 100% all the time anymore.

EDIT: Actually just replacing it doesnt work, since thrown weapons like grenades don't have an accuracy value... You could just replace it with whatever you want then, I guess the accuracy stat of the thrower would be an idea.

Ultimately however, making changes to this would introduce gameplay changes, since grenades could behave differently. We would need the opinion of more people if these should be changed and about what they should be changed to.

int Soldier::assign_target(Action action, int iplace)
{
	Item *it = item(iplace);
	if (it == NULL) return ERR_NO_ITEM;
	switch (action)
	{
		case THROW:
			target.accur = 100;
			target.time = required(16);
			break;
		case SNAPSHOT:
			target.accur = FAccuracy(it->obdata_accuracy(SNAP), it->obdata_twoHanded());
			target.time = required(it->obdata_time(SNAP));
			break;

 ... some more cases ....

		case AIMEDTHROW:   // <-- I checked icon.cpp and this does not seem to be used anywhere.
			target.accur = TAccuracy(it->obdata_accuracy(ATHROW));
			target.time = required(50);
			break;

 ... the rest of the switch clause ....

Edited by Zyzyx, 10 January 2010 - 03:29 PM.


#4 Serge

Serge

    Project Leader: UFO 2000

  • Xenocide Programming Department
  • 785 posts

Posted 10 January 2010 - 04:19 PM

Thanks for having a look at this stuff.

Actually in the long run we have to banish all the floating point calculations and switch to fixed point math, so this part of code will have to be changed and tweaked for better gameplay balace as well. Physics is not so complex in the game to require floating point. And floating point calculations are one of the sources of game state synchronization errors (reported as 'crc errors' in the game). Too bad that instead of reducing the usage of floating point math, even random number generator started depending on it, which is completely insane :)
ufo2000 development team
http://ufo2000.sourceforge.net