From cb6e022bb7aadf56d4f7ebc136f652fc18fbc44e Mon Sep 17 00:00:00 2001 From: Mikko Tiusanen Date: Thu, 9 Oct 2014 17:49:05 +0300 Subject: Added spawn [buildingname] admin command. --- src/game/g_admin.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/game/g_admin.h | 1 + src/game/g_buildable.c | 30 +++++++++++++++++++++++ src/game/g_local.h | 1 + 4 files changed, 97 insertions(+) diff --git a/src/game/g_admin.c b/src/game/g_admin.c index 9dd5b58..430650d 100644 --- a/src/game/g_admin.c +++ b/src/game/g_admin.c @@ -235,6 +235,11 @@ g_admin_cmd_t g_admin_cmds[ ] = "[^7name|slot^7]" }, + {"spawn", G_admin_spawn, qtrue, "spawn", + "Spawn a buildable in front of admin", + "^7name" + }, + {"spec999", G_admin_spec999, qfalse, "spec999", "move 999 pingers to the spectator team", ""}, @@ -3685,6 +3690,66 @@ qboolean G_admin_slap( gentity_t *ent ) return qtrue; } +qboolean G_admin_spawn( gentity_t *ent ) +{ + char name[ MAX_NAME_LENGTH ]; + buildable_t buildable; + + int i; + playerState_t* ps = NULL; + + float buildDist; + vec3_t entityOrigin; + vec3_t forward,normal,angles; + if( trap_Argc() < 2 ) + { + ADMP( "^3spawn: ^7usage: spawn ^7name\n" ); + return qfalse; + } + + trap_Argv( 1, name, sizeof( name ) ); + + buildable = BG_BuildableByName( name )->number; + if( buildable <= BA_NONE || buildable >= BA_NUM_BUILDABLES ) + { + ADMP( "^3spawn: ^7no such buildable\n" ); + return qfalse; + } + + if( !ent ) { + for( i = 0; i < level.maxclients; i++ ) + { + if( level.clients[ i ].pers.connected != CON_DISCONNECTED ) + { + ps = &level.clients[ i ].ps; + break; + } + } + } else { + ps = &ent->client->ps; + } + + if (ps == NULL) { + ADMP( "^3spawn: ^7No (player-)entity with position found.\n" ); + return qfalse; + } + + buildDist = BG_Class( ps->stats[ STAT_CLASS ] )->buildDist; + + if( BG_Buildable( buildable )->traj == TR_BUOYANCY ) + VectorSet( normal, 0.0f, 0.0f, -1.0f ); + else + VectorSet( normal, 0.0f, 0.0f, 1.0f ); + + VectorSet( angles, 0.0f, 90.0f, 0.0f ); + + AngleVectors( ps->viewangles, forward, NULL, NULL ); + VectorNormalize( forward ); + VectorMA( ps->origin, buildDist, forward, entityOrigin ); + ADMP( va( "^3spawn: ^7%s at %f %f %f\n", name, entityOrigin[0], entityOrigin[1], entityOrigin[2] ) ); + G_LayoutForceBuildItem( buildable, entityOrigin, angles, normal, angles ); + return qtrue; +} qboolean G_admin_buildlog( gentity_t *ent ) { diff --git a/src/game/g_admin.h b/src/game/g_admin.h index e94b33d..04da54e 100644 --- a/src/game/g_admin.h +++ b/src/game/g_admin.h @@ -189,6 +189,7 @@ qboolean G_admin_info( gentity_t *ent ); qboolean G_admin_admintest( gentity_t *ent ); qboolean G_admin_allready( gentity_t *ent ); qboolean G_admin_endvote( gentity_t *ent ); +qboolean G_admin_spawn( gentity_t *ent ); qboolean G_admin_spec999( gentity_t *ent ); qboolean G_admin_rename( gentity_t *ent ); qboolean G_admin_restart( gentity_t *ent ); diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index 37e3e66..65e7077 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -4855,6 +4855,12 @@ static void G_SpawnBuildableThink( gentity_t *ent ) G_FreeEntity( ent ); } +static void G_ForceSpawnBuildableThink( gentity_t *ent ) +{ + G_FinishSpawningBuildable( ent, qtrue ); + G_FreeEntity( ent ); +} + /* ============ G_SpawnBuildable @@ -4875,6 +4881,16 @@ void G_SpawnBuildable( gentity_t *ent, buildable_t buildable ) ent->think = G_SpawnBuildableThink; } +void G_ForceSpawnBuildable( gentity_t *ent, buildable_t buildable ) +{ + ent->s.modelindex = buildable; + + // some movers spawn on the second frame, so delay item + // spawns until the third frame so they can ride trains + ent->nextthink = level.time + FRAMETIME * 2; + ent->think = G_ForceSpawnBuildableThink; +} + /* ============ G_LayoutSave @@ -5083,6 +5099,20 @@ static void G_LayoutBuildItem( buildable_t buildable, vec3_t origin, G_SpawnBuildable( builder, buildable ); } +static void G_LayoutForceBuildItem( buildable_t buildable, vec3_t origin, + vec3_t angles, vec3_t origin2, vec3_t angles2 ) +{ + gentity_t *builder; + + builder = G_Spawn( ); + builder->client = 0; + VectorCopy( origin, builder->s.pos.trBase ); + VectorCopy( angles, builder->s.angles ); + VectorCopy( origin2, builder->s.origin2 ); + VectorCopy( angles2, builder->s.angles2 ); + G_ForceSpawnBuildable( builder, buildable ); +} + /* ============== G_LayoutExists diff --git a/src/game/g_local.h b/src/game/g_local.h index d82c862..5ee2623 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -833,6 +833,7 @@ qboolean G_BuildIfValid( gentity_t *ent, buildable_t buildable ); void G_SetBuildableAnim( gentity_t *ent, buildableAnimNumber_t anim, qboolean force ); void G_SetIdleBuildableAnim( gentity_t *ent, buildableAnimNumber_t anim ); void G_SpawnBuildable(gentity_t *ent, buildable_t buildable); +void G_ForceSpawnBuildable(gentity_t *ent, buildable_t buildable); void FinishSpawningBuildable( gentity_t *ent ); void G_LayoutSave( char *name ); int G_LayoutList( const char *map, char *list, int len ); -- cgit