diff --git a/d3xp/AFEntity.cpp b/d3xp/AFEntity.cpp index 2e8aee1..f9b3668 100644 --- a/d3xp/AFEntity.cpp +++ b/d3xp/AFEntity.cpp @@ -1149,7 +1149,7 @@ bool idAFEntity_Gibbable::Collide( const trace_t &collision, const idVec3 &veloc if ( !gibbed && wasThrown ) { // Everything gibs (if possible) - if ( spawnArgs.GetBool( "gib" ) ) { +// PD3 if ( spawnArgs.GetBool( "gib" ) ) { idEntity *ent; ent = gameLocal.entities[ collision.c.entityNum ]; @@ -1157,10 +1157,15 @@ bool idAFEntity_Gibbable::Collide( const trace_t &collision, const idVec3 &veloc ent->Damage( this, gameLocal.GetLocalPlayer(), collision.c.normal, "damage_thrown_ragdoll", 1.f, CLIPMODEL_ID_TO_JOINT_HANDLE( collision.c.id ) ); } + idVec3 vel = velocity; // PD3 + vel.NormalizeFast(); // PD3 + +/* PD3 idVec3 vel = velocity; vel.NormalizeFast(); Gib( vel, "damage_gib" ); - } +*/ +// PD3 } } return idAFEntity_Base::Collide( collision, velocity ); @@ -3560,12 +3565,22 @@ void idHarvestable::Event_Touch( idEntity *other, trace_t *trace ) { bool okToGive = true; idStr requiredWeapons = spawnArgs.GetString("required_weapons"); +/* PD3 if(requiredWeapons.Length() > 0) { idStr playerWeap = thePlayer->GetCurrentWeapon(); if(playerWeap.Length() == 0 || requiredWeapons.Find(playerWeap, false) == -1) { okToGive = false; } } +*/ + + if(requiredWeapons.Length() > 0) { + int playerWeap = thePlayer->GetCurrentWeapon(); + if(playerWeap != 12) { + okToGive = false; + } + } + if(okToGive) { if(thePlayer->CanGive(spawnArgs.GetString("give_item"), spawnArgs.GetString("give_value"))) { diff --git a/d3xp/Actor.cpp b/d3xp/Actor.cpp index 1e467ad..3b91226 100644 --- a/d3xp/Actor.cpp +++ b/d3xp/Actor.cpp @@ -2242,13 +2242,17 @@ void idActor::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir gameLocal.Error( "Unknown damageDef '%s'", damageDefName ); } -// sikk---> Ammo Management: Custom Ammo Damage +// sikk---> Damage Type PD3 int damage; - if ( g_ammoDamageType.GetBool() && damageDef->GetInt( "custom_damage" ) ) - damage = damageDef->GetInt( "custom_damage" ) * damageScale; - else - damage = damageDef->GetInt( "damage" ) * damageScale; -// <---sikk + if ( g_damageType.GetInteger() == 1 && damageDef->GetInt( "damage_doom_scale" ) ) { + damage = damageDef->GetInt( "damage_doom_scale" ) * ( gameLocal.random.RandomInt( 255 ) % damageDef->GetInt( "damage_doom_range" ) + 1 ); + } else if ( g_damageType.GetInteger() == 2 && damageDef->GetInt( "damage_custom" ) ) { + damage = damageDef->GetInt( "damage_custom" ); + } else { + damage = damageDef->GetInt( "damage" ); + } +// <---sikk PD3 + damage *= damageScale; // PD3 damage = GetDamageForLocation( damage, location ); // inform the attacker that they hit someone @@ -2424,19 +2428,29 @@ void idActor::SetupDamageGroups( void ) { damageScale[ i ] = 1.0f; } +// sikk---> Doom 1/2 & custom Damage zones PD3 // set the percentage on damage zones - arg = spawnArgs.MatchPrefix( "damage_scale ", NULL ); + const char* scalePrefix; + if ( g_damageZoneType.GetInteger() == 1 ) + scalePrefix = "damage_scale_doom "; + else if ( g_damageZoneType.GetInteger() == 2 ) + scalePrefix = "damage_scale_custom "; + else + scalePrefix = "damage_scale "; + + arg = spawnArgs.MatchPrefix( scalePrefix, NULL ); while ( arg ) { scale = atof( arg->GetValue() ); groupname = arg->GetKey(); - groupname.Strip( "damage_scale " ); + groupname.Strip( scalePrefix ); for( i = 0; i < damageScale.Num(); i++ ) { if ( damageGroups[ i ] == groupname ) { damageScale[ i ] = scale; } } - arg = spawnArgs.MatchPrefix( "damage_scale ", arg ); + arg = spawnArgs.MatchPrefix( scalePrefix, arg ); } +// <---sikk PD3 } /* diff --git a/d3xp/Entity.cpp b/d3xp/Entity.cpp index dd91224..fd87163 100644 --- a/d3xp/Entity.cpp +++ b/d3xp/Entity.cpp @@ -120,6 +120,8 @@ const idEventDef EV_StartFx( "startFx", "s" ); const idEventDef EV_HasFunction( "hasFunction", "s", 'd' ); const idEventDef EV_CallFunction( "callFunction", "s" ); const idEventDef EV_SetNeverDormant( "setNeverDormant", "d" ); +const idEventDef EV_FireProjectile( "fireProjectile", "svv", 'e' ); // PD3 +const idEventDef EV_FireProjAtTarget( "fireProjAtTarget", "svE", 'e' ); // PD3 #ifdef _D3XP const idEventDef EV_SetGui ( "setGui", "ds" ); const idEventDef EV_PrecacheGui ( "precacheGui", "s" ); @@ -194,6 +196,8 @@ ABSTRACT_DECLARATION( idClass, idEntity ) EVENT( EV_HasFunction, idEntity::Event_HasFunction ) EVENT( EV_CallFunction, idEntity::Event_CallFunction ) EVENT( EV_SetNeverDormant, idEntity::Event_SetNeverDormant ) + EVENT( EV_FireProjectile, idEntity::Event_FireProjectile ) // PD3 + EVENT( EV_FireProjAtTarget, idEntity::Event_FireProjAtTarget ) // PD3 #ifdef _D3XP EVENT( EV_SetGui, idEntity::Event_SetGui ) EVENT( EV_PrecacheGui, idEntity::Event_PrecacheGui ) @@ -203,6 +207,83 @@ ABSTRACT_DECLARATION( idClass, idEntity ) #endif END_CLASS +/* +================ +idEntity::CommonFireProjectile // PD3 +================ +*/ +idProjectile* idEntity::CommonFireProjectile( const char *projDefName , const idVec3 &firePos, const idVec3 &dir ) { + idProjectile *proj; + idEntity *ent; + idDict projectileDict; + + if ( gameLocal.isClient ) { return NULL; } + + const idDeclEntityDef *projectileDef = gameLocal.FindEntityDef( projDefName, false ); + if ( !projectileDef ) { + gameLocal.Warning( "No def '%s' found", projDefName ); + return NULL; + } + + projectileDict = projectileDef->dict; + if ( !projectileDict.GetNumKeyVals() ) { + gameLocal.Warning( "No projectile defined '%s'", projDefName ); + return NULL; + } + + if ( IsType( idPlayer::Type ) ) { + static_cast( this )->AddProjectilesFired(1); + gameLocal.AlertAI( this ); + } + + gameLocal.SpawnEntityDef( projectileDict, &ent, false ); + + if ( !ent || !ent->IsType( idProjectile::Type ) ) { + gameLocal.Error( "'%s' is not an idProjectile", projDefName ); + } + + if ( projectileDict.GetBool( "net_instanthit" ) ) { + ent->fl.networkSync = false; + } + + proj = static_cast(ent); + proj->Create( this, firePos, dir ); + proj->Launch( firePos, dir, vec3_origin ); + return proj; +} + +/* +===================== +idEntity::CommonGetAimDir // PD3 +===================== +*/ +void idEntity::CommonGetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, idVec3 &aimDir ) { + idVec3 mainTargetPos; + idVec3 secTargetPos; //not used, but necessary + + if ( aimAtEnt ) { //target entity ok! + if ( aimAtEnt->IsType( idPlayer::Type ) ) { //player - head + static_cast( aimAtEnt )->GetAIAimTargets( aimAtEnt->GetPhysics()->GetOrigin(), mainTargetPos, secTargetPos ); + } else if ( aimAtEnt->IsType( idActor::Type ) ) { //AI - chest + static_cast( aimAtEnt )->GetAIAimTargets( aimAtEnt->GetPhysics()->GetOrigin(), secTargetPos, mainTargetPos ); + } else { //center + mainTargetPos = aimAtEnt->GetPhysics()->GetAbsBounds().GetCenter(); + } + + aimDir = mainTargetPos - firePos; + aimDir.Normalize(); + + } else { //no valid aimAtEnt entity! + if ( IsType( idPlayer::Type ) ) { //player - view + static_cast( this )->viewAngles.ToVectors( &aimDir, NULL, NULL ); + } else if ( IsType( idActor::Type ) ) { //AI - axis + aimDir = static_cast( this )->viewAxis[ 0 ]; + } else { + aimDir = GetPhysics()->GetAxis()[ 0 ]; + } + } +} + /* ================ UpdateGuiParms @@ -579,7 +660,15 @@ void idEntity::Spawn( void ) { } } - health = spawnArgs.GetInt( "health" ); +// sikk---> Doom/Custom Health Values + if ( g_enemyHealthType.GetInteger() == 1 && spawnArgs.GetInt( "health_doom" ) ) { + health = spawnArgs.GetInt( "health_doom" ); + } else if ( g_enemyHealthType.GetInteger() == 2 && spawnArgs.GetInt( "health_custom" ) ) { + health = spawnArgs.GetInt( "health_custom" ); + } else { + health = spawnArgs.GetInt( "health" ); + } +// <---sikk InitDefaultPhysics( origin, axis ); @@ -3094,13 +3183,16 @@ void idEntity::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &di gameLocal.Error( "Unknown damageDef '%s'\n", damageDefName ); } -// sikk---> Ammo Management: Custom Ammo Damage +// sikk---> Damage Type PD3 int damage; - if ( g_ammoDamageType.GetBool() && damageDef->GetInt( "custom_damage" ) ) - damage = damageDef->GetInt( "custom_damage" ); - else + if ( g_damageType.GetInteger() == 1 && damageDef->GetInt( "damage_doom_scale" ) ) { + damage = damageDef->GetInt( "damage_doom_scale" ) * ( gameLocal.random.RandomInt( 255 ) % damageDef->GetInt( "damage_doom_range" ) + 1 ); + } else if ( g_damageType.GetInteger() == 2 && damageDef->GetInt( "damage_custom" ) ) { + damage = damageDef->GetInt( "damage_custom" ); + } else { damage = damageDef->GetInt( "damage" ); -// <---sikk + } +// <---sikk PD3 // inform the attacker that they hit someone attacker->DamageFeedback( this, inflictor, damage ); @@ -4697,6 +4789,36 @@ void idEntity::Event_SetNeverDormant( int enable ) { dormantStart = 0; } +/* +================ +idEntity::Event_FireProjectile PD3 +================ +*/ +void idEntity::Event_FireProjectile( const char* projDefName , const idVec3 &firePos, const idAngles &fireAng ) { + idProjectile *proj; + idVec3 dir; + + dir = fireAng.ToForward(); + proj = CommonFireProjectile( projDefName , firePos, dir ); + + idThread::ReturnEntity( proj ); +} + +/* +================ +idEntity::Event_FireProjAtTarget PD3 +================ +*/ +void idEntity::Event_FireProjAtTarget( const char* projDefName , const idVec3 &firePos, idEntity* aimAtEnt) { + idProjectile *proj; + idVec3 dir; + + CommonGetAimDir( firePos, aimAtEnt, dir ); + proj = CommonFireProjectile( projDefName , firePos, dir ); + + idThread::ReturnEntity( proj ); +} + #ifdef _D3XP /* ================ @@ -5097,6 +5219,8 @@ const idEventDef EV_SetJointPos( "setJointPos", "ddv" ); const idEventDef EV_SetJointAngle( "setJointAngle", "ddv" ); const idEventDef EV_GetJointPos( "getJointPos", "d", 'v' ); const idEventDef EV_GetJointAngle( "getJointAngle", "d", 'v' ); +const idEventDef EV_FireProjectileFromJoint( "fireProjectileFromJoint", "sdv", 'e' ); +const idEventDef EV_FireProjAtTargetFromJoint( "fireProjAtTargetFromJoint", "sdE", 'e' ); CLASS_DECLARATION( idEntity, idAnimatedEntity ) EVENT( EV_GetJointHandle, idAnimatedEntity::Event_GetJointHandle ) @@ -5106,6 +5230,8 @@ CLASS_DECLARATION( idEntity, idAnimatedEntity ) EVENT( EV_SetJointAngle, idAnimatedEntity::Event_SetJointAngle ) EVENT( EV_GetJointPos, idAnimatedEntity::Event_GetJointPos ) EVENT( EV_GetJointAngle, idAnimatedEntity::Event_GetJointAngle ) + EVENT( EV_FireProjectileFromJoint, idAnimatedEntity::Event_FireProjectileFromJoint ) // PD3 + EVENT( EV_FireProjAtTargetFromJoint, idAnimatedEntity::Event_FireProjAtTargetFromJoint ) // PD3 END_CLASS /* @@ -5627,3 +5753,46 @@ void idAnimatedEntity::Event_GetJointAngle( jointHandle_t jointnum ) { idVec3 vec( ang[ 0 ], ang[ 1 ], ang[ 2 ] ); idThread::ReturnVector( vec ); } + + +/* +================ +idAnimatedEntity::Event_FireProjectileFromJoint // PD3 +================ +*/ +void idAnimatedEntity::Event_FireProjectileFromJoint( const char *projDefName, jointHandle_t jointnum, const idAngles &fireAng ) { + idProjectile *proj; + idVec3 dir; + idVec3 firePos; + idMat3 axis; //useless but needed + + if ( !GetJointWorldTransform( jointnum, gameLocal.time, firePos, axis ) ) { + gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() ); + } + + dir = fireAng.ToForward(); + proj = CommonFireProjectile( projDefName , firePos, dir ); + + idThread::ReturnEntity( proj ); +} + +/* +================ +idAnimatedEntity::Event_FireProjAtTargetFromJoint // PD3 +================ +*/ +void idAnimatedEntity::Event_FireProjAtTargetFromJoint( const char *projDefName, jointHandle_t jointnum, idEntity *aimAtEnt ) { + idProjectile *proj; + idVec3 dir; + idVec3 firePos; + idMat3 axis; //useless but needed + + if ( !GetJointWorldTransform( jointnum, gameLocal.time, firePos, axis ) ) { + gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() ); + } + + CommonGetAimDir( firePos, aimAtEnt, dir ); + proj = CommonFireProjectile( projDefName , firePos, dir ); + + idThread::ReturnEntity( proj ); +} \ No newline at end of file diff --git a/d3xp/Entity.h b/d3xp/Entity.h index 4413c30..ce06d5d 100644 --- a/d3xp/Entity.h +++ b/d3xp/Entity.h @@ -39,6 +39,8 @@ If you have questions concerning this license or the applicable additional terms #include "gamesys/Event.h" #include "Game_local.h" +class idProjectile; // PD3 + /* =============================================================================== @@ -180,6 +182,9 @@ public: idEntity(); ~idEntity(); + void CommonGetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, idVec3 &aimDir ); // PD3 + idProjectile* CommonFireProjectile( const char *projDefName, const idVec3 &firePos, const idVec3 &dir ); // PD3 + void Spawn( void ); void Save( idSaveGame *savefile ) const; @@ -481,6 +486,9 @@ private: void Event_HasFunction( const char *name ); void Event_CallFunction( const char *name ); void Event_SetNeverDormant( int enable ); + + void Event_FireProjectile( const char* projDefName , const idVec3 &firePos, const idAngles &fireAng ); // PD3 + void Event_FireProjAtTarget( const char* projDefName , const idVec3 &firePos, idEntity* aimAtEnt ); // PD3 #ifdef _D3XP void Event_SetGui( int guiNum, const char *guiName); void Event_PrecacheGui( const char *guiName ); @@ -552,6 +560,9 @@ private: void Event_SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles ); void Event_GetJointPos( jointHandle_t jointnum ); void Event_GetJointAngle( jointHandle_t jointnum ); + + void Event_FireProjectileFromJoint( const char *projDefName, jointHandle_t jointnum, const idAngles &fireAng ); // PD3 + void Event_FireProjAtTargetFromJoint( const char *projDefName, jointHandle_t jointnum, idEntity *aimAtEnt ); // PD3 }; diff --git a/d3xp/Game_local.cpp b/d3xp/Game_local.cpp index 747e8c6..a2a785a 100644 --- a/d3xp/Game_local.cpp +++ b/d3xp/Game_local.cpp @@ -3504,19 +3504,19 @@ bool idGameLocal::InhibitEntitySpawn( idDict &spawnArgs ) { idStr::Icmp( name, "moveable_item_medkit" ) == 0 || idStr::Icmp( name, "moveable_item_medkit_small" ) == 0 ) { result = true; -// sikk---> Health Management System (Health Regen) +// sikk---> Health Management System (Health Regen) PD3 // if medkit has a target, replace it with an adrenaline - This should be done in Nightmare difficulty as well - if ( spawnArgs.GetString( "target" ) != "" ) { + if ( idStr::Icmp( spawnArgs.GetString( "target" ), "" ) ) { idEntity *ent; idDict args; - args.Set( "classname", "moveable_powerup_adrenaline" ); + args.Set( "classname", "powerup_adrenaline" ); // args.Set( "name", spawnArgs.GetString( "name" ) ); args.Set( "target", spawnArgs.GetString( "target" ) ); args.Set( "origin", spawnArgs.GetString( "origin" ) ); args.Set( "rotation", spawnArgs.GetString( "rotation" ) ); gameLocal.SpawnEntityDef( args, &ent ); } -// <---sikk +// <---sikk PD3 } } diff --git a/d3xp/Grabber.cpp b/d3xp/Grabber.cpp index 40ffe93..e4fbd5f 100644 --- a/d3xp/Grabber.cpp +++ b/d3xp/Grabber.cpp @@ -43,7 +43,7 @@ If you have questions concerning this license or the applicable additional terms #define HOLD_DISTANCE 72.f #define FIRING_DELAY 1000.0f #define DRAG_FAIL_LEN 64.f -#define THROW_SCALE 1000 +#define THROW_SCALE 2500 // 1000 PD3 #define MAX_PICKUP_VELOCITY 1500 * 1500 #define MAX_PICKUP_SIZE 96 @@ -636,6 +636,7 @@ int idGrabber::Update( idPlayer *player, bool hide ) { // Currently holding an object return 2; + } // Not holding, nothing to hold diff --git a/d3xp/Item.cpp b/d3xp/Item.cpp index 66354f8..2adc34c 100644 --- a/d3xp/Item.cpp +++ b/d3xp/Item.cpp @@ -418,6 +418,8 @@ idItem::GiveToPlayer ================ */ bool idItem::GiveToPlayer( idPlayer *player ) { + int numPistols; // doomtrinity-dual weapon-> + int numShotguns; // doomtrinity-dual weapon-> if ( player == NULL ) { return false; } @@ -430,6 +432,22 @@ bool idItem::GiveToPlayer( idPlayer *player ) { if ( spawnArgs.GetBool( "inv_carry" ) ) { return player->GiveInventoryItem( &spawnArgs ); } +// doomtrinity-dual weapon-> + numPistols = player->inventory.pistolInInventory; + numShotguns = player->inventory.shotgunDoubleInInventory; + + if ( ( numPistols != WEAPON_COUNT_STOP ) || ( numShotguns != WEAPON_COUNT_STOP ) ) { + idStr inv_weapon; + inv_weapon = spawnArgs.GetString( va("inv_weapon") ); + if ( ( player->inventory.weapons & 2 ) && ( numPistols != WEAPON_COUNT_STOP ) && ( inv_weapon == "weapon_pistol" ) ) { + player->inventory.pistolInInventory++; + //gameLocal.Printf( "pistol # %i\n", player->inventory.pistolInInventory ); + } else if ( ( player->inventory.weapons & 8 ) && ( numShotguns != WEAPON_COUNT_STOP ) && ( inv_weapon == "weapon_shotgun_double" ) ) { + player->inventory.shotgunDoubleInInventory++; + //gameLocal.Printf( "shotgun # %i\n", player->inventory.shotgunDoubleInInventory ); + } + } +// doomtrinity-dual weapon-< return player->GiveItem( this ); } @@ -732,6 +750,7 @@ bool idItemPowerup::GiveToPlayer( idPlayer *player ) { #ifdef CTF +#define WEAPON_COUNT_STOP 2 // doomtrinity-dual weapon /* =============================================================================== diff --git a/d3xp/Player.cpp b/d3xp/Player.cpp index 6833ab5..322fbcc 100644 --- a/d3xp/Player.cpp +++ b/d3xp/Player.cpp @@ -103,6 +103,10 @@ const idEventDef EV_Player_ToggleBloom( "toggleBloom", "d" ); const idEventDef EV_Player_SetBloomParms( "setBloomParms", "ff" ); #endif +// doomtrinity-dual weapon +const idEventDef EV_Player_GetNumPistols( "getNumPistols", NULL, 'd' ); +const idEventDef EV_Player_GetNumShotguns( "getNumShotguns", NULL, 'd' ); + CLASS_DECLARATION( idActor, idPlayer ) EVENT( EV_Player_GetButtons, idPlayer::Event_GetButtons ) EVENT( EV_Player_GetMove, idPlayer::Event_GetMove ) @@ -133,6 +137,9 @@ CLASS_DECLARATION( idActor, idPlayer ) EVENT( EV_Player_ToggleBloom, idPlayer::Event_ToggleBloom ) EVENT( EV_Player_SetBloomParms, idPlayer::Event_SetBloomParms ) #endif + // doomtrinity-dual weapon + EVENT( EV_Player_GetNumPistols, idPlayer::Event_GetNumPistols ) + EVENT( EV_Player_GetNumShotguns, idPlayer::Event_GetNumShotguns ) END_CLASS const int MAX_RESPAWN_TIME = 10000; @@ -168,6 +175,8 @@ idInventory::Clear void idInventory::Clear( void ) { maxHealth = 0; weapons = 0; + shotgunDoubleInInventory = 0; // doomtrinity-dual weapon + pistolInInventory = 0; // doomtrinity-dual weapon powerups = 0; armor = 0; maxarmor = 0; @@ -282,6 +291,10 @@ void idInventory::GetPersistantData( idDict &dict ) { // armor dict.SetInt( "armor", armor ); + // doomtrinity-dual weapon + dict.SetInt( "hasDB", shotgunDoubleInInventory ); + dict.SetInt( "hasPistol", pistolInInventory ); + // don't bother with powerups, maxhealth, maxarmor, or the clip // ammo @@ -292,6 +305,13 @@ void idInventory::GetPersistantData( idDict &dict ) { } } +//doomtrinity -> //From D3XP + //Save the clip data + for( i = 0; i < MAX_WEAPONS; i++ ) { + dict.SetInt( va("clip%i", i), clip[ i ] ); + } +//<- doomtrinity + #ifdef _D3XP //Save the clip data for( i = 0; i < MAX_WEAPONS; i++ ) { @@ -381,6 +401,11 @@ void idInventory::RestoreInventory( idPlayer *owner, const idDict &dict ) { // health/armor maxHealth = dict.GetInt( "maxhealth", "100" ); armor = dict.GetInt( "armor", "50" ); + + // doomtrinity-dual weapon + shotgunDoubleInInventory = dict.GetInt( "hasDB" ); + pistolInInventory = dict.GetInt( "hasPistol" ); + maxarmor = dict.GetInt( "maxarmor", "100" ); deplete_armor = dict.GetInt( "deplete_armor", "0" ); deplete_rate = dict.GetFloat( "deplete_rate", "2.0" ); @@ -396,6 +421,13 @@ void idInventory::RestoreInventory( idPlayer *owner, const idDict &dict ) { } } +//doomtrinity -> //From D3XP + //Restore the clip data + for( i = 0; i < MAX_WEAPONS; i++ ) { + clip[i] = dict.GetInt(va("clip%i", i), "-1"); + } +//<- doomtrinity + #ifdef _D3XP //Restore the clip data for( i = 0; i < MAX_WEAPONS; i++ ) { @@ -464,6 +496,16 @@ void idInventory::RestoreInventory( idPlayer *owner, const idDict &dict ) { Give( owner, dict, "weapon", dict.GetString( "weapon" ), NULL, false ); } +// doomtrinity-dual weapon-> + // we need this for game saves prior to mod installation + if ( (weapons & 2) && !pistolInInventory ) { + pistolInInventory = 1; + } + if ( (weapons & 8) && !shotgunDoubleInInventory ) { + shotgunDoubleInInventory = 1; + } +// doomtrinity-dual weapon-< + num = dict.GetInt( "levelTriggers" ); for ( i = 0; i < num; i++ ) { sprintf( itemname, "levelTrigger_Level_%i", i ); @@ -486,6 +528,11 @@ void idInventory::Save( idSaveGame *savefile ) const { savefile->WriteInt( maxHealth ); savefile->WriteInt( weapons ); + + // doomtrinity-dual weapon + savefile->WriteInt( shotgunDoubleInInventory ); + savefile->WriteInt( pistolInInventory ); + savefile->WriteInt( powerups ); savefile->WriteInt( armor ); savefile->WriteInt( maxarmor ); @@ -593,6 +640,11 @@ void idInventory::Restore( idRestoreGame *savefile ) { savefile->ReadInt( maxHealth ); savefile->ReadInt( weapons ); + + // doomtrinity-dual weapon + savefile->ReadInt( shotgunDoubleInInventory ); + savefile->ReadInt( pistolInInventory ); + savefile->ReadInt( powerups ); savefile->ReadInt( armor ); savefile->ReadInt( maxarmor ); @@ -973,6 +1025,16 @@ bool idInventory::Give( idPlayer *owner, const idDict &spawnArgs, const char *st assert( !gameLocal.isClient ); *idealWeapon = i; } + +// doomtrinity-dual weapon-> + if ( weaponName == "weapon_pistol" ) { + pistolInInventory = 1; + } + if ( weaponName == "weapon_shotgun_double" ) { + shotgunDoubleInInventory = 1; + } +// doomtrinity-dual weapon-< + if ( owner->hud && updateHud && lastGiveTime + 1000 < gameLocal.time ) { owner->hud->SetStateInt( "newWeapon", i ); owner->hud->HandleNamedEvent( "newWeapon" ); @@ -1047,6 +1109,27 @@ int idInventory::HasAmmo( ammo_t type, int amount ) { } +/* +=============== +idInventory::HasAmmo +=============== +*/ +/* +int idInventory::HasAmmo( const char *weapon_classname, bool includeClip, idPlayer* owner ) {// doomtrinity (D3XP) + int ammoRequired; + ammo_t ammo_i = AmmoIndexForWeaponClass( weapon_classname, &ammoRequired ); +//doomtrinity -> //From D3XP + int ammoCount = HasAmmo( ammo_i, ammoRequired ); + if(includeClip && owner) { + ammoCount += clip[owner->SlotForWeapon(weapon_classname)]; + } + return ammoCount; + + //return HasAmmo( ammo_i, ammoRequired ); +*/ +//<- doomtrinity +//} + /* =============== idInventory::HasAmmo @@ -1292,6 +1375,7 @@ idPlayer::idPlayer() { firstPersonViewOrigin = vec3_zero; firstPersonViewAxis = mat3_identity; + firstPersonViewWeaponAxis = mat3_identity; // doomtrinity-headanim hipJoint = INVALID_JOINT; chestJoint = INVALID_JOINT; @@ -1321,6 +1405,14 @@ idPlayer::idPlayer() { weapon_soulcube = -1; weapon_pda = -1; weapon_fists = -1; +//doomtrinity -> + weapon_pistol = -1; + weapon_shotgun = -1; + weapon_superShotgun = -1; + weapon_machinegun = -1; + weapon_plasmagun = -1; + weapon_rocketlauncher = -1; +//<- doomtrinity #ifdef _D3XP weapon_bloodstone = -1; weapon_bloodstone_active1 = -1; @@ -1429,6 +1521,8 @@ idPlayer::idPlayer() { selfSmooth = false; + fSpreadModifier = 0.0f; // sikk - Weapon Management: Handling PD3 + focusMoveableTimer = 0; // sikk - Object Manipulation focusItem = NULL; // sikk - Manual Item Pickup @@ -1543,6 +1637,14 @@ void idPlayer::Init( void ) { weapon_soulcube = SlotForWeapon( "weapon_soulcube" ); weapon_pda = SlotForWeapon( "weapon_pda" ); weapon_fists = SlotForWeapon( "weapon_fists" ); +//doomtrinity -> + weapon_pistol = SlotForWeapon( "weapon_pistol" ); + weapon_shotgun = SlotForWeapon( "weapon_shotgun" ); + weapon_superShotgun = SlotForWeapon( "weapon_shotgun_double" ); + weapon_machinegun = SlotForWeapon( "weapon_machinegun" ); + weapon_plasmagun = SlotForWeapon( "weapon_plasmagun" ); + weapon_rocketlauncher = SlotForWeapon( "weapon_rocketlauncher" ); +//<- doomtrinity #ifdef _D3XP weapon_bloodstone = SlotForWeapon( "weapon_bloodstone_passive" ); weapon_bloodstone_active1 = SlotForWeapon( "weapon_bloodstone_active1" ); @@ -1602,6 +1704,8 @@ void idPlayer::Init( void ) { talkCursor = 0; focusVehicle = NULL; + fSpreadModifier = 0.0f; // sikk - Weapon Management: Handling PD3 + focusMoveableTimer = 0; // sikk - Object Manipulation focusItem = NULL; // sikk - Manual Item Pickup @@ -1804,6 +1908,12 @@ void idPlayer::Init( void ) { //isChatting = false; cvarSystem->SetCVarBool("ui_chat", false); +//doomtrinity -> + init_mSensitivity = in_mouseSensitivity.GetFloat(); + init_mSmooth = in_mouseSmooth.GetInteger(); + cvarSystem->SetCVarFloat( "sensitivity", init_mSensitivity ); + cvarSystem->SetCVarInteger( "m_smooth", init_mSmooth ); +//<- doomtrinity } /* @@ -2166,6 +2276,14 @@ void idPlayer::Save( idSaveGame *savefile ) const { savefile->WriteInt( weapon_soulcube ); savefile->WriteInt( weapon_pda ); savefile->WriteInt( weapon_fists ); +//doomtrinity -> + savefile->WriteInt( weapon_pistol ); + savefile->WriteInt( weapon_shotgun ); + savefile->WriteInt( weapon_superShotgun ); + savefile->WriteInt( weapon_machinegun ); + savefile->WriteInt( weapon_plasmagun ); + savefile->WriteInt( weapon_rocketlauncher ); +//<- doomtrinity #ifdef _D3XP savefile->WriteInt( weapon_bloodstone ); savefile->WriteInt( weapon_bloodstone_active1 ); @@ -2227,6 +2345,7 @@ void idPlayer::Save( idSaveGame *savefile ) const { savefile->WriteVec3( firstPersonViewOrigin ); savefile->WriteMat3( firstPersonViewAxis ); + savefile->WriteMat3( firstPersonViewWeaponAxis ); // doomtrinity-headanim // don't bother saving dragEntity since it's a dev tool @@ -2443,6 +2562,14 @@ void idPlayer::Restore( idRestoreGame *savefile ) { savefile->ReadInt( weapon_soulcube ); savefile->ReadInt( weapon_pda ); savefile->ReadInt( weapon_fists ); +//doomtrinity -> + savefile->ReadInt( weapon_pistol ); + savefile->ReadInt( weapon_shotgun ); + savefile->ReadInt( weapon_superShotgun ); + savefile->ReadInt( weapon_machinegun ); + savefile->ReadInt( weapon_plasmagun ); + savefile->ReadInt( weapon_rocketlauncher ); +//<- doomtrinity #ifdef _D3XP savefile->ReadInt( weapon_bloodstone ); savefile->ReadInt( weapon_bloodstone_active1 ); @@ -2509,6 +2636,7 @@ void idPlayer::Restore( idRestoreGame *savefile ) { savefile->ReadVec3( firstPersonViewOrigin ); savefile->ReadMat3( firstPersonViewAxis ); + savefile->ReadMat3( firstPersonViewWeaponAxis ); // doomtrinity-headanim // don't bother saving dragEntity since it's a dev tool dragEntity.Clear(); @@ -3194,7 +3322,7 @@ void idPlayer::UpdateHudAmmo( idUserInterface *_hud ) { #endif _hud->SetStateString( "player_ammo", weapon.GetEntity()->ClipSize() ? va( "%i", inclip ) : "--" ); // how much in the current clip _hud->SetStateString( "player_clips", weapon.GetEntity()->ClipSize() ? va( "%i", ammoamount / weapon.GetEntity()->ClipSize() ) : "--" ); - + _hud->SetStateString( "player_allammo", va( "%i/%i", inclip, ammoamount ) );// doomtrinity (D3XP) #ifdef _D3XP _hud->SetStateString( "player_allammo", va( "%i/%i", inclip, ammoamount ) ); #else @@ -3229,6 +3357,10 @@ void idPlayer::UpdateHudAmmo( idUserInterface *_hud ) { _hud->HandleNamedEvent( "bloodstoneAmmoUpdate" ); #endif +//doomtrinity -> //From D3XP + //Let the HUD know the total amount of ammo regardless of the ammo required value + _hud->SetStateString( "player_ammo_count", va("%i", weapon.GetEntity()->AmmoCount())); +//<- doomtrinity _hud->HandleNamedEvent( "updateAmmo" ); // sikk---> Dynamic Hud System @@ -3425,6 +3557,8 @@ idPlayer::DrawHUD */ void idPlayer::DrawHUD( idUserInterface *_hud ) { +int crosshairType = g_crosshair.GetInteger(); + if ( !weapon.GetEntity() || influenceActive != INFLUENCE_NONE || privateCameraView || gameLocal.GetCamera() || !_hud || !g_showHud.GetBool() ) { return; } @@ -3445,98 +3579,17 @@ void idPlayer::DrawHUD( idUserInterface *_hud ) { // weapon targeting crosshair if ( !GuiActive() ) { if ( cursor && weapon.GetEntity()->ShowCrosshair() ) { - -// sikk---> Crosshair Positioning - idStr buf; - if ( g_crosshairType.GetBool() && !GetTalkCursor() && !( focusItem || focusCorpse ) ) { - trace_t tr; - idVec3 ndc; - idVec3 muzzleOrigin; - idMat3 muzzleAxis; - - // detemine the point at which the weapon is aiming - if ( weapon.GetEntity()->GetBarrelJointView() != INVALID_JOINT && - weapon.GetEntity()->GetProjectileDict().GetBool( "launchFromBarrel" ) && - ( GetCurrentWeaponNum() < 9 && GetCurrentWeaponNum() > 11 ) ) { - // there is an explicit joint for the muzzle - weapon.GetEntity()->GetGlobalJointTransform( true, weapon.GetEntity()->GetBarrelJointView(), muzzleOrigin, muzzleAxis ); - } else { - // go straight out of the view - muzzleOrigin = firstPersonViewOrigin; - muzzleAxis = firstPersonViewAxis; - } - idVec3 endPos = muzzleOrigin + ( muzzleAxis.ToAngles().ToForward() * 65536.0f ); - gameLocal.clip.TracePoint( tr, muzzleOrigin, endPos, MASK_SHOT_RENDERMODEL, this ); - endPos = tr.endpos; - v3CrosshairPos.Lerp( endPos, v3CrosshairPos, g_crosshairLerp.GetFloat() ); - renderSystem->GlobalToNormalizedDeviceCoordinates( v3CrosshairPos, ndc ); - ndc.x = ( ( ndc.x * 0.5 + 0.5 ) * SCREEN_WIDTH ); - ndc.y = ( ( 1.0f - ( ndc.y * 0.5 + 0.5 ) ) * SCREEN_HEIGHT ); - sprintf( buf, "%d %d 100 32", (int)ndc.x - 16, (int)ndc.y - 16); - } else { - sprintf( buf, "%d %d 100 32", 304, 224 ); - } -// <---sikk - -// sikk---> Crosshair Cvar - int crosshairType = g_crosshair.GetInteger(); - if ( crosshairType == 0 ) { - cursor->SetStateString( "grabbercursor", "0" ); - cursor->SetStateString( "combatcursor", "0" ); - } else if ( crosshairType == 1 ) { - if ( weapon.GetEntity()->GetGrabberState() == 1 || weapon.GetEntity()->GetGrabberState() == 2 ) { - cursor->SetStateString( "grabbercursor", "1" ); +//doomtrinity PD3 -> + if ( usercmd.buttons & BUTTON_ZOOM ) { + if ( crosshairType == 0 || currentWeapon == weapon_pistol || currentWeapon == weapon_shotgun || currentWeapon == weapon_superShotgun /* PD3 || currentWeapon == weapon_machinegun || currentWeapon == weapon_plasmagun || currentWeapon == weapon_rocketlauncher */ ) { cursor->SetStateString( "combatcursor", "0" ); - cursor->SetStateString( "pickupcursor", "0" ); - } else if ( weapon.GetEntity()->GetGrabberState() != 2 && !grabEntity.GetGrabEntity() && ( focusItem || focusCorpse || focusMoveable ) ) { - cursor->SetStateString( "grabbercursor", "0" ); - cursor->SetStateString( "combatcursor", "0" ); - cursor->SetStateString( "pickupcursor", "1" ); } else { - cursor->SetStateString( "grabbercursor", "0" ); cursor->SetStateString( "combatcursor", "1" ); - cursor->SetStateString( "pickupcursor", "0" ); } - cursor->SetStateString( "cursorposition", buf ); - } else if ( crosshairType == 2 ) { - cursor->SetStateString( "cursorposition", buf ); - if ( ( bIsZoomed || GetTalkCursor() ) && - !( g_weaponHandlingType.GetBool() && ( bWATrace || bWAIsSprinting || OnLadder() ) ) && - ( GetCurrentWeaponNum() > 1 && GetCurrentWeaponNum() < 12 ) ) { - if ( weapon.GetEntity()->GetGrabberState() == 1 || weapon.GetEntity()->GetGrabberState() == 2 ) { - cursor->SetStateString( "grabbercursor", "1" ); - cursor->SetStateString( "combatcursor", "0" ); - cursor->SetStateString( "pickupcursor", "0" ); - } else if ( weapon.GetEntity()->GetGrabberState() != 2 && !grabEntity.GetGrabEntity() && ( focusItem || focusCorpse || focusMoveable ) ) { - cursor->SetStateString( "grabbercursor", "0" ); - cursor->SetStateString( "combatcursor", "0" ); - cursor->SetStateString( "pickupcursor", "1" ); - } else { - cursor->SetStateString( "grabbercursor", "0" ); - cursor->SetStateString( "combatcursor", "1" ); - cursor->SetStateString( "pickupcursor", "0" ); - } - } else { - cursor->SetStateString( "grabbercursor", "0" ); - cursor->SetStateString( "combatcursor", "0" ); - // we still want the pickup icon to show up - if ( weapon.GetEntity()->GetGrabberState() != 2 && !grabEntity.GetGrabEntity() && ( focusItem || focusCorpse || focusMoveable ) ) - cursor->SetStateString( "pickupcursor", "1" ); - else - cursor->SetStateString( "pickupcursor", "0" ); - } - } -#ifdef _D3XP -/* if ( weapon.GetEntity()->GetGrabberState() == 1 || weapon.GetEntity()->GetGrabberState() == 2 ) { - cursor->SetStateString( "grabbercursor", "1" ); - cursor->SetStateString( "combatcursor", "0" ); - } else { - cursor->SetStateString( "grabbercursor", "0" ); + } else if ( usercmd.buttons & !BUTTON_ZOOM && crosshairType != 0 ) { cursor->SetStateString( "combatcursor", "1" ); - }*/ -#endif -// <---sikk - + } +//<- doomtrinity PD3 cursor->Redraw( gameLocal.realClientTime ); } } @@ -3645,7 +3698,7 @@ void idPlayer::UpdateConditions( void ) { AI_STRAFE_RIGHT = false; } - AI_RUN = ( usercmd.buttons & BUTTON_RUN ) && ( ( !pm_stamina.GetFloat() ) || ( stamina > pm_staminathreshold.GetFloat() ) ); + AI_RUN = ( usercmd.buttons & BUTTON_RUN ) && ( ( !pm_stamina.GetFloat() ) || ( stamina > pm_staminathreshold.GetFloat() ) ); // && !( usercmd.buttons & BUTTON_ZOOM ) ;// doomtrinity AI_DEAD = ( health <= 0 ); } @@ -4216,6 +4269,14 @@ void idPlayer::ClearPowerup( int i ) { #endif break; } + +// PD3 start + case ADRENALINE: { + StopSound( SND_CHANNEL_DEMONIC, false ); + break; + } +// PD3 end + case INVISIBILITY: { if ( weapon.GetEntity() ) { weapon.GetEntity()->UpdateSkin(); @@ -4759,6 +4820,7 @@ void idPlayer::NextBestWeapon( void ) { while ( w > 0 ) { w--; weap = spawnArgs.GetString( va( "def_weapon%d", w ) ); +// if ( !weap[ 0 ] || ( ( inventory.weapons & ( 1 << w ) ) == 0 ) || ( !inventory.HasAmmo( weap, true, this ) ) ) {// doomtrinity (D3XP) #ifdef _D3XP if ( !weap[ 0 ] || ( ( inventory.weapons & ( 1 << w ) ) == 0 ) || ( !inventory.HasAmmo( weap, true, this ) ) ) { #else @@ -4778,7 +4840,6 @@ void idPlayer::NextBestWeapon( void ) { continue; } #endif - break; } idealWeapon = w; @@ -4831,6 +4892,7 @@ void idPlayer::NextWeapon( void ) { #else if ( inventory.HasAmmo( weap ) ) { #endif +// if ( inventory.HasAmmo( weap, true, this ) ) {// doomtrinity (D3XP) break; } } @@ -4886,6 +4948,7 @@ void idPlayer::PrevWeapon( void ) { #else if ( inventory.HasAmmo( weap ) ) { #endif + // if ( inventory.HasAmmo( weap, true, this ) ) {// doomtrinity (D3XP) break; } } @@ -4978,10 +5041,12 @@ void idPlayer::SelectWeapon( int num, bool force ) { #endif if ( force || ( inventory.weapons & ( 1 << num ) ) ) { + // if ( !inventory.HasAmmo( weap, true, this ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", num ) ) ) {// doomtrinity (D3XP) #ifdef _D3XP if ( !inventory.HasAmmo( weap, true, this ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", num ) ) ) { #else - if ( !inventory.HasAmmo( weap ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", num ) ) ) { + if ( !inventory.HasAmmo( weap, true, this ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", num ) ) ) {// doomtrinity (D3XP) + // if ( !inventory.HasAmmo( weap ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", num ) ) ) { #endif return; } @@ -4990,8 +5055,10 @@ void idPlayer::SelectWeapon( int num, bool force ) { #ifdef _D3XP if ( !inventory.HasAmmo( weap, true, this ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", previousWeapon ) ) ) { #else - if ( !inventory.HasAmmo( weap ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", previousWeapon ) ) ) { + if ( !inventory.HasAmmo( weap, true, this ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", previousWeapon ) ) ) {// doomtrinity (D3XP) + // if ( !inventory.HasAmmo( weap ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", previousWeapon ) ) ) { #endif + // if ( !inventory.HasAmmo( weap, true, this ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", previousWeapon ) ) ) {// doomtrinity (D3XP) return; } idealWeapon = previousWeapon; @@ -5402,17 +5469,19 @@ void idPlayer::UpdateWeapon( void ) { } else if ( focusCharacter && ( focusCharacter->health > 0 ) ) { Weapon_NPC(); // sikk---> Health Management System (Health Pack)|Manual Item Pickup|Searchable Corpses|Object Manipulation - } else if ( ( g_weaponHandlingType.GetBool() && ( healthPackTimer > gameLocal.time ) || ( searchTimer > gameLocal.time ) ) || + } else if ( ( g_weaponAwareness.GetBool() && ( healthPackTimer > gameLocal.time ) || ( searchTimer > gameLocal.time ) ) || ( g_grabMode.GetBool() && ( grabEntity.GetGrabEntity() || grabEntity.GetThrownTime() > gameLocal.time ) ) ) { StopFiring(); weapon.GetEntity()->LowerWeapon(); // <---sikk -// sikk---> Weapon Handling System - } else if ( GetWeaponHandling() ) { +// sikk---> Weapon Management: Awareness + } else if ( GetWeaponAwareness() ) { if ( idealWeapon != currentWeapon ) Weapon_Combat(); StopFiring(); weapon.GetEntity()->LowerWeapon(); + if ( !OnLadder() ) + bWAUseHideDist = true; // <---sikk } else { Weapon_Combat(); @@ -6182,8 +6251,14 @@ void idPlayer::BobCycle( const idVec3 &pushVelocity ) { bobmove = pm_crouchbob.GetFloat(); // ducked characters never play footsteps } else { - // vary the bobbing based on the speed of the player - bobmove = pm_walkbob.GetFloat() * ( 1.0f - bobFrac ) + pm_runbob.GetFloat() * bobFrac; +//doomtrinity -> + if ( usercmd.buttons & BUTTON_ZOOM ) { + bobmove = pm_adsbob.GetFloat(); + } else { + // vary the bobbing based on the speed of the player + bobmove = pm_walkbob.GetFloat() * ( 1.0f - bobFrac ) + pm_runbob.GetFloat() * bobFrac; + } +//<- doomtrinity } // check for footstep / splash sounds @@ -7117,7 +7192,8 @@ void idPlayer::PerformImpulse( int impulse ) { break; } - case IMPULSE_25: { + // PD3 case IMPULSE_25: { + case IMPULSE_21: { if ( gameLocal.isServer && gameLocal.mpGame.IsGametypeFlagBased() && (gameLocal.serverInfo.GetInt( "si_midnight" ) == 2) ) { if ( enviroSuitLight.IsValid() ) { enviroSuitLight.GetEntity()->PostEventMS( &EV_Remove, 0 ); @@ -7174,22 +7250,29 @@ void idPlayer::PerformImpulse( int impulse ) { break; } +// PD3 +// case IMPULSE_21: { +// SelectWeapon( 13, true ); +// break; +// } + // sikk---> Headlight Mod - case IMPULSE_21: { - if ( GetCurrentWeaponNum() > 0 && !gameLocal.inCinematic ) + case IMPULSE_23: { + if ( !gameLocal.inCinematic ) + // PD3 if ( GetCurrentWeapon() < 11 && !gameLocal.inCinematic ) ToggleHeadlight(); break; } // <---sikk // sikk---> Infrared Goggles PostProcess - case IMPULSE_23: { - if ( GetCurrentWeaponNum() != 16 && !gameLocal.inCinematic && ( !GetInfluenceMaterial() && GetInfluenceEntity() == NULL ) ) + case IMPULSE_24: { + if ( GetCurrentWeapon() != 12 && !gameLocal.inCinematic && ( !GetInfluenceMaterial() && GetInfluenceEntity() == NULL ) ) ToggleIRGoggles(); break; } // <---sikk // sikk---> Health Management System (Health Pack) - case IMPULSE_24: { + case IMPULSE_25: { if ( g_healthManagementType.GetInteger() == 1 ) UseHealthPack(); break; @@ -7305,13 +7388,30 @@ void idPlayer::AdjustSpeed( void ) { float speed; float rate; +// sikk---> Player Speed Type + float crouchSpeed, walkSpeed, runSpeed; + if ( g_playerSpeedType.GetInteger() == 0 ) { + crouchSpeed = 80.0f; + walkSpeed = 140.0f; + runSpeed = 220.0f; + } else if ( g_playerSpeedType.GetInteger() == 1 ) { + crouchSpeed = 120.0f; + walkSpeed = 220.0f; + runSpeed = 320.0f; + } else { + crouchSpeed = pm_crouchspeed.GetFloat(); + walkSpeed = pm_walkspeed.GetFloat(); + runSpeed = pm_runspeed.GetFloat(); + } +// <---sikk + if ( spectating ) { speed = pm_spectatespeed.GetFloat(); bobFrac = 0.0f; } else if ( noclip ) { speed = pm_noclipspeed.GetFloat(); bobFrac = 0.0f; - } else if ( !physicsObj.OnLadder() && ( usercmd.buttons & BUTTON_RUN ) && ( usercmd.forwardmove || usercmd.rightmove ) && ( usercmd.upmove >= 0 ) ) { + } else if ( !physicsObj.OnLadder() && ( usercmd.buttons & BUTTON_RUN ) && ( usercmd.forwardmove || usercmd.rightmove ) && ( usercmd.upmove >= 0 ) && !( usercmd.buttons & BUTTON_ZOOM ) ) {// doomtrinity if ( !gameLocal.isMultiplayer && !physicsObj.IsCrouching() && !PowerUpActive( ADRENALINE ) ) { stamina -= MS2SEC( gameLocal.msec ); } @@ -7339,7 +7439,14 @@ void idPlayer::AdjustSpeed( void ) { if ( stamina > pm_stamina.GetFloat() ) { stamina = pm_stamina.GetFloat(); } - speed = pm_walkspeed.GetFloat() * ( bIsZoomed ? 0.75f : 1.0f ); // sikk - Decreased movement speed when zoomed +//doomtrinity -> + if ( usercmd.buttons & BUTTON_ZOOM ) { + speed = pm_adsspeed.GetFloat(); + } else { + speed = walkSpeed; + } + //speed = walkSpeed * ( g_weaponAwareness.GetBool() && bIsZoomed ? 0.75f : 1.0f ); // sikk - Decreased movement speed when zoomed +//<- doomtrinity bobFrac = 0.0f; } @@ -7750,6 +7857,53 @@ void idPlayer::UpdateHud( void ) { } else { hud->SetStateString( "hudLag", "0" ); } + +// sikk---> Crosshair Positioning PD3 + idStr buf; + if ( g_crosshairType.GetBool() && !GetTalkCursor() && !( focusItem || focusCorpse ) ) { + trace_t tr; + idVec3 ndc; + idVec3 muzzleOrigin; + idMat3 muzzleAxis; + + // detemine the point at which the weapon is aiming + if ( weapon.GetEntity()->GetBarrelJointView() != INVALID_JOINT && + ( weapon.GetEntity()->GetProjectileDict().GetBool( "launchFromBarrel" ) || g_weaponProjectileOrigin.GetBool() ) ) { // sikk - Weapon Management: Projectile Origin + // there is an explicit joint for the muzzle + weapon.GetEntity()->GetGlobalJointTransform( true, weapon.GetEntity()->GetBarrelJointView(), muzzleOrigin, muzzleAxis ); + } else { + // go straight out of the view + muzzleOrigin = firstPersonViewOrigin; + muzzleAxis = firstPersonViewAxis; + } + idVec3 endPos = muzzleOrigin + ( firstPersonViewAxis.ToAngles().ToForward() * 65536.0f ); + gameLocal.clip.TracePoint( tr, muzzleOrigin, endPos, MASK_SHOT_RENDERMODEL, this ); + endPos = tr.endpos; + v3CrosshairPos.Lerp( endPos, v3CrosshairPos, g_crosshairLerp.GetFloat() ); + renderSystem->GlobalToNormalizedDeviceCoordinates( v3CrosshairPos, ndc ); + ndc.x = ( ( ndc.x * 0.5 + 0.5 ) * SCREEN_WIDTH ); + ndc.y = ( ( 1.0f - ( ndc.y * 0.5 + 0.5 ) ) * SCREEN_HEIGHT ); + sprintf( buf, "%d %d 100 32", (int)ndc.x - 16, (int)ndc.y - 16); + } else { + sprintf( buf, "%d %d 100 32", 304, 224 ); + } +// <---sikk PD3 + +// sikk---> Crosshair Cvar PD3 + int crosshairType = g_crosshair.GetInteger(); + if ( crosshairType == 0 ) { + cursor->SetStateString( "combatcursor", "0" ); + } else if ( crosshairType == 1 ) { + if ( !grabEntity.GetGrabEntity() && ( focusItem || focusCorpse || focusMoveable ) ) { + cursor->SetStateString( "combatcursor", "0" ); + cursor->SetStateString( "pickupcursor", "1" ); + } else { + cursor->SetStateString( "combatcursor", "1" ); + cursor->SetStateString( "pickupcursor", "0" ); + } + cursor->SetStateString( "cursorposition", buf ); + } +// <---sikk PD3 } /* @@ -7884,25 +8038,48 @@ void idPlayer::Think( void ) { if ( ( usercmd.buttons ^ oldCmd.buttons ) & BUTTON_MLOOK ) { centerView.Init( gameLocal.time, 200, viewAngles.pitch, 0 ); } +//doomtrinity -> + if ( init_mSensitivity != in_mouseSensitivity.GetFloat() ) { + init_mSensitivity = in_mouseSensitivity.GetFloat(); + cvarSystem->SetCVarFloat( "sensitivity", init_mSensitivity ); + } + if ( init_mSmooth != in_mouseSmooth.GetInteger() ) { + init_mSmooth = in_mouseSmooth.GetInteger(); + cvarSystem->SetCVarInteger( "m_smooth", init_mSmooth ); + } +//<- doomtrinity // zooming if ( ( usercmd.buttons ^ oldCmd.buttons ) & BUTTON_ZOOM ) { if ( ( usercmd.buttons & BUTTON_ZOOM ) && weapon.GetEntity() ) { zoomFov.Init( gameLocal.time, 200.0f, CalcFov( false ), weapon.GetEntity()->GetZoomFov() ); bIsZoomed = true; // sikk - Depth of Field PostProcess +//doomtrinity -> + cvarSystem->SetCVarFloat( "sensitivity", ( in_mouseSensitivity.GetFloat() * 0.75f ) );// Mouse sensitivity is 75% when zooming + cvarSystem->SetCVarInteger( "m_smooth", 8 );// Force the smoothness of the mouse view +//<- doomtrinity } else { zoomFov.Init( gameLocal.time, 200.0f, zoomFov.GetCurrentValue( gameLocal.time ), DefaultFov() ); bIsZoomed = false; // sikk - Depth of Field PostProcess +//doomtrinity -> + cvarSystem->SetCVarFloat( "sensitivity", in_mouseSensitivity.GetFloat() ); + cvarSystem->SetCVarInteger( "m_smooth", in_mouseSmooth.GetInteger() ); +//<- doomtrinity } } -// sikk---> Weapon Handling System - if ( g_weaponHandlingType.GetBool() && !weapon.GetEntity()->IsReady() && bIsZoomed ) { +// sikk---> Weapon Management: Handling/Awareness PD3 + if ( g_weaponAwareness.GetBool() && !weapon.GetEntity()->IsReady() && bIsZoomed ) { zoomFov.Init( gameLocal.time, 200.0f, zoomFov.GetCurrentValue( gameLocal.time ), DefaultFov() ); usercmd.buttons ^= BUTTON_ZOOM; bIsZoomed = false; } -// <---sikk + if ( g_weaponHandlingType.GetInteger() == 1 || g_weaponHandlingType.GetInteger() == 3 ) { + fSpreadModifier -= 0.05f; + if ( fSpreadModifier < 0.0f ) + fSpreadModifier = 0.0f; + } +// <---sikk PD3 // if we have an active gui, we will unrotate the view angles as // we turn the mouse movements into gui events @@ -8166,6 +8343,7 @@ void idPlayer::StopHealthRecharge() { idPlayer::GetCurrentWeapon ================= */ +/* PD3 idStr idPlayer::GetCurrentWeapon() { const char *weapon; @@ -8176,6 +8354,7 @@ idStr idPlayer::GetCurrentWeapon() { return ""; } } +*/ /* ================= @@ -8502,7 +8681,16 @@ void idPlayer::CalcDamagePoints( idEntity *inflictor, idEntity *attacker, const int damage; int armorSave; - damageDef->GetInt( "damage", "20", damage ); +// sikk---> Damage Type PD3 + if ( g_damageType.GetInteger() == 1 && damageDef->GetInt( "damage_doom_scale" ) ) { + damage = damageDef->GetInt( "damage_doom_scale" ) * ( gameLocal.random.RandomInt( 255 ) % damageDef->GetInt( "damage_doom_range" ) + 1 ); + } else if ( g_damageType.GetInteger() == 2 && damageDef->GetInt( "damage_custom" ) ) { + damage = damageDef->GetInt( "damage_custom" ); + } else { + damage = damageDef->GetInt( "damage", "20" ); + } +// <---sikk PD3 + damage = GetDamageForLocation( damage, location ); idPlayer *player = attacker->IsType( idPlayer::Type ) ? static_cast(attacker) : NULL; @@ -9033,7 +9221,8 @@ void idPlayer::CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis ) { // CalculateRenderView must have been called first const idVec3 &viewOrigin = firstPersonViewOrigin; - const idMat3 &viewAxis = firstPersonViewAxis; + //const idMat3 &viewAxis = firstPersonViewAxis; // doomtrinity-headanim - commented out. Use "firstPersonViewWeaponAxis" which doesn't take care of the head orientation. + const idMat3 &viewAxis = firstPersonViewWeaponAxis; // doomtrinity-headanim // these cvars are just for hand tweaking before moving a value to the weapon def idVec3 gunpos( g_gun_x.GetFloat(), g_gun_y.GetFloat(), g_gun_z.GetFloat() ); @@ -9073,12 +9262,16 @@ void idPlayer::CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis ) { origin -= gravity * ( landChange*0.25f * (LAND_DEFLECT_TIME + LAND_RETURN_TIME - delta) / LAND_RETURN_TIME ); } - // speed sensitive idle drift - scale = xyspeed + 40.0f; - fracsin = scale * sin( MS2SEC( gameLocal.time ) ) * 0.01f; - angles.roll += fracsin; - angles.yaw += fracsin; - angles.pitch += fracsin; +//doomtrinity -> + if ( !( usercmd.buttons & BUTTON_ZOOM ) ) { + // speed sensitive idle drift + scale = xyspeed + 40.0f; + fracsin = scale * sin( MS2SEC( gameLocal.time ) ) * 0.01f; + angles.roll += fracsin; + angles.yaw += fracsin; + angles.pitch += fracsin; + } +//<- doomtrinity axis = angles.ToMat3() * viewAxis; } @@ -9183,6 +9376,7 @@ idPlayer::GetViewPos */ void idPlayer::GetViewPos( idVec3 &origin, idMat3 &axis ) const { idAngles angles; + idAngles headAnimAngle; // doomtrinity-headanim // if dead, fix the angle and don't add any kick if ( health <= 0 ) { @@ -9194,6 +9388,17 @@ void idPlayer::GetViewPos( idVec3 &origin, idMat3 &axis ) const { } else { origin = GetEyePosition() + viewBob; angles = viewAngles + viewBobAngles + playerView.AngleOffset(); + //angles = viewAngles + viewBobAngles + playerView.AngleOffset(); // doomtrinity-headanim - commented out +// doomtrinity-headanim --> // Check in the viewmodel if the bone "head" is present, if true take care of its orientation. + if ( weapon.GetEntity()->HasHeadJoint() ) { + headAnimAngle = weapon.GetEntity()->GetHeadAngle(); + angles = viewAngles + viewBobAngles + headAnimAngle + playerView.AngleOffset(); + //gameLocal.Printf( "calculate head anim\n" ); + } else { + angles = viewAngles + viewBobAngles + playerView.AngleOffset(); + //gameLocal.Printf( "DO NOT calculate head anim\n" ); + } +// <-- doomtrinity-headanim axis = angles.ToMat3() * physicsObj.GetGravityAxis(); @@ -9203,6 +9408,31 @@ void idPlayer::GetViewPos( idVec3 &origin, idMat3 &axis ) const { } } +/* +=============== +idPlayer::GetViewWeaponAxis // doomtrinity-headanim +=============== +*/ +void idPlayer::GetViewWeaponAxis( idMat3 &axis ) const { + idAngles angles; + + // if dead, fix the angle and don't add any kick + if ( health <= 0 ) { + angles.yaw = viewAngles.yaw; + angles.roll = 40; + angles.pitch = -15; + axis = angles.ToMat3(); + + } else { + + angles = viewAngles + viewBobAngles + playerView.AngleOffset(); + + axis = angles.ToMat3() * physicsObj.GetGravityAxis(); + + + } +} + /* =============== idPlayer::CalculateFirstPersonView @@ -9231,6 +9461,7 @@ void idPlayer::CalculateFirstPersonView( void ) { firstPersonViewAxis = firstPersonViewAxis * playerView.ShakeAxis(); #endif } + GetViewWeaponAxis( firstPersonViewWeaponAxis ); // doomtrinity-headanim } /* @@ -10605,6 +10836,25 @@ void idPlayer::Event_Gibbed( void ) { // do nothing } +// doomtrinity-dual weapon-> +/* +================== +idPlayer::Event_GetNumPistols +================== +*/ +void idPlayer::Event_GetNumPistols( void ) { + idThread::ReturnInt( inventory.pistolInInventory ); +} +/* +================== +idPlayer::Event_GetNumShotguns +================== +*/ +void idPlayer::Event_GetNumShotguns( void ) { + idThread::ReturnInt( inventory.shotgunDoubleInInventory ); +} +// doomtrinity-dual weapon-< + /* =============== idPlayer::UpdatePlayerIcons @@ -10798,7 +11048,7 @@ void idPlayer::UpdateBattery() { if ( nBattery <= 0 ) { nBattery = 0; ToggleIRGoggles(); - } else if ( GetCurrentWeaponNum() == 16 || gameLocal.inCinematic || PowerUpActive( BERSERK ) || ( GetInfluenceMaterial() || GetInfluenceEntity() ) ) { + } else if ( GetCurrentWeapon() == 16 || gameLocal.inCinematic || PowerUpActive( BERSERK ) || ( GetInfluenceMaterial() || GetInfluenceEntity() ) ) { ToggleIRGoggles(); } } @@ -10828,7 +11078,8 @@ void idPlayer::UpdateBattery() { if ( nBattery <= 0 ) { nBattery = 0; ToggleHeadlight(); - } else if ( GetCurrentWeaponNum() == 0 || GetCurrentWeaponNum() == 16 || gameLocal.inCinematic ) { + } else if ( gameLocal.inCinematic ) { +// PD3 } else if ( GetCurrentWeapon() >= 11 || gameLocal.inCinematic ) { ToggleHeadlight(); } } @@ -10904,7 +11155,7 @@ void idPlayer::ToggleIRGoggles() { StartSoundShader( declManager->FindSound( "player_sounds_irgoggles_off" ), SND_CHANNEL_VOICE, 0, false, NULL ); // reset bloom parms - r_useBloom.SetBool( (bool)fIRBloomParms[ 0 ] ); + r_useBloom.SetInteger( fIRBloomParms[ 0 ] ); r_bloomBufferSize.SetInteger( (int)fIRBloomParms[ 1 ] ); r_bloomBlurIterations.SetInteger( (int)fIRBloomParms[ 2 ] ); r_bloomBlurScaleX.SetFloat( (int)fIRBloomParms[ 3 ] ); @@ -10942,9 +11193,9 @@ void idPlayer::ToggleHeadlight() { args.Set( "classname", "light" ); args.Set( "name", name + "_headlight" ); // light name args.Set( "texture", "lights/headlight" ); // light texture - args.Set( "light_target", "768 0 0" ); // light cone direction - args.Set( "light_up", "0 0 192" ); // light cone height - args.Set( "light_right", "0 -192 0" ); // light cone width + args.Set( "light_target", "1536 0 0" ); // light cone direction // doomtrinity-was 768 0 0 + args.Set( "light_up", "0 0 768" ); // light cone height // doomtrinity-was 0 0 192 + args.Set( "light_right", "0 -768 0" ); // light cone width // doomtrinity-was 0 -192 0 gameLocal.SpawnEntityDef( args, &ent ); ent->BindToJoint( this, "head", 0.0f ); // light bind parent joint ent->SetOrigin( idVec3( 8, -12, 4 ) ); // light origin @@ -11062,8 +11313,10 @@ idPlayer::UseAdrenaline */ void idPlayer::UseAdrenaline() { if ( adrenalineAmount ) { - inventory.GivePowerUp( this, ADRENALINE, 0 ); - StartSoundShader( declManager->FindSound( "pickup_adrenaline" ), SND_CHANNEL_ITEM, 0, false, NULL ); + inventory.GivePowerUp( this, BERSERK, 0 ); // PD3 + // PD3 inventory.GivePowerUp( this, ADRENALINE, 0 ); + // PD3 StartSoundShader( declManager->FindSound( "pickup_adrenaline" ), SND_CHANNEL_ITEM, 0, false, NULL ); + StartSoundShader( declManager->FindSound( "player_sounds_berserk" ), SND_CHANNEL_DEMONIC, 0, false, NULL ); // PD3 stamina = 100.0f; adrenalineAmount = 0; } @@ -11112,14 +11365,14 @@ void idPlayer::SearchCorpse( idAFEntity_Gibbable* corpse ) { } // <---sikk -// sikk---> Weapon Handling System +// sikk---> Weapon Management: Awareness PD3 /* ================== -idPlayer::GetWeaponHandling +idPlayer::GetWeaponAwareness ================== */ -bool idPlayer::GetWeaponHandling() { - if ( g_weaponHandlingType.GetBool() ) { +bool idPlayer::GetWeaponAwareness() { + if ( g_weaponAwareness.GetBool() ) { idEntity *ent; trace_t trace; idVec3 start = GetEyePosition(); @@ -11127,7 +11380,7 @@ bool idPlayer::GetWeaponHandling() { gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_RENDERMODEL, this ); bWATrace = false; - if ( ( trace.fraction < 1.0f ) && ( GetCurrentWeaponNum() > 1 && GetCurrentWeaponNum() < 12 ) ) { + if ( ( trace.fraction < 1.0f ) && ( GetCurrentWeapon() > 0 && GetCurrentWeapon() < 9 ) ) { ent = gameLocal.entities[ trace.c.entityNum ]; if ( ent && !ent->IsType( idAI::Type ) ) bWATrace = true; @@ -11135,7 +11388,7 @@ bool idPlayer::GetWeaponHandling() { bWATrace = false; } - bWAIsSprinting = ( ( GetCurrentWeaponNum() > 1 && GetCurrentWeaponNum() < 12 ) && AI_RUN && ( AI_FORWARD || AI_BACKWARD || AI_STRAFE_LEFT || AI_STRAFE_RIGHT ) ); + bWAIsSprinting = ( ( GetCurrentWeapon() >= 0 ) && AI_RUN && ( AI_FORWARD || AI_BACKWARD || AI_STRAFE_LEFT || AI_STRAFE_RIGHT ) ); if ( bWATrace || bWAIsSprinting || OnLadder() ) return true; @@ -11143,4 +11396,4 @@ bool idPlayer::GetWeaponHandling() { return false; } -// <---sikk +// <---sikk PD3 diff --git a/d3xp/Player.h b/d3xp/Player.h index b70cbc4..4074404 100644 --- a/d3xp/Player.h +++ b/d3xp/Player.h @@ -152,6 +152,8 @@ class idInventory { public: int maxHealth; int weapons; + int shotgunDoubleInInventory; // doomtrinity-dual weapon + int pistolInInventory; // doomtrinity-dual weapon int powerups; int armor; int maxarmor; @@ -221,6 +223,8 @@ public: bool HasEmptyClipCannotRefill(const char *weapon_classname, idPlayer* owner); #endif +// int HasAmmo( const char *weapon_classname, bool includeClip = false, idPlayer* owner = NULL ); // looks up the ammo information for the weapon class first // doomtrinity (D3XP) + void UpdateArmor( void ); int nextItemPickup; @@ -314,6 +318,14 @@ public: int weapon_soulcube; int weapon_pda; int weapon_fists; +//doomtrinity -> + int weapon_pistol; + int weapon_shotgun; + int weapon_superShotgun; + int weapon_machinegun; + int weapon_plasmagun; + int weapon_rocketlauncher; +//<- doomtrinity #ifdef _D3XP int weapon_bloodstone; int weapon_bloodstone_active1; @@ -385,6 +397,7 @@ public: // if a third person view is used idVec3 firstPersonViewOrigin; idMat3 firstPersonViewAxis; + idMat3 firstPersonViewWeaponAxis; // doomtrinity-headanim idDragEntity dragEntity; @@ -479,6 +492,7 @@ public: void CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis ); idVec3 GetEyePosition( void ) const; void GetViewPos( idVec3 &origin, idMat3 &axis ) const; + void GetViewWeaponAxis( idMat3 &axis ) const; // doomtrinity-headanim void OffsetThirdPersonView( float angle, float range, float height, bool clip ); bool Give( const char *statname, const char *value ); @@ -605,7 +619,7 @@ public: void StartHealthRecharge(int speed); void StopHealthRecharge(); - idStr GetCurrentWeapon(); +// PD3 idStr GetCurrentWeapon(); bool CanGive( const char *statname, const char *value ); @@ -657,15 +671,18 @@ public: int prevHeatlh; // sikk - holds player health after Health station has been used // <---sikk -// sikk---> Crosshair Positioning - int GetCurrentWeaponNum( void ) { return currentWeapon; }; +// sikk---> Crosshair Positioning PD3 + int GetCurrentWeapon( void ) { return currentWeapon; }; idVec3 v3CrosshairPos; // <---sikk -// sikk---> Weapon Handling System - bool GetWeaponHandling( void ); +// sikk---> Weapon Management: Awareness PD3 + bool GetWeaponAwareness( void ); bool bWATrace; bool bWAIsSprinting; + bool bWAUseHideDist; + float fSpreadModifier; + idEntity* entChainsawed; // <---sikk // sikk---> Depth Render @@ -749,6 +766,10 @@ private: idInterpolate zoomFov; idInterpolate centerView; bool fxFov; +//doomtrinity -> + float init_mSensitivity; + int init_mSmooth; +//<- doomtrinity float influenceFov; int influenceActive; // level of influence.. 1 == no gun or hud .. 2 == 1 + no movement @@ -895,6 +916,9 @@ private: void Event_ToggleBloom( int on ); void Event_SetBloomParms( float speed, float intensity ); #endif + // doomtrinity-dual weapon + void Event_GetNumPistols( void ); + void Event_GetNumShotguns( void ); }; ID_INLINE bool idPlayer::IsReady( void ) { diff --git a/d3xp/PlayerView.cpp b/d3xp/PlayerView.cpp index 000e871..52cfade 100644 --- a/d3xp/PlayerView.cpp +++ b/d3xp/PlayerView.cpp @@ -281,16 +281,17 @@ void idPlayerView::ClearEffects() { /* ============== -idPlayerView::GetScreenBlob +idPlayerView::GetScreenBlob PD3 ============== */ screenBlob_t *idPlayerView::GetScreenBlob() { screenBlob_t *oldest = &screenBlobs[0]; - for ( int i = 1 ; i < MAX_SCREEN_BLOBS ; i++ ) - if ( screenBlobs[i].finishTime < oldest->finishTime ) + for ( int i = 1 ; i < MAX_SCREEN_BLOBS ; i++ ) { + if ( screenBlobs[i].finishTime < oldest->finishTime ) { oldest = &screenBlobs[i]; - + } + } return oldest; } @@ -338,29 +339,36 @@ void idPlayerView::DamageImpulse( idVec3 localKickDir, const idDict *damageDef ) } // screen blob + /* PD3 float blobTime = damageDef->GetFloat( "blob_time" ); if ( blobTime ) { screenBlob_t *blob = GetScreenBlob(); - blob->startFadeTime = gameLocal.slow.time; - blob->finishTime = gameLocal.slow.time + blobTime * g_blobTime.GetFloat() * ( (float)gameLocal.msec / USERCMD_MSEC ); - + blob->startFadeTime = gameLocal.time; + blob->finishTime = gameLocal.time + blobTime * g_blobTime.GetFloat(); + blob->driftAmount = 0.0f; // sikk - Blood Spray Screen Effect - keeps damage blood splats from drifting const char *materialName = damageDef->GetString( "mtr_blob" ); blob->material = declManager->FindMaterial( materialName ); blob->x = damageDef->GetFloat( "blob_x" ); - blob->x += ( gameLocal.random.RandomInt()&63 ) - 32; + blob->x += ( gameLocal.random.RandomInt() & 63 ) - 32; blob->y = damageDef->GetFloat( "blob_y" ); - blob->y += ( gameLocal.random.RandomInt()&63 ) - 32; + blob->y += ( gameLocal.random.RandomInt() & 63 ) - 32; - float scale = ( 256 + ( ( gameLocal.random.RandomInt()&63 ) - 32 ) ) / 256.0f; + float scale = ( 256 + ( ( gameLocal.random.RandomInt() & 63 ) - 32 ) ) / 256.0f; blob->w = damageDef->GetFloat( "blob_width" ) * g_blobSize.GetFloat() * scale; blob->h = damageDef->GetFloat( "blob_height" ) * g_blobSize.GetFloat() * scale; - blob->s1 = 0.0f; - blob->t1 = 0.0f; - blob->s2 = 1.0f; - blob->t2 = 1.0f; + blob->s1 = 0; + blob->t1 = 0; + blob->s2 = 1; + blob->t2 = 1; } + */ + + //PD3 + if ( g_showBloodSpray.GetBool() ) { + player->playerView.AddBloodSpray( g_bloodSprayTime.GetFloat() ); + } // save lastDamageTime for tunnel vision accentuation lastDamageTime = MS2SEC( gameLocal.slow.time ); @@ -375,8 +383,9 @@ but having it localized here lets the material be pre-looked up etc. ================== */ void idPlayerView::AddBloodSpray( float duration ) { - if ( duration <= 0 || bloodSprayMaterial == NULL || g_skipViewEffects.GetBool() ) + if ( duration <= 0 || bloodSprayMaterial == NULL || g_skipViewEffects.GetBool() ) { // PD3 return; + } // PD3 // sikk---> Blood Spray Screen Effect // Use random material @@ -393,8 +402,8 @@ void idPlayerView::AddBloodSpray( float duration ) { blob->material = bloodSprayMaterial; blob->x = ( gameLocal.random.RandomInt() & 63 ) - 32; blob->y = ( gameLocal.random.RandomInt() & 63 ) - 32; - blob->driftAmount = 0.5f + gameLocal.random.CRandomFloat() * 0.5; - float scale = ( 256 + ( ( gameLocal.random.RandomInt()&63 ) - 32 ) ) / 256.0f; + blob->driftAmount = 0.0f;// 0.5f + gameLocal.random.CRandomFloat() * 0.5f; // sikk - No more drifting PD3 + float scale = ( 256 + ( ( gameLocal.random.RandomInt() & 63 ) - 32 ) ) / 256.0f; // PD3 blob->w = 640 * g_blobSize.GetFloat() * scale; // sikk - This was "600". Typo? blob->h = 480 * g_blobSize.GetFloat() * scale; float s1 = 0.0f; @@ -427,7 +436,8 @@ void idPlayerView::AddBloodSpray( float duration ) { t1 = 1.0f; t2 = 0.0f; } -// <---sikk blob->s1 = s1; +// <---sikk PD3 + blob->s1 = s1; blob->t1 = t1; blob->s2 = s2; blob->t2 = t2; @@ -449,6 +459,19 @@ void idPlayerView::WeaponFireFeedback( const idDict *weaponDef ) { idAngles angles; weaponDef->GetAngles( "recoilAngles", "5 0 0", angles ); kickAngles = angles; + +// sikk---> Weapon Management: Handling/Awareness + if ( g_weaponHandlingType.GetInteger() > 1 ) { + float mod = ( ( player->GetCurrentWeapon() == 2 ) ? 1.0f : weaponDef->GetFloat( "spread" ) + 1.0f ) * player->fSpreadModifier; + + idVec2 vec = idVec2( -gameLocal.random.RandomFloat(), gameLocal.random.CRandomFloat() ); + vec.NormalizeFast(); + vec *= gameLocal.random.RandomFloat() * mod; + kickAngles.pitch += vec.x; + kickAngles.yaw += vec.y; + } +// <---sikk + int finish = gameLocal.slow.time + g_kickTime.GetFloat() * recoilTime; kickFinishTime = finish; } @@ -1887,13 +1910,11 @@ void idPlayerView::RenderDepth( bool bCrop ) { // set our depthView parms renderView_t depthView = hackedView; depthView.viewID = -8; -// depthView.globalMaterial = depthMaterial; - cvarSystem->SetCVarString( "r_materialOverride", "render/depth" ); + depthView.globalMaterial = depthMaterial; // render scene gameRenderWorld->RenderScene( &depthView ); // capture image for our depth buffer renderSystem->CaptureRenderToImage( "_ssDepth" ); - cvarSystem->SetCVarString( "r_materialOverride", "" ); } // Restore player models @@ -1980,7 +2001,7 @@ void idPlayerView::ToggleShadows( bool noShadows ) { idLight *light; // handle player's flashlight specifically - if ( player->GetCurrentWeaponNum() == 0 ) { + if ( player->GetCurrentWeapon() == 11 ) { if ( pm_thirdPerson.GetBool() ) { renderLight_t *mf = player->weapon.GetEntity()->GetWorldMuzzleFlash(); int mfHandle = player->weapon.GetEntity()->GetWorldMuzzleFlashHandle(); @@ -2030,7 +2051,7 @@ void idPlayerView::ResetShadows() { idLight *light; // handle player's flashlight specifically - if ( player->GetCurrentWeaponNum() == 0 ) { + if ( player->GetCurrentWeapon() == 11 ) { if ( pm_thirdPerson.GetBool() ) { renderLight_t *mf = player->weapon.GetEntity()->GetWorldMuzzleFlash(); int mfHandle = player->weapon.GetEntity()->GetWorldMuzzleFlashHandle(); @@ -2072,8 +2093,8 @@ idPlayerView::PostFX_EdgeAA */ void idPlayerView::PostFX_EdgeAA() { renderSystem->CaptureRenderToImage( "_currentRender" ); - renderSystem->SetColor4( r_edgeAASampleScale.GetFloat(), r_edgeAAFilterScale.GetFloat(), 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, edgeAAMaterial ); + renderSystem->SetColor4( r_edgeAASampleScale.GetFloat(), r_edgeAAFilterScale.GetFloat(), 1.0f, r_useEdgeAA.GetFloat() ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, edgeAAMaterial ); } /* @@ -2107,7 +2128,7 @@ void idPlayerView::PostFX_HDR() { renderSystem->CropRenderSize( 256, 256, true, true ); renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, shiftScale.y, shiftScale.x, 0.0f, currentRenderMaterial ); renderSystem->CaptureRenderToImage( "_hdrLum" ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrLumBaseMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrLumBaseMaterial ); renderSystem->CaptureRenderToImage( "_hdrLum" ); renderSystem->CaptureRenderToImage( "_hdrLumAvg" ); renderSystem->UnCrop(); @@ -2116,7 +2137,7 @@ void idPlayerView::PostFX_HDR() { // Output will be a 1x1 pixel of the average luminance for ( int i = 256; i > 1; i *= 0.5 ) { renderSystem->CropRenderSize( i, i, true, true ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrLumAverageMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrLumAverageMaterial ); renderSystem->CaptureRenderToImage( "_hdrLumAvg" ); renderSystem->UnCrop(); } @@ -2124,7 +2145,7 @@ void idPlayerView::PostFX_HDR() { // create adapted luminance map based on current average luminance and previous adapted luminance maps renderSystem->CropRenderSize( 2, 2, true, true ); renderSystem->SetColor4( r_hdrAdaptationRate.GetFloat(), fElapsedTime, r_hdrLumThresholdMin.GetFloat(), r_hdrLumThresholdMax.GetFloat() ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrLumAdaptedMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrLumAdaptedMaterial ); renderSystem->CaptureRenderToImage( "_hdrLumAdpt" ); renderSystem->UnCrop(); @@ -2135,15 +2156,15 @@ void idPlayerView::PostFX_HDR() { renderSystem->CaptureRenderToImage( "_hdrBloom" ); renderSystem->SetColor4( r_hdrBloomMiddleGray.GetFloat(), r_hdrBloomWhitePoint.GetFloat(), r_hdrBloomThreshold.GetFloat(), r_hdrBloomOffset.GetFloat() ); if ( r_hdrBloomToneMapper.GetInteger() == 0 ) - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrBrightPass1Material ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrBrightPass1Material ); else if ( r_hdrBloomToneMapper.GetInteger() == 1 ) - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrBrightPass2Material ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrBrightPass2Material ); else if ( r_hdrBloomToneMapper.GetInteger() == 2 ) - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrBrightPass3Material ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrBrightPass3Material ); else if ( r_hdrBloomToneMapper.GetInteger() == 3 ) - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrBrightPass4Material ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrBrightPass4Material ); else if ( r_hdrBloomToneMapper.GetInteger() == 4 ) - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrBrightPass5Material ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrBrightPass5Material ); renderSystem->CaptureRenderToImage( "_hdrBloom" ); renderSystem->CaptureRenderToImage( "_hdrFlare" ); renderSystem->UnCrop(); @@ -2152,10 +2173,10 @@ void idPlayerView::PostFX_HDR() { for ( int i = 0; i < 2; i++ ) { renderSystem->CropRenderSize( nBloomWidth, nBloomHeight, true, true ); renderSystem->SetColor4( r_hdrBloomSize.GetFloat(), 0.0f, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrBloomMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrBloomMaterial ); renderSystem->CaptureRenderToImage( "_hdrBloom" ); renderSystem->SetColor4( 0.0f, r_hdrBloomSize.GetFloat(), r_hdrBloomScale.GetFloat(), 1.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrBloomMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrBloomMaterial ); renderSystem->CaptureRenderToImage( "_hdrBloom" ); renderSystem->UnCrop(); } @@ -2166,16 +2187,16 @@ void idPlayerView::PostFX_HDR() { renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 1.0f, 0.0f, 0.0f, 1.0f, declManager->FindMaterial( "_hdrFlare" ) ); renderSystem->CaptureRenderToImage( "_hdrFlare" ); renderSystem->SetColor4( r_hdrFlareGamma.GetFloat(), 1.0f, 1.0f, 0.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrFlareMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrFlareMaterial ); renderSystem->CaptureRenderToImage( "_hdrFlare" ); renderSystem->SetColor4( r_hdrFlareSize.GetFloat(), 1.0f, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrFlareMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrFlareMaterial ); renderSystem->CaptureRenderToImage( "_hdrFlare" ); renderSystem->SetColor4( DEG2RAD( r_hdrFlareSize.GetFloat() ), 1.0f, 1.0f, 2.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrFlareMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrFlareMaterial ); renderSystem->CaptureRenderToImage( "_hdrFlare" ); renderSystem->SetColor4( DEG2RAD( r_hdrFlareSize.GetFloat() ), r_hdrFlareScale.GetFloat(), 1.0f, 2.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrFlareMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrFlareMaterial ); renderSystem->CaptureRenderToImage( "_hdrFlare" ); renderSystem->UnCrop(); } @@ -2185,7 +2206,7 @@ void idPlayerView::PostFX_HDR() { if ( r_hdrGlareStyle.GetInteger() == 0 ) { // bloom off (clear textures) renderSystem->CropRenderSize( 1, 1, true, true ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, blackMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, blackMaterial ); renderSystem->CaptureRenderToImage( "_hdrBloom" ); renderSystem->CaptureRenderToImage( "_hdrFlare" ); renderSystem->CaptureRenderToImage( "_hdrGlare" ); @@ -2193,11 +2214,13 @@ void idPlayerView::PostFX_HDR() { } else if ( r_hdrGlareStyle.GetInteger() == 1 ) { // natural bloom (clear just _hdrGlare) renderSystem->CropRenderSize( 1, 1, true, true ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, blackMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, blackMaterial ); renderSystem->CaptureRenderToImage( "_hdrGlare" ); renderSystem->UnCrop(); } else if ( r_hdrGlareStyle.GetInteger() > 1 ) { - int nGlareBlend; + int nGlareBlend = 0; + idVec3 v3GlareParm; + v3GlareParm.Zero(); // crop _hdrBloom1 for glare textures renderSystem->CropRenderSize( nGlareWidth, nGlareHeight, true, true ); @@ -2206,138 +2229,79 @@ void idPlayerView::PostFX_HDR() { renderSystem->CaptureRenderToImage( "_hdrGlareY" ); renderSystem->CaptureRenderToImage( "_hdrGlareZ" ); - switch ( r_hdrGlareStyle.GetInteger() ) { - case 2: // star glare - for ( int i = 1; i <= 3; i++ ) { - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 0.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareX" ); - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareY" ); - } + if ( r_hdrGlareStyle.GetInteger() == 2 ) { // star glare + v3GlareParm = idVec3( 0.0f, 1.0, -1.0f ); nGlareBlend = 2; - break; - case 3: // cross glare - for ( int i = 1; i <= 3; i++ ) { - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 2.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareX" ); - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 3.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareY" ); - } + } else if ( r_hdrGlareStyle.GetInteger() == 3 ) { // cross glare + v3GlareParm = idVec3( 2.0f, 3.0, -1.0f ); nGlareBlend = 2; - break; - case 4: // snow cross glare - for ( int i = 1; i <= 3; i++ ) { - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 4.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareX" ); - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 5.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareY" ); - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 6.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareZ" ); - } + } else if ( r_hdrGlareStyle.GetInteger() == 4 ) { // snow cross glare + v3GlareParm = idVec3( 4.0f, 5.0, 6.0f ); nGlareBlend = 3; - break; - case 5: // horizontal glare - for ( int i = 1; i <= 3; i++ ) { - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 7.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareX" ); - } + } else if ( r_hdrGlareStyle.GetInteger() == 5 ) { // horizontal glare + v3GlareParm = idVec3( 7.0f, -1.0, -1.0f ); nGlareBlend = 0; - break; - case 6: // vertical glare - for ( int i = 1; i <= 3; i++ ) { - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 8.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareY" ); - } + } else if ( r_hdrGlareStyle.GetInteger() == 6 ) { // vertical glare + v3GlareParm = idVec3( -1.0f, 8.0, -1.0f ); nGlareBlend = 1; - break; - case 7: // star glare with chromatic abberation - for ( int i = 1; i <= 3; i++ ) { - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 9.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareX" ); - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 10.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareY" ); - } + } else if ( r_hdrGlareStyle.GetInteger() == 7 ) { // star glare with chromatic abberation + v3GlareParm = idVec3( 9.0f, 10.0, -1.0f ); nGlareBlend = 2; - break; - case 8: // cross glare with chromatic abberation - for ( int i = 1; i <= 3; i++ ) { - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 11.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareX" ); - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 12.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareY" ); - } + } else if ( r_hdrGlareStyle.GetInteger() == 8 ) { // cross glare with chromatic abberation + v3GlareParm = idVec3( 11.0f, 12.0, -1.0f ); nGlareBlend = 2; - break; - case 9: // snow cross glare with chromatic abberation - for ( int i = 1; i <= 3; i++ ) { - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 13.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareX" ); - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 14.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareY" ); - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 15.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareZ" ); - } + } else if ( r_hdrGlareStyle.GetInteger() == 9 ) { // snow cross glare with chromatic abberation + v3GlareParm = idVec3( 13.0f, 14.0, 15.0f ); nGlareBlend = 3; - break; - case 10: // horizontal glare with chromatic abberation - for ( int i = 1; i <= 3; i++ ) { - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 16.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareX" ); - } + } else if ( r_hdrGlareStyle.GetInteger() == 10 ) { // horizontal glare with chromatic abberation + v3GlareParm = idVec3( 16.0f, -1.0, -1.0f ); nGlareBlend = 0; - break; - case 11: // vertical glare with chromatic abberation - for ( int i = 1; i <= 3; i++ ) { - renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, 17.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); - renderSystem->CaptureRenderToImage( "_hdrGlareY" ); - } + } else if ( r_hdrGlareStyle.GetInteger() == 11 ) { // vertical glare with chromatic abberation + v3GlareParm = idVec3( -1.0f, 17.0, -1.0f ); nGlareBlend = 1; - break; } + + for ( int i = 1; i <= 3; i++ ) { + if ( v3GlareParm.x >= 0.0f ) { + renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, v3GlareParm.x ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrGlareMaterial ); + renderSystem->CaptureRenderToImage( "_hdrGlareX" ); + } + if ( v3GlareParm.y >= 0.0f ) { + renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, v3GlareParm.y ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrGlareMaterial ); + renderSystem->CaptureRenderToImage( "_hdrGlareY" ); + } + if ( v3GlareParm.z >= 0.0f ) { + renderSystem->SetColor4( r_hdrGlareSize.GetFloat(), i, 1.0f, v3GlareParm.z ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrGlareMaterial ); + renderSystem->CaptureRenderToImage( "_hdrGlareZ" ); + } + } + // blend glare textures and capture to a single texture renderSystem->SetColor4( r_hdrGlareScale.GetFloat(), 1.0f, nGlareBlend, 18.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrGlareMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrGlareMaterial ); renderSystem->CaptureRenderToImage( "_hdrGlare" ); renderSystem->UnCrop(); } - if ( r_hdrDither.GetBool() && ( !bDitherRendered || ( fDitherSize != r_hdrDitherSize.GetFloat() ) ) ) { + if ( r_hdrDither.GetBool() ) { float size = 16.0f * r_hdrDitherSize.GetFloat(); renderSystem->SetColor4( renderSystem->GetScreenWidth() / size, renderSystem->GetScreenHeight() / size, 1.0f, -1.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrFinalMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrFinalMaterial ); renderSystem->CaptureRenderToImage( "_hdrDither" ); - bDitherRendered = true; - } else if ( !r_hdrDither.GetBool() && bDitherRendered ) { + } else { renderSystem->CropRenderSize( 1, 1, true, true ); renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, -2.0f ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrFinalMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrFinalMaterial ); renderSystem->CaptureRenderToImage( "_hdrDither" ); renderSystem->UnCrop(); - bDitherRendered = false; } - fDitherSize = r_hdrDitherSize.GetFloat(); // perform final tone mapping renderSystem->SetColor4( r_hdrMiddleGray.GetFloat(), r_hdrWhitePoint.GetFloat(), r_hdrBlueShiftFactor.GetFloat(), r_hdrToneMapper.GetInteger() + 5 * r_useVignetting.GetBool() ); - renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f, 1.0f, 0.0f, hdrFinalMaterial ); + renderSystem->DrawStretchPic( 0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, hdrFinalMaterial ); } /* diff --git a/d3xp/Projectile.cpp b/d3xp/Projectile.cpp index 888dec4..105bac9 100644 --- a/d3xp/Projectile.cpp +++ b/d3xp/Projectile.cpp @@ -998,10 +998,14 @@ void idProjectile::Explode( const trace_t &collision, idEntity *ignore ) { if ( removeTime < delay * 1000 ) { removeTime = ( delay + 0.10 ) * 1000; } - PostEventSec( &EV_RadiusDamage, delay, ignore ); +// sikk---> Entities hit directly by a projectile will no longer be ignored by splash damage PD3 +// PostEventSec( &EV_RadiusDamage, delay, ignore ); + PostEventSec( &EV_RadiusDamage, delay, NULL ); } else { - Event_RadiusDamage( ignore ); +// Event_RadiusDamage( ignore ); + Event_RadiusDamage( NULL ); } +// <---sikk PD3 } // spawn debris entities @@ -2415,10 +2419,25 @@ void idDebris::Restore( idRestoreGame *savefile ) { idDebris::Launch ================= */ +/********************************************************* +doomtrinity-> +Following method includes code from Denton's mod v. 2.02 +to enhance brass ejection behaviour. +Be sure to add the macro +_DENTONMOD +in the game properties if you want to compile the code +with his changes. +Thanks to Clone JC Denton +*********************************************************/ void idDebris::Launch( void ) { float fuse; idVec3 velocity; +#ifdef _DENTONMOD + idVec3 angular_velocity_vect; +#else idAngles angular_velocity; +#endif + float linear_friction; float angular_friction; float contact_friction; @@ -2432,7 +2451,12 @@ void idDebris::Launch( void ) { renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); spawnArgs.GetVector( "velocity", "0 0 0", velocity ); +#ifdef _DENTONMOD + angular_velocity_vect = spawnArgs.GetAngles( "angular_velocity", "0 0 0").ToAngularVelocity(); +#else spawnArgs.GetAngles( "angular_velocity", "0 0 0", angular_velocity ); +#endif + linear_friction = spawnArgs.GetFloat( "linear_friction" ); angular_friction = spawnArgs.GetFloat( "angular_friction" ); @@ -2448,9 +2472,29 @@ void idDebris::Launch( void ) { } if ( randomVelocity ) { +#ifdef _DENTONMOD + float rand = spawnArgs.GetFloat("linear_velocity_rand", "0.35"); + + // sets velocity randomly between ((1-rand)*100)% and ((1+rand)*100)% + // e.g.1: if rand = 0.2, velocity will be randomly set between 80% and 120% + // e.g.2: if rand = 0.3, velocity will be randomly set between 70% and 130% + // and so on. + velocity.x *= gameLocal.random.RandomFloat()*rand*2.0 + 1.0 - rand; + velocity.y *= gameLocal.random.RandomFloat()*rand*2.0 + 1.0 - rand; + velocity.z *= gameLocal.random.RandomFloat()*rand*2.0 + 1.0 - rand; + + // do not perform following calculations unless there's key in decl that says so. + if( spawnArgs.GetFloat( "angular_velocity_rand", "0.0", rand) && rand > 0.0f ) { + angular_velocity_vect.x *= gameLocal.random.RandomFloat()*rand*2.0 + 1.0 - rand; + angular_velocity_vect.y *= gameLocal.random.RandomFloat()*rand*2.0 + 1.0 - rand; + angular_velocity_vect.z *= gameLocal.random.RandomFloat()*rand*2.0 + 1.0 - rand; + } +#else velocity.x *= gameLocal.random.RandomFloat() + 0.5f; velocity.y *= gameLocal.random.RandomFloat() + 0.5f; velocity.z *= gameLocal.random.RandomFloat() + 0.5f; +#endif + } if ( health ) { @@ -2491,8 +2535,22 @@ void idDebris::Launch( void ) { physicsObj.SetGravity( gravVec * gravity ); physicsObj.SetContents( 0 ); physicsObj.SetClipMask( MASK_SOLID | CONTENTS_MOVEABLECLIP ); +#ifdef _DENTONMOD + // Make sure that the linear velocity is added with + // owner's linear velocity for more accurate physics simulation. + idEntity *ownerEnt = owner.GetEntity(); + if( ownerEnt != NULL ) { + physicsObj.SetLinearVelocity( (axis[ 0 ] * velocity[ 0 ] + axis[ 1 ] * velocity[ 1 ] + axis[ 2 ] * velocity[ 2 ]) + ownerEnt->GetPhysics()->GetLinearVelocity()); + } + else { + physicsObj.SetLinearVelocity( axis[ 0 ] * velocity[ 0 ] + axis[ 1 ] * velocity[ 1 ] + axis[ 2 ] * velocity[ 2 ] ); + } + physicsObj.SetAngularVelocity( angular_velocity_vect * axis ); +#else physicsObj.SetLinearVelocity( axis[ 0 ] * velocity[ 0 ] + axis[ 1 ] * velocity[ 1 ] + axis[ 2 ] * velocity[ 2 ] ); physicsObj.SetAngularVelocity( angular_velocity.ToAngularVelocity() * axis ); +#endif + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); physicsObj.SetAxis( axis ); SetPhysics( &physicsObj ); diff --git a/d3xp/Weapon.cpp b/d3xp/Weapon.cpp index 20c0bd5..02acf8d 100644 --- a/d3xp/Weapon.cpp +++ b/d3xp/Weapon.cpp @@ -75,6 +75,7 @@ const idEventDef EV_Weapon_AllowDrop( "allowDrop", "d" ); const idEventDef EV_Weapon_AutoReload( "autoReload", NULL, 'f' ); const idEventDef EV_Weapon_NetReload( "netReload" ); const idEventDef EV_Weapon_IsInvisible( "isInvisible", NULL, 'f' ); +const idEventDef EV_Weapon_IsLowered( "isLowered", NULL, 'd' ); // doomtrinity const idEventDef EV_Weapon_NetEndReload( "netEndReload" ); #ifdef _D3XP const idEventDef EV_Weapon_GrabberHasTarget( "grabberHasTarget", NULL, 'd' ); @@ -129,6 +130,7 @@ CLASS_DECLARATION( idAnimatedEntity, idWeapon ) EVENT( EV_Weapon_AutoReload, idWeapon::Event_AutoReload ) EVENT( EV_Weapon_NetReload, idWeapon::Event_NetReload ) EVENT( EV_Weapon_IsInvisible, idWeapon::Event_IsInvisible ) + EVENT( EV_Weapon_IsLowered, idWeapon::Event_IsLowered ) // doomtrinity EVENT( EV_Weapon_NetEndReload, idWeapon::Event_NetEndReload ) #ifdef _D3XP EVENT( EV_Weapon_Grabber, idWeapon::Event_Grabber ) @@ -373,6 +375,7 @@ void idWeapon::Save( idSaveGame *savefile ) const { savefile->WriteJoint( ejectJointView ); savefile->WriteJoint( guiLightJointView ); savefile->WriteJoint( ventLightJointView ); + savefile->WriteJoint( headJointView ); // doomtrinity-headanim savefile->WriteJoint( flashJointWorld ); savefile->WriteJoint( barrelJointWorld ); @@ -443,7 +446,7 @@ void idWeapon::Save( idSaveGame *savefile ) const { } #endif - savefile->WriteFloat( wh_hide_distance ); // sikk - Weapon Handling System + savefile->WriteFloat( wm_hide_distance ); // sikk - Weapon Management: Awareness PD3 } /* @@ -574,6 +577,7 @@ void idWeapon::Restore( idRestoreGame *savefile ) { savefile->ReadJoint( ejectJointView ); savefile->ReadJoint( guiLightJointView ); savefile->ReadJoint( ventLightJointView ); + savefile->ReadJoint( headJointView ); // doomtrinity-headanim savefile->ReadJoint( flashJointWorld ); savefile->ReadJoint( barrelJointWorld ); @@ -672,7 +676,7 @@ void idWeapon::Restore( idRestoreGame *savefile ) { } #endif - savefile->ReadFloat( wh_hide_distance ); // sikk - Weapon Handling System + savefile->ReadFloat( wm_hide_distance ); // sikk - Weapon Management: Awareness } /*********************************************************************** @@ -827,6 +831,7 @@ void idWeapon::Clear( void ) { ejectJointView = INVALID_JOINT; guiLightJointView = INVALID_JOINT; ventLightJointView = INVALID_JOINT; + headJointView = INVALID_JOINT; // doomtrinity-headanim barrelJointWorld = INVALID_JOINT; flashJointWorld = INVALID_JOINT; @@ -882,7 +887,7 @@ void idWeapon::Clear( void ) { isFiring = false; - wh_hide_distance = -15; // sikk - Weapon Handling System + wm_hide_distance = -15; // sikk - Weapon Management: Awareness } /* @@ -973,7 +978,7 @@ void idWeapon::GetWeaponDef( const char *objectname, int ammoinclip ) { hideTime = SEC2MS( weaponDef->dict.GetFloat( "hide_time", "0.3" ) ); hideDistance = weaponDef->dict.GetFloat( "hide_distance", "-15" ); - wh_hide_distance = weaponDef->dict.GetFloat( "wh_hide_distance", "-15" ); // sikk - Weapon Handling System + wm_hide_distance = weaponDef->dict.GetFloat( "wm_hide_distance", "-15" ); // sikk - Weapon Management: Awareness // muzzle smoke smokeName = weaponDef->dict.GetString( "smoke_muzzle" ); @@ -1025,6 +1030,7 @@ void idWeapon::GetWeaponDef( const char *objectname, int ammoinclip ) { ejectJointView = animator.GetJointHandle( "eject" ); guiLightJointView = animator.GetJointHandle( "guiLight" ); ventLightJointView = animator.GetJointHandle( "ventLight" ); + headJointView = animator.GetJointHandle( "head" ); // doomtrinity-headanim #ifdef _D3XP idStr smokeJoint = weaponDef->dict.GetString("smoke_joint"); @@ -1153,6 +1159,10 @@ void idWeapon::GetWeaponDef( const char *objectname, int ammoinclip ) { //In D3XP we use ammo as soon as it is moved into the clip. This allows for weapons that share ammo owner->inventory.UseAmmo(ammoType, ammoClip); #endif +//doomtrinity -> //From D3XP + //In D3XP we use ammo as soon as it is moved into the clip. This allows for weapons that share ammo + owner->inventory.UseAmmo(ammoType, ammoClip); +//<- doomtrinity } renderEntity.gui[ 0 ] = NULL; @@ -1346,6 +1356,7 @@ void idWeapon::UpdateGUI( void ) { #else renderEntity.gui[ 0 ]->SetStateString( "player_totalammo", va( "%i", ammoamount - inclip) ); #endif + renderEntity.gui[ 0 ]->SetStateString( "player_totalammo", va( "%i", ammoamount ) );// doomtrinity (D3XP) renderEntity.gui[ 0 ]->SetStateString( "player_ammo", ClipSize() ? va( "%i", inclip ) : "--" ); renderEntity.gui[ 0 ]->SetStateString( "player_clips", ClipSize() ? va("%i", ammoamount / ClipSize()) : "--" ); @@ -1354,6 +1365,7 @@ void idWeapon::UpdateGUI( void ) { #else renderEntity.gui[ 0 ]->SetStateString( "player_allammo", va( "%i/%i", inclip, ammoamount - inclip ) ); #endif + renderEntity.gui[ 0 ]->SetStateString( "player_allammo", va( "%i/%i", inclip, ammoamount ) );// doomtrinity (D3XP) } renderEntity.gui[ 0 ]->SetStateBool( "player_ammo_empty", ( ammoamount == 0 ) ); renderEntity.gui[ 0 ]->SetStateBool( "player_clip_empty", ( inclip == 0 ) ); @@ -1366,6 +1378,10 @@ void idWeapon::UpdateGUI( void ) { //Grabber Gui Info renderEntity.gui[ 0 ]->SetStateString( "grabber_state", va("%i", grabberState)); #endif +//doomtrinity -> //From D3XP + //Let the HUD know the total amount of ammo regardless of the ammo required value + renderEntity.gui[ 0 ]->SetStateString( "player_ammo_count", va("%i", AmmoCount())); +//<- doomtrinity } /*********************************************************************** @@ -1511,6 +1527,27 @@ bool idWeapon::GetGlobalJointTransform( bool viewModel, const jointHandle_t join return false; } +/* +================ +idWeapon::GetHeadAngle // doomtrinity-headanim + +returns the orientation of the joint in local space +================ +*/ +idAngles idWeapon::GetHeadAngle( void ) {// was idVec3 + idVec3 offset; + idMat3 axis; + + if ( !animator.GetJointTransform( headJointView, gameLocal.time, offset, axis ) ) { + gameLocal.Warning( "Joint # %d out of range on entity '%s'", headJointView, name.c_str() ); + } + + idAngles ang = axis.ToAngles(); + return ang; + //idVec3 vec( ang[ 0 ], ang[ 1 ], ang[ 2 ] ); + //return vec; +} + /* ================ idWeapon::SetPushVelocity @@ -1579,13 +1616,14 @@ idWeapon::LowerWeapon void idWeapon::LowerWeapon( void ) { if ( !hide ) { hideStart = 0.0f; - hideEnd = ( owner->GetWeaponHandling() && !owner->OnLadder() ) ? wh_hide_distance : hideDistance; // sikk - Weapon Handling System + hideEnd = owner->bWAUseHideDist ? wm_hide_distance : hideDistance; // sikk - Weapon Management: Awareness PD3 if ( gameLocal.time - hideStartTime < hideTime ) { hideStartTime = gameLocal.time - ( hideTime - ( gameLocal.time - hideStartTime ) ); } else { hideStartTime = gameLocal.time; } hide = true; + Event_IsLowered(); // doomtrinity } } @@ -1598,7 +1636,7 @@ void idWeapon::RaiseWeapon( void ) { Show(); if ( hide ) { - hideStart = hideDistance; + hideStart = owner->bWAUseHideDist ? wm_hide_distance : hideDistance; // sikk - Weapon Management: Awareness hideEnd = 0.0f; if ( gameLocal.time - hideStartTime < hideTime ) { hideStartTime = gameLocal.time - ( hideTime - ( gameLocal.time - hideStartTime ) ); @@ -1606,6 +1644,7 @@ void idWeapon::RaiseWeapon( void ) { hideStartTime = gameLocal.time; } hide = false; + Event_IsLowered(); // doomtrinity } } @@ -1975,6 +2014,19 @@ bool idWeapon::BloodSplat( float size ) { return true; } +/* +================ +idWeapon::HasHeadJoint // doomtrinity-headanim +================ +*/ +bool idWeapon::HasHeadJoint( void ) { + + if ( headJointView != INVALID_JOINT ) { + return true; + } + + return false; +} /*********************************************************************** @@ -2658,6 +2710,26 @@ int idWeapon::AmmoRequired( void ) const { return ammoRequired; } +//doomtrinity -> //From D3XP +/* +================ +idWeapon::AmmoCount + +Returns the total number of rounds regardless of the required ammo +================ +*/ +/* +int idWeapon::AmmoCount() const { + + if ( owner ) { + return owner->inventory.HasAmmo( ammoType, 1 ); + } else { + return 0; + } +} +*/ +//<- doomtrinity + #ifdef _D3XP /* ================ @@ -2906,7 +2978,7 @@ void idWeapon::Event_UseAmmo( int amount ) { return; } - owner->inventory.UseAmmo( ammoType, ( powerAmmo ) ? amount : ( amount * ammoRequired ) ); + //owner->inventory.UseAmmo( ammoType, ( powerAmmo ) ? amount : ( amount * ammoRequired ) ); // Commented out, now this event works as it should. // doomtrinity if ( clipSize && ammoRequired ) { ammoClip -= powerAmmo ? amount : ( amount * ammoRequired ); if ( ammoClip < 0 ) { @@ -2927,6 +2999,11 @@ void idWeapon::Event_AddToClip( int amount ) { return; } +//doomtrinity -> //From D3XP +// int oldAmmo = ammoClip; +// ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired ) + AmmoInClip(); +//<- doomtrinity + #ifdef _D3XP int oldAmmo = ammoClip; ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired ) + AmmoInClip(); @@ -2955,6 +3032,12 @@ void idWeapon::Event_AddToClip( int amount ) { // <---sikk owner->inventory.UseAmmo(ammoType, usedAmmo); #endif + +//doomtrinity -> //From D3XP + // for shared ammo we need to use the ammo when it is moved into the clip +// int usedAmmo = ammoClip - oldAmmo; +// owner->inventory.UseAmmo(ammoType, usedAmmo); +//<- doomtrinity } /* @@ -2979,7 +3062,7 @@ void idWeapon::Event_AmmoAvailable( void ) { #else int ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired ); #endif - + ammoAvail += AmmoInClip();// doomtrinity (D3XP) idThread::ReturnFloat( ammoAvail ); } @@ -3317,6 +3400,21 @@ void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float // avoid all ammo considerations on an MP client if ( !gameLocal.isClient ) { +//doomtrinity -> //From D3XP + +// int ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired ); +// if ( ( clipSize != 0 ) && ( ammoClip <= 0 ) ) { +// return; +// } + +/* // check if we're out of ammo or the clip is empty + int ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired ); + if ( !ammoAvail || ( ( clipSize != 0 ) && ( ammoClip <= 0 ) ) ) { + return; + } +*/ +//<- doomtrinity + #ifdef _D3XP if ( ( clipSize != 0 ) && ( ammoClip <= 0 ) ) { @@ -3342,6 +3440,18 @@ void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float dmgPower = ammoClip; } } +//doomtrinity -> //From D3XP PD3 + /* + if(clipSize == 0) { + //Weapons with a clip size of 0 launch strait from inventory without moving to a clip + + //In D3XP we used the ammo when the ammo was moved into the clip so we don't want to + //use it now. + owner->inventory.UseAmmo( ammoType, ( powerAmmo ) ? dmgPower : ammoRequired ); + + } + */ +//<- doomtrinity #ifdef _D3XP if(clipSize == 0) { @@ -3359,7 +3469,7 @@ void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float #ifdef _D3XP ammoClip -= powerAmmo ? dmgPower : ammoRequired; #else - ammoClip -= powerAmmo ? dmgPower : 1; + ammoClip -= powerAmmo ? dmgPower : ammoRequired;// doomtrinity (D3XP) #endif } @@ -3381,7 +3491,7 @@ void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float } // calculate the muzzle position - if ( barrelJointView != INVALID_JOINT && projectileDict.GetBool( "launchFromBarrel" ) ) { + if ( barrelJointView != INVALID_JOINT && ( projectileDict.GetBool( "launchFromBarrel" ) || g_weaponProjectileOrigin.GetBool() ) ) { // sikk - Weapon Management: Projectile Origin // there is an explicit joint for the muzzle GetGlobalJointTransform( true, barrelJointView, muzzleOrigin, muzzleAxis ); } else { @@ -3399,9 +3509,17 @@ void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float kick_endtime = gameLocal.realClientTime + muzzle_kick_maxtime; } -// sikk---> Zoom Spread Reduction - if ( g_weaponHandlingType.GetBool() ) - spread = spawnArgs.GetFloat( "wh_spread", "0" ); +// sikk---> Weapon Management: Handling/Awareness + if ( ( g_weaponHandlingType.GetInteger() == 1 || g_weaponHandlingType.GetInteger() == 3 ) && owner->GetCurrentWeapon() != 2 ) { + spread = ( spread + 2.0f ) * owner->fSpreadModifier; + + owner->fSpreadModifier += 0.25f; + if ( owner->fSpreadModifier > 2.0f ) + owner->fSpreadModifier = 2.0f; + } + + if ( g_weaponAwareness.GetBool() && owner->bIsZoomed ) + spread *= 0.5f; // <---sikk if ( gameLocal.isClient ) { @@ -3433,6 +3551,12 @@ void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float dir = playerViewAxis[ 0 ] + playerViewAxis[ 2 ] * ( ang * idMath::Sin( spin ) ) - playerViewAxis[ 1 ] * ( ang * idMath::Cos( spin ) ); dir.Normalize(); +// sikk---> Weapon Management: Handling + if ( g_weaponHandlingType.GetInteger() > 1 && !( g_weaponAwareness.GetBool() && owner->bIsZoomed ) ) { + owner->SetViewAngles( owner->viewAngles + idAngles( -0.5f * owner->fSpreadModifier, 0.0f, 0.0f ) ); + } +// <---sikk + if ( projectileEnt ) { ent = projectileEnt; ent->Show(); @@ -3483,7 +3607,13 @@ void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float #ifdef _D3XP if(brassDelay >= 0) #endif - PostEventMS( &EV_Weapon_EjectBrass, brassDelay ); +//doomtrinity -> // From D3XP + + if( brassDelay >= 0 ) { + PostEventMS( &EV_Weapon_EjectBrass, brassDelay ); + } + +//<- doomtrinity } // add the light for the muzzleflash @@ -3944,11 +4074,15 @@ void idWeapon::Event_EjectBrass( void ) { debris->Create( owner, origin, axis ); debris->Launch(); +//doomtrinity -> // following code commented out. Linear velocity in brass def works properly now. +/* linear_velocity = 40 * ( playerViewAxis[0] + playerViewAxis[1] + playerViewAxis[2] ); angular_velocity.Set( 10 * gameLocal.random.CRandomFloat(), 10 * gameLocal.random.CRandomFloat(), 10 * gameLocal.random.CRandomFloat() ); debris->GetPhysics()->SetLinearVelocity( linear_velocity ); debris->GetPhysics()->SetAngularVelocity( angular_velocity ); +*/ +//doomtrinity -< } /* @@ -3964,6 +4098,17 @@ void idWeapon::Event_IsInvisible( void ) { idThread::ReturnFloat( owner->PowerUpActive( INVISIBILITY ) ? 1 : 0 ); } +//doomtrinity-> +/* +=============== +idWeapon::Event_IsLowered +=============== +*/ +void idWeapon::Event_IsLowered( void ) { + idThread::ReturnInt( hide ); +} +//<-doomtrinity + /* =============== idWeapon::ClientPredictionThink diff --git a/d3xp/Weapon.h b/d3xp/Weapon.h index a755774..8628ea1 100644 --- a/d3xp/Weapon.h +++ b/d3xp/Weapon.h @@ -166,6 +166,8 @@ public: void GetWeaponAngleOffsets( int *average, float *scale, float *max ); void GetWeaponTimeOffsets( float *time, float *scale ); bool BloodSplat( float size ); + bool HasHeadJoint( void ); // doomtrinity-headanim + idAngles GetHeadAngle( void ); // doomtrinity-headanim //was idVec3 // Ammo static ammo_t GetAmmoNumForName( const char *ammoname ); @@ -178,6 +180,7 @@ public: int ClipSize( void ) const; int LowAmmo( void ) const; int AmmoRequired( void ) const; +// int AmmoCount() const;// doomtrinity (D3XP) #ifdef _D3XP int AmmoCount() const; int GetGrabberState() const; @@ -196,7 +199,7 @@ public: virtual void ClientPredictionThink( void ); - float wh_hide_distance; // sikk - Weapon Handling System + float wm_hide_distance; // sikk - Weapon Management: Awareness idGrabber* GetGrabber( void ) { return &grabber; }; // sikk - Object Manipulation @@ -326,6 +329,7 @@ private: jointHandle_t ejectJointView; jointHandle_t guiLightJointView; jointHandle_t ventLightJointView; + jointHandle_t headJointView; // doomtrinity-headanim jointHandle_t flashJointWorld; jointHandle_t barrelJointWorld; @@ -417,6 +421,7 @@ private: void Event_AutoReload( void ); void Event_NetReload( void ); void Event_IsInvisible( void ); + void Event_IsLowered( void ); // doomtrinity void Event_NetEndReload( void ); #ifdef _D3XP diff --git a/d3xp/ai/AI.cpp b/d3xp/ai/AI.cpp index 4fda0e7..6739580 100644 --- a/d3xp/ai/AI.cpp +++ b/d3xp/ai/AI.cpp @@ -994,11 +994,11 @@ void idAI::Spawn( void ) { spawnArgs.SetFloat( "burnaway", g_burnAwayDelay.GetFloat() ); // <---sikk -// sikk---> Enemy Health Management (also modifies friendlies but it doesn't make any difference) +// sikk---> Enemy Health Management (also modifies friendlies but that doesn't matter) health *= g_enemyHealthScale.GetFloat(); - if ( g_enemyHealthType.GetBool() ) - health = ( health * 0.5f ) + ( health * gameLocal.random.RandomFloat() ); + if ( g_enemyHealthRandom.GetBool() ) + health += health * 0.5f * gameLocal.random.CRandomFloat(); health = ( health <= 0 ) ? 1 : health; // <---sikk @@ -4293,6 +4293,35 @@ idProjectile *idAI::LaunchProjectile( const char *jointname, idEntity *target, b forceMuzzle = spawnArgs.GetBool( "forceMuzzle", "0" ); #endif +// sikk---> Damage Type/Spread PD3 + if ( g_damageType.GetInteger() == 1 ) { + if ( spawnArgs.GetFloat( "projectile_spread_doom", "-1.0" ) != -1.0 ) + projectile_spread = spawnArgs.GetFloat( "projectile_spread_doom", "0" ); + else + projectile_spread = spawnArgs.GetFloat( "projectile_spread", "0" ); + + if ( spawnArgs.GetInt( "num_projectiles_doom" ) ) + num_projectiles = spawnArgs.GetInt( "num_projectiles_doom", "1" ); + else + num_projectiles = spawnArgs.GetInt( "num_projectiles", "1" ); + + } else if ( g_damageType.GetInteger() == 2 ) { + if ( spawnArgs.GetFloat( "projectile_spread_custom", "-1.0" ) != -1.0 ) + projectile_spread = spawnArgs.GetFloat( "projectile_spread_custom", "0" ); + else + projectile_spread = spawnArgs.GetFloat( "projectile_spread", "0" ); + + if ( spawnArgs.GetInt( "num_projectiles_custom" ) ) + num_projectiles = spawnArgs.GetInt( "num_projectiles_custom", "1" ); + else + num_projectiles = spawnArgs.GetInt( "num_projectiles", "1" ); + + } else { + projectile_spread = spawnArgs.GetFloat( "projectile_spread", "0" ); + num_projectiles = spawnArgs.GetInt( "num_projectiles", "1" ); + } +// <---sikk PD3 + GetMuzzle( jointname, muzzle, axis ); if ( !projectile.GetEntity() ) { diff --git a/d3xp/gamesys/SysCmds.cpp b/d3xp/gamesys/SysCmds.cpp index cc63b8f..e954e2f 100644 --- a/d3xp/gamesys/SysCmds.cpp +++ b/d3xp/gamesys/SysCmds.cpp @@ -347,6 +347,16 @@ void Cmd_Give_f( const idCmdArgs &args ) { if ( give_all || idStr::Icmp( name, "weapons" ) == 0 ) { player->inventory.weapons = 0xffffffff >> ( 32 - MAX_WEAPONS ); + +// doomtrinity-dual weapon-> + if ( !player->inventory.pistolInInventory ) { + player->inventory.pistolInInventory = 1; + } + if ( !player->inventory.shotgunDoubleInInventory ) { + player->inventory.shotgunDoubleInInventory = 1; + } +// doomtrinity-dual weapon-< + player->CacheWeapons(); if ( !give_all ) { diff --git a/d3xp/gamesys/SysCvar.cpp b/d3xp/gamesys/SysCvar.cpp index dde597a..4621e9d 100644 --- a/d3xp/gamesys/SysCvar.cpp +++ b/d3xp/gamesys/SysCvar.cpp @@ -448,9 +448,15 @@ idCVar g_screenFrostTime( "g_screenFrostTime", "0", CVAR_GAME | CVAR_NOCHEA idCVar g_burnAwayDelay( "g_burnAwayDelay", "0.0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_FLOAT, "enemy burn away delay. 0.0 = use default value" ); // <---sikk -// sikk---> Enemy Health Management -idCVar g_enemyHealthType( "g_enemyHealthType", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_BOOL, "sets enemy health type: 0 = normal; 1 = random" ); +// sikk---> Locational Damage Type PD3 +idCVar g_damageType( "g_damageType", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_INTEGER, "sets damage value type: 0 = Doom 3; 1 = Doom 1/2; 2 = Custom" ); +idCVar g_damageZoneType( "g_damageZoneType", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_INTEGER, "sets locational damage type: 0 = Doom 3; 1 = Doom 1/2; 2 = Custom" ); +// <---sikk PD3 + +// sikk---> Enemy Health Management PD3 +idCVar g_enemyHealthType( "g_enemyHealthType", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_INTEGER, "sets enemy health type: 0 = Doom 3; 1 = Doom 1/2; 2 = Custom" ); idCVar g_enemyHealthScale( "g_enemyHealthScale", "1.0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_FLOAT, "sets the health scale for enemies" ); +idCVar g_enemyHealthRandom( "g_enemyHealthRandom", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_BOOL, "sets whether to randomize enemy health values" ); // <---sikk // sikk---> Inter Rank Aggression @@ -504,8 +510,14 @@ idCVar g_ammoCapacityType( "g_ammoCapacityType", "0", CVAR_GAME | CVAR_NOCH idCVar g_ammoUsageType( "g_ammoUsageType", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_BOOL, "enables realistic ammo usage when reloading and collecting ammo" ); // <---sikk -// sikk---> Weapon Handling System -idCVar g_weaponHandlingType( "g_weaponHandlingType", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_BOOL, "toggles between normal and realistic weapon handling" ); +// sikk---> Weapon Management PD3 +idCVar g_weaponAwareness( "g_weaponAwareness", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_BOOL, "toggles weapon awareness" ); +idCVar g_weaponHandlingType( "g_weaponHandlingType", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_INTEGER, "sets the weapon handling type: 0 = spread (fixed); 1 = spread (variable); 2 spread (fixed) + recoil; 2 spread (variable) + recoil" ); +idCVar g_weaponProjectileOrigin( "g_weaponProjectileOrigin", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_BOOL, "sets whether projectiles are launched from their def defined origin or to launch all projectiles from the weapon's barrel: 0 = Default; 1 = Weapon Barrel" ); +// <---sikk PD3 + +// sikk---> Player Speed Type +idCVar g_playerSpeedType( "g_playerSpeedType", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_INTEGER, "sets the player's speed configuration: 0 = Doom 3; 1 = Doom 1/2; 2 = Custom" ); // <---sikk // sikk---> Tracer Frequency @@ -542,7 +554,7 @@ idCVar r_softShadowsBlurFilter( "r_softShadowsBlurFilter", "1", CVAR_GAME | C idCVar r_softShadowsBlurScale( "r_softShadowsBlurScale", "1.0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_FLOAT, "Sample offset scale for the blur filter" ); idCVar r_softShadowsBlurEpsilon( "r_softShadowsBlurEpsilon", "4.0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_INTEGER, "Set the blur depth difference factor for the blur filter" ); -idCVar r_useEdgeAA( "r_useEdgeAA", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_BOOL, "Enable edge anti-aliasing" ); +idCVar r_useEdgeAA( "r_useEdgeAA", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_INTEGER, "Enable edge anti-aliasing: 0 = RGB edge AA; 1 = FXAA" ); idCVar r_edgeAASampleScale( "r_edgeAASampleScale", "1.0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_FLOAT, "Set the sample offset scale for edge detection" ); idCVar r_edgeAAFilterScale( "r_edgeAAFilterScale", "1.0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_FLOAT, "Set the filter offset scale for blurring" ); @@ -649,3 +661,10 @@ idCVar r_filmgrainStrength( "r_filmgrainStrength", "1.0", CVAR_GAME | CVAR_ idCVar r_useVignetting( "r_useVignetting", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_BOOL, "Enable vignetting postprocessing effect" ); // <---sikk +//doomtrinity -> +// These mouse Cvars do NOT affect directly the mouse settings, "sensitivity" and "m_smooth" are still used. +idCVar in_mouseSensitivity( "in_mouseSensitivity", "5", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "mouse view sensitivity" ); +idCVar in_mouseSmooth( "in_mouseSmooth", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "number of samples blended for mouse viewing" ); +idCVar pm_adsspeed( "pm_adsspeed", "80", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while walking and zooming" ); +idCVar pm_adsbob( "pm_adsbob", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob slowly when walking and zooming" ); +//<- doomtrinity \ No newline at end of file diff --git a/d3xp/gamesys/SysCvar.h b/d3xp/gamesys/SysCvar.h index 1ee545d..cf05597 100644 --- a/d3xp/gamesys/SysCvar.h +++ b/d3xp/gamesys/SysCvar.h @@ -331,9 +331,13 @@ extern idCVar g_screenFrostTime; // sikk - Screen Frost extern idCVar g_burnAwayDelay; // sikk - Monster Burn Away Delay -// sikk---> Enemy Health Management +extern idCVar g_damageType; // sikk - Damage Type +extern idCVar g_damageZoneType; // sikk - Locational Damage Type + +// sikk---> Enemy Health Management PD3 extern idCVar g_enemyHealthType; extern idCVar g_enemyHealthScale; +extern idCVar g_enemyHealthRandom; // <---sikk extern idCVar g_interRankAggression; // sikk - Inter Rank Aggression @@ -379,6 +383,14 @@ extern idCVar g_ammoCapacityType; extern idCVar g_ammoUsageType; // <---sikk +// sikk---> Weapon Management +extern idCVar g_weaponAwareness; +extern idCVar g_weaponHandlingType; +extern idCVar g_weaponProjectileOrigin; +// <---sikk + +extern idCVar g_playerSpeedType; // sikk - Player Speed Type + extern idCVar g_weaponHandlingType; // sikk - Weapon Handling extern idCVar g_tracerFrequency; // sikk - Tracer Frequency @@ -514,5 +526,12 @@ extern idCVar r_filmgrainStrength; extern idCVar r_useVignetting; // <---sikk +//doomtrinity -> +// These mouse Cvars do NOT affect directly the mouse settings, "sensitivity" and "m_smooth" are still used. +extern idCVar in_mouseSensitivity; +extern idCVar in_mouseSmooth; +extern idCVar pm_adsspeed;// player speed in zoomed mode +extern idCVar pm_adsbob;// bob in zoomed mode +//<- doomtrinity #endif /* !__SYS_CVAR_H__ */ diff --git a/game/Entity.cpp b/game/Entity.cpp index 2b2d94c..b0e8ce3 100644 --- a/game/Entity.cpp +++ b/game/Entity.cpp @@ -55,6 +55,7 @@ If you have questions concerning this license or the applicable additional terms */ // overridable events + const idEventDef EV_PostSpawn( "", NULL ); const idEventDef EV_FindTargets( "", NULL ); const idEventDef EV_Touch( "", "et" ); @@ -120,6 +121,8 @@ const idEventDef EV_StartFx( "startFx", "s" ); const idEventDef EV_HasFunction( "hasFunction", "s", 'd' ); const idEventDef EV_CallFunction( "callFunction", "s" ); const idEventDef EV_SetNeverDormant( "setNeverDormant", "d" ); +const idEventDef EV_FireProjectile( "fireProjectile", "svv", 'e' ); // PD3 +const idEventDef EV_FireProjAtTarget( "fireProjAtTarget", "svE", 'e' ); // PD3 ABSTRACT_DECLARATION( idClass, idEntity ) EVENT( EV_GetName, idEntity::Event_GetName ) @@ -185,8 +188,87 @@ ABSTRACT_DECLARATION( idClass, idEntity ) EVENT( EV_HasFunction, idEntity::Event_HasFunction ) EVENT( EV_CallFunction, idEntity::Event_CallFunction ) EVENT( EV_SetNeverDormant, idEntity::Event_SetNeverDormant ) + EVENT( EV_FireProjectile, idEntity::Event_FireProjectile ) // PD3 + EVENT( EV_FireProjAtTarget, idEntity::Event_FireProjAtTarget ) // PD3 END_CLASS +/* +================ +idEntity::CommonFireProjectile // PD3 +================ +*/ +idProjectile* idEntity::CommonFireProjectile( const char *projDefName , const idVec3 &firePos, const idVec3 &dir ) { + idProjectile *proj; + idEntity *ent; + idDict projectileDict; + + if ( gameLocal.isClient ) { return NULL; } + + const idDeclEntityDef *projectileDef = gameLocal.FindEntityDef( projDefName, false ); + if ( !projectileDef ) { + gameLocal.Warning( "No def '%s' found", projDefName ); + return NULL; + } + + projectileDict = projectileDef->dict; + if ( !projectileDict.GetNumKeyVals() ) { + gameLocal.Warning( "No projectile defined '%s'", projDefName ); + return NULL; + } + + if ( IsType( idPlayer::Type ) ) { + static_cast( this )->AddProjectilesFired(1); + gameLocal.AlertAI( this ); + } + + gameLocal.SpawnEntityDef( projectileDict, &ent, false ); + + if ( !ent || !ent->IsType( idProjectile::Type ) ) { + gameLocal.Error( "'%s' is not an idProjectile", projDefName ); + } + + if ( projectileDict.GetBool( "net_instanthit" ) ) { + ent->fl.networkSync = false; + } + + proj = static_cast(ent); + proj->Create( this, firePos, dir ); + proj->Launch( firePos, dir, vec3_origin ); + return proj; +} + +/* +===================== +idEntity::CommonGetAimDir // PD3 +===================== +*/ +void idEntity::CommonGetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, idVec3 &aimDir ) { + idVec3 mainTargetPos; + idVec3 secTargetPos; //not used, but necessary + + if ( aimAtEnt ) { //target entity ok! + if ( aimAtEnt->IsType( idPlayer::Type ) ) { //player - head + static_cast( aimAtEnt )->GetAIAimTargets( aimAtEnt->GetPhysics()->GetOrigin(), mainTargetPos, secTargetPos ); + } else if ( aimAtEnt->IsType( idActor::Type ) ) { //AI - chest + static_cast( aimAtEnt )->GetAIAimTargets( aimAtEnt->GetPhysics()->GetOrigin(), secTargetPos, mainTargetPos ); + } else { //center + mainTargetPos = aimAtEnt->GetPhysics()->GetAbsBounds().GetCenter(); + } + + aimDir = mainTargetPos - firePos; + aimDir.Normalize(); + + } else { //no valid aimAtEnt entity! + if ( IsType( idPlayer::Type ) ) { //player - view + static_cast( this )->viewAngles.ToVectors( &aimDir, NULL, NULL ); + } else if ( IsType( idActor::Type ) ) { //AI - axis + aimDir = static_cast( this )->viewAxis[ 0 ]; + } else { + aimDir = GetPhysics()->GetAxis()[ 0 ]; + } + } +} + /* ================ UpdateGuiParms @@ -4596,6 +4678,36 @@ void idEntity::Event_SetNeverDormant( int enable ) { dormantStart = 0; } +/* +================ +idEntity::Event_FireProjectile PD3 +================ +*/ +void idEntity::Event_FireProjectile( const char* projDefName , const idVec3 &firePos, const idAngles &fireAng ) { + idProjectile *proj; + idVec3 dir; + + dir = fireAng.ToForward(); + proj = CommonFireProjectile( projDefName , firePos, dir ); + + idThread::ReturnEntity( proj ); +} + +/* +================ +idEntity::Event_FireProjAtTarget PD3 +================ +*/ +void idEntity::Event_FireProjAtTarget( const char* projDefName , const idVec3 &firePos, idEntity* aimAtEnt) { + idProjectile *proj; + idVec3 dir; + + CommonGetAimDir( firePos, aimAtEnt, dir ); + proj = CommonFireProjectile( projDefName , firePos, dir ); + + idThread::ReturnEntity( proj ); +} + /*********************************************************************** Network @@ -4900,6 +5012,8 @@ const idEventDef EV_SetJointPos( "setJointPos", "ddv" ); const idEventDef EV_SetJointAngle( "setJointAngle", "ddv" ); const idEventDef EV_GetJointPos( "getJointPos", "d", 'v' ); const idEventDef EV_GetJointAngle( "getJointAngle", "d", 'v' ); +const idEventDef EV_FireProjectileFromJoint( "fireProjectileFromJoint", "sdv", 'e' ); // PD3 +const idEventDef EV_FireProjAtTargetFromJoint( "fireProjAtTargetFromJoint", "sdE", 'e' ); // PD3 CLASS_DECLARATION( idEntity, idAnimatedEntity ) EVENT( EV_GetJointHandle, idAnimatedEntity::Event_GetJointHandle ) @@ -4909,6 +5023,8 @@ CLASS_DECLARATION( idEntity, idAnimatedEntity ) EVENT( EV_SetJointAngle, idAnimatedEntity::Event_SetJointAngle ) EVENT( EV_GetJointPos, idAnimatedEntity::Event_GetJointPos ) EVENT( EV_GetJointAngle, idAnimatedEntity::Event_GetJointAngle ) + EVENT( EV_FireProjectileFromJoint, idAnimatedEntity::Event_FireProjectileFromJoint ) // PD3 + EVENT( EV_FireProjAtTargetFromJoint, idAnimatedEntity::Event_FireProjAtTargetFromJoint ) // PD3 END_CLASS /* @@ -5426,3 +5542,45 @@ void idAnimatedEntity::Event_GetJointAngle( jointHandle_t jointnum ) { idVec3 vec( ang[ 0 ], ang[ 1 ], ang[ 2 ] ); idThread::ReturnVector( vec ); } + +/* +================ +idAnimatedEntity::Event_FireProjectileFromJoint // PD3 +================ +*/ +void idAnimatedEntity::Event_FireProjectileFromJoint( const char *projDefName, jointHandle_t jointnum, const idAngles &fireAng ) { + idProjectile *proj; + idVec3 dir; + idVec3 firePos; + idMat3 axis; //useless but needed + + if ( !GetJointWorldTransform( jointnum, gameLocal.time, firePos, axis ) ) { + gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() ); + } + + dir = fireAng.ToForward(); + proj = CommonFireProjectile( projDefName , firePos, dir ); + + idThread::ReturnEntity( proj ); +} + +/* +================ +idAnimatedEntity::Event_FireProjAtTargetFromJoint // PD3 +================ +*/ +void idAnimatedEntity::Event_FireProjAtTargetFromJoint( const char *projDefName, jointHandle_t jointnum, idEntity *aimAtEnt ) { + idProjectile *proj; + idVec3 dir; + idVec3 firePos; + idMat3 axis; //useless but needed + + if ( !GetJointWorldTransform( jointnum, gameLocal.time, firePos, axis ) ) { + gameLocal.Warning( "Joint # %d out of range on entity '%s'", jointnum, name.c_str() ); + } + + CommonGetAimDir( firePos, aimAtEnt, dir ); + proj = CommonFireProjectile( projDefName , firePos, dir ); + + idThread::ReturnEntity( proj ); +} \ No newline at end of file diff --git a/game/Entity.h b/game/Entity.h index 709543b..42fb1da 100644 --- a/game/Entity.h +++ b/game/Entity.h @@ -39,6 +39,8 @@ If you have questions concerning this license or the applicable additional terms #include "gamesys/Event.h" #include "Game_local.h" +class idProjectile; // PD3 + /* =============================================================================== @@ -113,7 +115,6 @@ public: idList signal[ NUM_SIGNALS ]; }; - class idEntity : public idClass { public: static const int MAX_PVS_AREAS = 4; @@ -164,6 +165,9 @@ public: idEntity(); ~idEntity(); + void CommonGetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, idVec3 &aimDir ); // PD3 + idProjectile* CommonFireProjectile( const char *projDefName, const idVec3 &firePos, const idVec3 &dir ); // PD3 + void Spawn( void ); void Save( idSaveGame *savefile ) const; @@ -465,6 +469,9 @@ private: void Event_HasFunction( const char *name ); void Event_CallFunction( const char *name ); void Event_SetNeverDormant( int enable ); + + void Event_FireProjectile( const char* projDefName , const idVec3 &firePos, const idAngles &fireAng ); // PD3 + void Event_FireProjAtTarget( const char* projDefName , const idVec3 &firePos, idEntity* aimAtEnt ); // PD3 }; /* @@ -529,6 +536,10 @@ private: void Event_SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles ); void Event_GetJointPos( jointHandle_t jointnum ); void Event_GetJointAngle( jointHandle_t jointnum ); + + void Event_FireProjectileFromJoint( const char *projDefName, jointHandle_t jointnum, const idAngles &fireAng ); // PD3 + void Event_FireProjAtTargetFromJoint( const char *projDefName, jointHandle_t jointnum, idEntity *aimAtEnt ); // PD3 + }; #endif /* !__GAME_ENTITY_H__ */ diff --git a/game/Game_local.cpp b/game/Game_local.cpp index 872b418..ea17583 100644 --- a/game/Game_local.cpp +++ b/game/Game_local.cpp @@ -3154,6 +3154,12 @@ bool idGameLocal::SpawnEntityDef( const idDict &args, idEntity **ent, bool setDe spawnArgs.GetString( "classname", NULL, &classname ); +// PD3---> SSG Factor + if ( !idStr::Icmp( classname, "weapon_shotgun" ) ) { + classname = ( ( random.RandomFloat() * 0.99999f ) < g_weaponSSGFactor.GetFloat() ) ? "weapon_shotgun_double" : classname; + } +// <---PD3 + // sikk---> Spectre Factor if ( !idStr::Icmp( classname, "monster_demon_pinky" ) ) { classname = ( ( random.RandomFloat() * 0.99999f ) < g_enemySpectreFactor.GetFloat() ) ? "monster_demon_spectre" : classname; diff --git a/game/Grabber.cpp b/game/Grabber.cpp new file mode 100644 index 0000000..fc977a4 --- /dev/null +++ b/game/Grabber.cpp @@ -0,0 +1,708 @@ +#include "../idlib/precompiled.h" +#pragma hdrstop + +#ifdef _D3XP + +#include "Game_local.h" +#include "Misc.h" + +#define MAX_DRAG_TRACE_DISTANCE 384.0f +#define TRACE_BOUNDS_SIZE 3.f +#define HOLD_DISTANCE 72.f +#define FIRING_DELAY 1000.0f +#define DRAG_FAIL_LEN 64.f +#define THROW_SCALE 1000 +#define MAX_PICKUP_VELOCITY 1500 * 1500 +#define MAX_PICKUP_SIZE 96 + +/* +=============================================================================== + + Allows entities to be dragged through the world with physics. + +=============================================================================== +*/ + +CLASS_DECLARATION( idEntity, idGrabber ) +END_CLASS + +/* +============== +idGrabber::idGrabber +============== +*/ +idGrabber::idGrabber( void ) { + dragEnt = NULL; + owner = NULL; + beam = NULL; + beamTarget = NULL; + oldUcmdFlags = 0; + shakeForceFlip = false; + holdingAF = false; + endTime = 0; + lastFiredTime = -FIRING_DELAY; + dragFailTime = 0; + startDragTime = 0; + warpId = -1; + dragTraceDist = MAX_DRAG_TRACE_DISTANCE; +} + +/* +============== +idGrabber::~idGrabber +============== +*/ +idGrabber::~idGrabber( void ) { + StopDrag( true ); + if ( beam ) { + delete beam; + } + if ( beamTarget ) { + delete beamTarget; + } +} + +/* +============== +idGrabber::Save +============== +*/ +void idGrabber::Save( idSaveGame *savefile ) const { + + dragEnt.Save( savefile ); + savefile->WriteStaticObject( drag ); + + savefile->WriteVec3( saveGravity ); + savefile->WriteInt( id ); + + savefile->WriteVec3( localPlayerPoint ); + + owner.Save( savefile ); + + savefile->WriteBool( holdingAF ); + savefile->WriteBool( shakeForceFlip ); + + savefile->WriteInt( endTime ); + savefile->WriteInt( lastFiredTime ); + savefile->WriteInt( dragFailTime ); + savefile->WriteInt( startDragTime ); + savefile->WriteFloat( dragTraceDist ); + savefile->WriteInt( savedContents ); + savefile->WriteInt( savedClipmask ); + + savefile->WriteObject( beam ); + savefile->WriteObject( beamTarget ); + + savefile->WriteInt( warpId ); +} + +/* +============== +idGrabber::Restore +============== +*/ +void idGrabber::Restore( idRestoreGame *savefile ) { + //Spawn the beams + Initialize(); + + dragEnt.Restore( savefile ); + savefile->ReadStaticObject( drag ); + + savefile->ReadVec3( saveGravity ); + savefile->ReadInt( id ); + + // Restore the drag force's physics object + if ( dragEnt.IsValid() ) { + drag.SetPhysics( dragEnt.GetEntity()->GetPhysics(), id, dragEnt.GetEntity()->GetPhysics()->GetOrigin() ); + } + + savefile->ReadVec3( localPlayerPoint ); + + owner.Restore( savefile ); + + savefile->ReadBool( holdingAF ); + savefile->ReadBool( shakeForceFlip ); + + savefile->ReadInt( endTime ); + savefile->ReadInt( lastFiredTime ); + savefile->ReadInt( dragFailTime ); + savefile->ReadInt( startDragTime ); + savefile->ReadFloat( dragTraceDist ); + savefile->ReadInt( savedContents ); + savefile->ReadInt( savedClipmask ); + + savefile->ReadObject( reinterpret_cast(beam) ); + savefile->ReadObject( reinterpret_cast(beamTarget) ); + + savefile->ReadInt( warpId ); +} + +/* +============== +idGrabber::Initialize +============== +*/ +void idGrabber::Initialize( void ) { + if ( !gameLocal.isMultiplayer ) { + idDict args; + + if ( !beamTarget ) { + args.SetVector( "origin", vec3_origin ); + args.SetBool( "start_off", true ); + beamTarget = ( idBeam * )gameLocal.SpawnEntityType( idBeam::Type, &args ); + } + + if ( !beam ) { + args.Clear(); + args.Set( "target", beamTarget->name.c_str() ); + args.SetVector( "origin", vec3_origin ); + args.SetBool( "start_off", true ); + args.Set( "width", "6" ); + args.Set( "skin", "textures/smf/flareSizeable" ); + args.Set( "_color", "0.0235 0.843 0.969 0.2" ); + beam = ( idBeam * )gameLocal.SpawnEntityType( idBeam::Type, &args ); + beam->SetShaderParm( 6, 1.0f ); + } + + endTime = 0; + dragTraceDist = MAX_DRAG_TRACE_DISTANCE; + } + else { + beam = NULL; + beamTarget = NULL; + endTime = 0; + dragTraceDist = MAX_DRAG_TRACE_DISTANCE; + }; +} + +/* +============== +idGrabber::SetDragDistance +============== +*/ +void idGrabber::SetDragDistance( float dist ) { + dragTraceDist = dist; +} + +/* +============== +idGrabber::StartDrag +============== +*/ +void idGrabber::StartDrag( idEntity *grabEnt, int id ) { + int clipModelId = id; + idPlayer *thePlayer = owner.GetEntity(); + + holdingAF = false; + dragFailTime = gameLocal.slow.time; + startDragTime = gameLocal.slow.time; + + oldUcmdFlags = thePlayer->usercmd.flags; + + // set grabbed state for networking + grabEnt->SetGrabbedState( true ); + + // This is the new object to drag around + dragEnt = grabEnt; + + // Show the beams! + UpdateBeams(); + if ( beam ) { + beam->Show(); + } + if ( beamTarget ) { + beamTarget->Show(); + } + + // Move the object to the fast group (helltime) + grabEnt->timeGroup = TIME_GROUP2; + + // Handle specific class types + if ( grabEnt->IsType( idProjectile::Type ) ) { + idProjectile* p = (idProjectile*)grabEnt; + + p->CatchProjectile( thePlayer, "_catch" ); + + // Make the projectile non-solid to other projectiles/enemies (special hack for helltime hunter) + if ( !idStr::Cmp( grabEnt->GetEntityDefName(), "projectile_helltime_killer" ) ) { + savedContents = CONTENTS_PROJECTILE; + savedClipmask = MASK_SHOT_RENDERMODEL|CONTENTS_PROJECTILE; + } else { + savedContents = grabEnt->GetPhysics()->GetContents(); + savedClipmask = grabEnt->GetPhysics()->GetClipMask(); + } + grabEnt->GetPhysics()->SetContents( 0 ); + grabEnt->GetPhysics()->SetClipMask( CONTENTS_SOLID|CONTENTS_BODY ); + + } else if ( grabEnt->IsType( idExplodingBarrel::Type ) ) { + idExplodingBarrel *ebarrel = static_cast(grabEnt); + + ebarrel->StartBurning(); + + } else if ( grabEnt->IsType( idAFEntity_Gibbable::Type ) ) { + holdingAF = true; + clipModelId = 0; + + if ( grabbableAI( grabEnt->spawnArgs.GetString( "classname" ) ) ) { + idAI *aiEnt = static_cast(grabEnt); + + aiEnt->StartRagdoll(); + } + } else if ( grabEnt->IsType( idMoveableItem::Type ) ) { + grabEnt->PostEventMS( &EV_Touch, 250, thePlayer, NULL ); + } + + // Get the current physics object to manipulate + idPhysics *phys = grabEnt->GetPhysics(); + + // Turn off gravity on object + saveGravity = phys->GetGravity(); + phys->SetGravity( vec3_origin ); + + // hold it directly in front of player + localPlayerPoint = ( thePlayer->firstPersonViewAxis[0] * HOLD_DISTANCE ) * thePlayer->firstPersonViewAxis.Transpose(); + + // Set the ending time for the hold + endTime = gameLocal.time + g_grabberHoldSeconds.GetFloat() * 1000; + + // Start up the Force_Drag to bring it in + drag.Init( g_grabberDamping.GetFloat() ); + drag.SetPhysics( phys, clipModelId, thePlayer->firstPersonViewOrigin + localPlayerPoint * thePlayer->firstPersonViewAxis); + + // start the screen warp + warpId = thePlayer->playerView.AddWarp( phys->GetOrigin(), SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 160, 2000 ); +} + +/* +============== +idGrabber::StopDrag +============== +*/ +void idGrabber::StopDrag( bool dropOnly ) { + idPlayer *thePlayer = owner.GetEntity(); + + if ( beam ) { + beam->Hide(); + } + if ( beamTarget ) { + beamTarget->Hide(); + } + + if ( dragEnt.IsValid() ) { + idEntity *ent = dragEnt.GetEntity(); + + // set grabbed state for networking + ent->SetGrabbedState( false ); + + // If a cinematic has started, allow dropped object to think in cinematics + if ( gameLocal.inCinematic ) { + ent->cinematic = true; + } + + // Restore Gravity + ent->GetPhysics()->SetGravity( saveGravity ); + + // Move the object back to the slow group (helltime) + ent->timeGroup = TIME_GROUP1; + + if ( holdingAF ) { + idAFEntity_Gibbable *af = static_cast(ent); + idPhysics_AF *af_Phys = static_cast(af->GetPhysics()); + + if ( grabbableAI( ent->spawnArgs.GetString( "classname" ) ) ) { + idAI *aiEnt = static_cast(ent); + + aiEnt->Damage( thePlayer, thePlayer, vec3_origin, "damage_suicide", 1.0f, INVALID_JOINT ); + } + + af->SetThrown( !dropOnly ); + + // Reset timers so that it isn't forcibly put to rest in mid-air + af_Phys->PutToRest(); + af_Phys->Activate(); + + af_Phys->SetTimeScaleRamp( MS2SEC(gameLocal.slow.time) - 1.5f, MS2SEC(gameLocal.slow.time) + 1.0f ); + } + + // If the object isn't near its goal, just drop it in place. + if ( !ent->IsType( idProjectile::Type ) && ( dropOnly || drag.GetDistanceToGoal() > DRAG_FAIL_LEN ) ) { + ent->GetPhysics()->SetLinearVelocity( vec3_origin ); + thePlayer->StartSoundShader( declManager->FindSound( "grabber_maindrop" ), SND_CHANNEL_WEAPON, 0, false, NULL ); + + if ( ent->IsType( idExplodingBarrel::Type ) ) { + idExplodingBarrel *ebarrel = static_cast(ent); + + ebarrel->SetStability( true ); + ebarrel->StopBurning(); + } + } else { + // Shoot the object forward + ent->ApplyImpulse( thePlayer, 0, ent->GetPhysics()->GetOrigin(), thePlayer->firstPersonViewAxis[0] * THROW_SCALE * ent->GetPhysics()->GetMass() ); + thePlayer->StartSoundShader( declManager->FindSound( "grabber_release" ), SND_CHANNEL_WEAPON, 0, false, NULL ); + + // Orient projectiles away from the player + if ( ent->IsType( idProjectile::Type ) ) { + idPlayer *player = owner.GetEntity(); + idAngles ang = player->firstPersonViewAxis[0].ToAngles(); + + ang.pitch += 90.f; + ent->GetPhysics()->SetAxis( ang.ToMat3() ); + ent->GetPhysics()->SetAngularVelocity( vec3_origin ); + + // Restore projectile contents + ent->GetPhysics()->SetContents( savedContents ); + ent->GetPhysics()->SetClipMask( savedClipmask ); + + } else if ( ent->IsType( idMoveable::Type ) ) { + // Turn on damage for this object + idMoveable *obj = static_cast(ent); + obj->EnableDamage( true, 2.5f ); + obj->SetAttacker( thePlayer ); + + if ( ent->IsType( idExplodingBarrel::Type ) ) { + idExplodingBarrel *ebarrel = static_cast(ent); + ebarrel->SetStability( false ); + } + + } else if ( ent->IsType( idMoveableItem::Type ) ) { + ent->GetPhysics()->SetClipMask( MASK_MONSTERSOLID ); + } + } + + // Remove the Force_Drag's control of the entity + drag.RemovePhysics( ent->GetPhysics() ); + } + + if ( warpId != -1 ) { + thePlayer->playerView.FreeWarp( warpId ); + warpId = -1; + } + + lastFiredTime = gameLocal.time; + dragEnt = NULL; + endTime = 0; +} + +/* +============== +idGrabber::Update +============== +*/ +int idGrabber::Update( idPlayer *player, bool hide ) { + trace_t trace; + idEntity *newEnt; + + // pause before allowing refire + if ( lastFiredTime + FIRING_DELAY > gameLocal.time ) { + return 3; + } + + // Dead players release the trigger + if ( hide || player->health <= 0 ) { + StopDrag( true ); + if ( hide ) { + lastFiredTime = gameLocal.time - FIRING_DELAY + 250; + } + return 3; + } + + // Check if object being held has been removed (dead demon, projectile, etc.) + if ( endTime > gameLocal.time ) { + bool abort = !dragEnt.IsValid(); + + if ( !abort && dragEnt.GetEntity()->IsType( idProjectile::Type ) ) { + idProjectile *proj = (idProjectile *)dragEnt.GetEntity(); + + if ( proj->GetProjectileState() >= 3 ) { + abort = true; + } + } + if ( !abort && dragEnt.GetEntity()->IsHidden() ) { + abort = true; + } + // Not in multiplayer :: Pressing "reload" lets you carefully drop an item + if ( !gameLocal.isMultiplayer && !abort && (( player->usercmd.flags & UCF_IMPULSE_SEQUENCE ) != ( oldUcmdFlags & UCF_IMPULSE_SEQUENCE )) && (player->usercmd.impulse == IMPULSE_13) ) { + abort = true; + } + + if ( abort ) { + StopDrag( true ); + return 3; + } + } + + owner = player; + + // if no entity selected for dragging + if ( !dragEnt.GetEntity() ) { + idBounds bounds; + idVec3 end = player->firstPersonViewOrigin + player->firstPersonViewAxis[0] * dragTraceDist; + + bounds.Zero(); + bounds.ExpandSelf( TRACE_BOUNDS_SIZE ); + + gameLocal.clip.TraceBounds( trace, player->firstPersonViewOrigin, end, bounds, MASK_SHOT_RENDERMODEL|CONTENTS_PROJECTILE|CONTENTS_MOVEABLECLIP, player ); + // If the trace hit something + if ( trace.fraction < 1.0f ) { + newEnt = gameLocal.entities[ trace.c.entityNum ]; + + // if entity is already being grabbed then bypass + if ( gameLocal.isMultiplayer && newEnt->IsGrabbed() ) { + return 0; + } + + // Check if this is a valid entity to hold + if ( newEnt && ( newEnt->IsType( idMoveable::Type ) || + newEnt->IsType( idMoveableItem::Type ) || + newEnt->IsType( idProjectile::Type ) || + newEnt->IsType( idAFEntity_Gibbable::Type ) ) && + newEnt->noGrab == false && + newEnt->GetPhysics()->GetBounds().GetRadius() < MAX_PICKUP_SIZE && + newEnt->GetPhysics()->GetLinearVelocity().LengthSqr() < MAX_PICKUP_VELOCITY ) { + + bool validAF = true; + + if ( newEnt->IsType( idAFEntity_Gibbable::Type ) ) { + idAFEntity_Gibbable *afEnt = static_cast(newEnt); + + if ( grabbableAI( newEnt->spawnArgs.GetString( "classname" ) ) ) { + // Make sure it's also active + if ( !afEnt->IsActive() ) { + validAF = false; + } + } else if ( !afEnt->IsActiveAF() ) { + validAF = false; + } + } + + if ( validAF && player->usercmd.buttons & BUTTON_ATTACK ) { + // Grab this entity and start dragging it around + StartDrag( newEnt, trace.c.id ); + } else if ( validAF ) { + // A holdable object is ready to be grabbed + return 1; + } + } + } + } + + // check backwards server time in multiplayer + bool allow = true; + + if ( gameLocal.isMultiplayer ) { + + // if we've marched backwards + if ( gameLocal.slow.time < startDragTime ) { + allow = false; + } + } + + + // if there is an entity selected for dragging + if ( dragEnt.GetEntity() && allow ) { + idPhysics *entPhys = dragEnt.GetEntity()->GetPhysics(); + idVec3 goalPos; + + // If the player lets go of attack, or time is up + if ( !( player->usercmd.buttons & BUTTON_ATTACK ) ) { + StopDrag( false ); + return 3; + } + if ( gameLocal.time > endTime ) { + StopDrag( true ); + return 3; + } + + // Check if the player is standing on the object + if ( !holdingAF ) { + idBounds playerBounds; + idBounds objectBounds = entPhys->GetAbsBounds(); + idVec3 newPoint = player->GetPhysics()->GetOrigin(); + + // create a bounds at the players feet + playerBounds.Clear(); + playerBounds.AddPoint( newPoint ); + newPoint.z -= 1.f; + playerBounds.AddPoint( newPoint ); + playerBounds.ExpandSelf( 8.f ); + + // If it intersects the object bounds, then drop it + if ( playerBounds.IntersectsBounds( objectBounds ) ) { + StopDrag( true ); + return 3; + } + } + + // Shake the object at the end of the hold + if ( g_grabberEnableShake.GetBool() && !gameLocal.isMultiplayer ) { + ApplyShake(); + } + + // Set and evaluate drag force + goalPos = player->firstPersonViewOrigin + localPlayerPoint * player->firstPersonViewAxis; + + drag.SetGoalPosition( goalPos ); + drag.Evaluate( gameLocal.time ); + + // If an object is flying too fast toward the player, stop it hard + if ( g_grabberHardStop.GetBool() ) { + idPlane theWall; + idVec3 toPlayerVelocity, objectCenter; + float toPlayerSpeed; + + toPlayerVelocity = -player->firstPersonViewAxis[0]; + toPlayerSpeed = entPhys->GetLinearVelocity() * toPlayerVelocity; + + if ( toPlayerSpeed > 64.f ) { + objectCenter = entPhys->GetAbsBounds().GetCenter(); + + theWall.SetNormal( player->firstPersonViewAxis[0] ); + theWall.FitThroughPoint( goalPos ); + + if ( theWall.Side( objectCenter, 0.1f ) == PLANESIDE_BACK ) { + int i, num; + + num = entPhys->GetNumClipModels(); + for ( i=0; iSetLinearVelocity( vec3_origin, i ); + } + } + } + + // Make sure the object isn't spinning too fast + const float MAX_ROTATION_SPEED = 12.f; + + idVec3 angVel = entPhys->GetAngularVelocity(); + float rotationSpeed = angVel.LengthFast(); + + if ( rotationSpeed > MAX_ROTATION_SPEED ) { + angVel.NormalizeFast(); + angVel *= MAX_ROTATION_SPEED; + entPhys->SetAngularVelocity( angVel ); + } + } + + // Orient projectiles away from the player + if ( dragEnt.GetEntity()->IsType( idProjectile::Type ) ) { + idAngles ang = player->firstPersonViewAxis[0].ToAngles(); + ang.pitch += 90.f; + entPhys->SetAxis( ang.ToMat3() ); + } + + // Some kind of effect from gun to object? + UpdateBeams(); + + // If the object is stuck away from its intended position for more than 500ms, let it go. + if ( drag.GetDistanceToGoal() > DRAG_FAIL_LEN ) { + if ( dragFailTime < (gameLocal.slow.time - 500) ) { + StopDrag( true ); + return 3; + } + } else { + dragFailTime = gameLocal.slow.time; + } + + // Currently holding an object + return 2; + } + + // Not holding, nothing to hold + return 0; +} + +/* +====================== +idGrabber::UpdateBeams +====================== +*/ +void idGrabber::UpdateBeams( void ) { + jointHandle_t muzzle_joint; + idVec3 muzzle_origin; + idMat3 muzzle_axis; + renderEntity_t *re; + + if ( !beam ) { + return; + } + + if ( dragEnt.IsValid() ) { + idPlayer *thePlayer = owner.GetEntity(); + + if ( beamTarget ) { + beamTarget->SetOrigin( dragEnt.GetEntity()->GetPhysics()->GetAbsBounds().GetCenter() ); + } + + muzzle_joint = thePlayer->weapon.GetEntity()->GetAnimator()->GetJointHandle( "particle_upper" ); + if ( muzzle_joint != INVALID_JOINT ) { + thePlayer->weapon.GetEntity()->GetJointWorldTransform( muzzle_joint, gameLocal.time, muzzle_origin, muzzle_axis ); + } else { + muzzle_origin = thePlayer->GetPhysics()->GetOrigin(); + } + + beam->SetOrigin( muzzle_origin ); + re = beam->GetRenderEntity(); + re->origin = muzzle_origin; + + beam->UpdateVisuals(); + beam->Present(); + } +} + +/* +============== +idGrabber::ApplyShake +============== +*/ +void idGrabber::ApplyShake( void ) { + float u = 1 - (float)( endTime - gameLocal.time ) / ( g_grabberHoldSeconds.GetFloat() * 1000 ); + + if ( u >= 0.8f ) { + idVec3 point, impulse; + float shakeForceMagnitude = 450.f; + float mass = dragEnt.GetEntity()->GetPhysics()->GetMass(); + + shakeForceFlip = !shakeForceFlip; + + // get point to rotate around + point = dragEnt.GetEntity()->GetPhysics()->GetOrigin(); + point.y += 1; + + // Articulated figures get less violent shake + if ( holdingAF ) { + shakeForceMagnitude = 120.f; + } + + // calc impulse + if ( shakeForceFlip ) { + impulse.Set( 0, 0, shakeForceMagnitude * u * mass ); + } + else { + impulse.Set( 0, 0, -shakeForceMagnitude * u * mass ); + } + + dragEnt.GetEntity()->ApplyImpulse( NULL, 0, point, impulse ); + } +} + +/* +============== +idGrabber::grabbableAI +============== +*/ +bool idGrabber::grabbableAI( const char *aiName ) { + // skip "monster_" + aiName += 8; + + if (!idStr::Cmpn( aiName, "flying_lostsoul", 15 ) || + !idStr::Cmpn( aiName, "demon_trite", 11 ) || + !idStr::Cmp( aiName, "flying_forgotten" ) || + !idStr::Cmp( aiName, "demon_cherub" ) || + !idStr::Cmp( aiName, "demon_tick" )) { + + return true; + } + + return false; +} + +#endif diff --git a/game/Grabber.h b/game/Grabber.h new file mode 100644 index 0000000..4470d55 --- /dev/null +++ b/game/Grabber.h @@ -0,0 +1,59 @@ +#ifdef _D3XP + +/* +=============================================================================== + + Grabber Object - Class to extend idWeapon to include functionality for + manipulating physics objects. + +=============================================================================== +*/ + +class idBeam; + +class idGrabber : public idEntity { +public: + CLASS_PROTOTYPE( idGrabber ); + + idGrabber( void ); + ~idGrabber( void ); + + void Save( idSaveGame *savefile ) const; + void Restore( idRestoreGame *savefile ); + + void Initialize( void ); + void SetDragDistance( float dist ); + int Update( idPlayer *player, bool hide ); + +private: + idEntityPtr dragEnt; // entity being dragged + idForce_Grab drag; + idVec3 saveGravity; + + int id; // id of body being dragged + idVec3 localPlayerPoint; // dragged point in player space + idEntityPtr owner; + int oldUcmdFlags; + bool holdingAF; + bool shakeForceFlip; + int endTime; + int lastFiredTime; + int dragFailTime; + int startDragTime; + float dragTraceDist; + int savedContents; + int savedClipmask; + + idBeam* beam; + idBeam* beamTarget; + + int warpId; + + bool grabbableAI( const char *aiName ); + void StartDrag( idEntity *grabEnt, int id ); + void StopDrag( bool dropOnly ); + void UpdateBeams( void ); + void ApplyShake( void ); +}; + +#endif diff --git a/game/Item.cpp b/game/Item.cpp index 30803fa..04e04c6 100644 --- a/game/Item.cpp +++ b/game/Item.cpp @@ -36,6 +36,8 @@ If you have questions concerning this license or the applicable additional terms #include "Item.h" +#define WEAPON_COUNT_STOP 2 // doomtrinity-dual weapon + /* =============================================================================== @@ -391,6 +393,9 @@ idItem::GiveToPlayer ================ */ bool idItem::GiveToPlayer( idPlayer *player ) { + int numPistols; // doomtrinity-dual weapon-> + int numShotguns; // doomtrinity-dual weapon-> + if ( player == NULL ) { return false; } @@ -403,6 +408,22 @@ bool idItem::GiveToPlayer( idPlayer *player ) { if ( spawnArgs.GetBool( "inv_carry" ) ) { return player->GiveInventoryItem( &spawnArgs ); } +// doomtrinity-dual weapon-> + numPistols = player->inventory.pistolInInventory; + numShotguns = player->inventory.shotgunDoubleInInventory; + + if ( ( numPistols != WEAPON_COUNT_STOP ) || ( numShotguns != WEAPON_COUNT_STOP ) ) { + idStr inv_weapon; + inv_weapon = spawnArgs.GetString( va("inv_weapon") ); + if ( ( player->inventory.weapons & 2 ) && ( numPistols != WEAPON_COUNT_STOP ) && ( inv_weapon == "weapon_pistol" ) ) { + player->inventory.pistolInInventory++; + //gameLocal.Printf( "pistol # %i\n", player->inventory.pistolInInventory ); + } else if ( ( player->inventory.weapons & 8 ) && ( numShotguns != WEAPON_COUNT_STOP ) && ( inv_weapon == "weapon_shotgun_double" ) ) { + player->inventory.shotgunDoubleInInventory++; + //gameLocal.Printf( "shotgun # %i\n", player->inventory.shotgunDoubleInInventory ); + } + } +// doomtrinity-dual weapon-< return player->GiveItem( this ); } diff --git a/game/Player.cpp b/game/Player.cpp index 0c72b9b..052e896 100644 --- a/game/Player.cpp +++ b/game/Player.cpp @@ -92,6 +92,9 @@ const idEventDef EV_Player_HideTip( "hideTip" ); const idEventDef EV_Player_LevelTrigger( "levelTrigger" ); const idEventDef EV_SpectatorTouch( "spectatorTouch", "et" ); const idEventDef EV_Player_GetIdealWeapon( "getIdealWeapon", NULL, 's' ); +// doomtrinity-dual weapon +const idEventDef EV_Player_GetNumPistols( "getNumPistols", NULL, 'd' ); +const idEventDef EV_Player_GetNumShotguns( "getNumShotguns", NULL, 'd' ); CLASS_DECLARATION( idActor, idPlayer ) EVENT( EV_Player_GetButtons, idPlayer::Event_GetButtons ) @@ -112,6 +115,9 @@ CLASS_DECLARATION( idActor, idPlayer ) EVENT( EV_Player_LevelTrigger, idPlayer::Event_LevelTrigger ) EVENT( EV_Gibbed, idPlayer::Event_Gibbed ) EVENT( EV_Player_GetIdealWeapon, idPlayer::Event_GetIdealWeapon ) + // doomtrinity-dual weapon + EVENT( EV_Player_GetNumPistols, idPlayer::Event_GetNumPistols ) + EVENT( EV_Player_GetNumShotguns, idPlayer::Event_GetNumShotguns ) END_CLASS const int MAX_RESPAWN_TIME = 10000; @@ -137,6 +143,8 @@ idInventory::Clear void idInventory::Clear( void ) { maxHealth = 0; weapons = 0; + shotgunDoubleInInventory = 0; // doomtrinity-dual weapon + pistolInInventory = 0; // doomtrinity-dual weapon powerups = 0; armor = 0; maxarmor = 0; @@ -243,6 +251,10 @@ void idInventory::GetPersistantData( idDict &dict ) { // armor dict.SetInt( "armor", armor ); + // doomtrinity-dual weapon + dict.SetInt( "hasDB", shotgunDoubleInInventory ); + dict.SetInt( "hasPistol", pistolInInventory ); + // don't bother with powerups, maxhealth, maxarmor, or the clip // ammo @@ -252,6 +264,12 @@ void idInventory::GetPersistantData( idDict &dict ) { dict.SetInt( name, ammo[ i ] ); } } +//doomtrinity -> //From D3XP + //Save the clip data + for( i = 0; i < MAX_WEAPONS; i++ ) { + dict.SetInt( va("clip%i", i), clip[ i ] ); + } +//<- doomtrinity // items num = 0; @@ -336,6 +354,10 @@ void idInventory::RestoreInventory( idPlayer *owner, const idDict &dict ) { maxHealth = dict.GetInt( "maxhealth", "100" ); armor = dict.GetInt( "armor", "50" ); + // doomtrinity-dual weapon + shotgunDoubleInInventory = dict.GetInt( "hasDB" ); + pistolInInventory = dict.GetInt( "hasPistol" ); + // sikk---> Item Management: Max Armor Type if ( g_itemMaxArmorType.GetInteger() == 1 ) maxarmor = dict.GetInt( "maxarmor_doom", "100" ); @@ -358,6 +380,12 @@ void idInventory::RestoreInventory( idPlayer *owner, const idDict &dict ) { ammo[ i ] = dict.GetInt( name ); } } +//doomtrinity -> //From D3XP + //Restore the clip data + for( i = 0; i < MAX_WEAPONS; i++ ) { + clip[i] = dict.GetInt(va("clip%i", i), "-1"); + } +//<- doomtrinity // items num = dict.GetInt( "items" ); @@ -420,6 +448,16 @@ void idInventory::RestoreInventory( idPlayer *owner, const idDict &dict ) { Give( owner, dict, "weapon", dict.GetString( "weapon" ), NULL, false ); } +// doomtrinity-dual weapon-> + // we need this for game saves prior to mod installation + if ( (weapons & 2) && !pistolInInventory ) { + pistolInInventory = 1; + } + if ( (weapons & 8) && !shotgunDoubleInInventory ) { + shotgunDoubleInInventory = 1; + } +// doomtrinity-dual weapon-< + num = dict.GetInt( "levelTriggers" ); for ( i = 0; i < num; i++ ) { sprintf( itemname, "levelTrigger_Level_%i", i ); @@ -442,6 +480,11 @@ void idInventory::Save( idSaveGame *savefile ) const { savefile->WriteInt( maxHealth ); savefile->WriteInt( weapons ); + + // doomtrinity-dual weapon + savefile->WriteInt( shotgunDoubleInInventory ); + savefile->WriteInt( pistolInInventory ); + savefile->WriteInt( powerups ); savefile->WriteInt( armor ); savefile->WriteInt( maxarmor ); @@ -541,6 +584,11 @@ void idInventory::Restore( idRestoreGame *savefile ) { savefile->ReadInt( maxHealth ); savefile->ReadInt( weapons ); + + // doomtrinity-dual weapon + savefile->ReadInt( shotgunDoubleInInventory ); + savefile->ReadInt( pistolInInventory ); + savefile->ReadInt( powerups ); savefile->ReadInt( armor ); savefile->ReadInt( maxarmor ); @@ -874,6 +922,16 @@ bool idInventory::Give( idPlayer *owner, const idDict &spawnArgs, const char *st assert( !gameLocal.isClient ); *idealWeapon = i; } + +// doomtrinity-dual weapon-> + if ( weaponName == "weapon_pistol" ) { + pistolInInventory = 1; + } + if ( weaponName == "weapon_shotgun_double" ) { + shotgunDoubleInInventory = 1; + } +// doomtrinity-dual weapon-< + if ( owner->hud && updateHud && lastGiveTime + 1000 < gameLocal.time ) { owner->hud->SetStateInt( "newWeapon", i ); owner->hud->HandleNamedEvent( "newWeapon" ); @@ -952,10 +1010,18 @@ int idInventory::HasAmmo( ammo_t type, int amount ) { idInventory::HasAmmo =============== */ -int idInventory::HasAmmo( const char *weapon_classname ) { +int idInventory::HasAmmo( const char *weapon_classname, bool includeClip, idPlayer* owner ) {// doomtrinity (D3XP) int ammoRequired; ammo_t ammo_i = AmmoIndexForWeaponClass( weapon_classname, &ammoRequired ); - return HasAmmo( ammo_i, ammoRequired ); +//doomtrinity -> //From D3XP + int ammoCount = HasAmmo( ammo_i, ammoRequired ); + if(includeClip && owner) { + ammoCount += clip[owner->SlotForWeapon(weapon_classname)]; + } + return ammoCount; + + //return HasAmmo( ammo_i, ammoRequired ); +//<- doomtrinity } /* @@ -1057,6 +1123,7 @@ idPlayer::idPlayer() { firstPersonViewOrigin = vec3_zero; firstPersonViewAxis = mat3_identity; + firstPersonViewWeaponAxis = mat3_identity; // doomtrinity-headanim hipJoint = INVALID_JOINT; chestJoint = INVALID_JOINT; @@ -1086,6 +1153,14 @@ idPlayer::idPlayer() { weapon_soulcube = -1; weapon_pda = -1; weapon_fists = -1; +//doomtrinity -> + weapon_pistol = -1; + weapon_shotgun = -1; + weapon_superShotgun = -1; + weapon_machinegun = -1; + weapon_plasmagun = -1; + weapon_rocketlauncher = -1; +//<- doomtrinity showWeaponViewModel = true; skin = NULL; @@ -1302,6 +1377,14 @@ void idPlayer::Init( void ) { weapon_soulcube = SlotForWeapon( "weapon_soulcube" ); weapon_pda = SlotForWeapon( "weapon_pda" ); weapon_fists = SlotForWeapon( "weapon_fists" ); +//doomtrinity -> + weapon_pistol = SlotForWeapon( "weapon_pistol" ); + weapon_shotgun = SlotForWeapon( "weapon_shotgun" ); + weapon_superShotgun = SlotForWeapon( "weapon_shotgun_double" ); + weapon_machinegun = SlotForWeapon( "weapon_machinegun" ); + weapon_plasmagun = SlotForWeapon( "weapon_plasmagun" ); + weapon_rocketlauncher = SlotForWeapon( "weapon_rocketlauncher" ); +//<- doomtrinity showWeaponViewModel = GetUserInfo()->GetBool( "ui_showGun" ); @@ -1538,6 +1621,12 @@ void idPlayer::Init( void ) { } cvarSystem->SetCVarBool( "ui_chat", false ); +//doomtrinity -> + init_mSensitivity = in_mouseSensitivity.GetFloat(); + init_mSmooth = in_mouseSmooth.GetInteger(); + cvarSystem->SetCVarFloat( "sensitivity", init_mSensitivity ); + cvarSystem->SetCVarInteger( "m_smooth", init_mSmooth ); +//<- doomtrinity } /* @@ -1818,7 +1907,14 @@ void idPlayer::Save( idSaveGame *savefile ) const { savefile->WriteInt( weapon_soulcube ); savefile->WriteInt( weapon_pda ); savefile->WriteInt( weapon_fists ); - +//doomtrinity -> + savefile->WriteInt( weapon_pistol ); + savefile->WriteInt( weapon_shotgun ); + savefile->WriteInt( weapon_superShotgun ); + savefile->WriteInt( weapon_machinegun ); + savefile->WriteInt( weapon_plasmagun ); + savefile->WriteInt( weapon_rocketlauncher ); +//<- doomtrinity savefile->WriteInt( heartRate ); savefile->WriteFloat( heartInfo.GetStartTime() ); @@ -1867,6 +1963,7 @@ void idPlayer::Save( idSaveGame *savefile ) const { savefile->WriteVec3( firstPersonViewOrigin ); savefile->WriteMat3( firstPersonViewAxis ); + savefile->WriteMat3( firstPersonViewWeaponAxis ); // doomtrinity-headanim // don't bother saving dragEntity since it's a dev tool @@ -2060,7 +2157,14 @@ void idPlayer::Restore( idRestoreGame *savefile ) { savefile->ReadInt( weapon_soulcube ); savefile->ReadInt( weapon_pda ); savefile->ReadInt( weapon_fists ); - +//doomtrinity -> + savefile->ReadInt( weapon_pistol ); + savefile->ReadInt( weapon_shotgun ); + savefile->ReadInt( weapon_superShotgun ); + savefile->ReadInt( weapon_machinegun ); + savefile->ReadInt( weapon_plasmagun ); + savefile->ReadInt( weapon_rocketlauncher ); +//<- doomtrinity savefile->ReadInt( heartRate ); savefile->ReadFloat( set ); @@ -2113,6 +2217,7 @@ void idPlayer::Restore( idRestoreGame *savefile ) { savefile->ReadVec3( firstPersonViewOrigin ); savefile->ReadMat3( firstPersonViewAxis ); + savefile->ReadMat3( firstPersonViewWeaponAxis ); // doomtrinity-headanim // don't bother saving dragEntity since it's a dev tool dragEntity.Clear(); @@ -2721,7 +2826,7 @@ void idPlayer::UpdateHudAmmo( idUserInterface *_hud ) { atoi( _hud->GetStateString( "player_totalammo" ) ) != ( ammoamount - inclip ) ) { bStatsChanged = true; } - _hud->SetStateString( "player_totalammo", va( "%i", ammoamount - inclip ) ); + _hud->SetStateString( "player_totalammo", va( "%i", ammoamount ) );// doomtrinity (D3XP) _hud->SetStateString( "player_ammo", va( "%i", inclip ) ); // how much in the current clip } else { if ( atoi( _hud->GetStateString( "player_totalammo" ) ) != ammoamount ) @@ -2732,13 +2837,16 @@ void idPlayer::UpdateHudAmmo( idUserInterface *_hud ) { // <---sikk _hud->SetStateString( "player_clips", weapon.GetEntity()->ClipSize() ? va( "%i", ammoamount / weapon.GetEntity()->ClipSize() ) : "--" ); - _hud->SetStateString( "player_allammo", va( "%i/%i", inclip, ammoamount - inclip ) ); + _hud->SetStateString( "player_allammo", va( "%i/%i", inclip, ammoamount ) );// doomtrinity (D3XP) } _hud->SetStateBool( "player_ammo_empty", ( ammoamount == 0 ) ); _hud->SetStateBool( "player_clip_empty", ( weapon.GetEntity()->ClipSize() ? inclip == 0 : false ) ); _hud->SetStateBool( "player_clip_low", ( weapon.GetEntity()->ClipSize() ? inclip <= weapon.GetEntity()->LowAmmo() : false ) ); - +//doomtrinity -> //From D3XP + //Let the HUD know the total amount of ammo regardless of the ammo required value + _hud->SetStateString( "player_ammo_count", va("%i", weapon.GetEntity()->AmmoCount())); +//<- doomtrinity _hud->HandleNamedEvent( "updateAmmo" ); // sikk---> Dynamic Hud System @@ -2901,6 +3009,8 @@ idPlayer::DrawHUD */ void idPlayer::DrawHUD( idUserInterface *_hud ) { +int crosshairType = g_crosshair.GetInteger(); + if ( !weapon.GetEntity() || influenceActive != INFLUENCE_NONE || privateCameraView || gameLocal.GetCamera() || !_hud || !g_showHud.GetBool() ) { return; } @@ -2921,6 +3031,17 @@ void idPlayer::DrawHUD( idUserInterface *_hud ) { // weapon targeting crosshair if ( !GuiActive() ) { if ( cursor && weapon.GetEntity()->ShowCrosshair() ) { +//doomtrinity PD3 -> + if ( usercmd.buttons & BUTTON_ZOOM ) { + if ( crosshairType == 0 || currentWeapon == weapon_pistol || currentWeapon == weapon_shotgun || currentWeapon == weapon_superShotgun /* PD3 || currentWeapon == weapon_machinegun || currentWeapon == weapon_plasmagun || currentWeapon == weapon_rocketlauncher */ ) { + cursor->SetStateString( "combatcursor", "0" ); + } else { + cursor->SetStateString( "combatcursor", "1" ); + } + } else if ( usercmd.buttons & !BUTTON_ZOOM && crosshairType != 0 ) { + cursor->SetStateString( "combatcursor", "1" ); + } +//<- doomtrinity PD3 cursor->Redraw( gameLocal.realClientTime ); } } @@ -3023,7 +3144,7 @@ void idPlayer::UpdateConditions( void ) { AI_STRAFE_RIGHT = false; } - AI_RUN = ( usercmd.buttons & BUTTON_RUN ) && ( ( !pm_stamina.GetFloat() ) || ( stamina > pm_staminathreshold.GetFloat() ) ); + AI_RUN = ( usercmd.buttons & BUTTON_RUN ) && ( ( !pm_stamina.GetFloat() ) || ( stamina > pm_staminathreshold.GetFloat() ) ); // && !( usercmd.buttons & BUTTON_ZOOM ) ;// doomtrinity AI_DEAD = ( health <= 0 ); } @@ -3083,12 +3204,15 @@ void idPlayer::FireWeapon( void ) { if ( weapon.GetEntity()->AmmoInClip() || weapon.GetEntity()->AmmoAvailable() ) { AI_ATTACK_HELD = true; weapon.GetEntity()->BeginAttack(); + /* PD3 if ( ( weapon_soulcube >= 0 ) && ( currentWeapon == weapon_soulcube ) ) { if ( hud ) { hud->HandleNamedEvent( "soulCubeNotReady" ); } SelectWeapon( previousWeapon, false ); + } + */ } else { NextBestWeapon(); } @@ -3441,6 +3565,13 @@ void idPlayer::ClearPowerup( int i ) { StopSound( SND_CHANNEL_DEMONIC, false ); break; } + +// PD3 start + case ADRENALINE: { + StopSound( SND_CHANNEL_DEMONIC, false ); + break; + } +// PD3 end case INVISIBILITY: { if ( weapon.GetEntity() ) { weapon.GetEntity()->UpdateSkin(); @@ -3855,7 +3986,7 @@ void idPlayer::NextBestWeapon( void ) { while ( w > 0 ) { w--; weap = spawnArgs.GetString( va( "def_weapon%d", w ) ); - if ( !weap[ 0 ] || ( ( inventory.weapons & ( 1 << w ) ) == 0 ) || ( !inventory.HasAmmo( weap ) ) ) { + if ( !weap[ 0 ] || ( ( inventory.weapons & ( 1 << w ) ) == 0 ) || ( !inventory.HasAmmo( weap, true, this ) ) ) {// doomtrinity (D3XP) continue; } if ( !spawnArgs.GetBool( va( "weapon%d_best", w ) ) ) { @@ -3906,7 +4037,7 @@ void idPlayer::NextWeapon( void ) { if ( ( inventory.weapons & ( 1 << w ) ) == 0 ) { continue; } - if ( inventory.HasAmmo( weap ) ) { + if ( inventory.HasAmmo( weap, true, this ) ) {// doomtrinity (D3XP) break; } } @@ -3956,7 +4087,7 @@ void idPlayer::PrevWeapon( void ) { if ( ( inventory.weapons & ( 1 << w ) ) == 0 ) { continue; } - if ( inventory.HasAmmo( weap ) ) { + if ( inventory.HasAmmo( weap, true, this ) ) {// doomtrinity (D3XP) break; } } @@ -4005,12 +4136,12 @@ void idPlayer::SelectWeapon( int num, bool force ) { } if ( force || ( inventory.weapons & ( 1 << num ) ) ) { - if ( !inventory.HasAmmo( weap ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", num ) ) ) { + if ( !inventory.HasAmmo( weap, true, this ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", num ) ) ) {// doomtrinity (D3XP) return; } if ( ( previousWeapon >= 0 ) && ( idealWeapon == num ) && ( spawnArgs.GetBool( va( "weapon%d_toggle", num ) ) ) ) { weap = spawnArgs.GetString( va( "def_weapon%d", previousWeapon ) ); - if ( !inventory.HasAmmo( weap ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", previousWeapon ) ) ) { + if ( !inventory.HasAmmo( weap, true, this ) && !spawnArgs.GetBool( va( "weapon%d_allowempty", previousWeapon ) ) ) {// doomtrinity (D3XP) return; } idealWeapon = previousWeapon; @@ -5178,8 +5309,14 @@ void idPlayer::BobCycle( const idVec3 &pushVelocity ) { bobmove = pm_crouchbob.GetFloat(); // ducked characters never play footsteps } else { - // vary the bobbing based on the speed of the player - bobmove = pm_walkbob.GetFloat() * ( 1.0f - bobFrac ) + pm_runbob.GetFloat() * bobFrac; +//doomtrinity -> + if ( usercmd.buttons & BUTTON_ZOOM ) { + bobmove = pm_adsbob.GetFloat(); + } else { + // vary the bobbing based on the speed of the player + bobmove = pm_walkbob.GetFloat() * ( 1.0f - bobFrac ) + pm_runbob.GetFloat() * bobFrac; + } +//<- doomtrinity } // check for footstep / splash sounds @@ -6066,9 +6203,16 @@ void idPlayer::PerformImpulse( int impulse ) { break; } +// PD3 + case IMPULSE_21: { + SelectWeapon( 13, true ); + break; + } + // sikk---> Headlight Mod case IMPULSE_23: { - if ( GetCurrentWeapon() < 11 && !gameLocal.inCinematic ) + if ( !gameLocal.inCinematic ) + // PD3 if ( GetCurrentWeapon() < 11 && !gameLocal.inCinematic ) ToggleHeadlight(); break; } @@ -6220,7 +6364,7 @@ void idPlayer::AdjustSpeed( void ) { } else if ( noclip ) { speed = pm_noclipspeed.GetFloat(); bobFrac = 0.0f; - } else if ( !physicsObj.OnLadder() && ( usercmd.buttons & BUTTON_RUN ) && ( usercmd.forwardmove || usercmd.rightmove ) && ( usercmd.upmove >= 0 ) ) { + } else if ( !physicsObj.OnLadder() && ( usercmd.buttons & BUTTON_RUN ) && ( usercmd.forwardmove || usercmd.rightmove ) && ( usercmd.upmove >= 0 ) && !( usercmd.buttons & BUTTON_ZOOM ) ) {// doomtrinity if ( !gameLocal.isMultiplayer && !physicsObj.IsCrouching() && !PowerUpActive( ADRENALINE ) ) { stamina -= MS2SEC( gameLocal.msec ); } @@ -6247,7 +6391,14 @@ void idPlayer::AdjustSpeed( void ) { if ( stamina > pm_stamina.GetFloat() ) { stamina = pm_stamina.GetFloat(); } - speed = walkSpeed * ( g_weaponAwareness.GetBool() && bIsZoomed ? 0.75f : 1.0f ); // sikk - Decreased movement speed when zoomed +//doomtrinity -> + if ( usercmd.buttons & BUTTON_ZOOM ) { + speed = pm_adsspeed.GetFloat(); + } else { + speed = walkSpeed; + } + //speed = walkSpeed * ( g_weaponAwareness.GetBool() && bIsZoomed ? 0.75f : 1.0f ); // sikk - Decreased movement speed when zoomed +//<- doomtrinity bobFrac = 0.0f; } @@ -6677,7 +6828,7 @@ void idPlayer::UpdateHud( void ) { } // <---sikk -// sikk---> Crosshair Cvar +// sikk---> Crosshair Cvar PD3 int crosshairType = g_crosshair.GetInteger(); if ( crosshairType == 0 ) { cursor->SetStateString( "combatcursor", "0" ); @@ -6690,27 +6841,8 @@ void idPlayer::UpdateHud( void ) { cursor->SetStateString( "pickupcursor", "0" ); } cursor->SetStateString( "cursorposition", buf ); - } else if ( crosshairType == 2 ) { - cursor->SetStateString( "cursorposition", buf ); - if ( ( bIsZoomed || GetTalkCursor() ) && - !( g_weaponAwareness.GetBool() && ( bWATrace || bWAIsSprinting || OnLadder() ) ) && - ( GetCurrentWeapon() > 0 && GetCurrentWeapon() < 9 ) ) { - if ( !grabEntity.GetGrabEntity() && ( focusItem || focusCorpse || focusMoveable ) ) { - cursor->SetStateString( "combatcursor", "0" ); - cursor->SetStateString( "pickupcursor", "1" ); - } else { - cursor->SetStateString( "combatcursor", "1" ); - cursor->SetStateString( "pickupcursor", "0" ); - } - } else { - cursor->SetStateString( "combatcursor", "0" ); - if ( !grabEntity.GetGrabEntity() && ( focusItem || focusCorpse || focusMoveable ) ) - cursor->SetStateString( "pickupcursor", "1" ); - else - cursor->SetStateString( "pickupcursor", "0" ); - } } -// <---sikk +// <---sikk PD3 } /* @@ -6837,15 +6969,33 @@ void idPlayer::Think( void ) { if ( ( usercmd.buttons ^ oldCmd.buttons ) & BUTTON_MLOOK ) { centerView.Init( gameLocal.time, 200, viewAngles.pitch, 0 ); } +//doomtrinity -> + if ( init_mSensitivity != in_mouseSensitivity.GetFloat() ) { + init_mSensitivity = in_mouseSensitivity.GetFloat(); + cvarSystem->SetCVarFloat( "sensitivity", init_mSensitivity ); + } + if ( init_mSmooth != in_mouseSmooth.GetInteger() ) { + init_mSmooth = in_mouseSmooth.GetInteger(); + cvarSystem->SetCVarInteger( "m_smooth", init_mSmooth ); + } +//<- doomtrinity // zooming if ( ( usercmd.buttons ^ oldCmd.buttons ) & BUTTON_ZOOM ) { if ( ( usercmd.buttons & BUTTON_ZOOM ) && weapon.GetEntity() ) { zoomFov.Init( gameLocal.time, 200.0f, CalcFov( false ), weapon.GetEntity()->GetZoomFov() ); bIsZoomed = true; // sikk - Depth of Field PostProcess +//doomtrinity -> + cvarSystem->SetCVarFloat( "sensitivity", ( in_mouseSensitivity.GetFloat() * 0.75f ) );// Mouse sensitivity is 75% when zooming + cvarSystem->SetCVarInteger( "m_smooth", 8 );// Force the smoothness of the mouse view +//<- doomtrinity } else { zoomFov.Init( gameLocal.time, 200.0f, zoomFov.GetCurrentValue( gameLocal.time ), DefaultFov() ); bIsZoomed = false; // sikk - Depth of Field PostProcess +//doomtrinity -> + cvarSystem->SetCVarFloat( "sensitivity", in_mouseSensitivity.GetFloat() ); + cvarSystem->SetCVarInteger( "m_smooth", in_mouseSmooth.GetInteger() ); +//<- doomtrinity } } @@ -7755,7 +7905,8 @@ void idPlayer::CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis ) { // CalculateRenderView must have been called first const idVec3 &viewOrigin = firstPersonViewOrigin; - const idMat3 &viewAxis = firstPersonViewAxis; + //const idMat3 &viewAxis = firstPersonViewAxis; // doomtrinity-headanim - commented out. Use "firstPersonViewWeaponAxis" which doesn't take care of the head orientation. + const idMat3 &viewAxis = firstPersonViewWeaponAxis; // doomtrinity-headanim // these cvars are just for hand tweaking before moving a value to the weapon def idVec3 gunpos( g_gun_x.GetFloat(), g_gun_y.GetFloat(), g_gun_z.GetFloat() ); @@ -7794,14 +7945,16 @@ void idPlayer::CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis ) { } else if ( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME ) { origin -= gravity * ( landChange*0.25f * (LAND_DEFLECT_TIME + LAND_RETURN_TIME - delta) / LAND_RETURN_TIME ); } - - // speed sensitive idle drift - scale = xyspeed + 40.0f; - fracsin = scale * sin( MS2SEC( gameLocal.time ) ) * 0.01f; - angles.roll += fracsin; - angles.yaw += fracsin; - angles.pitch += fracsin; - +//doomtrinity -> + if ( !( usercmd.buttons & BUTTON_ZOOM ) ) { + // speed sensitive idle drift + scale = xyspeed + 40.0f; + fracsin = scale * sin( MS2SEC( gameLocal.time ) ) * 0.01f; + angles.roll += fracsin; + angles.yaw += fracsin; + angles.pitch += fracsin; + } +//<- doomtrinity axis = angles.ToMat3() * viewAxis; } @@ -7905,6 +8058,7 @@ idPlayer::GetViewPos */ void idPlayer::GetViewPos( idVec3 &origin, idMat3 &axis ) const { idAngles angles; + idAngles headAnimAngle; // doomtrinity-headanim // if dead, fix the angle and don't add any kick if ( health <= 0 ) { @@ -7916,6 +8070,17 @@ void idPlayer::GetViewPos( idVec3 &origin, idMat3 &axis ) const { } else { origin = GetEyePosition() + viewBob; angles = viewAngles + viewBobAngles + playerView.AngleOffset(); + //angles = viewAngles + viewBobAngles + playerView.AngleOffset(); // doomtrinity-headanim - commented out +// doomtrinity-headanim --> // Check in the viewmodel if the bone "head" is present, if true take care of its orientation. + if ( weapon.GetEntity()->HasHeadJoint() ) { + headAnimAngle = weapon.GetEntity()->GetHeadAngle(); + angles = viewAngles + viewBobAngles + headAnimAngle + playerView.AngleOffset(); + //gameLocal.Printf( "calculate head anim\n" ); + } else { + angles = viewAngles + viewBobAngles + playerView.AngleOffset(); + //gameLocal.Printf( "DO NOT calculate head anim\n" ); + } +// <-- doomtrinity-headanim axis = angles.ToMat3() * physicsObj.GetGravityAxis(); @@ -7925,6 +8090,31 @@ void idPlayer::GetViewPos( idVec3 &origin, idMat3 &axis ) const { } } +/* +=============== +idPlayer::GetViewWeaponAxis // doomtrinity-headanim +=============== +*/ +void idPlayer::GetViewWeaponAxis( idMat3 &axis ) const { + idAngles angles; + + // if dead, fix the angle and don't add any kick + if ( health <= 0 ) { + angles.yaw = viewAngles.yaw; + angles.roll = 40; + angles.pitch = -15; + axis = angles.ToMat3(); + + } else { + + angles = viewAngles + viewBobAngles + playerView.AngleOffset(); + + axis = angles.ToMat3() * physicsObj.GetGravityAxis(); + + + } +} + /* =============== idPlayer::CalculateFirstPersonView @@ -7954,6 +8144,7 @@ void idPlayer::CalculateFirstPersonView( void ) { firstPersonViewAxis = firstPersonViewAxis * playerView.ShakeAxis(); #endif } + GetViewWeaponAxis( firstPersonViewWeaponAxis ); // doomtrinity-headanim } /* @@ -9167,6 +9358,26 @@ void idPlayer::Event_GetIdealWeapon( void ) { } } +// doomtrinity-dual weapon-> +/* +================== +idPlayer::Event_GetNumPistols +================== +*/ +void idPlayer::Event_GetNumPistols( void ) { + idThread::ReturnInt( inventory.pistolInInventory ); +} +/* +================== +idPlayer::Event_GetNumShotguns +================== +*/ +void idPlayer::Event_GetNumShotguns( void ) { + idThread::ReturnInt( inventory.shotgunDoubleInInventory ); +} +// doomtrinity-dual weapon-< + + /* =============== idPlayer::UpdatePlayerIcons @@ -9332,7 +9543,8 @@ void idPlayer::UpdateBattery() { if ( nBattery <= 0 ) { nBattery = 0; ToggleHeadlight(); - } else if ( GetCurrentWeapon() >= 11 || gameLocal.inCinematic ) { + } else if ( gameLocal.inCinematic ) { +// PD3 } else if ( GetCurrentWeapon() >= 11 || gameLocal.inCinematic ) { ToggleHeadlight(); } } @@ -9445,10 +9657,10 @@ void idPlayer::ToggleHeadlight() { // spawn headlight light args.Set( "classname", "light" ); args.Set( "name", name + "_headlight" ); // light name - args.Set( "texture", "lights/headlight" ); // light texture - args.Set( "light_target", "768 0 0" ); // light cone direction - args.Set( "light_up", "0 0 192" ); // light cone height - args.Set( "light_right", "0 -192 0" ); // light cone width + args.Set( "texture", "lights/wrakelight" ); // light texture + args.Set( "light_target", "1536 0 0" ); // light cone direction // doomtrinity-was 768 0 0 + args.Set( "light_up", "0 0 768" ); // light cone height // doomtrinity-was 0 0 192 + args.Set( "light_right", "0 -768 0" ); // light cone width // doomtrinity-was 0 -192 0 gameLocal.SpawnEntityDef( args, &ent ); ent->BindToJoint( this, "head", 0.0f ); // light bind parent joint ent->SetOrigin( idVec3( 8, -12, 4 ) ); // light origin @@ -9566,8 +9778,10 @@ idPlayer::UseAdrenaline */ void idPlayer::UseAdrenaline() { if ( adrenalineAmount ) { - inventory.GivePowerUp( this, ADRENALINE, 0 ); - StartSoundShader( declManager->FindSound( "pickup_adrenaline" ), SND_CHANNEL_ITEM, 0, false, NULL ); + inventory.GivePowerUp( this, BERSERK, 0 ); // PD3 + // PD3 inventory.GivePowerUp( this, ADRENALINE, 0 ); + // PD3 StartSoundShader( declManager->FindSound( "pickup_adrenaline" ), SND_CHANNEL_ITEM, 0, false, NULL ); + StartSoundShader( declManager->FindSound( "player_sounds_berserk" ), SND_CHANNEL_DEMONIC, 0, false, NULL ); // PD3 stamina = 100.0f; adrenalineAmount = 0; } @@ -9639,7 +9853,7 @@ bool idPlayer::GetWeaponAwareness() { bWATrace = false; } - bWAIsSprinting = ( ( GetCurrentWeapon() > 0 ) && AI_RUN && ( AI_FORWARD || AI_BACKWARD || AI_STRAFE_LEFT || AI_STRAFE_RIGHT ) ); + bWAIsSprinting = ( ( GetCurrentWeapon() >= 0 ) && AI_RUN && ( AI_FORWARD || AI_BACKWARD || AI_STRAFE_LEFT || AI_STRAFE_RIGHT ) ); if ( bWATrace || bWAIsSprinting || OnLadder() ) return true; diff --git a/game/Player.h b/game/Player.h index 11b2e47..620709f 100644 --- a/game/Player.h +++ b/game/Player.h @@ -127,6 +127,8 @@ class idInventory { public: int maxHealth; int weapons; + int shotgunDoubleInInventory; // doomtrinity-dual weapon + int pistolInInventory; // doomtrinity-dual weapon int powerups; int armor; int maxarmor; @@ -186,7 +188,7 @@ public: int HasAmmo( ammo_t type, int amount ); bool UseAmmo( ammo_t type, int amount ); - int HasAmmo( const char *weapon_classname ); // looks up the ammo information for the weapon class first + int HasAmmo( const char *weapon_classname, bool includeClip = false, idPlayer* owner = NULL ); // looks up the ammo information for the weapon class first // doomtrinity (D3XP) void UpdateArmor( void ); @@ -272,7 +274,14 @@ public: int weapon_soulcube; int weapon_pda; int weapon_fists; - +//doomtrinity -> + int weapon_pistol; + int weapon_shotgun; + int weapon_superShotgun; + int weapon_machinegun; + int weapon_plasmagun; + int weapon_rocketlauncher; +//<- doomtrinity int heartRate; idInterpolate heartInfo; int lastHeartAdjust; @@ -327,6 +336,7 @@ public: // if a third person view is used idVec3 firstPersonViewOrigin; idMat3 firstPersonViewAxis; + idMat3 firstPersonViewWeaponAxis; // doomtrinity-headanim idDragEntity dragEntity; @@ -406,6 +416,7 @@ public: void CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis ); idVec3 GetEyePosition( void ) const; void GetViewPos( idVec3 &origin, idMat3 &axis ) const; + void GetViewWeaponAxis( idMat3 &axis ) const; // doomtrinity-headanim void OffsetThirdPersonView( float angle, float range, float height, bool clip ); bool Give( const char *statname, const char *value ); @@ -658,7 +669,10 @@ private: idInterpolate zoomFov; idInterpolate centerView; bool fxFov; - +//doomtrinity -> + float init_mSensitivity; + int init_mSmooth; +//<- doomtrinity float influenceFov; int influenceActive; // level of influence.. 1 == no gun or hud .. 2 == 1 + no movement idEntity * influenceEntity; @@ -779,6 +793,9 @@ private: void Event_LevelTrigger( void ); void Event_Gibbed( void ); void Event_GetIdealWeapon( void ); + // doomtrinity-dual weapon + void Event_GetNumPistols( void ); + void Event_GetNumShotguns( void ); }; ID_INLINE bool idPlayer::IsReady( void ) { diff --git a/game/PlayerView.cpp b/game/PlayerView.cpp index 7f598a1..e0a142d 100644 --- a/game/PlayerView.cpp +++ b/game/PlayerView.cpp @@ -321,6 +321,7 @@ void idPlayerView::DamageImpulse( idVec3 localKickDir, const idDict *damageDef ) } // screen blob + /* PD3 float blobTime = damageDef->GetFloat( "blob_time" ); if ( blobTime ) { screenBlob_t *blob = GetScreenBlob(); @@ -344,6 +345,12 @@ void idPlayerView::DamageImpulse( idVec3 localKickDir, const idDict *damageDef ) blob->s2 = 1; blob->t2 = 1; } + */ + + //PD3 + if ( g_showBloodSpray.GetBool() ) { + player->playerView.AddBloodSpray( g_bloodSprayTime.GetFloat() ); + } // save lastDamageTime for tunnel vision attenuation lastDamageTime = MS2SEC( gameLocal.time ); diff --git a/game/Projectile.cpp b/game/Projectile.cpp index c6d6aa5..16a72dc 100644 --- a/game/Projectile.cpp +++ b/game/Projectile.cpp @@ -2180,10 +2180,25 @@ void idDebris::Restore( idRestoreGame *savefile ) { idDebris::Launch ================= */ +/********************************************************* +doomtrinity-> +Following method includes code from Denton's mod v. 2.02 +to enhance brass ejection behaviour. +Be sure to add the macro +_DENTONMOD +in the game properties if you want to compile the code +with his changes. +Thanks to Clone JC Denton +*********************************************************/ void idDebris::Launch( void ) { float fuse; idVec3 velocity; +#ifdef _DENTONMOD + idVec3 angular_velocity_vect; +#else idAngles angular_velocity; +#endif + float linear_friction; float angular_friction; float contact_friction; @@ -2197,7 +2212,12 @@ void idDebris::Launch( void ) { renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time ); spawnArgs.GetVector( "velocity", "0 0 0", velocity ); +#ifdef _DENTONMOD + angular_velocity_vect = spawnArgs.GetAngles( "angular_velocity", "0 0 0").ToAngularVelocity(); +#else spawnArgs.GetAngles( "angular_velocity", "0 0 0", angular_velocity ); +#endif + linear_friction = spawnArgs.GetFloat( "linear_friction" ); angular_friction = spawnArgs.GetFloat( "angular_friction" ); @@ -2213,9 +2233,29 @@ void idDebris::Launch( void ) { } if ( randomVelocity ) { +#ifdef _DENTONMOD + float rand = spawnArgs.GetFloat("linear_velocity_rand", "0.35"); + + // sets velocity randomly between ((1-rand)*100)% and ((1+rand)*100)% + // e.g.1: if rand = 0.2, velocity will be randomly set between 80% and 120% + // e.g.2: if rand = 0.3, velocity will be randomly set between 70% and 130% + // and so on. + velocity.x *= gameLocal.random.RandomFloat()*rand*2.0 + 1.0 - rand; + velocity.y *= gameLocal.random.RandomFloat()*rand*2.0 + 1.0 - rand; + velocity.z *= gameLocal.random.RandomFloat()*rand*2.0 + 1.0 - rand; + + // do not perform following calculations unless there's key in decl that says so. + if( spawnArgs.GetFloat( "angular_velocity_rand", "0.0", rand) && rand > 0.0f ) { + angular_velocity_vect.x *= gameLocal.random.RandomFloat()*rand*2.0 + 1.0 - rand; + angular_velocity_vect.y *= gameLocal.random.RandomFloat()*rand*2.0 + 1.0 - rand; + angular_velocity_vect.z *= gameLocal.random.RandomFloat()*rand*2.0 + 1.0 - rand; + } +#else velocity.x *= gameLocal.random.RandomFloat() + 0.5f; velocity.y *= gameLocal.random.RandomFloat() + 0.5f; velocity.z *= gameLocal.random.RandomFloat() + 0.5f; +#endif + } if ( health ) { @@ -2256,8 +2296,22 @@ void idDebris::Launch( void ) { physicsObj.SetGravity( gravVec * gravity ); physicsObj.SetContents( 0 ); physicsObj.SetClipMask( MASK_SOLID | CONTENTS_MOVEABLECLIP ); +#ifdef _DENTONMOD + // Make sure that the linear velocity is added with + // owner's linear velocity for more accurate physics simulation. + idEntity *ownerEnt = owner.GetEntity(); + if( ownerEnt != NULL ) { + physicsObj.SetLinearVelocity( (axis[ 0 ] * velocity[ 0 ] + axis[ 1 ] * velocity[ 1 ] + axis[ 2 ] * velocity[ 2 ]) + ownerEnt->GetPhysics()->GetLinearVelocity()); + } + else { + physicsObj.SetLinearVelocity( axis[ 0 ] * velocity[ 0 ] + axis[ 1 ] * velocity[ 1 ] + axis[ 2 ] * velocity[ 2 ] ); + } + physicsObj.SetAngularVelocity( angular_velocity_vect * axis ); +#else physicsObj.SetLinearVelocity( axis[ 0 ] * velocity[ 0 ] + axis[ 1 ] * velocity[ 1 ] + axis[ 2 ] * velocity[ 2 ] ); physicsObj.SetAngularVelocity( angular_velocity.ToAngularVelocity() * axis ); +#endif + physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); physicsObj.SetAxis( axis ); SetPhysics( &physicsObj ); diff --git a/game/Weapon.cpp b/game/Weapon.cpp index fd426f8..58f1fff 100644 --- a/game/Weapon.cpp +++ b/game/Weapon.cpp @@ -74,6 +74,7 @@ const idEventDef EV_Weapon_AllowDrop( "allowDrop", "d" ); const idEventDef EV_Weapon_AutoReload( "autoReload", NULL, 'f' ); const idEventDef EV_Weapon_NetReload( "netReload" ); const idEventDef EV_Weapon_IsInvisible( "isInvisible", NULL, 'f' ); +const idEventDef EV_Weapon_IsLowered( "isLowered", NULL, 'd' ); // doomtrinity const idEventDef EV_Weapon_NetEndReload( "netEndReload" ); // @@ -115,6 +116,7 @@ CLASS_DECLARATION( idAnimatedEntity, idWeapon ) EVENT( EV_Weapon_AutoReload, idWeapon::Event_AutoReload ) EVENT( EV_Weapon_NetReload, idWeapon::Event_NetReload ) EVENT( EV_Weapon_IsInvisible, idWeapon::Event_IsInvisible ) + EVENT( EV_Weapon_IsLowered, idWeapon::Event_IsLowered ) // doomtrinity EVENT( EV_Weapon_NetEndReload, idWeapon::Event_NetEndReload ) END_CLASS @@ -337,6 +339,7 @@ void idWeapon::Save( idSaveGame *savefile ) const { savefile->WriteJoint( ejectJointView ); savefile->WriteJoint( guiLightJointView ); savefile->WriteJoint( ventLightJointView ); + savefile->WriteJoint( headJointView ); // doomtrinity-headanim savefile->WriteJoint( flashJointWorld ); savefile->WriteJoint( barrelJointWorld ); @@ -501,6 +504,7 @@ void idWeapon::Restore( idRestoreGame *savefile ) { savefile->ReadJoint( ejectJointView ); savefile->ReadJoint( guiLightJointView ); savefile->ReadJoint( ventLightJointView ); + savefile->ReadJoint( headJointView ); // doomtrinity-headanim savefile->ReadJoint( flashJointWorld ); savefile->ReadJoint( barrelJointWorld ); @@ -693,6 +697,7 @@ void idWeapon::Clear( void ) { ejectJointView = INVALID_JOINT; guiLightJointView = INVALID_JOINT; ventLightJointView = INVALID_JOINT; + headJointView = INVALID_JOINT; // doomtrinity-headanim barrelJointWorld = INVALID_JOINT; flashJointWorld = INVALID_JOINT; @@ -878,6 +883,7 @@ void idWeapon::GetWeaponDef( const char *objectname, int ammoinclip ) { ejectJointView = animator.GetJointHandle( "eject" ); guiLightJointView = animator.GetJointHandle( "guiLight" ); ventLightJointView = animator.GetJointHandle( "ventLight" ); + headJointView = animator.GetJointHandle( "head" ); // doomtrinity-headanim // get the projectile projectileDict.Clear(); @@ -993,6 +999,10 @@ void idWeapon::GetWeaponDef( const char *objectname, int ammoinclip ) { if ( ammoClip > ammoAvail ) { ammoClip = ammoAvail; } +//doomtrinity -> //From D3XP + //In D3XP we use ammo as soon as it is moved into the clip. This allows for weapons that share ammo + owner->inventory.UseAmmo(ammoType, ammoClip); +//<- doomtrinity } renderEntity.gui[ 0 ] = NULL; @@ -1105,16 +1115,20 @@ void idWeapon::UpdateGUI( void ) { renderEntity.gui[ 0 ]->SetStateString( "player_ammo", ClipSize() ? va( "%i", inclip ) : "" ); renderEntity.gui[ 0 ]->SetStateString( "player_clips", ClipSize() ? va("%i", ammoamount / ClipSize()) : "" ); } else { - renderEntity.gui[ 0 ]->SetStateString( "player_totalammo", va( "%i", ammoamount - inclip ) ); + renderEntity.gui[ 0 ]->SetStateString( "player_totalammo", va( "%i", ammoamount ) );// doomtrinity (D3XP) renderEntity.gui[ 0 ]->SetStateString( "player_ammo", ClipSize() ? va( "%i", inclip ) : "--" ); renderEntity.gui[ 0 ]->SetStateString( "player_clips", ClipSize() ? va("%i", ammoamount / ClipSize()) : "--" ); } // <---sikk - renderEntity.gui[ 0 ]->SetStateString( "player_allammo", va( "%i/%i", inclip, ammoamount - inclip ) ); + renderEntity.gui[ 0 ]->SetStateString( "player_allammo", va( "%i/%i", inclip, ammoamount ) );// doomtrinity (D3XP) } renderEntity.gui[ 0 ]->SetStateBool( "player_ammo_empty", ( ammoamount == 0 ) ); renderEntity.gui[ 0 ]->SetStateBool( "player_clip_empty", ( inclip == 0 ) ); renderEntity.gui[ 0 ]->SetStateBool( "player_clip_low", ( inclip <= lowAmmo ) ); +//doomtrinity -> //From D3XP + //Let the HUD know the total amount of ammo regardless of the ammo required value + renderEntity.gui[ 0 ]->SetStateString( "player_ammo_count", va("%i", AmmoCount())); +//<- doomtrinity } /*********************************************************************** @@ -1260,6 +1274,27 @@ bool idWeapon::GetGlobalJointTransform( bool viewModel, const jointHandle_t join return false; } +/* +================ +idWeapon::GetHeadAngle // doomtrinity-headanim + +returns the orientation of the joint in local space +================ +*/ +idAngles idWeapon::GetHeadAngle( void ) {// was idVec3 + idVec3 offset; + idMat3 axis; + + if ( !animator.GetJointTransform( headJointView, gameLocal.time, offset, axis ) ) { + gameLocal.Warning( "Joint # %d out of range on entity '%s'", headJointView, name.c_str() ); + } + + idAngles ang = axis.ToAngles(); + return ang; + //idVec3 vec( ang[ 0 ], ang[ 1 ], ang[ 2 ] ); + //return vec; +} + /* ================ idWeapon::SetPushVelocity @@ -1335,6 +1370,7 @@ void idWeapon::LowerWeapon( void ) { hideStartTime = gameLocal.time; } hide = true; + Event_IsLowered(); // doomtrinity } } @@ -1355,6 +1391,7 @@ void idWeapon::RaiseWeapon( void ) { hideStartTime = gameLocal.time; } hide = false; + Event_IsLowered(); // doomtrinity } } @@ -1717,6 +1754,19 @@ bool idWeapon::BloodSplat( float size ) { return true; } +/* +================ +idWeapon::HasHeadJoint // doomtrinity-headanim +================ +*/ +bool idWeapon::HasHeadJoint( void ) { + + if ( headJointView != INVALID_JOINT ) { + return true; + } + + return false; +} /*********************************************************************** @@ -2295,7 +2345,23 @@ idWeapon::AmmoRequired int idWeapon::AmmoRequired( void ) const { return ammoRequired; } +//doomtrinity -> //From D3XP +/* +================ +idWeapon::AmmoCount +Returns the total number of rounds regardless of the required ammo +================ +*/ +int idWeapon::AmmoCount() const { + + if ( owner ) { + return owner->inventory.HasAmmo( ammoType, 1 ); + } else { + return 0; + } +} +//<- doomtrinity /* ================ idWeapon::WriteToSnapshot @@ -2410,6 +2476,8 @@ idWeapon::Event_WeaponState */ void idWeapon::Event_WeaponState( const char *statename, int blendFrames ) { const function_t *func; +// idStr inv_weapon; // doomtrinity-dual weapon test +// float result; // doomtrinity-dual weapon test func = scriptObject.GetFunction( statename ); if ( !func ) { @@ -2425,6 +2493,15 @@ void idWeapon::Event_WeaponState( const char *statename, int blendFrames ) { isFiring = false; } +// doomtrinity-dual weapon test-> +// inv_weapon = spawnArgs.GetString( va("inv_weapon") ); +// gameLocal.persistentLevelInfo.GetFloat( "player1_pistol_single", "0", result ); +// +// if ( ( inv_weapon == "weapon_pistol" ) && ( !idealState.Icmp( "Raise" ) ) && !result ) { +// gameLocal.Printf( "raise pistol!\n" ); +// } +// doomtrinity-dual weapon test-< + animBlendFrames = blendFrames; thread->DoneProcessing(); } @@ -2514,7 +2591,7 @@ void idWeapon::Event_UseAmmo( int amount ) { return; } - owner->inventory.UseAmmo( ammoType, ( powerAmmo ) ? amount : ( amount * ammoRequired ) ); + //owner->inventory.UseAmmo( ammoType, ( powerAmmo ) ? amount : ( amount * ammoRequired ) ); // Commented out, now this event works as it should. // doomtrinity if ( clipSize && ammoRequired ) { ammoClip -= powerAmmo ? amount : ( amount * ammoRequired ); if ( ammoClip < 0 ) { @@ -2534,16 +2611,24 @@ void idWeapon::Event_AddToClip( int amount ) { if ( gameLocal.isClient ) { return; } - +//doomtrinity -> //From D3XP + int oldAmmo = ammoClip; + ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired ) + AmmoInClip(); +//<- doomtrinity ammoClip += amount; if ( ammoClip > clipSize ) { ammoClip = clipSize; } - ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired ); + //ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired );// doomtrinity (D3XP) if ( ammoClip > ammoAvail ) { ammoClip = ammoAvail; } +//doomtrinity -> //From D3XP + // for shared ammo we need to use the ammo when it is moved into the clip + int usedAmmo = ammoClip - oldAmmo; + owner->inventory.UseAmmo(ammoType, usedAmmo); +//<- doomtrinity } /* @@ -2563,6 +2648,7 @@ idWeapon::Event_AmmoAvailable */ void idWeapon::Event_AmmoAvailable( void ) { int ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired ); + ammoAvail += AmmoInClip();// doomtrinity (D3XP) idThread::ReturnFloat( ammoAvail ); } @@ -2865,13 +2951,20 @@ void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float // avoid all ammo considerations on an MP client if ( !gameLocal.isClient ) { +//doomtrinity -> //From D3XP - // check if we're out of ammo or the clip is empty + int ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired ); + if ( ( clipSize != 0 ) && ( ammoClip <= 0 ) ) { + return; + } + +/* // check if we're out of ammo or the clip is empty int ammoAvail = owner->inventory.HasAmmo( ammoType, ammoRequired ); if ( !ammoAvail || ( ( clipSize != 0 ) && ( ammoClip <= 0 ) ) ) { return; } - +*/ +//<- doomtrinity // if this is a power ammo weapon ( currently only the bfg ) then make sure // we only fire as much power as available in each clip if ( powerAmmo ) { @@ -2884,10 +2977,19 @@ void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float dmgPower = ammoClip; } } +//doomtrinity -> //From D3XP + if(clipSize == 0) { + //Weapons with a clip size of 0 launch strait from inventory without moving to a clip + + //In D3XP we used the ammo when the ammo was moved into the clip so we don't want to + //use it now. + owner->inventory.UseAmmo( ammoType, ( powerAmmo ) ? dmgPower : ammoRequired ); + + } +//<- doomtrinity - owner->inventory.UseAmmo( ammoType, ( powerAmmo ) ? dmgPower : ammoRequired ); if ( clipSize && ammoRequired ) { - ammoClip -= powerAmmo ? dmgPower : 1; + ammoClip -= powerAmmo ? dmgPower : ammoRequired;// doomtrinity (D3XP) } } @@ -3019,7 +3121,15 @@ void idWeapon::Event_LaunchProjectiles( int num_projectiles, float spread, float } // toss the brass - PostEventMS( &EV_Weapon_EjectBrass, brassDelay ); + +//doomtrinity -> // From D3XP + + if( brassDelay >= 0 ) { + PostEventMS( &EV_Weapon_EjectBrass, brassDelay ); + } + +//<- doomtrinity + } // add the light for the muzzleflash @@ -3094,8 +3204,8 @@ void idWeapon::Event_Melee( void ) { ent->Damage( owner, owner, globalKickDir, meleeDefName, owner->PowerUpModifier( MELEE_DAMAGE ), tr.c.id ); hit = true; -// sikk---> Chainsaw View Sticking - if ( ent->IsType( idAI::Type ) && !idStr::Icmp( weaponDef->GetName(), "weapon_chainsaw" ) ) { +// sikk---> Chainsaw View Sticking // commented out ( we want default chainsaw behaviour ),doomtrinity +/* if ( ent->IsType( idAI::Type ) && !idStr::Icmp( weaponDef->GetName(), "weapon_chainsaw" ) ) { idVec3 playerOrigin; idMat3 playerAxis; idVec3 targetVec = ent->GetPhysics()->GetAbsBounds().GetCenter(); @@ -3113,6 +3223,7 @@ void idWeapon::Event_Melee( void ) { // push the player towards the monster owner->ApplyImpulse( ent, 0, playerOrigin, playerAxis[ 0 ] * 20000.0f ); } +*/ // <---sikk } @@ -3232,12 +3343,15 @@ void idWeapon::Event_EjectBrass( void ) { idDebris *debris = static_cast(ent); debris->Create( owner, origin, axis ); debris->Launch(); - +//doomtrinity -> // following code commented out. Linear velocity in brass def works properly now. +/* linear_velocity = 40 * ( playerViewAxis[0] + playerViewAxis[1] + playerViewAxis[2] ); angular_velocity.Set( 10 * gameLocal.random.CRandomFloat(), 10 * gameLocal.random.CRandomFloat(), 10 * gameLocal.random.CRandomFloat() ); debris->GetPhysics()->SetLinearVelocity( linear_velocity ); debris->GetPhysics()->SetAngularVelocity( angular_velocity ); +*/ +//doomtrinity -< } /* @@ -3252,7 +3366,16 @@ void idWeapon::Event_IsInvisible( void ) { } idThread::ReturnFloat( owner->PowerUpActive( INVISIBILITY ) ? 1 : 0 ); } - +//doomtrinity-> +/* +=============== +idWeapon::Event_IsLowered +=============== +*/ +void idWeapon::Event_IsLowered( void ) { + idThread::ReturnInt( hide ); +} +//<-doomtrinity /* =============== idWeapon::ClientPredictionThink diff --git a/game/Weapon.h b/game/Weapon.h index fdd94ed..80a2d0b 100644 --- a/game/Weapon.h +++ b/game/Weapon.h @@ -132,6 +132,8 @@ public: void GetWeaponAngleOffsets( int *average, float *scale, float *max ); void GetWeaponTimeOffsets( float *time, float *scale ); bool BloodSplat( float size ); + bool HasHeadJoint( void ); // doomtrinity-headanim + idAngles GetHeadAngle( void ); // doomtrinity-headanim //was idVec3 // Ammo static ammo_t GetAmmoNumForName( const char *ammoname ); @@ -144,6 +146,7 @@ public: int ClipSize( void ) const; int LowAmmo( void ) const; int AmmoRequired( void ) const; + int AmmoCount() const;// doomtrinity (D3XP) virtual void WriteToSnapshot( idBitMsgDelta &msg ) const; virtual void ReadFromSnapshot( const idBitMsgDelta &msg ); @@ -286,6 +289,7 @@ private: jointHandle_t ejectJointView; jointHandle_t guiLightJointView; jointHandle_t ventLightJointView; + jointHandle_t headJointView; // doomtrinity-headanim jointHandle_t flashJointWorld; jointHandle_t barrelJointWorld; @@ -370,6 +374,7 @@ private: void Event_AutoReload( void ); void Event_NetReload( void ); void Event_IsInvisible( void ); + void Event_IsLowered( void ); // doomtrinity void Event_NetEndReload( void ); }; diff --git a/game/ai/AI_events.cpp b/game/ai/AI_events.cpp index 279b91c..04d6687 100644 --- a/game/ai/AI_events.cpp +++ b/game/ai/AI_events.cpp @@ -850,8 +850,6 @@ idAI::Event_StopRagdoll void idAI::Event_StopRagdoll( void ) { StopRagdoll(); - physicsObj.SetOrigin( af.GetPhysics()->GetOrigin() ); // sikk - Zombie Ressurection Fix - // set back the monster physics SetPhysics( &physicsObj ); } diff --git a/game/gamesys/SysCmds.cpp b/game/gamesys/SysCmds.cpp index 105ff57..afbc68c 100644 --- a/game/gamesys/SysCmds.cpp +++ b/game/gamesys/SysCmds.cpp @@ -327,6 +327,16 @@ void Cmd_Give_f( const idCmdArgs &args ) { if ( give_all || idStr::Icmp( name, "weapons" ) == 0 ) { player->inventory.weapons = BIT( MAX_WEAPONS ) - 1; + +// doomtrinity-dual weapon-> + if ( !player->inventory.pistolInInventory ) { + player->inventory.pistolInInventory = 1; + } + if ( !player->inventory.shotgunDoubleInInventory ) { + player->inventory.shotgunDoubleInInventory = 1; + } +// doomtrinity-dual weapon-< + player->CacheWeapons(); if ( !give_all ) { diff --git a/game/gamesys/SysCvar.cpp b/game/gamesys/SysCvar.cpp index 0ee33d6..eea9f26 100644 --- a/game/gamesys/SysCvar.cpp +++ b/game/gamesys/SysCvar.cpp @@ -346,7 +346,7 @@ idCVar net_serverDlTable( "net_serverDlTable", "", CVAR_GAME | CVAR_ARCHIV // sikk - New Cvars - //------------------------------------------------- // sikk---> Crosshair Cvar -idCVar g_crosshair( "g_crosshair", "1", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_INTEGER, "0 = crosshair off, 1 = crosshair on, 2 = crosshair on only when zoomed or npc has focus" ); +idCVar g_crosshair( "g_crosshair", "1", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_INTEGER, "0 = crosshair off, 1 = crosshair on" ); idCVar g_crosshairType( "g_crosshairType", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_BOOL, "toggle between static and precise crosshair positioning" ); idCVar g_crosshairLerp( "g_crosshairLerp", "0.5", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_FLOAT, "smoothness for the movement of the crosshair when g_crosshairType = 1" ); // <---sikk @@ -460,6 +460,11 @@ idCVar g_enemyHealthScale( "g_enemyHealthScale", "1.0", CVAR_GAME | CVAR_NO idCVar g_enemyHealthRandom( "g_enemyHealthRandom", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_BOOL, "sets whether to randomize enemy health values" ); // <---sikk +// PD3---> SSG Factor +idCVar g_weaponSSGFactor( "g_weaponSSGFactor", "0.0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_FLOAT, "sets the factor that a Pumpshotgun will spawn as a Double Barrel Shotgun" ); +// <---PD3 + + // sikk---> Spectre Factor idCVar g_enemySpectreFactor( "g_enemySpectreFactor", "0.0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_FLOAT, "sets the factor that a Pinky demon will spawn as a Spectre" ); // <---sikk @@ -613,3 +618,10 @@ idCVar r_filmgrainStrength( "r_filmgrainStrength", "1.0", CVAR_GAME | CVAR_ idCVar r_useVignetting( "r_useVignetting", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_BOOL, "Enable vignetting postprocessing effect" ); // <---sikk +//doomtrinity -> +// These mouse Cvars do NOT affect directly the mouse settings, "sensitivity" and "m_smooth" are still used. +idCVar in_mouseSensitivity( "in_mouseSensitivity", "5", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "mouse view sensitivity" ); +idCVar in_mouseSmooth( "in_mouseSmooth", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER, "number of samples blended for mouse viewing" ); +idCVar pm_adsspeed( "pm_adsspeed", "80", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while walking and zooming" ); +idCVar pm_adsbob( "pm_adsbob", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob slowly when walking and zooming" ); +//<- doomtrinity \ No newline at end of file diff --git a/game/gamesys/SysCvar.h b/game/gamesys/SysCvar.h index 1ffee00..6ca412b 100644 --- a/game/gamesys/SysCvar.h +++ b/game/gamesys/SysCvar.h @@ -333,11 +333,11 @@ extern idCVar g_ammoClipSizeType; extern idCVar g_ammoUsageType; // <---sikk -// sikk---> Weapon Management +// sikk---> Weapon Management PD3 extern idCVar g_weaponAwareness; extern idCVar g_weaponHandlingType; extern idCVar g_weaponProjectileOrigin; -// <---sikk +// <---sikk PD3 extern idCVar g_grabMode; // sikk - Object Manipulation @@ -354,6 +354,7 @@ extern idCVar g_enemyHealthScale; extern idCVar g_enemyHealthRandom; // <---sikk +extern idCVar g_weaponSSGFactor; // PD3 - Baron of Hell Factor extern idCVar g_enemySpectreFactor; // sikk - Spectre Factor extern idCVar g_enemyPainElementalFactor; // sikk - Pain Elemental Factor extern idCVar g_enemyBaronFactor; // sikk - Baron of Hell Factor @@ -491,5 +492,12 @@ extern idCVar r_filmgrainStrength; extern idCVar r_useVignetting; // <---sikk +//doomtrinity -> +// These mouse Cvars do NOT affect directly the mouse settings, "sensitivity" and "m_smooth" are still used. +extern idCVar in_mouseSensitivity; +extern idCVar in_mouseSmooth; +extern idCVar pm_adsspeed;// player speed in zoomed mode +extern idCVar pm_adsbob;// bob in zoomed mode +//<- doomtrinity #endif /* !__SYS_CVAR_H__ */ diff --git a/game/script/Script_Program.h b/game/script/Script_Program.h index 29ee8a0..25a25ff 100644 --- a/game/script/Script_Program.h +++ b/game/script/Script_Program.h @@ -44,10 +44,10 @@ class idSaveGame; class idRestoreGame; #define MAX_STRING_LEN 128 -#define MAX_GLOBALS 296608 // in bytes - DG: increased this to the same value d3xp uses +#define MAX_GLOBALS 393216 // 196608 in bytes #define MAX_STRINGS 1024 #define MAX_FUNCS 3072 -#define MAX_STATEMENTS 81920 // statement_t - 18 bytes last I checked +#define MAX_STATEMENTS 8192000 // 81920 statement_t - 18 bytes last I checked typedef enum { ev_error = -1, ev_void, ev_scriptevent, ev_namespace, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_virtualfunction, ev_pointer, ev_object, ev_jumpoffset, ev_argsize, ev_boolean diff --git a/game/script/Script_Thread.cpp b/game/script/Script_Thread.cpp index 3aa8054..e2ff7f2 100644 --- a/game/script/Script_Thread.cpp +++ b/game/script/Script_Thread.cpp @@ -78,6 +78,10 @@ const idEventDef EV_Thread_VecLength( "vecLength", "v", 'f' ); const idEventDef EV_Thread_VecDotProduct( "DotProduct", "vv", 'f' ); const idEventDef EV_Thread_VecCrossProduct( "CrossProduct", "vv", 'v' ); const idEventDef EV_Thread_VecToAngles( "VecToAngles", "v", 'v' ); + +const idEventDef EV_Thread_VecToOrthoBasisAngles( "VecToOrthoBasisAngles", "v", 'v' ); // PD3 +const idEventDef EV_Thread_RotateVector("rotateVector", "vv", 'v'); // PD3 + const idEventDef EV_Thread_OnSignal( "onSignal", "des" ); const idEventDef EV_Thread_ClearSignal( "clearSignalThread", "de" ); const idEventDef EV_Thread_SetCamera( "setCamera", "e" ); @@ -156,6 +160,10 @@ CLASS_DECLARATION( idClass, idThread ) EVENT( EV_Thread_VecDotProduct, idThread::Event_VecDotProduct ) EVENT( EV_Thread_VecCrossProduct, idThread::Event_VecCrossProduct ) EVENT( EV_Thread_VecToAngles, idThread::Event_VecToAngles ) + + EVENT( EV_Thread_VecToOrthoBasisAngles, idThread::Event_VecToOrthoBasisAngles ) // PD3 + EVENT( EV_Thread_RotateVector, idThread::Event_RotateVector ) // PD3 + EVENT( EV_Thread_OnSignal, idThread::Event_OnSignal ) EVENT( EV_Thread_ClearSignal, idThread::Event_ClearSignalThread ) EVENT( EV_Thread_SetCamera, idThread::Event_SetCamera ) @@ -1344,6 +1352,32 @@ void idThread::Event_VecToAngles( idVec3 &vec ) { ReturnVector( idVec3( ang[0], ang[1], ang[2] ) ); } +/* +================ +idThread::Event_VecToOrthoBasisAngles PD3 +================ +*/ +void idThread::Event_VecToOrthoBasisAngles( idVec3 &vec ) { + idVec3 left, up; + idAngles ang; + + vec.OrthogonalBasis( left, up ); + idMat3 axis( left, up, vec ); + + ang = axis.ToAngles(); + + ReturnVector( idVec3( ang[0], ang[1], ang[2] ) ); +} + +void idThread::Event_RotateVector( idVec3 &vec, idVec3 &ang ) { + + idAngles tempAng(ang); + idMat3 axis = tempAng.ToMat3(); + idVec3 ret = vec * axis; + ReturnVector(ret); + +} + /* ================ idThread::Event_OnSignal diff --git a/game/script/Script_Thread.h b/game/script/Script_Thread.h index fe24943..3f847dd 100644 --- a/game/script/Script_Thread.h +++ b/game/script/Script_Thread.h @@ -150,6 +150,10 @@ private: void Event_VecDotProduct( idVec3 &vec1, idVec3 &vec2 ); void Event_VecCrossProduct( idVec3 &vec1, idVec3 &vec2 ); void Event_VecToAngles( idVec3 &vec ); + + void Event_VecToOrthoBasisAngles( idVec3 &vec ); // PD3 + void Event_RotateVector( idVec3 &vec, idVec3 &ang ); // PD3 + void Event_OnSignal( int signal, idEntity *ent, const char *func ); void Event_ClearSignalThread( int signal, idEntity *ent ); void Event_SetCamera( idEntity *ent );