GithubHelp home page GithubHelp logo

snmetamorph / primext Goto Github PK

View Code? Open in Web Editor NEW
107.0 11.0 31.0 18.89 MB

Modern Half-Life 1 SDK for Xash3D FWGS engine, has enhanced graphics and physics and a lot of new features for mod-makers. Crossplatform, supports Windows/Linux. Based on XashXT and Spirit Of Half-Life.

Home Page: https://snmetamorph.github.io/PrimeXT/

C++ 88.15% C 9.56% GLSL 1.33% CMake 0.92% Python 0.01% Java 0.02%
xash3d half-life hlsdk physx opengl goldsrc modding docusaurus cmake cross-platform

primext's Introduction

SNMetamorph's github stats

primext's People

Contributors

a1batross avatar apamk2 avatar dependabot[bot] avatar mittorn avatar ncuxonat avatar nekonomicon avatar nillerusr avatar sanyasho avatar snmetamorph avatar velaron avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

primext's Issues

Improper scaling of env_static (with fix)

Some env_static models occasionaly have incorrect mesh scaling in-game, while the collision remains correct.
FIX:
delta.lst file, line: entity_state_t gamedll Entity_Encode
In here, replace in the lines startpos [0,1,2] the number 8.0 to 1024.0.

DEFINE_DELTA( startpos[0], DT_SIGNED | DT_FLOAT, 16, 1024.0 ),
DEFINE_DELTA( startpos[1], DT_SIGNED | DT_FLOAT, 16, 1024.0 ),
DEFINE_DELTA( startpos[2], DT_SIGNED | DT_FLOAT, 16, 1024.0 ),

FOV не сбрасывается, если сохраниться в зуме и загрузить другую игру

player.cpp, CBasePlayer :: UpdateClientData
Перед условием
if ( m_iFOV != m_iClientFOV )
Поставить новое условие:

if( m_iFOV == 0 )
		m_iFOV = CVAR_GET_FLOAT("default_fov");

Дополнительно предлагаю добавить еще и такое условие, нужно его ставить еще выше, над новым условием:

if( CVAR_GET_FLOAT("default_fov") <= 0 )
	{
		ALERT(at_error, "default_fov should be above zero!\n");
		CVAR_SET_FLOAT( "default_fov", 90 );
	}

UPD: выяснился баг! Dedicated server начинает спамить что квар default fov не найден, поэтому лучше сделать все вот так:

if ( !IS_DEDICATED_SERVER() )
{
	if (CVAR_GET_FLOAT("default_fov") <= 0)
	{
		ALERT(at_error, "default_fov should be above zero!\n");
		CVAR_SET_FLOAT("default_fov", 85);
	}
	if (m_iFOV == 0)
		m_iFOV = CVAR_GET_FLOAT("default_fov");
}

Slow turning of monsters if the fps value is too high (with FIX)

monsters.cpp: replace float CBaseMonster::ChangeYaw ( int yawSpeed ) function with this new code:

float CBaseMonster::ChangeYaw ( int yawSpeed )
{
    float    ideal, current, move, speed;
    Vector    angles = GetAbsAngles();

    current = UTIL_AngleMod( angles.y );
    ideal = pev->ideal_yaw;
    if (current != ideal)
    {
        float delta = gpGlobals->time - m_flLastYawTime;
        move = ideal - current;
        if( delta > 0.25 )
            delta = 0.25;
        speed = yawSpeed * delta * 2;

        const float originalSpeed = ( float ) yawSpeed * gpGlobals->frametime * 10;

        const float multiplier = originalSpeed / ( yawSpeed * delta );
        if (ideal > current)
        {
            if (move >= 180)
                move = move - 360;
        }
        else
        {
            if (move <= -180)
                move = move + 360;
        }

        if (move > 0)
        {// turning to the monster's left
            if (move > speed)
                move = speed;
        }
        else
        {// turning to the monster's right
            if (move < -speed)
                move = -speed;
        }
      
        angles.y = UTIL_AngleMod (current + move);

        // turn head in desired direction only if they have a turnable head
        if (m_afCapability & bits_CAP_TURN_HEAD)
        {
            float yaw = pev->ideal_yaw - angles.y;
            if (yaw > 180) yaw -= 360;
            if (yaw < -180) yaw += 360;
            // yaw *= 0.8;
            SetBoneController( 0, yaw );
        }

        SetAbsAngles( angles );
    }
    else
        move = 0;
        m_flLastYawTime = gpGlobals->time;
    return move;
}

