Rework how the z velocity is passed from *zshoot to A_Shoot().

Previously, actor[].shootzvel (implementation detail, not available to CON)
was checked, and if it was !=0, that was the overridden velocity. The value
0 meant "hardcoded, projectile-dependent velocity". But that neccesiated a
hack where if zvel 0 was passed and really meant, it needed to be set to
1 instead.  Now we have A_ShootWithZvel() taking an additional last argument
plus a macro SHOOT_HARDCODED_ZVEL permissible for that argument.

git-svn-id: https://svn.eduke32.com/eduke32@3465 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-02-07 21:01:12 +00:00
parent 24e6aca5f7
commit 7c861cac42
9 changed files with 99 additions and 71 deletions

View file

@ -123,6 +123,8 @@ typedef struct {
int16_t picnum,ang,extra,owner; //8b
int16_t movflag,tempang,timetosleep; //6b
// NOTE: shootzvel is not exposed but only used temporarily in player.c
// shooting routines.
int16_t actorstayput, dispicnum, shootzvel, cgg; // 8b
int16_t lightId, lightcount, lightmaxrange; //6b

View file

@ -2321,31 +2321,24 @@ nullquote:
case CON_EZSHOOT:
case CON_ZSHOOT:
insptr++;
{
int32_t j;
if (tw != CON_ESHOOT)
{
actor[vm.g_i].shootzvel = Gv_GetVarX(*insptr++);
if (actor[vm.g_i].shootzvel == 0)
actor[vm.g_i].shootzvel = 1;
}
// NOTE: (int16_t) cast because actor[].shootzvel is int16_t
// and we want exclude that SHOOT_HARDCODED_ZVEL is passed.
const int32_t zvel = (tw == CON_ESHOOT) ?
SHOOT_HARDCODED_ZVEL : (int16_t)Gv_GetVarX(*insptr++);
if ((unsigned)vm.g_sp->sectnum >= (unsigned)numsectors)
{
CON_ERRPRINTF("Invalid sector %d\n", TrackerCast(vm.g_sp->sectnum));
insptr++;
actor[vm.g_i].shootzvel=0;
continue;
}
j = A_Shoot(vm.g_i,*insptr++);
j = A_ShootWithZvel(vm.g_i,*insptr++,zvel);
if (tw != CON_ZSHOOT)
aGameVars[g_iReturnVarID].val.lValue = j;
actor[vm.g_i].shootzvel=0;
}
continue;
@ -2358,40 +2351,31 @@ nullquote:
if ((unsigned)vm.g_sp->sectnum >= (unsigned)numsectors)
{
CON_ERRPRINTF("Invalid sector %d\n", TrackerCast(vm.g_sp->sectnum));
actor[vm.g_i].shootzvel=0;
continue;
}
j = A_Shoot(vm.g_i, j);
if (tw == CON_ESHOOTVAR)
aGameVars[g_iReturnVarID].val.lValue = j;
actor[vm.g_i].shootzvel=0;
continue;
}
case CON_EZSHOOTVAR:
case CON_ZSHOOTVAR:
insptr++;
actor[vm.g_i].shootzvel = Gv_GetVarX(*insptr++);
if (actor[vm.g_i].shootzvel == 0)
actor[vm.g_i].shootzvel = 1;
{
const int32_t zvel = (int16_t)Gv_GetVarX(*insptr++);
int32_t j=Gv_GetVarX(*insptr++);
if ((unsigned)vm.g_sp->sectnum >= (unsigned)numsectors)
{
CON_ERRPRINTF("Invalid sector %d\n", TrackerCast(vm.g_sp->sectnum));
actor[vm.g_i].shootzvel=0;
continue;
}
j = A_Shoot(vm.g_i, j);
j = A_ShootWithZvel(vm.g_i, j, zvel);
if (tw == CON_EZSHOOTVAR)
aGameVars[g_iReturnVarID].val.lValue = j;
actor[vm.g_i].shootzvel=0;
continue;
}

View file

