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 picnum,ang,extra,owner; //8b
int16_t movflag,tempang,timetosleep; //6b 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 actorstayput, dispicnum, shootzvel, cgg; // 8b
int16_t lightId, lightcount, lightmaxrange; //6b int16_t lightId, lightcount, lightmaxrange; //6b

View file

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

View file

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

View file

@ -434,7 +434,7 @@ end
function _A_Shoot(i, atwith) function _A_Shoot(i, atwith)
check_sprite_idx(i) check_sprite_idx(i)
check_tile_idx(atwith) check_tile_idx(atwith)
return ffiC.A_Shoot(i, atwith) return ffiC.A_ShootWithZvel(i, atwith, 0x80000000) -- SHOOT_HARDCODED_ZVEL
end end
function _A_IncurDamage(sn) 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! int32_t A_IncurDamage(int32_t sn); // not bound-checked!
void P_AddWeaponMaybeSwitch(DukePlayer_t *ps, int32_t weap); 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_IncurDamage(int32_t sn);
int32_t A_Spawn(int32_t j, int32_t pn); int32_t A_Spawn(int32_t j, int32_t pn);
void VM_FallSprite(int32_t i); void VM_FallSprite(int32_t i);

View file

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

View file

@ -1,4 +1,6 @@
gamevar snd 351 0 // thunder sound gamevar snd 351 0 // thunder sound
gamevar tmp 0 0
gamevar tmp2 0 0
gamevar shoots 2605 2 // RPG gamevar shoots 2605 2 // RPG
gamevar WEAPON1_SHOOTS 2605 0 gamevar WEAPON1_SHOOTS 2605 0
@ -6,11 +8,11 @@ gamevar WEAPON1_SHOOTS 2605 0
define MORTER2 1653 define MORTER2 1653
defineprojectile MORTER2 PROJ_WORKSLIKE 6150 defineprojectile MORTER2 PROJ_WORKSLIKE 6150
defineprojectile MORTER2 PROJ_SPAWNS EXPLOSION2 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_VEL 600
defineprojectile MORTER2 PROJ_EXTRA 165 defineprojectile MORTER2 PROJ_EXTRA 165
defineprojectile MORTER2 PROJ_EXTRA_RAND 10 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_ISOUND PIPEBOMB_EXPLODE
defineprojectile MORTER2 PROJ_HITRADIUS 2800 defineprojectile MORTER2 PROJ_HITRADIUS 2800
defineprojectile MORTER2 PROJ_BOUNCES 4 defineprojectile MORTER2 PROJ_BOUNCES 4
@ -23,3 +25,15 @@ onevent EVENT_GAME
setvarvar WEAPON1_FIRESOUND snd setvarvar WEAPON1_FIRESOUND snd
// setvarvar WEAPON1_SHOOTS shoots // setvarvar WEAPON1_SHOOTS shoots
endevent 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. // Prepare hitscan weapon fired from player p.
static void P_PreFireHitscan(int32_t i, int32_t p, int32_t atwith, static void P_PreFireHitscan(int32_t i, int32_t p, int32_t atwith,
vec3_t *srcvect, int32_t *zvel, int16_t *sa, 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; hitdata_t hit;
*zvel = (100-ps->horiz-ps->horizoff)<<5; *zvel = A_GetShootZvel(i, (100-ps->horiz-ps->horizoff)<<5);
if (actor[i].shootzvel)
*zvel = actor[i].shootzvel;
hitscan(srcvect, sprite[i].sectnum, sintable[(*sa+512)&2047], sintable[*sa&2047], hitscan(srcvect, sprite[i].sectnum, sintable[(*sa+512)&2047], sintable[*sa&2047],
*zvel<<6,&hit,CLIPMASK1); *zvel<<6,&hit,CLIPMASK1);
@ -544,8 +550,7 @@ static int32_t Proj_DoHitscan(int32_t i, int32_t cstatmask,
s->cstat &= ~cstatmask; s->cstat &= ~cstatmask;
if (actor[i].shootzvel) zvel = A_GetShootZvel(i, zvel);
zvel = actor[i].shootzvel;
hitscan(srcvect, s->sectnum, hitscan(srcvect, s->sectnum,
sintable[(sa+512)&2047], 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; int16_t l, sa, j, k=-1;
int32_t vel, zvel = 0, x, oldzvel; 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; const int32_t p = (s->picnum == APLAYER) ? s->yvel : -1;
DukePlayer_t *const ps = p >= 0 ? g_player[p].ps : NULL; 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) if (s->picnum == APLAYER)
{ {
Bmemcpy(&srcvect,ps,sizeof(vec3_t)); 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 (numplayers > 1 && g_netClient) return -1;
if (actor[i].shootzvel) zvel = actor[i].shootzvel; zvel = A_GetShootZvel(i, zvel);
j = A_InsertSprite(sect, j = A_InsertSprite(sect,
srcvect.x+(sintable[(348+sa+512)&2047]/proj->offset), srcvect.x+(sintable[(348+sa+512)&2047]/proj->offset),
srcvect.y+(sintable[(sa+348)&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); 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; 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) 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 (numplayers > 1 && g_netClient) return -1;
if (actor[i].shootzvel) zvel = actor[i].shootzvel; zvel = A_GetShootZvel(i, zvel);
j = A_InsertSprite(sect, j = A_InsertSprite(sect,
srcvect.x+(sintable[(348+sa+512)&2047]/448), srcvect.x+(sintable[(348+sa+512)&2047]/448),
srcvect.y+(sintable[(sa+348)&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) if (zvel < -4096)
zvel = -2048; zvel = -2048;
vel = x>>4; vel = x>>4;
if (actor[i].shootzvel) zvel = actor[i].shootzvel;
zvel = A_GetShootZvel(i, zvel);
A_InsertSprite(sect, A_InsertSprite(sect,
srcvect.x+(sintable[(512+sa+512)&2047]>>8), srcvect.x+(sintable[(512+sa+512)&2047]>>8),
srcvect.y+(sintable[(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 ; zvel = ((g_player[j].ps->opos.z-srcvect.z)*512) / l ;
} }
else zvel = 0; else zvel = 0;
if (actor[i].shootzvel) zvel = actor[i].shootzvel;
zvel = A_GetShootZvel(i, zvel);
j = A_InsertSprite(sect, j = A_InsertSprite(sect,
srcvect.x+(sintable[(512+sa+512)&2047]>>12), srcvect.x+(sintable[(512+sa+512)&2047]>>12),
srcvect.y+(sintable[(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].cstat = 128;
sprite[j].clipdist = 32; sprite[j].clipdist = 32;
return j; return j;
} }
} }
return -1; return -1;
} }

View file

@ -332,8 +332,15 @@ extern int32_t lastvisinc;
extern int32_t mouseyaxismode; extern int32_t mouseyaxismode;
extern int32_t ticrandomseed; 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_GetHitscanRange(int32_t i);
int32_t A_Shoot(int32_t i,int32_t atwith);
void getinput(int32_t snum); void getinput(int32_t snum);
void P_AddAmmo(int32_t weapon,DukePlayer_t *p,int32_t amount); void P_AddAmmo(int32_t weapon,DukePlayer_t *p,int32_t amount);
void P_AddWeapon(DukePlayer_t *p,int32_t weapon); void P_AddWeapon(DukePlayer_t *p,int32_t weapon);