Then, add DEFINE_FIELD( m_flLastYawTime, FIELD_TIME ),
into BEGIN_DATADESC( CBaseMonster )

Then, in the basemonster.h add float m_flLastYawTime;
into public section of class CBaseMonster : public CBaseToggle

That should be all.

Не работает ентитя 3d_sky

В ванильном ксаше присутствует ентитя 3d_sky. В прайме есть ентитя которая позволяет сделать 3д скайбокс (envpos_sky), но он морально устарел и лишен всей функциональности, так как перенесен вообще с первой паранои. Отличия очень сильно влияют на визуальную составляющую.

Для теста взята одна идентичная карта и произведен тест на двух версиях.

Пример из ксаш мода :
https://www.youtube.com/watch?v=1CERomac4Lo

На данной карте, в 3д скайбоксе, стоят модели (env_model), возле них стоят дополнительные источники света . В центре стоит цитадель (env_static), вокруг которой стоят источники света (красные), и внизу брашевый пол. Как видно, свет работает, тени работают, браши работают.

И вот пример из второй паранои, где как раз старая версия скайбокса:
https://www.youtube.com/watch?v=UYsoHzinZuU

Тут можно увидеть, что старая версия скайбокса, полностью игнорирует env_static, не считает тени, env_model дополнительные источники света игнорируют и в целом неверно просчитали свет от солнца, так же браши отсутствуют.

Дополнительно: В ванильном ксаше можно включать и выключать тот или иной скайбокс, старая версия скайбокса из п2 это не позволяет

monster_human_grunt: broken weapon system (with FIX, but without compatibility with Half-Life)

Currently, soldiers are trying to spawn with all weapons at once. The weapons field doesn't read bits correctly because in Xash there's no more pev->weapons. Can be fixed adding new field in the entity. Unfortunately, compatibility with HL will be lost, but the soldier will be choosing their equipment randomly if it's not set, which is good I think.
FIX:
Add:
string_t wpns; and void KeyValue( KeyValueData *pkvd );
into class CHGrunt

Add:
DEFINE_KEYFIELD( wpns, FIELD_STRING, "wpns" ),
into BEGIN_DATADESC( CHGrunt )

Add new function:

void CHGrunt::KeyValue( KeyValueData *pkvd )
{
	if( FStrEq( pkvd->szKeyName, "wpns" ))
	{
		wpns = ALLOC_STRING( pkvd->szValue );
		pkvd->fHandled = TRUE;
	}
	else
		CBaseMonster::KeyValue(pkvd);
}

Next, in the CHGrunt :: Spawn(), replace:

if (!m_bHaveWeapons)
{
     AddWeapon(HGRUNT_9MMAR);
     AddWeapon(HGRUNT_HANDGRENADE);
}

to this:

if (FStrEq( STRING(wpns), "9mmar" ))
	{
		AddWeapon(HGRUNT_9MMAR);
	}
	else if (FStrEq( STRING(wpns), "9mmar_hg" ))
	{
		AddWeapon(HGRUNT_9MMAR);
		AddWeapon(HGRUNT_HANDGRENADE);
	}
	else if (FStrEq( STRING(wpns), "9mmar_gl" ))
	{
		AddWeapon(HGRUNT_9MMAR);
		AddWeapon(HGRUNT_GRENADELAUNCHER);
	}
	else if (FStrEq( STRING(wpns), "shotgun" ))
	{
		AddWeapon(HGRUNT_SHOTGUN);
	}
	else if (FStrEq( STRING(wpns), "shotgun_hg" ))
	{
		AddWeapon(HGRUNT_SHOTGUN);
		AddWeapon(HGRUNT_HANDGRENADE);
	}
	else if ( FStringNull(wpns) )
	{
		switch( RANDOM_LONG( 0, 3 ))
		{
		case 0:
			AddWeapon(HGRUNT_9MMAR);
			AddWeapon(HGRUNT_HANDGRENADE);
			break;
		case 1:
			AddWeapon(HGRUNT_SHOTGUN);
			break;
		case 2:
			AddWeapon(HGRUNT_9MMAR);
			AddWeapon(HGRUNT_GRENADELAUNCHER);
			break;
		case 3:
			AddWeapon(HGRUNT_SHOTGUN);
			AddWeapon(HGRUNT_HANDGRENADE);
			break;
		}
	}

That should be all.

player_keycatcher не всегда активирует multi_manager

Некоторые кикатчеры могут без проблем напрямую активировать мультименеджеры, а порой другие кикатчеры отказываются это делать. Приходится между ними ставить промежуточный фанк_баттон

Фича-реквест: env_rope или cable

Сделать кабели наподобие сурса. Черный провод, задающийся двумя точками. Первой точкой будет сама энтитя, а второй точкой - любая другая энтитя, в том числе и другая env_rope (можно будет сделать цепь). Из свойств - сделать толщину и уровень натяжения кабеля (насколько сильно провисает).

Issues with materials.txt (with FIX) + increasing limits

The texture sound is not picking up correctly from materials.txt file.
In playermove.cpp, in char PM_FindTextureType( char *name )
Replace:
val = strnicmp( name, grgszTextureName[ pivot ], CBTEXTURENAMEMAX-1 );
to
val = Q_stricmp( name, grgszTextureName[ pivot ] );

Additional improvements (from a1batross):
In the void PM_InitTextureTypes():
Change:

  1. int fileSize, filePos to int fileSize, filePos = 0
memset(&( grgszTextureName[0][0] ), 0, CTEXTURESMAX * CBTEXTURENAMEMAX );
memset( grgchTextureType, 0, CTEXTURESMAX );

to

memset(&(grgszTextureName[0][0]), 0, sizeof( grgszTextureName ));
memset(grgchTextureType, 0, sizeof( grgchTextureType ));
  1. memset(buffer, 0, 512); to memset(buffer, 0, sizeof( buffer ));
fileSize = pmove->COM_FileSize( "sound/materials.txt" );
pMemFile = pmove->COM_LoadFile( "sound/materials.txt", 5, NULL );

to
pMemFile = pmove->COM_LoadFile( "sound/materials.txt", 5, &fileSize );
5) while (pmove->memfgets(pMemFile, fileSize, &filePos, buffer, 511) != NULL && (gcTextures < CTEXTURESMAX))
to
while ( pmove->memfgets( pMemFile, fileSize, &filePos, buffer, sizeof(buffer) - 1 ) != NULL && gcTextures < CTEXTURESMAX )

Additional improvements, expanding limits (from me):
In the playermove.cpp, set new values:

#define CTEXTURESMAX		1024			// max number of textures loaded
#define CBTEXTURENAMEMAX	24			// only load first n chars of name

Now, in the PM_InitTextureTypes(), set new values:
Change:
char buffer[512]; to char buffer[1024];

All of this should probably be applied in the sound.cpp file in similar manner.

Баг с травой и спрайтами

Если на карте есть хоть одна текстура, описанная в grassinfo.txt - некоторые спрайты (почему-то не все) начинают моргать или исчезать под определенным углом. Отключение травы (r_grass 0) или тот факт, что рендер рапортует "0 grass" в кадре - не влияет. Браш с "травяной" текстурой может быть вообще где угодно и каким-то образом влиять на спрайты. Только исключение всех "травяных" текстур из grassinfo решает проблему.

r_grass_alpha напрямую влияет. При значении 0 - все нормально. Если выше 0.3, спрайты начинают исчезать. При 0.8 один из анимированных спрайтов (что я тестировал) исчез полностью.

Suggestion: trigger_camera to update the target if it's changed

trigger_camera doesn't update its target if the target was changed with trigger_changetarget.
To fix this, go to CTriggerCamera::FollowTarget and right before the line
Vector vecGoal = UTIL_VecToAngles( m_hTarget->GetLocalOrigin() - GetLocalOrigin() );
add

// update target, maybe it was changed by changetarget.
if( !(pev->spawnflags & SF_CAMERA_PLAYER_TARGET) ) // without this check the game will crash upon using camera
	m_hTarget = GetNextTarget();

func_monitor bugs

Few func_monitors can't work with one info_target. Each monitor needs separate info_target.
The other issue is how the monitor is being set up - how it gets its angles - you have to set it up facing the other way sometimes and also set the angles "0 180 0" in the entity.
It would be better if the monitor would magically find the required texture on the brush and rendered the camera, regardless of the brush angles.

Дополнение 23 марта 2021:
Чтобы установить монитор на карту, мапперу нужно задать отрицательную координату Х, чтобы избавиться от горизонтального отражения изображения, и повернуть текстуру на 180 градусов, чтобы изображение не было вверх ногами.

Генерация коллизии моделей использует только первый body (FIX)

В файле novodex.cpp полностью заменить эту функцию. Желательно основательно перепроверить.

NxTriangleMesh *CPhysicNovodex :: TriangleMeshFromStudio( entvars_t *pev, int modelindex )
{
	if( UTIL_GetModelType( modelindex ) != mod_studio )
	{
		ALERT( at_error, "TriangleMeshFromStudio: not a studio model\n" );
		return NULL;
	}

	model_t *smodel = (model_t *)MODEL_HANDLE( modelindex );
	studiohdr_t *phdr = (studiohdr_t *)smodel->cache.data;
	int solidMeshes = 0;

	if( !phdr || phdr->numbones < 1 )
	{
		ALERT( at_error, "TriangleMeshFromStudio: bad model header\n" );
		return NULL;
	}

	mstudiotexture_t *ptexture = (mstudiotexture_t *)((byte *)phdr + phdr->textureindex);

	for( int i = 0; i < phdr->numtextures; i++ )
	{
		// skip this mesh it's probably foliage or somewhat
		if( ptexture[i].flags & STUDIO_NF_MASKED )
			continue;
		solidMeshes++;
	}

	// model is non-solid
	if( !solidMeshes )
	{
		m_fDisableWarning = TRUE;
		return NULL;
	}

	char szMeshFilename[MAX_PATH];
	NxTriangleMesh *pMesh = NULL;

	MeshNameForModel( smodel->name, szMeshFilename, sizeof( szMeshFilename ));

	if( CheckFileTimes( smodel->name, szMeshFilename ) && !m_fWorldChanged )
	{
		// hull is never than studiomodel. Trying to load it
		pMesh = m_pPhysics->createTriangleMesh( UserStream( szMeshFilename, true ));

		if( !pMesh )
		{
			// we failed to loading existed hull and can't cooking new :(
			if( m_pCooking == NULL )
				return NULL; // don't spam console about missed nxCooking.dll

			// trying to rebuild hull
			ALERT( at_error, "Triangle mesh for %s is corrupted. Rebuilding...\n", smodel->name );
		}
		else
		{
			// all is ok
			return pMesh;
		}
	}
	else
	{
		// can't cooking new hull because nxCooking.dll is missed
		if( m_pCooking == NULL )
			return NULL; // don't spam console about missed nxCooking.dll

		// trying to rebuild hull
		ALERT( at_console, "Triangle mesh for %s is out of Date. Rebuilding...\n", smodel->name );
	}

	// at this point nxCooking instance is always valid

	// compute default pose for building mesh from
	mstudioseqdesc_t *pseqdesc = (mstudioseqdesc_t *)((byte *)phdr + phdr->seqindex);
	mstudioseqgroup_t *pseqgroup = (mstudioseqgroup_t *)((byte *)phdr + phdr->seqgroupindex) + pseqdesc->seqgroup;

	// sanity check
	if( pseqdesc->seqgroup != 0 )
	{
		ALERT( at_error, "TriangleMeshFromStudio: bad sequence group (must be 0)\n" );
		return NULL;
	}

	mstudioanim_t *panim = (mstudioanim_t *)((byte *)phdr + pseqgroup->data + pseqdesc->animindex);
	mstudiobone_t *pbone = (mstudiobone_t *)((byte *)phdr + phdr->boneindex);
	static Vector pos[MAXSTUDIOBONES];
	static Vector4D q[MAXSTUDIOBONES];

	for( i = 0; i < phdr->numbones; i++, pbone++, panim++ ) 
	{
		StudioCalcBoneQuaterion( pbone, panim, q[i] );
		StudioCalcBonePosition( pbone, panim, pos[i] );
	}

	pbone = (mstudiobone_t *)((byte *)phdr + phdr->boneindex);
	matrix4x4	transform, bonematrix, bonetransform[MAXSTUDIOBONES];

	if( pev->startpos != g_vecZero )
		transform = matrix3x4( g_vecZero, g_vecZero, pev->startpos );
	else transform.Identity();

	// compute bones for default anim
	for( i = 0; i < phdr->numbones; i++ ) 
	{
		// initialize bonematrix
		bonematrix = matrix3x4( pos[i], q[i] );

		if( pbone[i].parent == -1 ) 
			bonetransform[i] = transform.ConcatTransforms( bonematrix );
		else bonetransform[i] = bonetransform[pbone[i].parent].ConcatTransforms( bonematrix );
	}

//	mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)phdr + phdr->bodypartindex);
//	mstudiomodel_t *psubmodel = (mstudiomodel_t *)((byte *)phdr + pbodypart->modelindex);
	int body = 0;
	int totalVertSize = 0;
	for( i = 0; i < phdr->numbodyparts; i++ )
	{
		mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)phdr + phdr->bodypartindex) + i;
		int index = body / pbodypart->base;
		index = index % pbodypart->nummodels;

		mstudiomodel_t *psubmodel = (mstudiomodel_t *)((byte *)phdr + pbodypart->modelindex) + index;
		totalVertSize += psubmodel->numverts;
	}



	

//	Vector *verts = new Vector[psubmodel->numverts * 8];	// allocate temporary vertices array
	Vector *verts = new Vector[totalVertSize * 8]; // allocate temporary vertices array

//	NxU32 *indices = new NxU32[psubmodel->numverts * 24];
	NxU32 *indices = new NxU32[totalVertSize * 24];

	int numVerts = 0, numElems = 0;
	Vector tmp;

	for( int k = 0; k < phdr->numbodyparts; k++ )
	{
		mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)phdr + phdr->bodypartindex) + k;

		int index = body / pbodypart->base;
		index = index % pbodypart->nummodels;
		
		mstudiomodel_t *psubmodel = (mstudiomodel_t *)((byte *)phdr + pbodypart->modelindex) + index;
		Vector *pstudioverts = (Vector *)((byte *)phdr + psubmodel->vertindex);
		Vector *m_verts = new Vector[psubmodel->numverts];
		byte *pvertbone = ((byte *)phdr + psubmodel->vertinfoindex);
		
		// setup all the vertices
		for( i = 0; i < psubmodel->numverts; i++ )
			m_verts[i] = bonetransform[pvertbone[i]].VectorTransform( pstudioverts[i] );

		ptexture = (mstudiotexture_t *)((byte *)phdr + phdr->textureindex);
		short *pskinref = (short *)((byte *)phdr + phdr->skinindex);

		for( int j = 0; j < psubmodel->nummesh; j++ ) 
		{
			mstudiomesh_t *pmesh = (mstudiomesh_t *)((byte *)phdr + psubmodel->meshindex) + j;
			short *ptricmds = (short *)((byte *)phdr + pmesh->triindex);

			if( phdr->numtextures != 0 && phdr->textureindex != 0 )
			{
				// skip this mesh it's probably foliage or somewhat
				if( ptexture[pskinref[pmesh->skinref]].flags & STUDIO_NF_MASKED )
					continue;
			}

			while( i = *( ptricmds++ ))
			{
				int	vertexState = 0;
				bool tri_strip;

				if( i < 0 )
				{
					tri_strip = false;
					i = -i;
				}
				else
					tri_strip = true;

				for( ; i > 0; i--, ptricmds += 4 )
				{
					// build in indices
					if( vertexState++ < 3 )
					{
						indices[numElems++] = numVerts;
					}
					else if( tri_strip )
					{
						// flip triangles between clockwise and counter clockwise
						if( vertexState & 1 )
						{
							// draw triangle [n-2 n-1 n]
							indices[numElems++] = numVerts - 2;
							indices[numElems++] = numVerts - 1;
							indices[numElems++] = numVerts;
						}
						else
						{
							// draw triangle [n-1 n-2 n]
							indices[numElems++] = numVerts - 1;
							indices[numElems++] = numVerts - 2;
							indices[numElems++] = numVerts;
						}
					}
					else
					{
						// draw triangle fan [0 n-1 n]
						indices[numElems++] = numVerts - ( vertexState - 1 );
						indices[numElems++] = numVerts - 1;
						indices[numElems++] = numVerts;
					}

				//	verts[numVerts++] = m_verts[ptricmds[0]];
					verts[numVerts] = m_verts[ptricmds[0]];
					numVerts++;
				}
			}
		}

		delete [] m_verts;
	}

	NxTriangleMeshDesc meshDesc;
	meshDesc.numTriangles = numElems / 3;
	meshDesc.pointStrideBytes = sizeof(Vector);
	meshDesc.triangleStrideBytes	= 3 * sizeof( NxU32 );
	meshDesc.points = verts;
	meshDesc.triangles = indices;
	meshDesc.numVertices = numVerts;
	meshDesc.flags = 0;

	m_pCooking->NxInitCooking();
	bool status = m_pCooking->NxCookTriangleMesh( meshDesc, UserStream( szMeshFilename, false ));

	delete [] verts;
//	delete [] m_verts;
	delete [] indices;

	if( !status )
	{
		ALERT( at_error, "failed to create triangle mesh from %s\n", smodel->name );
		return NULL;
	}

	pMesh = m_pPhysics->createTriangleMesh( UserStream( szMeshFilename, true ));
	if( !pMesh ) ALERT( at_error, "failed to create triangle mesh from %s\n", smodel->name );

	return pMesh;
}

No saverestore in game_player_equip (FIX)

Server, maprules.cpp:
Add:

BEGIN_DATADESC( CGamePlayerEquip )
	DEFINE_AUTO_ARRAY( m_weaponCount, FIELD_INTEGER ),
	DEFINE_AUTO_ARRAY( m_weaponNames, FIELD_STRING ),
	DEFINE_FUNCTION( EquipPlayer ),
END_DATADESC()

Before the line LINK_ENTITY_TO_CLASS( game_player_equip, CGamePlayerEquip );

Also add:
DECLARE_DATADESC();
into class CGamePlayerEquip : public CRulePointEntity

Broken animation blending of monsters (with FIX)

client.dll, gl_studio.c -> R_StudioSetUpTransform.
Here, add somewhere in the middle:

e->latched.prevseqblending[0] = e->curstate.blending[0]; 
e->latched.prevseqblending[1] = e->curstate.blending[1];

Model rendering bug

