Support for getting correct light-level for waypoints. Thanks to Immortal_BLG for light-level calculation code.
This commit is contained in:
parent
7b3b80354d
commit
7ebf1b6ef4
10 changed files with 500 additions and 17 deletions
|
|
@ -361,6 +361,20 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SimpleColor final : private NonCopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int red, green, blue;
|
||||||
|
|
||||||
|
inline void reset (void) {
|
||||||
|
red = green = blue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const int avg (void) const {
|
||||||
|
return (red + green + blue) / (sizeof (SimpleColor) / sizeof (int));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class Vector final {
|
class Vector final {
|
||||||
public:
|
public:
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
|
|
@ -380,15 +394,15 @@ public:
|
||||||
return &x;
|
return &x;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Vector operator+ (const Vector &right) const {
|
inline const Vector operator + (const Vector &right) const {
|
||||||
return Vector (x + right.x, y + right.y, z + right.z);
|
return Vector (x + right.x, y + right.y, z + right.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Vector operator- (const Vector &right) const {
|
inline const Vector operator - (const Vector &right) const {
|
||||||
return Vector (x - right.x, y - right.y, z - right.z);
|
return Vector (x - right.x, y - right.y, z - right.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Vector operator- (void) const {
|
inline const Vector operator - (void) const {
|
||||||
return Vector (-x, -y, -z);
|
return Vector (-x, -y, -z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -396,26 +410,26 @@ public:
|
||||||
return Vector (right.x * vec, right.y * vec, right.z * vec);
|
return Vector (right.x * vec, right.y * vec, right.z * vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Vector operator* (float vec) const {
|
inline const Vector operator * (float vec) const {
|
||||||
return Vector (vec * x, vec * y, vec * z);
|
return Vector (vec * x, vec * y, vec * z);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Vector operator/ (float vec) const {
|
inline const Vector operator / (float vec) const {
|
||||||
const float inv = 1 / vec;
|
const float inv = 1 / vec;
|
||||||
return Vector (inv * x, inv * y, inv * z);
|
return Vector (inv * x, inv * y, inv * z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cross product
|
// cross product
|
||||||
inline const Vector operator^ (const Vector &right) const {
|
inline const Vector operator ^ (const Vector &right) const {
|
||||||
return Vector (y * right.z - z * right.y, z * right.x - x * right.z, x * right.y - y * right.x);
|
return Vector (y * right.z - z * right.y, z * right.x - x * right.z, x * right.y - y * right.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dot product
|
// dot product
|
||||||
inline float operator| (const Vector &right) const {
|
inline float operator | (const Vector &right) const {
|
||||||
return x * right.x + y * right.y + z * right.z;
|
return x * right.x + y * right.y + z * right.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Vector &operator+= (const Vector &right) {
|
inline const Vector &operator += (const Vector &right) {
|
||||||
x += right.x;
|
x += right.x;
|
||||||
y += right.y;
|
y += right.y;
|
||||||
z += right.z;
|
z += right.z;
|
||||||
|
|
@ -423,7 +437,7 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Vector &operator-= (const Vector &right) {
|
inline const Vector &operator -= (const Vector &right) {
|
||||||
x -= right.x;
|
x -= right.x;
|
||||||
y -= right.y;
|
y -= right.y;
|
||||||
z -= right.z;
|
z -= right.z;
|
||||||
|
|
@ -431,7 +445,7 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Vector &operator*= (float vec) {
|
inline const Vector &operator *= (float vec) {
|
||||||
x *= vec;
|
x *= vec;
|
||||||
y *= vec;
|
y *= vec;
|
||||||
z *= vec;
|
z *= vec;
|
||||||
|
|
@ -439,7 +453,7 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Vector &operator/= (float vec) {
|
inline const Vector &operator /= (float vec) {
|
||||||
const float inv = 1 / vec;
|
const float inv = 1 / vec;
|
||||||
|
|
||||||
x *= inv;
|
x *= inv;
|
||||||
|
|
@ -449,15 +463,15 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator== (const Vector &right) const {
|
inline bool operator == (const Vector &right) const {
|
||||||
return fequal (x, right.x) && fequal (y, right.y) && fequal (z, right.z);
|
return fequal (x, right.x) && fequal (y, right.y) && fequal (z, right.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator!= (const Vector &right) const {
|
inline bool operator != (const Vector &right) const {
|
||||||
return !fequal (x, right.x) && !fequal (y, right.y) && !fequal (z, right.z);
|
return !fequal (x, right.x) && !fequal (y, right.y) && !fequal (z, right.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Vector &operator= (const Vector &right) {
|
inline const Vector &operator = (const Vector &right) {
|
||||||
x = right.x;
|
x = right.x;
|
||||||
y = right.y;
|
y = right.y;
|
||||||
z = right.z;
|
z = right.z;
|
||||||
|
|
|
||||||
|
|
@ -395,3 +395,43 @@ public:
|
||||||
return cr::clamp <short> (static_cast <short> (value * scale), -32767, 32767);
|
return cr::clamp <short> (static_cast <short> (value * scale), -32767, 32767);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LightMeasure final : public Singleton <LightMeasure> {
|
||||||
|
private:
|
||||||
|
lightstyle_t m_lightstyle[MAX_LIGHTSTYLES];
|
||||||
|
int m_lightstyleValue[MAX_LIGHTSTYLEVALUE];
|
||||||
|
bool m_doAnimation;
|
||||||
|
|
||||||
|
SimpleColor m_point;
|
||||||
|
model_t *m_worldModel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LightMeasure (void) : m_worldModel (nullptr), m_doAnimation (false) {
|
||||||
|
initializeLightstyles ();
|
||||||
|
m_point.reset ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
void initializeLightstyles (void);
|
||||||
|
void animateLight (void);
|
||||||
|
|
||||||
|
bool recursiveLightPoint (const mnode_t *node, const Vector &start, const Vector &end);
|
||||||
|
float getLightLevel (const Vector &point);
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline void resetWorldModel (void) {
|
||||||
|
m_worldModel = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setWorldModel (model_t *model) {
|
||||||
|
if (m_worldModel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_worldModel = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void enableAnimation (bool enable) {
|
||||||
|
m_doAnimation = enable;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -61,6 +61,7 @@ using namespace cr::types;
|
||||||
|
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "progdefs.h"
|
#include "progdefs.h"
|
||||||
|
#include "model.h"
|
||||||
|
|
||||||
#define MAX_ENT_LEAFS 48
|
#define MAX_ENT_LEAFS 48
|
||||||
|
|
||||||
|
|
|
||||||
218
include/engine/model.h
Normal file
218
include/engine/model.h
Normal file
|
|
@ -0,0 +1,218 @@
|
||||||
|
/***
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999-2005, Valve Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* This product contains software technology licensed from Id
|
||||||
|
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This source code contains proprietary and confidential information of
|
||||||
|
* Valve LLC and its suppliers. Access to this code is restricted to
|
||||||
|
* persons who have executed a written SDK license with Valve. Any access,
|
||||||
|
* use or distribution of this code by or to any unlicensed person is illegal.
|
||||||
|
*
|
||||||
|
****/
|
||||||
|
|
||||||
|
// stripped down version of com_model.h & pm_info.h
|
||||||
|
|
||||||
|
#ifndef MODEL_H
|
||||||
|
#define MODEL_H
|
||||||
|
|
||||||
|
typedef vec_t vec2_t[2];
|
||||||
|
typedef vec_t vec4_t[4];
|
||||||
|
|
||||||
|
typedef int qboolean;
|
||||||
|
typedef unsigned char byte;
|
||||||
|
|
||||||
|
#define VERTEXSIZE 7
|
||||||
|
#define MAXLIGHTMAPS 4
|
||||||
|
#define NUM_AMBIENTS 4
|
||||||
|
#define MAX_MAP_HULLS 4
|
||||||
|
#define MAX_PHYSINFO_STRING 256
|
||||||
|
#define MAX_PHYSENTS 600
|
||||||
|
#define MAX_MOVEENTS 64
|
||||||
|
#define MAX_LIGHTSTYLES 64
|
||||||
|
#define MAX_LIGHTSTYLEVALUE 256
|
||||||
|
#define SURF_DRAWTILED 0x20
|
||||||
|
|
||||||
|
typedef struct mplane_s {
|
||||||
|
vec3_t normal;
|
||||||
|
float dist;
|
||||||
|
byte type; // for fast side tests
|
||||||
|
byte signbits; // signx + (signy<<1) + (signz<<1)
|
||||||
|
byte pad[2];
|
||||||
|
} mplane_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
vec3_t position;
|
||||||
|
} mvertex_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float vecs[2][4]; // [s/t] unit vectors in world space [i][3] is the s/t offset relative to the origin s or t = dot( 3Dpoint, vecs[i] ) + vecs[i][3]
|
||||||
|
float mipadjust; // mipmap limits for very small surfaces
|
||||||
|
struct texture_t* texture;
|
||||||
|
int flags; // sky or slime, no lightmap or 256 subdivision
|
||||||
|
} mtexinfo_t;
|
||||||
|
|
||||||
|
typedef struct mnode_s {
|
||||||
|
int contents; // 0, to differentiate from leafs
|
||||||
|
int visframe; // node needs to be traversed if current
|
||||||
|
float minmaxs[6]; // for bounding box culling
|
||||||
|
struct mnode_s* parent;
|
||||||
|
mplane_t* plane;
|
||||||
|
struct mnode_s* children[2];
|
||||||
|
unsigned short firstsurface;
|
||||||
|
unsigned short numsurfaces;
|
||||||
|
} mnode_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
byte r, g, b;
|
||||||
|
} color24;
|
||||||
|
|
||||||
|
typedef struct msurface_s {
|
||||||
|
int visframe; // should be drawn when node is crossed
|
||||||
|
mplane_t* plane; // pointer to shared plane
|
||||||
|
int flags; // see SURF_ #defines
|
||||||
|
int firstedge; // look up in model->surfedges[], negative numbers
|
||||||
|
int numedges; // are backwards edges
|
||||||
|
short texturemins[2];
|
||||||
|
short extents[2];
|
||||||
|
int light_s, light_t; // gl lightmap coordinates
|
||||||
|
struct glpoly_t* polys; // multiple if warped
|
||||||
|
struct msurface_s* texturechain;
|
||||||
|
mtexinfo_t* texinfo;
|
||||||
|
int dlightframe; // last frame the surface was checked by an animated light
|
||||||
|
int dlightbits; // dynamically generated. Indicates if the surface illumination is modified by an animated light.
|
||||||
|
int lightmaptexturenum;
|
||||||
|
byte styles[MAXLIGHTMAPS];
|
||||||
|
int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap
|
||||||
|
msurface_s* lightmapchain; // for new dlights rendering (was cached_dlight)
|
||||||
|
color24* samples; // note: this is the actual lightmap data for this surface
|
||||||
|
struct decal_t* pdecals;
|
||||||
|
} msurface_t;
|
||||||
|
|
||||||
|
typedef struct cache_user_s {
|
||||||
|
void* data; // extradata
|
||||||
|
} cache_user_t;
|
||||||
|
|
||||||
|
typedef struct hull_s {
|
||||||
|
struct dclipnode_t* clipnodes;
|
||||||
|
mplane_t* planes;
|
||||||
|
int firstclipnode;
|
||||||
|
int lastclipnode;
|
||||||
|
vec3_t clip_mins;
|
||||||
|
vec3_t clip_maxs;
|
||||||
|
} hull_t;
|
||||||
|
|
||||||
|
typedef struct model_s {
|
||||||
|
char name[64]; // model name
|
||||||
|
qboolean needload; // bmodels and sprites don't cache normally
|
||||||
|
int type; // model type
|
||||||
|
int numframes; // sprite's framecount
|
||||||
|
byte* mempool; // private mempool (was synctype)
|
||||||
|
int flags; // hl compatibility
|
||||||
|
vec3_t mins, maxs; // bounding box at angles '0 0 0'
|
||||||
|
float radius;
|
||||||
|
int firstmodelsurface;
|
||||||
|
int nummodelsurfaces;
|
||||||
|
int numsubmodels;
|
||||||
|
struct dmodel_t* submodels; // or studio animations
|
||||||
|
int numplanes;
|
||||||
|
mplane_t* planes;
|
||||||
|
int numleafs; // number of visible leafs, not counting 0
|
||||||
|
struct mleaf_t* leafs;
|
||||||
|
int numvertexes;
|
||||||
|
mvertex_t* vertexes;
|
||||||
|
int numedges;
|
||||||
|
struct medge_t* edges;
|
||||||
|
int numnodes;
|
||||||
|
mnode_t* nodes;
|
||||||
|
int numtexinfo;
|
||||||
|
mtexinfo_t* texinfo;
|
||||||
|
int numsurfaces;
|
||||||
|
msurface_t* surfaces;
|
||||||
|
int numsurfedges;
|
||||||
|
int* surfedges;
|
||||||
|
int numclipnodes;
|
||||||
|
struct dclipnode_t* clipnodes;
|
||||||
|
int nummarksurfaces;
|
||||||
|
msurface_t** marksurfaces;
|
||||||
|
hull_t hulls[MAX_MAP_HULLS];
|
||||||
|
int numtextures;
|
||||||
|
texture_t** textures;
|
||||||
|
byte* visdata;
|
||||||
|
color24* lightdata;
|
||||||
|
char* entities;
|
||||||
|
cache_user_t cache; // only access through Mod_Extradata
|
||||||
|
} model_t;
|
||||||
|
|
||||||
|
struct lightstyle_t {
|
||||||
|
int length;
|
||||||
|
char map[MAX_LIGHTSTYLES];
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct physent_s {
|
||||||
|
char name[32]; // name of model, or "player" or "world".
|
||||||
|
int player;
|
||||||
|
vec3_t origin; // model's origin in world coordinates.
|
||||||
|
struct model_s* model; // only for bsp models
|
||||||
|
} physent_t;
|
||||||
|
|
||||||
|
typedef struct playermove_s {
|
||||||
|
int player_index; // So we don't try to run the PM_CheckStuck nudging too quickly.
|
||||||
|
qboolean server; // For debugging, are we running physics code on server side?
|
||||||
|
qboolean multiplayer; // 1 == multiplayer server
|
||||||
|
float time; // realtime on host, for reckoning duck timing
|
||||||
|
float frametime; // Duration of this frame
|
||||||
|
vec3_t forward, right, up; // Vectors for angles
|
||||||
|
vec3_t origin; // Movement origin.
|
||||||
|
vec3_t angles; // Movement view angles.
|
||||||
|
vec3_t oldangles; // Angles before movement view angles were looked at.
|
||||||
|
vec3_t velocity; // Current movement direction.
|
||||||
|
vec3_t movedir; // For waterjumping, a forced forward velocity so we can fly over lip of ledge.
|
||||||
|
vec3_t basevelocity; // Velocity of the conveyor we are standing, e.g.
|
||||||
|
vec3_t view_ofs; // Our eye position.
|
||||||
|
float flDuckTime; // Time we started duck
|
||||||
|
qboolean bInDuck; // In process of ducking or ducked already?
|
||||||
|
int flTimeStepSound; // Next time we can play a step sound
|
||||||
|
int iStepLeft;
|
||||||
|
float flFallVelocity;
|
||||||
|
vec3_t punchangle;
|
||||||
|
float flSwimTime;
|
||||||
|
float flNextPrimaryAttack;
|
||||||
|
int effects; // MUZZLE FLASH, e.g.
|
||||||
|
int flags; // FL_ONGROUND, FL_DUCKING, etc.
|
||||||
|
int usehull; // 0 = regular player hull, 1 = ducked player hull, 2 = point hull
|
||||||
|
float gravity; // Our current gravity and friction.
|
||||||
|
float friction;
|
||||||
|
int oldbuttons; // Buttons last usercmd
|
||||||
|
float waterjumptime; // Amount of time left in jumping out of water cycle.
|
||||||
|
qboolean dead; // Are we a dead player?
|
||||||
|
int deadflag;
|
||||||
|
int spectator; // Should we use spectator physics model?
|
||||||
|
int movetype; // Our movement type, NOCLIP, WALK, FLY
|
||||||
|
int onground;
|
||||||
|
int waterlevel;
|
||||||
|
int watertype;
|
||||||
|
int oldwaterlevel;
|
||||||
|
char sztexturename[256];
|
||||||
|
char chtexturetype;
|
||||||
|
float maxspeed;
|
||||||
|
float clientmaxspeed; // Player specific maxspeed
|
||||||
|
int iuser1;
|
||||||
|
int iuser2;
|
||||||
|
int iuser3;
|
||||||
|
int iuser4;
|
||||||
|
float fuser1;
|
||||||
|
float fuser2;
|
||||||
|
float fuser3;
|
||||||
|
float fuser4;
|
||||||
|
vec3_t vuser1;
|
||||||
|
vec3_t vuser2;
|
||||||
|
vec3_t vuser3;
|
||||||
|
vec3_t vuser4;
|
||||||
|
int numphysent;
|
||||||
|
physent_t physents[MAX_PHYSENTS];
|
||||||
|
} playermove_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1431,6 +1431,7 @@ private:
|
||||||
float m_pathDisplayTime;
|
float m_pathDisplayTime;
|
||||||
float m_arrowDisplayTime;
|
float m_arrowDisplayTime;
|
||||||
float m_waypointDisplayTime[MAX_WAYPOINTS];
|
float m_waypointDisplayTime[MAX_WAYPOINTS];
|
||||||
|
float m_waypointLightLevel[MAX_WAYPOINTS];
|
||||||
int m_findWPIndex;
|
int m_findWPIndex;
|
||||||
int m_facingAtIndex;
|
int m_facingAtIndex;
|
||||||
char m_infoBuffer[MAX_PRINT_BUFFER];
|
char m_infoBuffer[MAX_PRINT_BUFFER];
|
||||||
|
|
@ -1458,6 +1459,7 @@ public:
|
||||||
void initExperience (void);
|
void initExperience (void);
|
||||||
void initVisibility (void);
|
void initVisibility (void);
|
||||||
void initTypes (void);
|
void initTypes (void);
|
||||||
|
void initLightLevels (void);
|
||||||
|
|
||||||
void addPath (int addIndex, int pathIndex, float distance);
|
void addPath (int addIndex, int pathIndex, float distance);
|
||||||
|
|
||||||
|
|
@ -1544,6 +1546,11 @@ public:
|
||||||
return m_numWaypoints;
|
return m_numWaypoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get the light level of waypoint
|
||||||
|
inline float getLightLevel (int id) const {
|
||||||
|
return m_waypointLightLevel[id];
|
||||||
|
}
|
||||||
|
|
||||||
// free's socket handle
|
// free's socket handle
|
||||||
void closeSocket (int sock);
|
void closeSocket (int sock);
|
||||||
|
|
||||||
|
|
@ -1567,6 +1574,7 @@ static auto &waypoints = Waypoint::ref ();
|
||||||
static auto &bots = BotManager::ref ();
|
static auto &bots = BotManager::ref ();
|
||||||
static auto &engine = Engine::ref ();
|
static auto &engine = Engine::ref ();
|
||||||
static auto &rng = RandomSequence::ref ();
|
static auto &rng = RandomSequence::ref ();
|
||||||
|
static auto &illum = LightMeasure::ref ();
|
||||||
|
|
||||||
// prototypes of bot functions...
|
// prototypes of bot functions...
|
||||||
extern int getWeaponData (bool isString, const char *weaponAlias, int weaponIndex = -1);
|
extern int getWeaponData (bool isString, const char *weaponAlias, int weaponIndex = -1);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\include\compress.h" />
|
<ClInclude Include="..\include\compress.h" />
|
||||||
|
<ClInclude Include="..\include\engine\model.h" />
|
||||||
<ClInclude Include="..\include\yapb.h" />
|
<ClInclude Include="..\include\yapb.h" />
|
||||||
<ClInclude Include="..\include\corelib.h" />
|
<ClInclude Include="..\include\corelib.h" />
|
||||||
<ClInclude Include="..\include\engine.h" />
|
<ClInclude Include="..\include\engine.h" />
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,9 @@
|
||||||
<ClInclude Include="..\include\yapb.h">
|
<ClInclude Include="..\include\yapb.h">
|
||||||
<Filter>include</Filter>
|
<Filter>include</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\engine\model.h">
|
||||||
|
<Filter>include\engine</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\source\chatlib.cpp">
|
<ClCompile Include="..\source\chatlib.cpp">
|
||||||
|
|
|
||||||
|
|
@ -1103,3 +1103,145 @@ void Engine::processMessages (void *ptr) {
|
||||||
}
|
}
|
||||||
m_msgBlock.state++; // and finally update network message state
|
m_msgBlock.state++; // and finally update network message state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LightMeasure::initializeLightstyles (void) {
|
||||||
|
// this function initializes lighting information...
|
||||||
|
|
||||||
|
// reset all light styles
|
||||||
|
for (int i = 0; i < MAX_LIGHTSTYLES; i++) {
|
||||||
|
m_lightstyle[i].length = 0;
|
||||||
|
m_lightstyle[i].map[0] = 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_LIGHTSTYLEVALUE; i++) {
|
||||||
|
m_lightstyleValue[i] = 264;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LightMeasure::animateLight (void) {
|
||||||
|
// this function performs light animations
|
||||||
|
|
||||||
|
if (!m_doAnimation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'm' is normal light, 'a' is no light, 'z' is double bright
|
||||||
|
const int index = static_cast <int> (engine.timebase () * 10.0f);
|
||||||
|
|
||||||
|
for (int j = 0; j < MAX_LIGHTSTYLES; j++) {
|
||||||
|
if (!m_lightstyle[j].length) {
|
||||||
|
m_lightstyleValue[j] = 256;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int value = m_lightstyle[j].map[index % m_lightstyle[j].length] - 'a';
|
||||||
|
m_lightstyleValue[j] = value * 22;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool LightMeasure::recursiveLightPoint (const mnode_t *node, const Vector &start, const Vector &end) {
|
||||||
|
if (node->contents < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine which side of the node plane our points are on, fixme: optimize for axial
|
||||||
|
auto plane = node->plane;
|
||||||
|
|
||||||
|
float front = (start | plane->normal) - plane->dist;
|
||||||
|
float back = (end | plane->normal) - plane->dist;
|
||||||
|
|
||||||
|
int side = front < 0.0f;
|
||||||
|
|
||||||
|
// if they're both on the same side of the plane, don't bother to split just check the appropriate child
|
||||||
|
if ((back < 0.0f) == side) {
|
||||||
|
return recursiveLightPoint (node->children[side], start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate mid point
|
||||||
|
float frac = front / (front - back);
|
||||||
|
auto mid = start + (end - start) * frac;
|
||||||
|
|
||||||
|
// go down front side
|
||||||
|
if (recursiveLightPoint (node->children[side], start, mid)) {
|
||||||
|
return true; // hit something
|
||||||
|
}
|
||||||
|
|
||||||
|
// blow it off if it doesn't split the plane...
|
||||||
|
if ((back < 0.0f) == side) {
|
||||||
|
return false; // didn't hit anything
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for impact on this node
|
||||||
|
// lightspot = mid;
|
||||||
|
// lightplane = plane;
|
||||||
|
auto surf = reinterpret_cast <msurface_t *> (m_worldModel->surfaces) + node->firstsurface;
|
||||||
|
|
||||||
|
for (int i = 0; i < node->numsurfaces; i++, surf++) {
|
||||||
|
if (surf->flags & SURF_DRAWTILED) {
|
||||||
|
continue; // no lightmaps
|
||||||
|
}
|
||||||
|
auto tex = surf->texinfo;
|
||||||
|
|
||||||
|
// see where in lightmap space our intersection point is
|
||||||
|
int s = static_cast <int> ((mid | Vector (tex->vecs[0])) + tex->vecs[0][3]);
|
||||||
|
int t = static_cast <int> ((mid | Vector (tex->vecs[1])) + tex->vecs[1][3]);
|
||||||
|
|
||||||
|
// not in the bounds of our lightmap? punt...
|
||||||
|
if (s < surf->texturemins[0] || t < surf->texturemins[1]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assuming a square lightmap (fixme: which ain't always the case), lets see if it lies in that rectangle. if not, punt...
|
||||||
|
int ds = s - surf->texturemins[0];
|
||||||
|
int dt = t - surf->texturemins[1];
|
||||||
|
|
||||||
|
if (ds > surf->extents[0] || dt > surf->extents[1]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!surf->samples) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ds >>= 4;
|
||||||
|
dt >>= 4;
|
||||||
|
|
||||||
|
m_point.reset (); // reset point color.
|
||||||
|
|
||||||
|
int smax = (surf->extents[0] >> 4) + 1;
|
||||||
|
int tmax = (surf->extents[1] >> 4) + 1;
|
||||||
|
int size = smax * tmax;
|
||||||
|
|
||||||
|
auto lightmap = surf->samples + dt * smax + ds;
|
||||||
|
|
||||||
|
// compute the lightmap color at a particular point
|
||||||
|
for (int maps = 0u; maps < MAXLIGHTMAPS && surf->styles[maps] != 255u; ++maps) {
|
||||||
|
uint32 scale = m_lightstyleValue[surf->styles[maps]];
|
||||||
|
|
||||||
|
m_point.red += lightmap->r * scale;
|
||||||
|
m_point.green += lightmap->g * scale;
|
||||||
|
m_point.blue += lightmap->b * scale;
|
||||||
|
|
||||||
|
lightmap += size; // skip to next lightmap
|
||||||
|
}
|
||||||
|
m_point.red >>= 8u;
|
||||||
|
m_point.green >>= 8u;
|
||||||
|
m_point.blue >>= 8u;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return recursiveLightPoint (node->children[!side], mid, end); // go down back side
|
||||||
|
}
|
||||||
|
|
||||||
|
float LightMeasure::getLightLevel (const Vector &point) {
|
||||||
|
if (!m_worldModel) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_worldModel->lightdata) {
|
||||||
|
return 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector endPoint (point);
|
||||||
|
endPoint.z -= 2048.0f;
|
||||||
|
|
||||||
|
return recursiveLightPoint (m_worldModel->nodes, point, endPoint) == false ? 0.0f : 100 * cr::sqrtf (cr::min (75.0f, static_cast <float> (m_point.avg ())) / 75.0f);
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,7 @@ ConVar yb_version ("yb_version", PRODUCT_VERSION, VT_READONLY);
|
||||||
ConVar mp_startmoney ("mp_startmoney", nullptr, VT_NOREGISTER, true, "800");
|
ConVar mp_startmoney ("mp_startmoney", nullptr, VT_NOREGISTER, true, "800");
|
||||||
|
|
||||||
int handleBotCommands (edict_t *ent, const char *arg0, const char *arg1, const char *arg2, const char *arg3, const char *arg4, const char *arg5, const char *self) {
|
int handleBotCommands (edict_t *ent, const char *arg0, const char *arg1, const char *arg2, const char *arg3, const char *arg4, const char *arg5, const char *self) {
|
||||||
|
|
||||||
// adding one bot with random parameters to random team
|
// adding one bot with random parameters to random team
|
||||||
if (stricmp (arg0, "addbot") == 0 || stricmp (arg0, "add") == 0) {
|
if (stricmp (arg0, "addbot") == 0 || stricmp (arg0, "add") == 0) {
|
||||||
bots.addbot (arg4, arg1, arg2, arg3, arg5, true);
|
bots.addbot (arg4, arg1, arg2, arg3, arg5, true);
|
||||||
|
|
@ -352,6 +353,18 @@ int handleBotCommands (edict_t *ent, const char *arg0, const char *arg1, const c
|
||||||
waypoints.cachePoint ();
|
waypoints.cachePoint ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (stricmp (arg1, "glp") == 0) {
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < waypoints.length (); i++) {
|
||||||
|
|
||||||
|
|
||||||
|
engine.print ("%d - %f", i, waypoints.getLightLevel (i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// do a cleanup
|
// do a cleanup
|
||||||
else if (stricmp (arg1, "clean") == 0) {
|
else if (stricmp (arg1, "clean") == 0) {
|
||||||
if (!isEmptyStr (arg2)) {
|
if (!isEmptyStr (arg2)) {
|
||||||
|
|
@ -2097,6 +2110,9 @@ void ServerActivate (edict_t *pentEdictList, int edictCount, int clientMax) {
|
||||||
// do a level initialization
|
// do a level initialization
|
||||||
engine.levelInitialize ();
|
engine.levelInitialize ();
|
||||||
|
|
||||||
|
// update worldmodel
|
||||||
|
illum.resetWorldModel ();
|
||||||
|
|
||||||
// do level initialization stuff here...
|
// do level initialization stuff here...
|
||||||
waypoints.init ();
|
waypoints.init ();
|
||||||
waypoints.load ();
|
waypoints.load ();
|
||||||
|
|
@ -2139,6 +2155,9 @@ void ServerDeactivate (void) {
|
||||||
// set state to unprecached
|
// set state to unprecached
|
||||||
engine.setUnprecached ();
|
engine.setUnprecached ();
|
||||||
|
|
||||||
|
// enable lightstyle animations on level change
|
||||||
|
illum.enableAnimation (true);
|
||||||
|
|
||||||
// xash is not kicking fakeclients on changelevel
|
// xash is not kicking fakeclients on changelevel
|
||||||
if (g_gameFlags & GAME_XASH_ENGINE) {
|
if (g_gameFlags & GAME_XASH_ENGINE) {
|
||||||
bots.kickEveryone (true, false);
|
bots.kickEveryone (true, false);
|
||||||
|
|
@ -2164,6 +2183,9 @@ void StartFrame (void) {
|
||||||
// run periodic update of bot states
|
// run periodic update of bot states
|
||||||
bots.frame ();
|
bots.frame ();
|
||||||
|
|
||||||
|
// update lightstyle animations
|
||||||
|
illum.animateLight ();
|
||||||
|
|
||||||
// record some stats of all players on the server
|
// record some stats of all players on the server
|
||||||
for (int i = 0; i < engine.maxClients (); i++) {
|
for (int i = 0; i < engine.maxClients (); i++) {
|
||||||
edict_t *player = engine.entityOfIndex (i + 1);
|
edict_t *player = engine.entityOfIndex (i + 1);
|
||||||
|
|
@ -2229,6 +2251,9 @@ void StartFrame (void) {
|
||||||
}
|
}
|
||||||
bots.calculatePingOffsets ();
|
bots.calculatePingOffsets ();
|
||||||
|
|
||||||
|
// calculate light levels for all waypoints if needed
|
||||||
|
waypoints.initLightLevels ();
|
||||||
|
|
||||||
if (g_gameFlags & GAME_METAMOD) {
|
if (g_gameFlags & GAME_METAMOD) {
|
||||||
static auto dmActive = g_engfuncs.pfnCVarGetPointer ("csdm_active");
|
static auto dmActive = g_engfuncs.pfnCVarGetPointer ("csdm_active");
|
||||||
static auto freeForAll = g_engfuncs.pfnCVarGetPointer ("mp_freeforall");
|
static auto freeForAll = g_engfuncs.pfnCVarGetPointer ("mp_freeforall");
|
||||||
|
|
@ -2786,7 +2811,7 @@ typedef void (*entity_func_t) (entvars_t *);
|
||||||
gamedll_funcs_t gameDLLFunc;
|
gamedll_funcs_t gameDLLFunc;
|
||||||
|
|
||||||
SHARED_LIBRARAY_EXPORT int GetEntityAPI2 (gamefuncs_t *functionTable, int *) {
|
SHARED_LIBRARAY_EXPORT int GetEntityAPI2 (gamefuncs_t *functionTable, int *) {
|
||||||
// this function is called right after FuncPointers_t() by the engine in the game DLL (or
|
// this function is called right after GiveFnptrsToDll() by the engine in the game DLL (or
|
||||||
// what it BELIEVES to be the game DLL), in order to copy the list of MOD functions that can
|
// what it BELIEVES to be the game DLL), in order to copy the list of MOD functions that can
|
||||||
// be called by the engine, into a memory block pointed to by the functionTable pointer
|
// be called by the engine, into a memory block pointed to by the functionTable pointer
|
||||||
// that is passed into this function (explanation comes straight from botman). This allows
|
// that is passed into this function (explanation comes straight from botman). This allows
|
||||||
|
|
@ -2824,6 +2849,19 @@ SHARED_LIBRARAY_EXPORT int GetEntityAPI2 (gamefuncs_t *functionTable, int *) {
|
||||||
functionTable->pfnStartFrame = StartFrame;
|
functionTable->pfnStartFrame = StartFrame;
|
||||||
functionTable->pfnUpdateClientData = UpdateClientData;
|
functionTable->pfnUpdateClientData = UpdateClientData;
|
||||||
|
|
||||||
|
functionTable->pfnPM_Move = [] (playermove_t *playerMove, int server) {
|
||||||
|
// this is the player movement code clients run to predict things when the server can't update
|
||||||
|
// them often enough (or doesn't want to). The server runs exactly the same function for
|
||||||
|
// moving players. There is normally no distinction between them, else client-side prediction
|
||||||
|
// wouldn't work properly (and it doesn't work that well, already...)
|
||||||
|
|
||||||
|
illum.setWorldModel (playerMove->physents[0u].model);
|
||||||
|
|
||||||
|
if (g_gameFlags & GAME_METAMOD) {
|
||||||
|
RETURN_META (MRES_IGNORED);
|
||||||
|
}
|
||||||
|
g_functionTable.pfnPM_Move (playerMove, server);
|
||||||
|
};
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2861,7 +2899,7 @@ SHARED_LIBRARAY_EXPORT int GetNewDLLFunctions (newgamefuncs_t *functionTable, in
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!api_GetNewDLLFunctions (functionTable, interfaceVersion)) {
|
if (!api_GetNewDLLFunctions (functionTable, interfaceVersion)) {
|
||||||
logEntry (true, LL_FATAL, "GetNewDLLFunctions: ERROR - Not Initialized.");
|
logEntry (true, LL_ERROR, "GetNewDLLFunctions: ERROR - Not Initialized.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1367,6 +1367,22 @@ void Waypoint::initVisibility (void) {
|
||||||
fp.close ();
|
fp.close ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Waypoint::initLightLevels (void) {
|
||||||
|
// this function get's the light level for each waypoin on the map
|
||||||
|
|
||||||
|
// no waypoints ? no light levels, and only one-time init
|
||||||
|
if (!m_numWaypoints || !cr::fzero (m_waypointLightLevel[0])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
engine.print ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1");
|
||||||
|
// update light levels for all waypoints
|
||||||
|
for (int i = 0; i < m_numWaypoints; i++) {
|
||||||
|
m_waypointLightLevel[i] = illum.getLightLevel (m_paths[i]->origin);
|
||||||
|
}
|
||||||
|
// disable lightstyle animations on finish (will be auto-enabled on mapchange)
|
||||||
|
illum.enableAnimation (false);
|
||||||
|
}
|
||||||
|
|
||||||
void Waypoint::initTypes (void) {
|
void Waypoint::initTypes (void) {
|
||||||
m_terrorPoints.clear ();
|
m_terrorPoints.clear ();
|
||||||
m_ctPoints.clear ();
|
m_ctPoints.clear ();
|
||||||
|
|
@ -1506,7 +1522,8 @@ bool Waypoint::load (void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < m_numWaypoints; i++) {
|
for (int i = 0; i < m_numWaypoints; i++) {
|
||||||
m_waypointDisplayTime[i] = 0.0;
|
m_waypointDisplayTime[i] = 0.0f;
|
||||||
|
m_waypointLightLevel[i] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
initPathMatrix ();
|
initPathMatrix ();
|
||||||
|
|
@ -2679,6 +2696,7 @@ Waypoint::Waypoint (void) {
|
||||||
|
|
||||||
memset (m_visLUT, 0, sizeof (m_visLUT));
|
memset (m_visLUT, 0, sizeof (m_visLUT));
|
||||||
memset (m_waypointDisplayTime, 0, sizeof (m_waypointDisplayTime));
|
memset (m_waypointDisplayTime, 0, sizeof (m_waypointDisplayTime));
|
||||||
|
memset (m_waypointLightLevel, 0, sizeof (m_waypointLightLevel));
|
||||||
memset (m_infoBuffer, 0, sizeof (m_infoBuffer));
|
memset (m_infoBuffer, 0, sizeof (m_infoBuffer));
|
||||||
|
|
||||||
m_waypointPaths = false;
|
m_waypointPaths = false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue