SERVER/CLIENT: Draw Power-Ups in CSQC; add custom EF_ROTATE implementation

This commit is contained in:
cypress 2024-05-15 19:17:45 -07:00
parent 30f01b2e12
commit 61aaa52d0d
2 changed files with 129 additions and 1 deletions

View file

@ -186,6 +186,66 @@ vector dampening_factor;
float vaccel;
float vzaccel;
// FIXME: Move Power-Up CSQC drawing to separate file :)
float mdlflag_poweruprotate_duration;
float mdlflag_poweruprotate_starttime;
vector mdlflag_poweruprotate_startangles;
vector mdlflag_poweruprotate_differenceangles;
vector mdlflag_poweruprotate_currentangles;
float last_puframetime;
void() PU_UpdateAngles =
{
// Don't update more than once per frame.
if (last_puframetime != frametime) {
// New cycle, dictate new rotation time and target angle.
if (mdlflag_poweruprotate_duration <= time) {
mdlflag_poweruprotate_starttime = time;
mdlflag_poweruprotate_duration = time + (random() * 25 + 25)/10; // Take between 2.5 and 5 seconds.
mdlflag_poweruprotate_startangles[0] = mdlflag_poweruprotate_currentangles[0];
mdlflag_poweruprotate_startangles[1] = mdlflag_poweruprotate_currentangles[1];
mdlflag_poweruprotate_startangles[2] = mdlflag_poweruprotate_currentangles[2];
float target_pitch = (random() * 120) - 60;
float target_yaw = (random() * 240) + 60;
float target_roll = (random() * 90) - 45;
vector target_angles;
target_angles[0] = target_pitch;
target_angles[1] = target_yaw;
target_angles[2] = target_roll;
// Calculate the difference from our start to our target.
for(float i = 0; i < 2; i++) {
if (mdlflag_poweruprotate_currentangles[i] > target_angles[i])
mdlflag_poweruprotate_differenceangles[i] = (mdlflag_poweruprotate_currentangles[i] - target_angles[i]) * -1;
else
mdlflag_poweruprotate_differenceangles[i] = fabs(mdlflag_poweruprotate_currentangles[i] - target_angles[i]);
}
}
float percentage_complete = (time - mdlflag_poweruprotate_starttime) / (mdlflag_poweruprotate_duration - mdlflag_poweruprotate_starttime);
for(float j = 0; j < 2; j++) {
mdlflag_poweruprotate_currentangles[j] = mdlflag_poweruprotate_startangles[j] + (mdlflag_poweruprotate_differenceangles[j] * percentage_complete);
}
last_puframetime = frametime;
}
};
float() PU_PreDraw =
{
PU_UpdateAngles();
self.angles = mdlflag_poweruprotate_currentangles;
addentity(self);
return PREDRAW_NEXT;
};
float Player_PreDraw() =
{
self.lerpfrac -= frametime*10;
@ -257,6 +317,7 @@ noref void(float isnew) CSQC_Ent_Update =
{
float ent_type = readbyte();
// Player
if (ent_type == 1) {
if (isnew == TRUE) {
self.classname = "player";
@ -304,7 +365,24 @@ noref void(float isnew) CSQC_Ent_Update =
} else {
setsize(self, PLAYER_MINS_QUAKE, PLAYER_MAXS_QUAKE);
}
} else {
}
// Power-Up
else if (ent_type == 2) {
if (isnew == TRUE) {
self.classname = "item_powerup";
self.solid = SOLID_NOT;
self.predraw = PU_PreDraw;
self.drawmask = MASK_ENGINE;
}
self.origin_x = readcoord();
self.origin_y = readcoord();
self.origin_z = readcoord();
self.modelindex = readshort();
setmodelindex(self, self.modelindex);
}
else {
if(isnew)
addentity(self);
}

View file

@ -66,6 +66,14 @@ inline void(entity ent) PU_FreeEnt =
ent.frame = 0;
ent.scale = 1;
ent.effects = 0;
#ifdef FTE
ent.SendEntity = __NULL__;
ent.SendFlags = 0;
#endif // FTE
};
//
@ -627,6 +635,14 @@ void() PU_Flash =
self.hitcount++;
#ifdef FTE
// Update the drawing of the Power-Up in CSQC to
// register the flash.
self.SendFlags = 1;
#endif // FTE
// Too late, free the Power-Up
if (self.hitcount >= 40) {
Light_None(self);
@ -660,6 +676,14 @@ void() PU_Touch =
self.think = PU_PlayVO;
self.nextthink = time + 1;
#ifdef FTE
// Update the drawing of the Power-Up in CSQC to
// register the flash.
self.SendFlags = 1;
#endif // FTE
// Free the Power-Up sparkle, slight cleanup
PU_FreeEnt(self.owner);
setmodel(self, "");
@ -696,6 +720,23 @@ void() PU_SparkleThink =
}
};
#ifdef FTE
//
// PU_SendEntity(ePVent, flChanged)
// Sends ourself to CSQC for rendering.
//
float PU_SendEntity( entity ePVEnt, float flChanged ) {
WriteByte( MSG_ENTITY, 2 );
WriteCoord( MSG_ENTITY, self.origin_x ); // Position X
WriteCoord( MSG_ENTITY, self.origin_y ); // Position Y
WriteCoord( MSG_ENTITY, self.origin_z ); // Position Z
WriteShort( MSG_ENTITY, self.modelindex ); // Power-Up Model
return TRUE;
};
#endif // FTE
//
// Spawn_Powerup(where, type)
// Power-Up spawning function. Use type to force what spawns.
@ -777,6 +818,15 @@ void(vector where, float type) Spawn_Powerup =
// Finally assign collision function
powerup.touch = PU_Touch;
// We draw the Power-Up in CSQC on FTE to employ our custom EF_ROTATE
// implementation.
#ifdef FTE
powerup.SendEntity = PU_SendEntity;
powerup.SendFlags = 1;
#endif // FTE
totalpowerups++;
};