我可能需要两个数组来存储值,并快速访问正在排序的值。
例如,float scan_fraction[4][2]
作为主数组,int fraction_order[4]
作为订单存储,这样我就可以使用订单数组快速访问具有最高值的方向。
在第一维中,我存储方向信息,如fraction[FR_LEFT][VALUE]
和fraction[FR_LEFT][FR_ENABLED]
在第二维中,我存储了一个float和另一个float(但可以使用int),后者告诉我们方向是启用的还是有条件启用的。
所以最后我可能会用一个结构体来做这个,如果有人也能给我一个例子来做这个,我会很感激的。
这是我得到的
void monster_jump(edict_t *self)
{
if(!(self->monsterinfo.aiflags & AI_JUMPDODGE) && !(self->monsterinfo.aiflags & AI_JUMPDODGEPROJ))
return;
if (!self->groundentity)
return;
vec3_t left, right;
vec3_t jump_dir = { 0 };
vec3_t back, front;
float scan_fraction[NUM_J_DIRS][2] =
{
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
};
int fraction_order[NUM_J_DIRS] =
{
0, 0, 0, 0
};
int i = 0, each_tr_incomplete = 0, num_fullyenabled = 0, no_random_dir = 1, random_count = 0;
if (self->monsterinfo.aiflags & AI_JUMPDODGEPROJ && self->monsterinfo.jump_ent)
{
VectorSubtract(self->s.origin, self->monsterinfo.jump_ent->s.origin, jump_dir);
gi.bprintf(PRINT_HIGH, "monster_jump: should jump away from projectile!\n");
jump_dir[2] *= 0.25;
VectorNormalize(jump_dir);
vec3_t end;
VectorMA(self->s.origin, 128, jump_dir, end);
trace_t tr = gi.trace(self->s.origin, NULL, NULL, end, self, MASK_SHOT);
if (tr.fraction != 1)
{
VectorInverse(jump_dir);
jump_dir[0] *= 1 + (crandom() * 0.25);
jump_dir[0] *= 1 + (crandom() * 0.25);
VectorNormalize(jump_dir);
gi.bprintf(PRINT_HIGH, "monster_jump: should jump away from projectile!, path is blocked, so go randomly towards projectile\n");
}
//else
//gi.bprintf(PRINT_HIGH, "monster_jump: should jump away from projectile!\n");
}
else
{
gi.bprintf(PRINT_HIGH, "monster_jump: should jump away from danger!\n");
scan_fraction[FRAC_LEFT][FR_VAL] = scan_dir(self, SCAN_LEFT, 128, left);
scan_fraction[FRAC_RIGHT][FR_VAL] = scan_dir(self, SCAN_RIGHT, 128, right);
scan_fraction[FRAC_BACK][FR_VAL] = scan_dir(self, SCAN_BACKWARDS, 128, back);
scan_fraction[FRAC_FORWARD][FR_VAL] = scan_dir(self, SCAN_FORWARD, 128, front);
gi.bprintf(PRINT_HIGH, "monster_jump: left = %f, right = %f, back = %f, forw = %f!\n", scan_fraction[FRAC_LEFT][FR_VAL], scan_fraction[FRAC_RIGHT][FR_VAL], scan_fraction[FRAC_BACK][FR_VAL], scan_fraction[FRAC_FORWARD][FR_VAL]);
if (scan_fraction[FRAC_LEFT][FR_VAL] != COMPLETE_TR_FRACTION && scan_fraction[FRAC_RIGHT][FR_VAL] != COMPLETE_TR_FRACTION && scan_fraction[FRAC_BACK][FR_VAL] != COMPLETE_TR_FRACTION && scan_fraction[FRAC_FORWARD][FR_VAL] != COMPLETE_TR_FRACTION)
each_tr_incomplete = 1;
if (scan_fraction[FRAC_LEFT][FR_VAL] == COMPLETE_TR_FRACTION)
{
num_fullyenabled++;
scan_fraction[FRAC_LEFT][FR_ENABLED] = ENABLED_FULLY;
}
if (scan_fraction[FRAC_RIGHT][FR_VAL] == COMPLETE_TR_FRACTION)
{
num_fullyenabled++;
scan_fraction[FRAC_RIGHT][FR_ENABLED] = ENABLED_FULLY;
}
if (scan_fraction[FRAC_BACK][FR_VAL] == COMPLETE_TR_FRACTION)
{
num_fullyenabled++;
scan_fraction[FRAC_BACK][FR_ENABLED] = ENABLED_FULLY;
}
if (scan_fraction[FRAC_FORWARD][FR_VAL] == COMPLETE_TR_FRACTION)
{
num_fullyenabled++;
scan_fraction[FRAC_FORWARD][FR_ENABLED] = ENABLED_FULLY;
}
if (self->monsterinfo.aiflags & AI_JUMPATTACK && scan_fraction[FRAC_FORWARD][FR_VAL] > 1.0f) //let's skip this for now
{
self->monsterinfo.aiflags &= ~AI_JUMPATTACK;
gi.bprintf(PRINT_HIGH, "monster_jump: should jump forward!\n");
//goto jump_attack;
VectorSubtract(self->s.origin, front, jump_dir);
}
else
{
gi.bprintf(PRINT_HIGH, "monster_jump: starting qsort!\n");
size_t element_count = sizeof scan_fraction / sizeof scan_fraction[0]; // or NUM_J_DIRS
size_t element_size = sizeof scan_fraction[0];
qsort(scan_fraction, element_count, element_size, cmp2);
for (i = 0; i < NUM_J_DIRS; i++)
{
gi.bprintf(PRINT_HIGH, "monster_jump: running qsort! i = %i, \n", i);
fraction_order[i] = i;
if (each_tr_incomplete)
{
gi.bprintf(PRINT_HIGH, "monster_jump: each trace was incomplete\n", i);
scan_fraction[i][FR_ENABLED] = ENABLED_CONDITIONALLY;
}
else if (scan_fraction[i][FR_VAL] > 0.85f)
scan_fraction[i][FR_ENABLED] = ENABLED_FULLY;
}
gi.bprintf(PRINT_HIGH, "monster_jump: ended qsort! %f %f %f %f\n", scan_fraction[fraction_order[0]][FR_VAL], scan_fraction[fraction_order[1]][FR_VAL], scan_fraction[fraction_order[2]][FR_VAL], scan_fraction[fraction_order[3]][FR_VAL]);
if (num_fullyenabled) //there is at least one direction that can be used
{
full_traces:
random_count++;
gi.bprintf(PRINT_HIGH, "monster_jump: choosing from full traces, num = %i!\n", random_count);
if (random_count >= RANDOM_FR_MAX_COUNT)
goto random_direction;
switch(fraction_order[rand() % num_fullyenabled])
{
case FRAC_LEFT:
if (scan_fraction[FRAC_LEFT][FR_ENABLED] != ENABLED_FULLY)
{
gi.bprintf(PRINT_HIGH, "monster_jump: LEFT is disabled, retry\n");
goto full_traces;
}
gi.bprintf(PRINT_HIGH, "monster_jump: JUMP LEFT(FULL + RANDOM)\n");
VectorSubtract(self->s.origin, right, jump_dir);
break;
case FRAC_RIGHT:
if (scan_fraction[FRAC_RIGHT][FR_ENABLED] != ENABLED_FULLY)
{
gi.bprintf(PRINT_HIGH, "monster_jump: RIGHT is disabled, retry\n");
goto full_traces;
}
gi.bprintf(PRINT_HIGH, "monster_jump: JUMP RIGHT(FULL + RANDOM)\n");
VectorSubtract(self->s.origin, left, jump_dir);
break;
case FRAC_BACK:
if (scan_fraction[FRAC_BACK][FR_ENABLED] != ENABLED_FULLY)
{
gi.bprintf(PRINT_HIGH, "monster_jump: BACK is disabled, retry\n");
goto full_traces;
}
gi.bprintf(PRINT_HIGH, "monster_jump: JUMP BACK(FULL + RANDOM)\n");
VectorSubtract(self->s.origin, front, jump_dir);
break;
case FRAC_FORWARD:
if (scan_fraction[FRAC_FORWARD][FR_ENABLED] != ENABLED_FULLY)
{
gi.bprintf(PRINT_HIGH, "monster_jump: FORWARD is disabled, retry\n");
goto full_traces;
}
gi.bprintf(PRINT_HIGH, "monster_jump: JUMP FRONT(FULL + RANDOM)\n");
VectorSubtract(self->s.origin, back, jump_dir);
break;
}
}
else if (no_random_dir)
{
sorted_traces:
random_count++;
gi.bprintf(PRINT_HIGH, "monster_jump: choosing from sorted, num = %i!\n", random_count);
if (random_count >= RANDOM_FR_MAX_COUNT)
goto random_direction;
switch (fraction_order[0])
{
case FRAC_LEFT:
if (!scan_fraction[FRAC_LEFT][FR_ENABLED])
goto sorted_traces;
gi.bprintf(PRINT_HIGH, "monster_jump: JUMP LEFT(sorted + RANDOM)\n");
VectorSubtract(self->s.origin, right, jump_dir);
break;
case FRAC_RIGHT:
if (!scan_fraction[FRAC_RIGHT][FR_ENABLED])
goto sorted_traces;
gi.bprintf(PRINT_HIGH, "monster_jump: JUMP RIGHT(sorted + RANDOM)\n");
VectorSubtract(self->s.origin, left, jump_dir);
break;
case FRAC_BACK:
if (!scan_fraction[FRAC_BACK][FR_ENABLED])
goto sorted_traces;
gi.bprintf(PRINT_HIGH, "monster_jump: JUMP BACK(sorted + RANDOM)\n");
VectorSubtract(self->s.origin, front, jump_dir);
break;
case FRAC_FORWARD:
if (!scan_fraction[FRAC_FORWARD][FR_ENABLED])
goto sorted_traces;
gi.bprintf(PRINT_HIGH, "monster_jump: JUMP FRONT(sorted + RANDOM)\n");
VectorSubtract(self->s.origin, back, jump_dir);
break;
}
}
else
{
random_direction:
gi.bprintf(PRINT_HIGH, "monster_jump: choosing from random dir!\n");
switch (rand() % 4)
{
case FRAC_LEFT:
gi.bprintf(PRINT_HIGH, "monster_jump: JUMP LEFT(RANDOM)\n");
VectorSubtract(self->s.origin, right, jump_dir);
break;
case FRAC_RIGHT:
gi.bprintf(PRINT_HIGH, "monster_jump: JUMP RIGHT(RANDOM)\n");
VectorSubtract(self->s.origin, left, jump_dir);
break;
case FRAC_BACK:
gi.bprintf(PRINT_HIGH, "monster_jump: JUMP BACK(RANDOM)\n");
VectorSubtract(self->s.origin, front, jump_dir);
break;
case FRAC_FORWARD:
gi.bprintf(PRINT_HIGH, "monster_jump: JUMP FRONT(RANDOM)\n");
VectorSubtract(self->s.origin, back, jump_dir);
break;
}
}
}
VectorNormalize(jump_dir);
}
VectorMA(self->velocity, 300 + (100 * random()), jump_dir, self->velocity);
self->velocity[2] += 150 + random() * 50;
self->monsterinfo.jump_ent = NULL;
self->monsterinfo.aiflags &= ~AI_JUMPDODGEPROJ;
self->monsterinfo.aiflags &= ~AI_JUMPDODGE;
gi.sound(self, CHAN_AUTO, gi.soundindex(va("player/step%i.wav", rand() % 5)), 1, ATTN_IDLE, 0);
gi.sound(self, CHAN_AUTO, gi.soundindex(va("player/step%i.wav", rand() % 5)), 1, ATTN_IDLE, 0.05f);
}
如果能从中世纪的东西中走出来就好了:random_direction: switch (rand() % 4) { case FRAC_LEFT: if (!scan_fraction[FRAC_LEFT][FR_ENABLED]) goto random_direction;
到不使用随机数的东西,以利用一个有一个案件(或案件)从开关禁用。
1条答案
按热度按时间ncgqoxb01#
OP不想对
scan_fraction[]
排序,即使代码包含qsort(scan_fraction, ...
。相反,OP希望得到排序的东西,可以访问一个不变的
scan_fraction[]
是一个排序的方式。scan_fraction[]
的每个元素的指针数组scan_fraction_sorted[]
。scan_fraction_sorted[]
scan_fraction_sorted[]
引用按排序顺序显示scan_fraction[]
下面的代码演示了这一点,有点难看--但是有一些东西让OP仔细考虑。
产出