@ -64,6 +64,7 @@ PROJ = {
}
-- PROJ_* define -> projectile_t member name
--[[
PROJ_MEMBNAME = {
[PROJ.PROJ_WORKSLIKE] = "workslike",
[PROJ.PROJ_SPAWNS] = "spawns",
@ -95,6 +96,7 @@ PROJ_MEMBNAME = {
[PROJ.PROJ_RANGE] = "range",
[PROJ.PROJ_FLASH_COLOR] = "flashcolor", -- NAME
}
--]]
-- TODO: EVENT_INIT currently can't run since we init Lunatic state only afterwards
EVENT = {
@ -387,6 +389,7 @@ local ActorLabels = {
httempang = AC".tempang",
htactorstayput = AC".actorstayput",
htdispicnum = { AC".dispicnum" },
-- NOTE: no access for .shootzvel
httimetosleep = AC".timetosleep",
htfloorz = AC".floorz",
htceilingz = AC".ceilingz",
@ -734,35 +737,35 @@ StructAccessCode =
local PROJ = function(memb) return "projectile[%s]"..memb end
local ProjectileLabels = {
workslike = PROJ"workslike",
cstat = PROJ"cstat",
hitradius = PROJ"hitradius",
range = PROJ"range",
flashcolor = PROJ"flashcolor",
spawns = { PROJ"spawns" },
sound = PROJ"sound",
isound = PROJ"isound",
vel = PROJ"vel",
decal = { PROJ"decal" },
trail = { PROJ"trail" },
tnum = PROJ"tnum",
drop = PROJ"drop",
offset = PROJ"offset",
bounces = PROJ"bounces",
bsound = PROJ"bsound",
toffset = PROJ"toffset",
extra = PROJ"extra",
extra_rand = PROJ"extra_rand",
sxrepeat = PROJ"sxrepeat",
syrepeat = PROJ"syrepeat",
txrepeat = PROJ"txrepeat",
tyrepeat = PROJ"tyrepeat",
shade = PROJ"shade",
xrepeat = PROJ"xrepeat",
yrepeat = PROJ"yrepeat",
pal = PROJ"pal",
velmult = PROJ"movecnt", -- NAME
clipdist = PROJ"clipdist",
workslike = PROJ".workslike",
cstat = PROJ".cstat",
hitradius = PROJ".hitradius",
range = PROJ".range",
flashcolor = PROJ".flashcolor",
spawns = { PROJ".spawns" },
sound = PROJ".sound",
isound = PROJ".isound",
vel = PROJ".vel",
decal = { PROJ".decal" },
trail = { PROJ".trail" },
tnum = PROJ".tnum",
drop = PROJ".drop",
offset = PROJ".offset",
bounces = PROJ".bounces",
bsound = PROJ".bsound",
toffset = PROJ".toffset",
extra = PROJ".extra",
extra_rand = PROJ".extra_rand",
sxrepeat = PROJ".sxrepeat",
syrepeat = PROJ".syrepeat",
txrepeat = PROJ".txrepeat",
tyrepeat = PROJ".tyrepeat",
shade = PROJ".shade",
xrepeat = PROJ".xrepeat",
yrepeat = PROJ".yrepeat",
pal = PROJ".pal",
velmult = PROJ".movecnt", -- NAME
clipdist = PROJ".clipdist",
}
-- These structs cannot be accessed by inline array exprs in CON:

View file

@ -434,7 +434,7 @@ end
function _A_Shoot(i, atwith)
check_sprite_idx(i)
check_tile_idx(atwith)
return ffiC.A_Shoot(i, atwith)
return ffiC.A_ShootWithZvel(i, atwith, 0x80000000) -- SHOOT_HARDCODED_ZVEL
end
function _A_IncurDamage(sn)

View file

@ -502,7 +502,7 @@ const int32_t g_currentMenu;
int32_t A_IncurDamage(int32_t sn); // not bound-checked!
void P_AddWeaponMaybeSwitch(DukePlayer_t *ps, int32_t weap);
int32_t A_Shoot(int32_t i, int32_t atwith);
int32_t A_ShootWithZvel(int32_t i, int32_t atwith, int32_t override_zvel);
int32_t A_IncurDamage(int32_t sn);
int32_t A_Spawn(int32_t j, int32_t pn);
void VM_FallSprite(int32_t i);

View file

@ -263,7 +263,7 @@ gameevent(gv.EVENT_ENTERLEVEL,
-- MORTER2 from test/weaponvars.con
player[0].weapon.SHOTGUN.shoots = 1653
projectile[1653].drop = -200
projectile[1653].drop = 0
checkfail("gameevent('GAME', function() print('qwe') end)",
"must be called from top level")

View file

@ -1,4 +1,6 @@
gamevar snd 351 0 // thunder sound
gamevar tmp 0 0
gamevar tmp2 0 0
gamevar shoots 2605 2 // RPG
gamevar WEAPON1_SHOOTS 2605 0
@ -6,11 +8,11 @@ gamevar WEAPON1_SHOOTS 2605 0
define MORTER2 1653
defineprojectile MORTER2 PROJ_WORKSLIKE 6150
defineprojectile MORTER2 PROJ_SPAWNS EXPLOSION2
defineprojectile MORTER2 PROJ_SOUND MORTER2_SHOOT
defineprojectile MORTER2 PROJ_SOUND RPG_SHOOT
defineprojectile MORTER2 PROJ_VEL 600
defineprojectile MORTER2 PROJ_EXTRA 165
defineprojectile MORTER2 PROJ_EXTRA_RAND 10
defineprojectile MORTER2 PROJ_DROP 0 // tested in test.elua
defineprojectile MORTER2 PROJ_DROP -200 // tested in test.elua
defineprojectile MORTER2 PROJ_ISOUND PIPEBOMB_EXPLODE
defineprojectile MORTER2 PROJ_HITRADIUS 2800
defineprojectile MORTER2 PROJ_BOUNCES 4
@ -23,3 +25,15 @@ onevent EVENT_GAME
setvarvar WEAPON1_FIRESOUND snd
// setvarvar WEAPON1_SHOOTS shoots
endevent
useractor notenemy 909 // tree trunk
ifcount 120
{
ezshoot -4096 MORTER2
getthisprojectile[RETURN].vel tmp
randvar tmp2 500
subvarvar tmp tmp2
setthisprojectile[RETURN].vel tmp
resetcount
}
enda

View file

@ -440,6 +440,14 @@ static void Proj_MaybeAddSpread(int32_t not_accurate_p, int32_t *zvel, int16_t *
}
}
static int32_t use_actor_shootzvel = 0;
static int32_t A_GetShootZvel(int32_t i, int32_t defaultzvel)
{
return use_actor_shootzvel ? actor[i].shootzvel : defaultzvel;
}
// Prepare hitscan weapon fired from player p.
static void P_PreFireHitscan(int32_t i, int32_t p, int32_t atwith,
vec3_t *srcvect, int32_t *zvel, int16_t *sa,
@ -477,9 +485,7 @@ static void P_PreFireHitscan(int32_t i, int32_t p, int32_t atwith,
{
hitdata_t hit;
*zvel = (100-ps->horiz-ps->horizoff)<<5;
if (actor[i].shootzvel)
*zvel = actor[i].shootzvel;
*zvel = A_GetShootZvel(i, (100-ps->horiz-ps->horizoff)<<5);
hitscan(srcvect, sprite[i].sectnum, sintable[(*sa+512)&2047], sintable[*sa&2047],
*zvel<<6,&hit,CLIPMASK1);
@ -544,8 +550,7 @@ static int32_t Proj_DoHitscan(int32_t i, int32_t cstatmask,
s->cstat &= ~cstatmask;
if (actor[i].shootzvel)
zvel = actor[i].shootzvel;
zvel = A_GetShootZvel(i, zvel);
hitscan(srcvect, s->sectnum,
sintable[(sa+512)&2047],
@ -818,7 +823,7 @@ static void Proj_HandleKnee(hitdata_t *hit, int32_t i, int32_t p, int32_t atwith
}
}
int32_t A_Shoot(int32_t i, int32_t atwith)
int32_t A_ShootWithZvel(int32_t i, int32_t atwith, int32_t override_zvel)
{
int16_t l, sa, j, k=-1;
int32_t vel, zvel = 0, x, oldzvel;
@ -830,6 +835,16 @@ int32_t A_Shoot(int32_t i, int32_t atwith)
const int32_t p = (s->picnum == APLAYER) ? s->yvel : -1;
DukePlayer_t *const ps = p >= 0 ? g_player[p].ps : NULL;
if (override_zvel != SHOOT_HARDCODED_ZVEL)
{
use_actor_shootzvel = 1;
actor[i].shootzvel = override_zvel;
}
else
{
use_actor_shootzvel = 0;
}
if (s->picnum == APLAYER)
{
Bmemcpy(&srcvect,ps,sizeof(vec3_t));
@ -1092,7 +1107,7 @@ int32_t A_Shoot(int32_t i, int32_t atwith)
if (numplayers > 1 && g_netClient) return -1;
if (actor[i].shootzvel) zvel = actor[i].shootzvel;
zvel = A_GetShootZvel(i, zvel);
j = A_InsertSprite(sect,
srcvect.x+(sintable[(348+sa+512)&2047]/proj->offset),
srcvect.y+(sintable[(sa+348)&2047]/proj->offset),
@ -1273,8 +1288,9 @@ int32_t A_Shoot(int32_t i, int32_t atwith)
hit.pos.x = safeldist(g_player[j].ps->i, s);
zvel = ((g_player[j].ps->opos.z - srcvect.z + (3<<8))*vel) / hit.pos.x;
}
if (actor[i].shootzvel) zvel = actor[i].shootzvel;
oldzvel = zvel;
zvel = A_GetShootZvel(i, zvel);
oldzvel = zvel; // NOTE: assigned to after last store to zvel, so redundant
if (atwith == SPIT)
{
@ -1367,7 +1383,7 @@ int32_t A_Shoot(int32_t i, int32_t atwith)
if (numplayers > 1 && g_netClient) return -1;
if (actor[i].shootzvel) zvel = actor[i].shootzvel;
zvel = A_GetShootZvel(i, zvel);
j = A_InsertSprite(sect,
srcvect.x+(sintable[(348+sa+512)&2047]/448),
srcvect.y+(sintable[(sa+348)&2047]/448),
@ -1527,7 +1543,8 @@ int32_t A_Shoot(int32_t i, int32_t atwith)
if (zvel < -4096)
zvel = -2048;
vel = x>>4;
if (actor[i].shootzvel) zvel = actor[i].shootzvel;
zvel = A_GetShootZvel(i, zvel);
A_InsertSprite(sect,
srcvect.x+(sintable[(512+sa+512)&2047]>>8),
srcvect.y+(sintable[(sa+512)&2047]>>8),
@ -1619,7 +1636,8 @@ int32_t A_Shoot(int32_t i, int32_t atwith)
zvel = ((g_player[j].ps->opos.z-srcvect.z)*512) / l ;
}
else zvel = 0;
if (actor[i].shootzvel) zvel = actor[i].shootzvel;
zvel = A_GetShootZvel(i, zvel);
j = A_InsertSprite(sect,
srcvect.x+(sintable[(512+sa+512)&2047]>>12),
srcvect.y+(sintable[(sa+512)&2047]>>12),
@ -1628,10 +1646,10 @@ int32_t A_Shoot(int32_t i, int32_t atwith)
sprite[j].cstat = 128;
sprite[j].clipdist = 32;
return j;
}
}
return -1;
}

View file

@ -332,8 +332,15 @@ extern int32_t lastvisinc;
extern int32_t mouseyaxismode;
extern int32_t ticrandomseed;
#define SHOOT_HARDCODED_ZVEL INT32_MIN
int32_t A_ShootWithZvel(int32_t i, int32_t atwith, int32_t override_zvel);
static inline int32_t A_Shoot(int32_t i, int32_t atwith)
{
return A_ShootWithZvel(i, atwith, SHOOT_HARDCODED_ZVEL);
}
int32_t A_GetHitscanRange(int32_t i);
int32_t A_Shoot(int32_t i,int32_t atwith);
void getinput(int32_t snum);
void P_AddAmmo(int32_t weapon,DukePlayer_t *p,int32_t amount);
void P_AddWeapon(DukePlayer_t *p,int32_t weapon);