Sometimes the model can be kind of seen through. The issue can be seen 100% of the time in my example on the screenshot.
On the right, the bugged model. On the left - a custom monster with an effect "glow shell" permanently enabled.
While I see both of them on screen, the girl is bugged.
If the monster is not in the view (not rendered?), the girl is not bugged.
If I disable "glow shell" on the monster, no bug occurs.
If gl_renderer is 0, no bug occurs as well.
model

Отсутствуют декали на студио моделях

Стандартная ентитя infodecal перестала работать и подхватывать декали через decals.wad. Так же ентитя env_static_decal которая добавляла hd кастомные декали в п2 не выполняет функционал.
Так же не работают декали выстрелов на студиомоделях.

Примечание: Не стоит фиксить радикально декали, как это сделано в ванильном ксашмоде, что невозможно использовать hd декали (xash\gfx\decals), а только из decals.wad. При использовании внешних текстур (xash\textures), декали из вадника выглядят убого на hd текстурках

К func_wall в игре не крепится парент через trigger_changeparent, если изначально поле было чистое

Есть два сту... волла func_wall.
У одного из них поле parent пустое, а у другого занято каким-нибудь именем. Если зайти в игру на карту и trigger_changeparent попробовать сменить парент, то сменится только у второго волла, у того, у которого поле parent изначально имело хоть какое-то значение. А первый волл, у которого это поле было пустое, не сменит парента.
С func_wall_toggle вроде все ОК

Trigger_inout плохо работает с func_pushable

Поставил trigger_inout с галочками No clients и Pushables. На in - выключение лампы, а на out - включение лампы. По идее, если пушабля будет находиться в триггере, то будет темно. Стоит вытащить пушаблю - станет светло. Но пока ты его толкаешь, то свет мерцает, а когда останавливаешься - светит.

Custom scale of the models is not being saved in save file

This is very important. Otherwise after loading the game some models with scale above 1.0 will be disappearing while still being in the view (when you can see small corner of the model). While their actual scale is not reset, their scale in the engine resets and it thinks the scale of the model is 1.0 and it's not in the view anymore.

Part 1:
xash.dll, sv_save.c:
find static TYPEDESCRIPTION gStaticEntry[] =
and add DEFINE_FIELD( entity_state_t, startpos, FIELD_VECTOR ),

Part 2:
server.dll, saverestore.cpp:
find TYPEDESCRIPTION gEntvarsDescription[] =
and add DEFINE_ENTITY_FIELD( startpos, FIELD_VECTOR ),

That should be all.

Расширить лимиты IsInWorld

cbase.cpp, BOOL CBaseEntity :: IsInWorld( BOOL checkVelocity ):

Заменить 16384 на значения 32768 или выше, для проверки ориджина.
2000 заменить на CVAR_GET_FLOAT( "sv_maxvelocity" ), для проверки велосити.

Поднять лимиты в delta.lst

Сделать такими:
В Entity_Encode:
DEFINE_DELTA( modelindex, DT_INTEGER, 18, 1.0 ),
Проявляется: модели могут меняться на другие, с фиксом этого не происходит.

DEFINE_DELTA( aiment, DT_INTEGER, 16, 1.0 ),
В player тоже есть aiment. Не знаю, нужно ли его тоже поднять, обрати внимание.
Проявляется - спрайт-аттачмент у монстра с индексом выше числа не аттачится к монстру, с фиксом не происходит.

В event_t none:
DEFINE_DELTA( entindex, DT_INTEGER, 18, 1.0 ),

Сломаны координаты в parent системе.

Студио модели, спрайты и система частиц при закреплении за брашем неверно считывают координаты.

Для примера использованная одна карта, как следует из второго видео, видно, что относительно редактора положение сдвинуто и считается неправильно.

Как это должно работать (ванильный ксашмод)
https://www.youtube.com/watch?v=4MqUjKDD--c

Ошибка в прайме
https://www.youtube.com/watch?v=iWwGo5f4heQ

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.