Exemple #1
0
/*
================
Drop_Item

Spawns an item and tosses it forward
================
*/
gentity_t *Drop_Item( gentity_t *ent, gitem_t *item, float angle, qboolean copytarget ) {
	gentity_t	*dropped = NULL;
	vec3_t	velocity;
	vec3_t	angles;

	VectorCopy( ent->s.apos.trBase, angles );
	angles[YAW] += angle;
	angles[PITCH] = 0;	// always forward

	AngleVectors( angles, velocity, NULL, NULL );
	VectorScale( velocity, 150, velocity );
	velocity[2] += 200 + crandom() * 50;
	
	if ( copytarget )
	{
		dropped = LaunchItem( item, ent->s.pos.trBase, velocity, ent->opentarget );
	}
	else
	{
		dropped = LaunchItem( item, ent->s.pos.trBase, velocity, NULL );
	}

	dropped->activator = ent;//so we know who we belonged to so they can pick it back up later
	dropped->s.time = level.time;//mark this time so we aren't picked up instantly by the guy who dropped us
	return dropped;
}
Exemple #2
0
void StartMenu::UpdateFavs(){
  //SYNTAX NOTE: (per-line) "<name>::::[dir/app/<mimetype>]::::<path>"
  QStringList newfavs = LUtils::listFavorites();
  if(favs == newfavs){ return; } //nothing to do - same as before
  favs = newfavs;
  ClearScrollArea(ui->scroll_favs);
  favs.sort();
  //Iterate over types of favorites
  QStringList rest = favs;
  for(int type = 0; type<3; type++){
    QStringList tmp;
    if(type==0){ tmp = favs.filter("::::app::::"); } //apps first
    else if(type==1){ tmp = favs.filter("::::dir::::"); } //dirs next
    else{ tmp = rest;  } //everything left over
    for(int i=0; i<tmp.length(); i++){
      if(type<2){ rest.removeAll(tmp[i]); }
      if(!QFile::exists(tmp[i].section("::::",2,50))){ continue; } //invalid favorite - skip it
      ItemWidget *it = new ItemWidget(ui->scroll_favs->widget(), tmp[i].section("::::",2,50), tmp[i].section("::::",1,1) );
      if(!it->gooditem){ continue; } //invalid for some reason
      ui->scroll_favs->widget()->layout()->addWidget(it);
      connect(it, SIGNAL(NewShortcut()), this, SLOT(UpdateFavs()) );
      connect(it, SIGNAL(RemovedShortcut()), this, SLOT(UpdateFavs()) );
      connect(it, SIGNAL(RunItem(QString)), this, SLOT(LaunchItem(QString)) );
    }
    QApplication::processEvents();
  }
}
Exemple #3
0
void UserWidget::updateFavItems(bool newfilter){
  if(updatingfavs){ return; }
  updatingfavs = true;
  //qDebug() << "Updating User Favorite Items";
  QStringList newfavs = LUtils::listFavorites();
  //qDebug() << "Favorites:" << newfavs;
  if(lastHomeUpdate.isNull() || (QFileInfo(QDir::homePath()+"/Desktop").lastModified() > lastHomeUpdate) || newfavs!=favs ){
    favs = newfavs;
   
    homefiles = LSession::handle()->DesktopFiles();
    lastHomeUpdate = QDateTime::currentDateTime();
  }else if(!newfilter){ updatingfavs = false; return; } //nothing new to change - stop now
  //qDebug() << " - Passed Smoke Test...";
  QStringList favitems;
  //Remember for format for favorites: <name>::::[app/dir/<mimetype>]::::<full path>
  if(ui->tool_fav_apps->isChecked()){ 
    favitems = favs.filter("::::app::::");
    for(int i=0; i<homefiles.length(); i++){
      if(homefiles[i].fileName().endsWith(".desktop")){
        favitems << homefiles[i].fileName()+"::::app-home::::"+homefiles[i].absoluteFilePath();
      }
    }
  }else if(ui->tool_fav_dirs->isChecked()){ 
    favitems = favs.filter("::::dir::::");
    for(int i=0; i<homefiles.length(); i++){
      if(homefiles[i].isDir()){
        favitems << homefiles[i].fileName()+"::::dir-home::::"+homefiles[i].absoluteFilePath();
      }
    }
  }else{ 
    //Files
    for(int i=0; i<favs.length(); i++){
      QString type = favs[i].section("::::",1,1);
      if(type != "app" && type !="dir"){
        favitems << favs[i];
      }
    }
    for(int i=0; i<homefiles.length(); i++){
      if(!homefiles[i].isDir() && !homefiles[i].fileName().endsWith(".desktop") ){
        favitems << homefiles[i].fileName()+"::::"+LXDG::findAppMimeForFile(homefiles[i].fileName())+"-home::::"+homefiles[i].absoluteFilePath();
      }
    }
  }
  ClearScrollArea(ui->scroll_fav);
  //qDebug() << " - Sorting Items";
    favitems.sort(); //sort them alphabetically
    //qDebug() << " - Creating Items:" << favitems;
    for(int i=0; i<favitems.length(); i++){
      UserItemWidget *it = new UserItemWidget(ui->scroll_fav->widget(), favitems[i].section("::::",2,50), favitems[i].section("::::",1,1) );
      if(!it->gooditem){ continue; }
      ui->scroll_fav->widget()->layout()->addWidget(it);
      connect(it, SIGNAL(RunItem(QString)), this, SLOT(LaunchItem(QString)) );
      connect(it, SIGNAL(NewShortcut()), this, SLOT(updateFavItems()) );
      connect(it, SIGNAL(RemovedShortcut()), this, SLOT(updateFavItems()) );
      QApplication::processEvents(); //keep the UI snappy - might be a number of these
    }
  SortScrollArea(ui->scroll_fav);
  updatingfavs = false;
  //qDebug() << " - Done";
}
Exemple #4
0
//Listing Update routines
void StartMenu::UpdateApps(){
  ClearScrollArea(ui->scroll_apps);
  //Now assemble the apps list (note: this normally happens in the background - not when it is visible/open)
  QStringList cats = sysapps->keys();
  cats.sort();
  cats.removeAll("All");
  for(int c=0; c<cats.length(); c++){
    QList<XDGDesktop> apps = sysapps->value(cats[c]);
    if(apps.isEmpty()){ continue; }
    //Add the category label to the scroll
    QLabel *catlabel = new QLabel("<b>"+cats[c]+"</b>",ui->scroll_apps->widget());
      catlabel->setAlignment(Qt::AlignCenter);
    ui->scroll_apps->widget()->layout()->addWidget(catlabel);
    //Now add all the apps for this category
    for(int i=0; i<apps.length(); i++){
      ItemWidget *it = new ItemWidget(ui->scroll_apps->widget(), apps[i] );
      if(!it->gooditem){ continue; } //invalid for some reason
      ui->scroll_apps->widget()->layout()->addWidget(it);
      connect(it, SIGNAL(NewShortcut()), this, SLOT(UpdateFavs()) );
      connect(it, SIGNAL(RemovedShortcut()), this, SLOT(UpdateFavs()) );
      connect(it, SIGNAL(RunItem(QString)), this, SLOT(LaunchItem(QString)) );
    }
  }
  
}
Exemple #5
0
//Listing Update routines
void StartMenu::UpdateApps(){
  ClearScrollArea(ui->scroll_apps);
  //Now assemble the apps list (note: this normally happens in the background - not when it is visible/open)
  //qDebug() << "Update Apps:" << CCat << ui->check_apps_showcats->checkState();
  if(ui->check_apps_showcats->checkState() == Qt::PartiallyChecked){
    //qDebug() << " - Partially Checked";
    //Show a single page of apps, but still divided up by categories
    CCat.clear();
    QStringList cats = sysapps->keys();
    cats.sort();
    cats.removeAll("All");
    for(int c=0; c<cats.length(); c++){
      QList<XDGDesktop> apps = sysapps->value(cats[c]);
      if(apps.isEmpty()){ continue; }
      //Add the category label to the scroll
      QLabel *catlabel = new QLabel("<b>"+cats[c]+"</b>",ui->scroll_apps->widget());
        catlabel->setAlignment(Qt::AlignCenter);
      ui->scroll_apps->widget()->layout()->addWidget(catlabel);
      //Now add all the apps for this category
      for(int i=0; i<apps.length(); i++){
        ItemWidget *it = new ItemWidget(ui->scroll_apps->widget(), apps[i] );
        if(!it->gooditem){ continue; } //invalid for some reason
        ui->scroll_apps->widget()->layout()->addWidget(it);
        connect(it, SIGNAL(NewShortcut()), this, SLOT(UpdateFavs()) );
        connect(it, SIGNAL(RemovedShortcut()), this, SLOT(UpdateFavs()) );
        connect(it, SIGNAL(RunItem(QString)), this, SLOT(LaunchItem(QString)) );
        connect(it, SIGNAL(toggleQuickLaunch(QString, bool)), this, SLOT(UpdateQuickLaunch(QString, bool)) );
      }
    }
    
  }else if(ui->check_apps_showcats->checkState() == Qt::Checked){
Exemple #6
0
void UserWidget::updateFavItems(){
  ClearScrollArea(ui->scroll_fav);
  QFileInfoList items;
  QDir homedir = QDir( QDir::homePath()+"/Desktop");
  QDir favdir = QDir( QDir::homePath()+"/.lumina/favorites");
  if(!favdir.exists()){ favdir.mkpath( QDir::homePath()+"/.lumina/favorites"); }
  if(ui->tool_fav_apps->isChecked()){ 
    items = homedir.entryInfoList(QStringList()<<"*.desktop", QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
    items << favdir.entryInfoList(QStringList()<<"*.desktop", QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
  }else if(ui->tool_fav_dirs->isChecked()){ 
    items = homedir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
    items << favdir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
  }else{ 
    //Files
    items = homedir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
    items << favdir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
    for(int i=0; i<items.length(); i++){
      if(items[i].suffix()=="desktop"){ items.removeAt(i); i--; }
    }
  }
  for(int i=0; i<items.length(); i++){
    UserItemWidget *it = new UserItemWidget(ui->scroll_fav->widget(), items[i].absoluteFilePath(), ui->tool_fav_dirs->isChecked());
    ui->scroll_fav->widget()->layout()->addWidget(it);
    connect(it, SIGNAL(RunItem(QString)), this, SLOT(LaunchItem(QString)) );
    connect(it, SIGNAL(NewShortcut()), this, SLOT(updateFavItems()) );
    connect(it, SIGNAL(RemovedShortcut()), this, SLOT(updateFavItems()) );
  }
  static_cast<QBoxLayout*>(ui->scroll_fav->widget()->layout())->addStretch();
}
Exemple #7
0
MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI) {
    ui->setupUi(this); //load the designer file
    //setupIcons();
    ui->radio_apps->setChecked(true); //always default to starting here
    ui->tool_stop->setVisible(false); //no search running initially
    ui->tool_configure->setVisible(false); //app search initially set

    livetime = new QTimer(this);
    livetime->setInterval(300); //1/3 second for live searches
    livetime->setSingleShot(true);

    workthread = new QThread(this);
    workthread->setObjectName("Lumina Search Process");

    searcher = new Worker();
    searcher->moveToThread(workthread);

    closeShort = new QShortcut(QKeySequence(tr("Esc")), this);

    //Setup the connections
    connect(livetime, SIGNAL(timeout()), this, SLOT(startSearch()) );
    connect(this, SIGNAL(SearchTerm(QString, bool)), searcher, SLOT(StartSearch(QString, bool)) );
    connect(searcher, SIGNAL(FoundItem(QString)), this, SLOT(foundSearchItem(QString)) );
    connect(searcher, SIGNAL(SearchUpdate(QString)), this, SLOT(searchMessage(QString)) );
    connect(searcher, SIGNAL(SearchDone()), this, SLOT(searchFinished()) );
    connect(ui->tool_stop, SIGNAL(clicked()), this, SLOT(stopSearch()) );
    connect(ui->push_done, SIGNAL(clicked()), this, SLOT(closeApplication()) );
    connect(ui->push_launch, SIGNAL(clicked()), this, SLOT(LaunchItem()) );
    connect(ui->line_search, SIGNAL(textEdited(QString)), this, SLOT(searchChanged()) );
    connect(ui->line_search, SIGNAL(returnPressed()), this, SLOT(LaunchItem()) );
    connect(ui->radio_apps, SIGNAL(toggled(bool)), this, SLOT(searchTypeChanged()) );
    connect(ui->listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(LaunchItem(QListWidgetItem*)) );
    connect(ui->listWidget, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(LaunchItem(QListWidgetItem*)) );
    connect(ui->tool_configure, SIGNAL(clicked()), this, SLOT(configureSearch()) );
    connect(closeShort, SIGNAL(activated()), this, SLOT( close() ) );

    //Setup the settings file
    QSettings::setPath(QSettings::NativeFormat, QSettings::UserScope, QDir::homePath()+"/.lumina");
    settings = new QSettings("LuminaDE", "lumina-search",this);
    searcher->startDir = settings->value("StartSearchDir", QDir::homePath()).toString();
    searcher->skipDirs = settings->value("SkipSearchDirs", QStringList()).toStringList();
    updateDefaultStatusTip();
    this->show();
    workthread->start();
    QTimer::singleShot(0,this, SLOT(setupIcons()) );
}
Exemple #8
0
void UserWidget::slotGoToDir(QString dir){
  if(!QFileInfo(dir).isDir()){
    LaunchItem(dir);
  }else{
    ui->label_home_dir->setWhatsThis(dir);
    updateHome();
  }
}
Exemple #9
0
/*
================
Drop_Item

Spawns an item and tosses it forward
================
*/
gentity_t *Drop_Item( gentity_t *ent, gitem_t *item, float angle ) {
	vec3_t	velocity;
	vec3_t	angles;

	VectorCopy( ent->s.apos.trBase, angles );
	angles[YAW] += angle;
	angles[PITCH] = 0;	// always forward

	AngleVectors( angles, velocity, NULL, NULL );
	VectorScale( velocity, 300, velocity );
	velocity[2] += 75 + crandom() * 50;

	return LaunchItem( item, ent, ent->s.pos.trBase, velocity, FL_DROPPED_ITEM, 0 ); // RPG-X: Marcin: for ThrowWeapon - 03/12/2008
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Parses command line options and invokes required functionality or reports an error to user.
// Returns TRUE if application should stay alive, FALSE if job is done and we need to exit.
BOOL ParseCommandLine ( LPCTSTR lpCmdLine )
{
    // First we need to parse command line options and perform validation.
    LPWSTR *szArglist;
    int nArgs;
    HRESULT hr ;

    szArglist = CommandLineToArgvW ( lpCmdLine , &nArgs ) ;

    if ( 2 != nArgs ) // we always expect 2 arguments - option and parameter
    {
        Usage ( ) ;
        return FALSE ;
    }

    switch ( szArglist [ 0 ] [ 1 ] )
    {
    case L'l': // User wants to list directory content
        // Copy path of the directory to list to the global buffer
        hr = StringCchCopy ( g_szTargetDir , MAX_PATH , szArglist [ 1 ] ) ;
        if ( FAILED ( hr ) )
        {
            MessageBox ( g_hWnd , 
                         TEXT ( "Invalid directory name passed as parameter" ) , 
                         TEXT ( "Invalid Parameter" ) , 
                         MB_ICONERROR | MB_OK ) ;
            return FALSE ;
        }

        // And ask directory lister to perform it's work
        g_pLister = new CDirectoryLister ( g_hWnd ) ;
        if ( -1 == g_pLister->ShowMenu ( g_szTargetDir ) )
        {
            MessageBox ( g_hWnd , 
                         g_szTargetDir , 
                         TEXT ( "Could not list directory" ) , 
                         MB_OK | MB_ICONERROR ) ;
            return FALSE ;
        }

        return TRUE ; // Wait while user selects something from the popup menu
    case L'o': // User wants to launch a predefined application
        LaunchItem ( szArglist [ 1 ] ) ;

        return FALSE ;
    default:
        Usage ( ) ;
        return FALSE ;
    }
}
Exemple #11
0
void UserWidget::updateApps(){
  if(ui->combo_app_cats->currentIndex() < 0){ return; } //no cat
  QString cat = ui->combo_app_cats->itemData( ui->combo_app_cats->currentIndex() ).toString();
  QList<XDGDesktop> items = sysapps->value(cat);
  ClearScrollArea(ui->scroll_apps);
  for(int i=0; i<items.length(); i++){
    UserItemWidget *it = new UserItemWidget(ui->scroll_apps->widget(), items[i]);
    ui->scroll_apps->widget()->layout()->addWidget(it);
    connect(it, SIGNAL(RunItem(QString)), this, SLOT(LaunchItem(QString)) );
    connect(it, SIGNAL(NewShortcut()), this, SLOT(updateFavItems()) );
    connect(it, SIGNAL(RemovedShortcut()), this, SLOT(updateFavItems()) );
  }
  static_cast<QBoxLayout*>(ui->scroll_apps->widget()->layout())->addStretch();
}
Exemple #12
0
//Home Tab
void UserWidget::updateHome(){
  ClearScrollArea(ui->scroll_home);
  QDir homedir = QDir::home();
  QStringList items = homedir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name); 
  for(int i=0; i<items.length(); i++){
    //qDebug() << "New Home subdir:" << homedir.absoluteFilePath(items[i]);
    UserItemWidget *it = new UserItemWidget(ui->scroll_home->widget(), homedir.absoluteFilePath(items[i]), true);
    ui->scroll_home->widget()->layout()->addWidget(it);
    connect(it, SIGNAL(RunItem(QString)), this, SLOT(LaunchItem(QString)) );
    connect(it, SIGNAL(NewShortcut()), this, SLOT(updateFavItems()) );
    connect(it, SIGNAL(RemovedShortcut()), this, SLOT(updateFavItems()) );
  }
  static_cast<QBoxLayout*>(ui->scroll_home->widget()->layout())->addStretch();
}
Exemple #13
0
void UserWidget::updateApps(){
  if(ui->combo_app_cats->currentIndex() < 0){ return; } //no cat
  QString cat = ui->combo_app_cats->itemData( ui->combo_app_cats->currentIndex() ).toString();
  QList<XDGDesktop> items = sysapps->value(cat);
  ClearScrollArea(ui->scroll_apps);
  for(int i=0; i<items.length(); i++){
    UserItemWidget *it = new UserItemWidget(ui->scroll_apps->widget(), items[i]);
    ui->scroll_apps->widget()->layout()->addWidget(it);
    connect(it, SIGNAL(RunItem(QString)), this, SLOT(LaunchItem(QString)) );
    connect(it, SIGNAL(NewShortcut()), this, SLOT(updateFavItems()) );
    connect(it, SIGNAL(RemovedShortcut()), this, SLOT(updateFavItems()) );
    QApplication::processEvents(); //keep the UI snappy - might be a number of these
  }
}
Exemple #14
0
void TossClientCubes(gentity_t * self)
{
	gitem_t        *item;
	gentity_t      *drop;
	vec3_t          velocity;
	vec3_t          angles;
	vec3_t          origin;

	self->client->ps.generic1 = 0;

	// this should never happen but we should never
	// get the server to crash due to skull being spawned in
	if(!G_EntitiesFree())
	{
		return;
	}

	if(self->client->sess.sessionTeam == TEAM_RED)
	{
		item = BG_FindItem("Red Cube");
	}
	else
	{
		item = BG_FindItem("Blue Cube");
	}

	angles[YAW] = (float)(level.time % 360);
	angles[PITCH] = 0;			// always forward
	angles[ROLL] = 0;

	AngleVectors(angles, velocity, NULL, NULL);
	VectorScale(velocity, 150, velocity);
	velocity[2] += 200 + crandom() * 50;

	if(neutralObelisk)
	{
		VectorCopy(neutralObelisk->s.pos.trBase, origin);
		origin[2] += 44;
	}
	else
	{
		VectorClear(origin);
	}

	drop = LaunchItem(item, origin, velocity);

	drop->nextthink = level.time + g_cubeTimeout.integer * 1000;
	drop->think = G_FreeEntity;
	drop->spawnflags = self->client->sess.sessionTeam;
}
Exemple #15
0
// Spawns an item and drops it
gentity_t *Drop_Item( gentity_t *ent, const gitem_t *item, float angle ) {
	vector3	velocity;
	vector3	angles;

	VectorCopy( &ent->s.apos.trBase, &angles );
	angles.yaw += angle;
	angles.pitch = 0;	// always forward

	AngleVectors( &angles, &velocity, NULL, NULL );
	VectorScale( &velocity, 150, &velocity );
	velocity.z += 200 + crandom() * 50;
	
	return LaunchItem( item, &ent->s.pos.trBase, &velocity );
}
Exemple #16
0
/*
================
Drop_Item

Spawns an item and tosses it forward
================
*/
gentity_t *Drop_Item( gentity_t *ent, gitem_t *item, float angle ) {
	vec3_t	velocity;
	vec3_t	angles;

	VectorCopy( ent->s.apos.trBase, angles );
	angles[YAW] += angle;
	angles[PITCH] = 0;	// always forward

	AngleVectors( angles, velocity, NULL, NULL );
	VectorScale( velocity, 150, velocity );
	velocity[2] += 200 + crandom() * 50;
	
	return LaunchItem( item, ent->s.pos.trBase, velocity );
}
/*
================
Drop_Item

Spawns an item and tosses it forward
================
*/
gentity_t *Drop_Item( gentity_t *ent, gitem_t *item, float angle ) {
	vec3_t	velocity;
	vec3_t	angles;

	VectorCopy( ent->s.apos.trBase, angles );
	angles[YAW] += angle;
	angles[PITCH] = 0;	// always forward

	AngleVectors( angles, velocity, NULL, NULL );
	VectorScale( velocity, 150, velocity );
	velocity[2] += 200 + crandom() * 50;

	// FIXME: Cartridges call LaunchItem() directly
	G_LogPrintf( "DropItem: %ld %s\n", ( ent - g_entities ), item->classname );
	
	return LaunchItem( item, ent->s.pos.trBase, velocity );
}
Exemple #18
0
/*
================
Modified by Elder

dropWeapon XRAY FMJ
================
*/
gentity_t *dropWeapon(gentity_t * ent, gitem_t * item, float angle, int xr_flags)
{
	vec3_t velocity;
	vec3_t angles;
	vec3_t origin;

	//int           throwheight;
	vec3_t mins, maxs;
	trace_t tr;

	VectorCopy(ent->s.pos.trBase, origin);
	VectorCopy(ent->s.apos.trBase, angles);
	angles[YAW] += angle;
	angles[PITCH] = -55;	// always at a 55 degree above horizontal angle

	AngleVectors(angles, velocity, NULL, NULL);

	// set aiming directions
	//AngleVectors (ent->client->ps.viewangles, velocity, NULL, NULL);

	//Elder: don't toss from the head, but from the "waist"
	origin[2] += 10;	// (ent->client->ps.viewheight / 2);
	VectorMA(origin, 5, velocity, origin);	// 14 34 10

	// Set temporary bounding box for trace
	VectorSet(mins, -ITEM_RADIUS, -ITEM_RADIUS, -ITEM_RADIUS);
	VectorSet(maxs, ITEM_RADIUS, ITEM_RADIUS, ITEM_RADIUS);

	// NiceAss: Check if the new location starts in a solid.
	// FIXME: Use trap_point or whatever?
	trap_Trace(&tr, origin, mins, maxs, origin, ent->s.number, MASK_SOLID);
	if (tr.startsolid == qtrue)
		VectorMA(origin, -7, velocity, origin);	// -5 won't work (hint: it should work). Only -7 or less will..

	// snap to integer coordinates for more efficient network bandwidth usage
	SnapVector(origin);

	// less vertical velocity
	//velocity[2] += 0.2f;
	//velocity[2] = 20;
	VectorNormalize(velocity);
	VectorScale(velocity, 5, velocity);
	return LaunchItem(item, origin, velocity, xr_flags);
}
Exemple #19
0
/*
================
DropWeapon
RPG-X
Marcin 03/12/2008
================
*/
gentity_t *DropWeapon( gentity_t *ent, gitem_t *item, float angle, int flags, char *txt ) {
	vec3_t	velocity;
	vec3_t	origin;

	VectorCopy( ent->s.pos.trBase, origin );

	// set aiming directions
	AngleVectors (ent->client->ps.viewangles, velocity, NULL, NULL);

	origin[2] += ent->client->ps.viewheight + 10;
	VectorMA( origin, 14, velocity, origin );
	// snap to integer coordinates for more efficient network bandwidth usage
	SnapVector( origin );

	// extra vertical velocity
	velocity[2] += 0.2;
	VectorNormalize( velocity );
	return LaunchItem( item, ent, origin, velocity, flags, txt );
}
void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) {
	int			contents = 0, i, killer = ENTITYNUM_WORLD;
	char		*killerName = "<world>";
	qboolean	nogib = qtrue;
	gitem_t		*item = NULL;
	gentity_t	*ent;
	qboolean	killedintank = qfalse;

	//float			timeLived;
	weapon_t	weap = BG_WeaponForMOD( meansOfDeath );

//	G_Printf( "player_die\n" );

	if(attacker == self) {
		if(self->client) {
			self->client->pers.playerStats.suicides++;
			trap_PbStat ( self - g_entities , "suicide" , 
				va ( "%d %d %d" , self->client->sess.sessionTeam , self->client->sess.playerType , weap ) ) ;
		}
	} else if(OnSameTeam( self, attacker )) {
		G_LogTeamKill(	attacker,	weap );
	} else {
		G_LogDeath( self,		weap );
		G_LogKill(	attacker,	weap );

		if( g_gamestate.integer == GS_PLAYING ) {
			if( attacker->client ) {
				attacker->client->combatState |= (1<<COMBATSTATE_KILLEDPLAYER);
			}
		}
	}

	// RF, record this death in AAS system so that bots avoid areas which have high death rates
	if( !OnSameTeam( self, attacker ) )
	{
// LC - not needed
//		BotRecordTeamDeath( self->s.number );

		self->isProp = qfalse;	// were we teamkilled or not?
	} else {
		self->isProp = qtrue;
	}	

	// if we got killed by a landmine, update our map
	if( self->client && meansOfDeath == MOD_LANDMINE ) {
		// if it's an enemy mine, update both teamlists
		/*int teamNum;
		mapEntityData_t	*mEnt;
		mapEntityData_Team_t *teamList;
	
		teamNum = inflictor->s.teamNum % 4;

		teamList = self->client->sess.sessionTeam == TEAM_AXIS ? &mapEntityData[0] : &mapEntityData[1];
		if((mEnt = G_FindMapEntityData(teamList, inflictor-g_entities)) != NULL) {
			G_FreeMapEntityData( teamList, mEnt );
		}

		if( teamNum != self->client->sess.sessionTeam ) {
			teamList = self->client->sess.sessionTeam == TEAM_AXIS ? &mapEntityData[1] : &mapEntityData[0];
			if((mEnt = G_FindMapEntityData(teamList, inflictor-g_entities)) != NULL) {
				G_FreeMapEntityData( teamList, mEnt );
			}
		}*/
		mapEntityData_t	*mEnt;

		if((mEnt = G_FindMapEntityData(&mapEntityData[0], inflictor-g_entities)) != NULL) {
			G_FreeMapEntityData( &mapEntityData[0], mEnt );
		}

		if((mEnt = G_FindMapEntityData(&mapEntityData[1], inflictor-g_entities)) != NULL) {
			G_FreeMapEntityData( &mapEntityData[1], mEnt );
		}
	}

	{
		mapEntityData_t	*mEnt;
		mapEntityData_Team_t *teamList = self->client->sess.sessionTeam == TEAM_AXIS ? &mapEntityData[1] : &mapEntityData[0];	// swapped, cause enemy team

		mEnt = G_FindMapEntityDataSingleClient( teamList, NULL, self->s.number, -1 );
		
		while( mEnt ) {
			if( mEnt->type == ME_PLAYER_DISGUISED ) {
				mapEntityData_t* mEntFree = mEnt;

				mEnt = G_FindMapEntityDataSingleClient( teamList, mEnt, self->s.number, -1 );

				G_FreeMapEntityData( teamList, mEntFree );
			} else {
				mEnt = G_FindMapEntityDataSingleClient( teamList, mEnt, self->s.number, -1 );
			}
		}
	}

	if( self->tankLink ) {
		G_LeaveTank( self, qfalse );

		killedintank = qtrue;
	}

	if( self->client->ps.pm_type == PM_DEAD || g_gamestate.integer == GS_INTERMISSION ) {
		return;
	}

	// OSP - death stats handled out-of-band of G_Damage for external calls
	G_addStats(self, attacker, damage, meansOfDeath);
	// OSP

	self->client->ps.pm_type = PM_DEAD;

	G_AddEvent( self, EV_STOPSTREAMINGSOUND, 0);

	if(attacker) {
		killer = attacker->s.number;
		killerName = (attacker->client) ? attacker->client->pers.netname : "<non-client>";
	}

	if(attacker == 0 || killer < 0 || killer >= MAX_CLIENTS) {
		killer = ENTITYNUM_WORLD;
		killerName = "<world>";
	}

	if(g_gamestate.integer == GS_PLAYING) {
		char *obit;

		if(meansOfDeath < 0 || meansOfDeath >= sizeof(modNames) / sizeof(modNames[0])) {
			obit = "<bad obituary>";
		} else {
			obit = modNames[meansOfDeath];
		}

		G_LogPrintf("Kill: %i %i %i: %s killed %s by %s\n", killer, self->s.number, meansOfDeath, killerName, self->client->pers.netname, obit );
	}


	// broadcast the death event to everyone
	ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY );
	ent->s.eventParm = meansOfDeath;
	ent->s.otherEntityNum = self->s.number;
	ent->s.otherEntityNum2 = killer;
	ent->r.svFlags = SVF_BROADCAST;	// send to everyone

	self->enemy = attacker;

	self->client->ps.persistant[PERS_KILLED]++;

	// JPW NERVE -- if player is holding ticking grenade, drop it
	if ((self->client->ps.grenadeTimeLeft) && (self->s.weapon != WP_DYNAMITE) && (self->s.weapon != WP_LANDMINE) && (self->s.weapon != WP_SATCHEL) && (self->s.weapon != WP_TRIPMINE)) {
		vec3_t launchvel, launchspot;

		launchvel[0] = crandom();
		launchvel[1] = crandom();
		launchvel[2] = random();
		VectorScale( launchvel, 160, launchvel );
		VectorCopy(self->r.currentOrigin, launchspot);
		launchspot[2] += 40;
		
		{
			// Gordon: fixes premature grenade explosion, ta bani ;)
			gentity_t *m = fire_grenade(self, launchspot, launchvel, self->s.weapon);
			m->damage = 0;
		}
	}

	if (attacker && attacker->client) {
		if ( attacker == self || OnSameTeam (self, attacker ) ) {

			// DHM - Nerve :: Complaint lodging
			if( attacker != self && level.warmupTime <= 0 && g_gamestate.integer == GS_PLAYING) {
				if( attacker->client->pers.localClient ) {
					trap_SendServerCommand( self-g_entities, "complaint -4" );
				} else {
					if( meansOfDeath != MOD_CRUSH_CONSTRUCTION && meansOfDeath != MOD_CRUSH_CONSTRUCTIONDEATH && meansOfDeath != MOD_CRUSH_CONSTRUCTIONDEATH_NOATTACKER ) {
						if( g_complaintlimit.integer ) {

							if( !(meansOfDeath == MOD_LANDMINE && g_disableComplaints.integer & TKFL_MINES ) &&
								!((meansOfDeath == MOD_ARTY || meansOfDeath == MOD_AIRSTRIKE) && g_disableComplaints.integer & TKFL_AIRSTRIKE ) &&
								!(meansOfDeath == MOD_MORTAR && g_disableComplaints.integer & TKFL_MORTAR ) ) {
								trap_SendServerCommand( self-g_entities, va( "complaint %i", attacker->s.number ) );
								self->client->pers.complaintClient = attacker->s.clientNum;
								self->client->pers.complaintEndTime = level.time + 20500;
							}
						}
					}
				}
			}

			// high penalty to offset medic heal
/*			AddScore( attacker, WOLF_FRIENDLY_PENALTY ); */

			if( g_gametype.integer == GT_WOLF_LMS ) {
				AddKillScore( attacker, WOLF_FRIENDLY_PENALTY );
			}
		} else {

			//G_AddExperience( attacker, 1 );

			// JPW NERVE -- mostly added as conveneience so we can tweak from the #defines all in one place
			AddScore(attacker, WOLF_FRAG_BONUS);

			if( g_gametype.integer == GT_WOLF_LMS ) {
				if( level.firstbloodTeam == -1 )
					level.firstbloodTeam = attacker->client->sess.sessionTeam;

				AddKillScore( attacker, WOLF_FRAG_BONUS );
			}

			attacker->client->lastKillTime = level.time;
		}
	} else {
		AddScore( self, -1 );

		if( g_gametype.integer == GT_WOLF_LMS )
			AddKillScore( self, -1 );
	}

	// Add team bonuses
	Team_FragBonuses(self, inflictor, attacker);

	// drop flag regardless
	if (self->client->ps.powerups[PW_REDFLAG]) {
		item = BG_FindItem("Red Flag");
		if (!item)
			item = BG_FindItem("Objective");

		self->client->ps.powerups[PW_REDFLAG] = 0;
	}
	if (self->client->ps.powerups[PW_BLUEFLAG]) {
		item = BG_FindItem("Blue Flag");
		if (!item)
			item = BG_FindItem("Objective");

		self->client->ps.powerups[PW_BLUEFLAG] = 0;
	}

	if (item) {
		vec3_t launchvel = { 0, 0, 0 };
		gentity_t *flag = LaunchItem(item, self->r.currentOrigin, launchvel, self->s.number);

		flag->s.modelindex2 = self->s.otherEntityNum2;// JPW NERVE FIXME set player->otherentitynum2 with old modelindex2 from flag and restore here
		flag->message = self->message;	// DHM - Nerve :: also restore item name
		// Clear out player's temp copies
		self->s.otherEntityNum2 = 0;
		self->message = NULL;
	}

	// send a fancy "MEDIC!" scream.  Sissies, ain' they?
	if (self->client != NULL) {
		if( self->health > GIB_HEALTH && meansOfDeath != MOD_SUICIDE && meansOfDeath != MOD_SWITCHTEAM ) {
			G_AddEvent( self, EV_MEDIC_CALL, 0 );
		}
	}

	Cmd_Score_f( self );		// show scores

	// send updated scores to any clients that are following this one,
	// or they would get stale scoreboards
	for(i=0; i<level.numConnectedClients; i++) {
		gclient_t *client = &level.clients[level.sortedClients[i]];

		if(client->pers.connected != CON_CONNECTED) continue;
		if(client->sess.sessionTeam != TEAM_SPECTATOR) continue;

		if(client->sess.spectatorClient == self->s.number) {
			Cmd_Score_f(g_entities + level.sortedClients[i]);
		}
	}

	self->takedamage = qtrue;	// can still be gibbed
	self->r.contents = CONTENTS_CORPSE;

	//self->s.angles[2] = 0;
	self->s.powerups = 0;
	self->s.loopSound = 0;
	
	self->client->limboDropWeapon = self->s.weapon; // store this so it can be dropped in limbo

	LookAtKiller( self, inflictor, attacker );
	self->client->ps.viewangles[0] = 0;
	self->client->ps.viewangles[2] = 0;
	//VectorCopy( self->s.angles, self->client->ps.viewangles );

//	trap_UnlinkEntity( self );
	self->r.maxs[2] = self->client->ps.crouchMaxZ;	//%	0;			// ydnar: so bodies don't clip into world
	self->client->ps.maxs[2] = self->client->ps.crouchMaxZ;	//%	0;	// ydnar: so bodies don't clip into world
	trap_LinkEntity( self );

	// don't allow respawn until the death anim is done
	// g_forcerespawn may force spawning at some later time
	self->client->respawnTime = level.timeCurrent + 800;

	// remove powerups
	memset( self->client->ps.powerups, 0, sizeof(self->client->ps.powerups) );

	// never gib in a nodrop
	// FIXME: contents is always 0 here
	if ( self->health <= GIB_HEALTH && !(contents & CONTENTS_NODROP) ) {
		GibEntity( self, killer );
		nogib = qfalse;
	}

	if(nogib){
		// normal death
		// for the no-blood option, we need to prevent the health
		// from going to gib level
		if ( self->health <= GIB_HEALTH ) {
			self->health = GIB_HEALTH + 1;
		}

		// Arnout: re-enable this for flailing
/*		if( self->client->ps.groundEntityNum == ENTITYNUM_NONE ) {
			self->client->ps.pm_flags |= PMF_FLAILING;
			self->client->ps.pm_time = 750;
			BG_AnimScriptAnimation( &self->client->ps, ANIM_MT_FLAILING, qtrue );

			// Face explosion directory
			{
				vec3_t angles;

				vectoangles( self->client->ps.velocity, angles );
				self->client->ps.viewangles[YAW] = angles[YAW];
				SetClientViewAngle( self, self->client->ps.viewangles );
			}
		} else*/

			// DHM - Play death animation, and set pm_time to delay 'fallen' animation
			//if( G_IsSinglePlayerGame() && self->client->sess.sessionTeam == TEAM_ALLIES ) {
			//	// play "falldown" animation since allies bots won't ever die completely
			//	self->client->ps.pm_time = BG_AnimScriptEvent( &self->client->ps, self->client->pers.character->animModelInfo, ANIM_ET_FALLDOWN, qfalse, qtrue );
			//	G_StartPlayerAppropriateSound(self, "death");
			//} else {
				self->client->ps.pm_time = BG_AnimScriptEvent( &self->client->ps, self->client->pers.character->animModelInfo, ANIM_ET_DEATH, qfalse, qtrue );
				// death animation script already contains sound
			//}

			// record the death animation to be used later on by the corpse
			self->client->torsoDeathAnim = self->client->ps.torsoAnim;
			self->client->legsDeathAnim = self->client->ps.legsAnim;

			G_AddEvent( self, EV_DEATH1 + 1, killer );

		// the body can still be gibbed
		self->die = body_die;
	}

	if( meansOfDeath == MOD_MACHINEGUN ) {
		switch( self->client->sess.sessionTeam ) {
			case TEAM_AXIS:
				level.axisMG42Counter = level.time;
				break;
			case TEAM_ALLIES:
				level.alliesMG42Counter = level.time;
				break;
		}
	}

	G_FadeItems( self, MOD_SATCHEL );

	CalculateRanks();

	if( killedintank /*Gordon: automatically go to limbo from tank*/ ) {
		limbo( self, qfalse ); // but no corpse
	} else if ( (meansOfDeath == MOD_SUICIDE && g_gamestate.integer == GS_PLAYING) ) {
		limbo( self, qtrue );
	} else if( g_gametype.integer == GT_WOLF_LMS ) {
		if( !G_CountTeamMedics( self->client->sess.sessionTeam, qtrue ) ) {
			limbo( self, qtrue );
		}
	}
}
Exemple #21
0
void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) {
	gentity_t   *ent;
	// TTimo might be used uninitialized
	int contents = 0;
	int killer;
	int i;
	const char        *killerName, *obit;
	qboolean nogib = qtrue;
	gitem_t     *item = NULL; // JPW NERVE for flag drop
	vec3_t launchvel,launchspot;      // JPW NERVE
	gentity_t   *flag; // JPW NERVE

	if ( self->client->ps.pm_type == PM_DEAD ) {
		return;
	}

	if ( level.intermissiontime ) {
		return;
	}

	self->client->ps.pm_type = PM_DEAD;

	G_AddEvent( self, EV_STOPSTREAMINGSOUND, 0 );

	if ( attacker ) {
		killer = attacker->s.number;
		if ( attacker->client ) {
			killerName = attacker->client->pers.netname;
		} else {
			killerName = "<non-client>";
		}
	} else {
		killer = ENTITYNUM_WORLD;
		killerName = "<world>";
	}

	if ( killer < 0 || killer >= MAX_CLIENTS ) {
		killer = ENTITYNUM_WORLD;
		killerName = "<world>";
	}

	if ( meansOfDeath < 0 || meansOfDeath >= sizeof( modNames ) / sizeof( modNames[0] ) ) {
		obit = "<bad obituary>";
	} else {
		obit = modNames[ meansOfDeath ];
	}

	G_LogPrintf( "Kill: %i %i %i: %s killed %s by %s\n",
				 killer, self->s.number, meansOfDeath, killerName,
				 self->client->pers.netname, obit );

	// broadcast the death event to everyone
	ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY );
	ent->s.eventParm = meansOfDeath;
	ent->s.otherEntityNum = self->s.number;
	ent->s.otherEntityNum2 = killer;
	ent->r.svFlags = SVF_BROADCAST; // send to everyone

	self->enemy = attacker;

	self->client->ps.persistant[PERS_KILLED]++;

// JPW NERVE -- if player is holding ticking grenade, drop it
	if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
		if ( ( self->client->ps.grenadeTimeLeft ) && ( self->s.weapon != WP_DYNAMITE ) ) {
			launchvel[0] = crandom();
			launchvel[1] = crandom();
			launchvel[2] = random();
			VectorScale( launchvel, 160, launchvel );
			VectorCopy( self->r.currentOrigin, launchspot );
			launchspot[2] += 40;
			fire_grenade( self, launchspot, launchvel, self->s.weapon );

		}
	}
// jpw

	if ( attacker && attacker->client ) {
		if ( attacker == self || OnSameTeam( self, attacker ) ) {

			// DHM - Nerve :: Complaint lodging
			if ( attacker != self && level.warmupTime <= 0 ) {
				if ( attacker->client->pers.localClient ) {
					trap_SendServerCommand( self - g_entities, "complaint -4" );
				} else {
					trap_SendServerCommand( self - g_entities, va( "complaint %i", attacker->s.number ) );
					self->client->pers.complaintClient = attacker->s.clientNum;
					self->client->pers.complaintEndTime = level.time + 20500;
				}
			}
			// dhm

			// JPW NERVE
			if ( g_gametype.integer >= GT_WOLF ) { // high penalty to offset medic heal
				AddScore( attacker, WOLF_FRIENDLY_PENALTY );
			} else {
				// jpw
				AddScore( attacker, -1 );
			}
		} else {
			// JPW NERVE -- mostly added as conveneience so we can tweak from the #defines all in one place
			if ( g_gametype.integer >= GT_WOLF ) {
				AddScore( attacker, WOLF_FRAG_BONUS );
			} else {
				// jpw
				AddScore( attacker, 1 );
			}

			attacker->client->lastKillTime = level.time;
		}
	} else {
		AddScore( self, -1 );
	}

	// Add team bonuses
	Team_FragBonuses( self, inflictor, attacker );

	// if client is in a nodrop area, don't drop anything
// JPW NERVE new drop behavior
	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {   // only drop here in single player; in multiplayer, drop @ limbo
		contents = trap_PointContents( self->r.currentOrigin, -1 );
		if ( !( contents & CONTENTS_NODROP ) ) {
			TossClientItems( self );
		}
	}

	// drop flag regardless
	if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
		if ( self->client->ps.powerups[PW_REDFLAG] ) {
			item = BG_FindItem( "Red Flag" );
			if ( !item ) {
				item = BG_FindItem( "Objective" );
			}

			self->client->ps.powerups[PW_REDFLAG] = 0;
		}
		if ( self->client->ps.powerups[PW_BLUEFLAG] ) {
			item = BG_FindItem( "Blue Flag" );
			if ( !item ) {
				item = BG_FindItem( "Objective" );
			}

			self->client->ps.powerups[PW_BLUEFLAG] = 0;
		}

		if ( item ) {
			launchvel[0] = crandom() * 20;
			launchvel[1] = crandom() * 20;
			launchvel[2] = 10 + random() * 10;

			flag = LaunchItem( item,self->r.currentOrigin,launchvel,self->s.number );
			flag->s.modelindex2 = self->s.otherEntityNum2; // JPW NERVE FIXME set player->otherentitynum2 with old modelindex2 from flag and restore here
			flag->message = self->message;  // DHM - Nerve :: also restore item name
			// Clear out player's temp copies
			self->s.otherEntityNum2 = 0;
			self->message = NULL;
		}

		// send a fancy "MEDIC!" scream.  Sissies, ain' they?
		if ( self->client != NULL ) {
			if ( self->health > GIB_HEALTH && meansOfDeath != MOD_SUICIDE ) {

				if ( self->client->sess.sessionTeam == TEAM_RED ) {
					if ( random() > 0.5 ) {
						G_AddEvent( self, EV_GENERAL_SOUND, G_SoundIndex( "sound/multiplayer/axis/g-medic2.wav" ) );
					} else {
						G_AddEvent( self, EV_GENERAL_SOUND, G_SoundIndex( "sound/multiplayer/axis/g-medic3.wav" ) );
					}
				} else {
					if ( random() > 0.5 ) {
						G_AddEvent( self, EV_GENERAL_SOUND, G_SoundIndex( "sound/multiplayer/allies/a-medic3.wav" ) );
					} else {
						G_AddEvent( self, EV_GENERAL_SOUND, G_SoundIndex( "sound/multiplayer/allies/a-medic2.wav" ) );
					}
				}
			}
		}
	}
// jpw

	Cmd_Score_f( self );        // show scores
	// send updated scores to any clients that are following this one,
	// or they would get stale scoreboards
	for ( i = 0 ; i < level.maxclients ; i++ ) {
		gclient_t   *client;

		client = &level.clients[i];
		if ( client->pers.connected != CON_CONNECTED ) {
			continue;
		}
		if ( client->sess.sessionTeam != TEAM_SPECTATOR ) {
			continue;
		}
		if ( client->sess.spectatorClient == self->s.number ) {
			Cmd_Score_f( g_entities + i );
		}
	}

	self->takedamage = qtrue;   // can still be gibbed
	self->r.contents = CONTENTS_CORPSE;

	self->s.powerups = 0;
// JPW NERVE -- only corpse in SP; in MP, need CONTENTS_BODY so medic can operate
	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
		self->s.weapon = WP_NONE;
		self->s.angles[0] = 0;
	} else {
		self->client->limboDropWeapon = self->s.weapon; // store this so it can be dropped in limbo
	}
// jpw
	self->s.angles[2] = 0;
	LookAtKiller( self, inflictor, attacker );

	VectorCopy( self->s.angles, self->client->ps.viewangles );
	self->s.loopSound = 0;

	trap_UnlinkEntity( self );
	self->r.maxs[2] = 0;
	self->client->ps.maxs[2] = 0;
	trap_LinkEntity( self );

	// don't allow respawn until the death anim is done
	// g_forcerespawn may force spawning at some later time
	self->client->respawnTime = level.time + 800;

	// remove powerups
	memset( self->client->ps.powerups, 0, sizeof( self->client->ps.powerups ) );

	// never gib in a nodrop
	if ( self->health <= GIB_HEALTH && !( contents & CONTENTS_NODROP ) ) {
		GibEntity( self, killer );
		nogib = qfalse;
	}

	if ( nogib ) {
		// normal death
		// for the no-blood option, we need to prevent the health
		// from going to gib level
		if ( self->health <= GIB_HEALTH ) {
			self->health = GIB_HEALTH + 1;
		}

// JPW NERVE for medic
		self->client->medicHealAmt = 0;
// jpw

		// DHM - Play death animation, and set pm_time to delay 'fallen' animation
		self->client->ps.pm_time = BG_AnimScriptEvent( &self->client->ps, ANIM_ET_DEATH, qfalse, qtrue );

		G_AddEvent( self, EV_DEATH1 + 1, killer );

		// the body can still be gibbed
		self->die = body_die;
	}

	trap_LinkEntity( self );

	if ( g_gametype.integer >= GT_WOLF && meansOfDeath == MOD_SUICIDE ) {
		limbo( self, qtrue );
	}
}
Exemple #22
0
void StartMenu::on_tool_launch_desksettings_clicked(){
  LaunchItem("lumina-config", false);
}
Exemple #23
0
void G_DropWeapon( gentity_t *ent, weapon_t weapon )
{
	vec3_t		angles, velocity, org, offset, mins, maxs;
	gclient_t	*client = ent->client;
	gentity_t	*ent2;
	gitem_t		*item;
	trace_t		tr;

	item = BG_FindItemForWeapon( weapon );
	VectorCopy( client->ps.viewangles, angles );

	// clamp pitch
	if ( angles[PITCH] < -30 )
		angles[PITCH] = -30;
	else if ( angles[PITCH] > 30 )
		angles[PITCH] = 30;

	AngleVectors( angles, velocity, NULL, NULL );
	VectorScale( velocity, 64, offset );
	offset[2] += client->ps.viewheight / 2.f;
	VectorScale( velocity, 75, velocity );
	velocity[2] += 50 + random() * 35;

	VectorAdd( client->ps.origin, offset, org );

	VectorSet( mins, -ITEM_RADIUS, -ITEM_RADIUS, 0 );
	VectorSet( maxs, ITEM_RADIUS, ITEM_RADIUS, 2*ITEM_RADIUS );

	trap_Trace( &tr, client->ps.origin, mins, maxs, org, ent->s.number, MASK_SOLID );
	VectorCopy( tr.endpos, org );

	ent2 = LaunchItem( item, org, velocity, client->ps.clientNum );
	COM_BitClear( client->ps.weapons, weapon );

	if( weapon == WP_KAR98 ) {
		COM_BitClear( client->ps.weapons, WP_GPG40 );
	} else if ( weapon == WP_CARBINE ) {
		COM_BitClear( client->ps.weapons, WP_M7 );
	} else if ( weapon == WP_FG42 ) {
		COM_BitClear( client->ps.weapons, WP_FG42SCOPE );
	} else if( weapon == WP_K43 ) {
		COM_BitClear( client->ps.weapons, WP_K43_SCOPE );
	} else if( weapon == WP_GARAND ) {
		COM_BitClear( client->ps.weapons, WP_GARAND_SCOPE );
	} else if( weapon == WP_MORTAR ) {
		COM_BitClear( client->ps.weapons, WP_MORTAR_SET );
	} else if( weapon == WP_MOBILE_MG42 ) {
		COM_BitClear( client->ps.weapons, WP_MOBILE_MG42_SET );
	}

	// Clear out empty weapon, change to next best weapon
	G_AddEvent( ent, EV_WEAPONSWITCHED, 0 );

	if( weapon == client->ps.weapon )
		client->ps.weapon = 0;

	if( weapon == WP_MORTAR ) {
		ent2->count = client->ps.ammo[BG_FindAmmoForWeapon(weapon)] + client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
	} else {
		ent2->count = client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
	}

	if( weapon == WP_KAR98 || weapon == WP_CARBINE ) {
		ent2->delay = client->ps.ammo[BG_FindAmmoForWeapon(weapAlts[weapon])] + client->ps.ammoclip[BG_FindClipForWeapon(weapAlts[weapon])];
	} else {
		ent2->delay = 0;
	}

//	ent2->item->quantity = client->ps.ammoclip[BG_FindClipForWeapon(weapon)]; // Gordon: um, modifying an item is not a good idea
	client->ps.ammoclip[BG_FindClipForWeapon(weapon)] = 0;
}
Exemple #24
0
/*
==============
ClientThink

This will be called once for each client frame, which will
usually be a couple times for each server frame on fast clients.

If "g_synchronousClients 1" is set, this will be called exactly
once for each server frame, which makes for smooth demo recording.
==============
*/
void ClientThink_real( gentity_t *ent ) {
	gclient_t   *client;
	pmove_t pm;
//	vec3_t		oldOrigin;
	int oldEventSequence;
	int msec;
	usercmd_t   *ucmd;
	int monsterslick = 0;
// JPW NERVE
	int i;
	vec3_t muzzlebounce;
	gitem_t *item;
	gentity_t *ent2;
	vec3_t velocity, org, offset;
	vec3_t angles,mins,maxs;
	int weapon;
	trace_t tr;
// jpw

	// Rafael wolfkick
	//int			validkick;
	//static int	wolfkicktimer = 0;

	client = ent->client;

	// don't think if the client is not yet connected (and thus not yet spawned in)
	if ( client->pers.connected != CON_CONNECTED ) {
		return;
	}

	if ( client->cameraPortal ) {
		G_SetOrigin( client->cameraPortal, client->ps.origin );
		trap_LinkEntity( client->cameraPortal );
		VectorCopy( client->cameraOrigin, client->cameraPortal->s.origin2 );
	}

	// mark the time, so the connection sprite can be removed
	ucmd = &ent->client->pers.cmd;

	ent->client->ps.identifyClient = ucmd->identClient;     // NERVE - SMF

// JPW NERVE -- update counter for capture & hold display
	if ( g_gametype.integer == GT_WOLF_CPH ) {
		client->ps.stats[STAT_CAPTUREHOLD_RED] = level.capturetimes[TEAM_RED];
		client->ps.stats[STAT_CAPTUREHOLD_BLUE] = level.capturetimes[TEAM_BLUE];
	}
// jpw

	// sanity check the command time to prevent speedup cheating
	if ( ucmd->serverTime > level.time + 200 ) {
		ucmd->serverTime = level.time + 200;
//		G_Printf("serverTime <<<<<\n" );
	}
	if ( ucmd->serverTime < level.time - 1000 ) {
		ucmd->serverTime = level.time - 1000;
//		G_Printf("serverTime >>>>>\n" );
	}

	msec = ucmd->serverTime - client->ps.commandTime;
	// following others may result in bad times, but we still want
	// to check for follow toggles
	if ( msec < 1 && client->sess.spectatorState != SPECTATOR_FOLLOW ) {
		return;
		/*
		// Ridah, fixes savegame timing issue
		if (msec < -100) {
			client->ps.commandTime = ucmd->serverTime - 100;
			msec = 100;
		} else {
			return;
		}
		*/
		// done.
	}
	if ( msec > 200 ) {
		msec = 200;
	}

	if ( pmove_msec.integer < 8 ) {
		trap_Cvar_Set( "pmove_msec", "8" );
	} else if ( pmove_msec.integer > 33 )     {
		trap_Cvar_Set( "pmove_msec", "33" );
	}

	if ( pmove_fixed.integer || client->pers.pmoveFixed ) {
		ucmd->serverTime = ( ( ucmd->serverTime + pmove_msec.integer - 1 ) / pmove_msec.integer ) * pmove_msec.integer;
		//if (ucmd->serverTime - client->ps.commandTime <= 0)
		//	return;
	}

	//
	// check for exiting intermission
	//
	if ( level.intermissiontime ) {
		ClientIntermissionThink( client );
		return;
	}

	// spectators don't do much
	// DHM - Nerve :: In limbo use SpectatorThink
	if ( client->sess.sessionTeam == TEAM_SPECTATOR || client->ps.pm_flags & PMF_LIMBO ) {
		if ( client->sess.spectatorState == SPECTATOR_SCOREBOARD ) {
			return;
		}
		SpectatorThink( ent, ucmd );
		return;
	}

	// JPW NERVE do some time-based muzzle flip -- this never gets touched in single player (see g_weapon.c)
	// #define RIFLE_SHAKE_TIME 150 // JPW NERVE this one goes with the commented out old damped "realistic" behavior below
	#define RIFLE_SHAKE_TIME 300 // per Id request, longer recoil time
	if ( client->sniperRifleFiredTime ) {
		if ( level.time - client->sniperRifleFiredTime > RIFLE_SHAKE_TIME ) {
			client->sniperRifleFiredTime = 0;
		} else {
			VectorCopy( client->ps.viewangles,muzzlebounce );

			// JPW per Id request, longer recoil time
			muzzlebounce[PITCH] -= 2 * cos( 2.5 * ( level.time - client->sniperRifleFiredTime ) / RIFLE_SHAKE_TIME );
			muzzlebounce[YAW] += 0.5*client->sniperRifleMuzzleYaw*cos( 1.0 - ( level.time - client->sniperRifleFiredTime ) * 3 / RIFLE_SHAKE_TIME );
			muzzlebounce[PITCH] -= 0.25 * random() * ( 1.0f - ( level.time - client->sniperRifleFiredTime ) / RIFLE_SHAKE_TIME );
			muzzlebounce[YAW] += 0.5 * crandom() * ( 1.0f - ( level.time - client->sniperRifleFiredTime ) / RIFLE_SHAKE_TIME );
			SetClientViewAngle( ent,muzzlebounce );
		}
	}
	if ( client->ps.stats[STAT_PLAYER_CLASS] == PC_MEDIC ) {
		if ( level.time > client->ps.powerups[PW_REGEN] + 5000 ) {
			client->ps.powerups[PW_REGEN] = level.time;
		}
	}
	// also update weapon recharge time

	// JPW drop button drops secondary weapon so new one can be picked up
	// TTimo explicit braces to avoid ambiguous 'else'
	if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
		if ( ucmd->wbuttons & WBUTTON_DROP ) {
			if ( !client->dropWeaponTime ) {
				client->dropWeaponTime = 1; // just latch it for now
				if ( ( client->ps.stats[STAT_PLAYER_CLASS] == PC_SOLDIER ) || ( client->ps.stats[STAT_PLAYER_CLASS] == PC_LT ) ) {
					for ( i = 0; i < MAX_WEAPS_IN_BANK_MP; i++ ) {
						weapon = weapBanksMultiPlayer[3][i];
						if ( COM_BitCheck( client->ps.weapons,weapon ) ) {

							item = BG_FindItemForWeapon( weapon );
							VectorCopy( client->ps.viewangles, angles );

							// clamp pitch
							if ( angles[PITCH] < -30 ) {
								angles[PITCH] = -30;
							} else if ( angles[PITCH] > 30 ) {
								angles[PITCH] = 30;
							}

							AngleVectors( angles, velocity, NULL, NULL );
							VectorScale( velocity, 64, offset );
							offset[2] += client->ps.viewheight / 2;
							VectorScale( velocity, 75, velocity );
							velocity[2] += 50 + random() * 35;

							VectorAdd( client->ps.origin,offset,org );

							VectorSet( mins, -ITEM_RADIUS, -ITEM_RADIUS, 0 );
							VectorSet( maxs, ITEM_RADIUS, ITEM_RADIUS, 2 * ITEM_RADIUS );

							trap_Trace( &tr, client->ps.origin, mins, maxs, org, ent->s.number, MASK_SOLID );
							VectorCopy( tr.endpos, org );

							ent2 = LaunchItem( item, org, velocity, client->ps.clientNum );
							COM_BitClear( client->ps.weapons,weapon );

							if ( weapon == WP_MAUSER ) {
								COM_BitClear( client->ps.weapons,WP_SNIPERRIFLE );
							}

							// Clear out empty weapon, change to next best weapon
							G_AddEvent( ent, EV_NOAMMO, 0 );

							i = MAX_WEAPS_IN_BANK_MP;
							// show_bug.cgi?id=568
							if ( client->ps.weapon == weapon ) {
								client->ps.weapon = 0;
							}
							ent2->count = client->ps.ammoclip[BG_FindClipForWeapon( weapon )];
							ent2->item->quantity = client->ps.ammoclip[BG_FindClipForWeapon( weapon )];
							client->ps.ammoclip[BG_FindClipForWeapon( weapon )] = 0;
						}
					}
				}
			}
		} else {
			client->dropWeaponTime = 0;
		}
	}
// jpw

	// check for inactivity timer, but never drop the local client of a non-dedicated server
	if ( !ClientInactivityTimer( client ) ) {
		return;
	}

	if ( reloading || client->cameraPortal ) {
		ucmd->buttons = 0;
		ucmd->forwardmove = 0;
		ucmd->rightmove = 0;
		ucmd->upmove = 0;
		ucmd->wbuttons = 0;
		ucmd->wolfkick = 0;
		if ( client->cameraPortal ) {
			client->ps.pm_type = PM_FREEZE;
		}
	} else if ( client->noclip ) {
		client->ps.pm_type = PM_NOCLIP;
	} else if ( client->ps.stats[STAT_HEALTH] <= 0 ) {
		client->ps.pm_type = PM_DEAD;
	} else {
		client->ps.pm_type = PM_NORMAL;
	}

	// set parachute anim condition flag
	BG_UpdateConditionValue( ent->s.number, ANIM_COND_PARACHUTE, ( ent->flags & FL_PARACHUTE ) != 0, qfalse );

	// all playing clients are assumed to be in combat mode
	if ( !client->ps.aiChar ) {
		client->ps.aiState = AISTATE_COMBAT;
	}

	client->ps.gravity = g_gravity.value;

	// set speed
	client->ps.speed = g_speed.value;

	if ( client->ps.powerups[PW_HASTE] ) {
		client->ps.speed *= 1.3;
	}

	// set up for pmove
	oldEventSequence = client->ps.eventSequence;

	client->currentAimSpreadScale = (float)client->ps.aimSpreadScale / 255.0;

	memset( &pm, 0, sizeof( pm ) );

	pm.ps = &client->ps;
	pm.pmext = &client->pmext;
	pm.cmd = *ucmd;
	pm.oldcmd = client->pers.oldcmd;
	if ( pm.ps->pm_type == PM_DEAD ) {
		pm.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY;
		// DHM-Nerve added:: EF_DEAD is checked for in Pmove functions, but wasn't being set
		//              until after Pmove
		pm.ps->eFlags |= EF_DEAD;
		// dhm-Nerve end
	} else {
		pm.tracemask = MASK_PLAYERSOLID;
	}
	// MrE: always use capsule for AI and player
	//pm.trace = trap_TraceCapsule;//trap_Trace;
	//DHM - Nerve :: We've gone back to using normal bbox traces
	pm.trace = trap_Trace;
	pm.pointcontents = trap_PointContents;
	pm.debugLevel = g_debugMove.integer;
	pm.noFootsteps = ( g_dmflags.integer & DF_NO_FOOTSTEPS ) > 0;

	pm.pmove_fixed = pmove_fixed.integer | client->pers.pmoveFixed;
	pm.pmove_msec = pmove_msec.integer;

	pm.noWeapClips = ( g_dmflags.integer & DF_NO_WEAPRELOAD ) > 0;
	if ( ent->aiCharacter && AICast_NoReload( ent->s.number ) ) {
		pm.noWeapClips = qtrue; // ensure AI characters don't use clips if they're not supposed to.

	}
	// Ridah
//	if (ent->r.svFlags & SVF_NOFOOTSTEPS)
//		pm.noFootsteps = qtrue;

	VectorCopy( client->ps.origin, client->oldOrigin );

	// NERVE - SMF
	pm.gametype = g_gametype.integer;
	pm.ltChargeTime = g_LTChargeTime.integer;
	pm.soldierChargeTime = g_soldierChargeTime.integer;
	pm.engineerChargeTime = g_engineerChargeTime.integer;
	pm.medicChargeTime = g_medicChargeTime.integer;
	// -NERVE - SMF

	monsterslick = Pmove( &pm );

	if ( monsterslick && !( ent->flags & FL_NO_MONSTERSLICK ) ) {
		//vec3_t	dir;
		//vec3_t	kvel;
		//vec3_t	forward;
		// TTimo gcc: might be used unitialized in this function
		float angle = 0.0f;
		qboolean bogus = qfalse;

		// NE
		if ( ( monsterslick & SURF_MONSLICK_N ) && ( monsterslick & SURF_MONSLICK_E ) ) {
			angle = 45;
		}
		// NW
		else if ( ( monsterslick & SURF_MONSLICK_N ) && ( monsterslick & SURF_MONSLICK_W ) ) {
			angle = 135;
		}
		// N
		else if ( monsterslick & SURF_MONSLICK_N ) {
			angle = 90;
		}
		// SE
		else if ( ( monsterslick & SURF_MONSLICK_S ) && ( monsterslick & SURF_MONSLICK_E ) ) {
			angle = 315;
		}
		// SW
		else if ( ( monsterslick & SURF_MONSLICK_S ) && ( monsterslick & SURF_MONSLICK_W ) ) {
			angle = 225;
		}
		// S
		else if ( monsterslick & SURF_MONSLICK_S ) {
			angle = 270;
		}
		// E
		else if ( monsterslick & SURF_MONSLICK_E ) {
			angle = 0;
		}
		// W
		else if ( monsterslick & SURF_MONSLICK_W ) {
			angle = 180;
		} else
		{
			bogus = qtrue;
		}
	}

	// server cursor hints
	if ( ent->lastHintCheckTime < level.time ) {
		G_CheckForCursorHints( ent );

		ent->lastHintCheckTime = level.time + FRAMETIME;
	}

	// DHM - Nerve :: Set animMovetype to 1 if ducking
	if ( ent->client->ps.pm_flags & PMF_DUCKED ) {
		ent->s.animMovetype = 1;
	} else {
		ent->s.animMovetype = 0;
	}

	// save results of pmove
	if ( ent->client->ps.eventSequence != oldEventSequence ) {
		ent->eventTime = level.time;
		ent->r.eventTime = level.time;
	}

	// Ridah, fixes jittery zombie movement
	if ( g_smoothClients.integer ) {
		BG_PlayerStateToEntityStateExtraPolate( &ent->client->ps, &ent->s, ent->client->ps.commandTime, qtrue );
	} else {
		BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, qtrue );
	}

	if ( !( ent->client->ps.eFlags & EF_FIRING ) ) {
		client->fireHeld = qfalse;      // for grapple
	}

//
//	// use the precise origin for linking
//	VectorCopy( ent->client->ps.origin, ent->r.currentOrigin );
//
//	// use the snapped origin for linking so it matches client predicted versions
	VectorCopy( ent->s.pos.trBase, ent->r.currentOrigin );

	VectorCopy( pm.mins, ent->r.mins );
	VectorCopy( pm.maxs, ent->r.maxs );

	ent->waterlevel = pm.waterlevel;
	ent->watertype = pm.watertype;

	// execute client events
	ClientEvents( ent, oldEventSequence );

	// link entity now, after any personal teleporters have been used
	trap_LinkEntity( ent );
	if ( !ent->client->noclip ) {
		G_TouchTriggers( ent );
	}

	// NOTE: now copy the exact origin over otherwise clients can be snapped into solid
	VectorCopy( ent->client->ps.origin, ent->r.currentOrigin );

	// store the client's current position for antilag traces
	G_StoreClientPosition( ent );

	// touch other objects
	ClientImpacts( ent, &pm );

	// save results of triggers and client events
	if ( ent->client->ps.eventSequence != oldEventSequence ) {
		ent->eventTime = level.time;
	}

	// swap and latch button actions
	client->oldbuttons = client->buttons;
	client->buttons = ucmd->buttons;
	client->latched_buttons = client->buttons & ~client->oldbuttons;
//	client->latched_buttons |= client->buttons & ~client->oldbuttons;	// FIXME:? (SA) MP method (causes problems for us.  activate 'sticks')

	//----(SA)	added
	client->oldwbuttons = client->wbuttons;
	client->wbuttons = ucmd->wbuttons;
	client->latched_wbuttons = client->wbuttons & ~client->oldwbuttons;
//	client->latched_wbuttons |= client->wbuttons & ~client->oldwbuttons;	// FIXME:? (SA) MP method

	// Rafael - Activate
	// Ridah, made it a latched event (occurs on keydown only)
	if ( client->latched_buttons & BUTTON_ACTIVATE ) {
		Cmd_Activate_f( ent );
	}

	if ( ent->flags & FL_NOFATIGUE ) {
		ent->client->ps.sprintTime = 20000;
	}


	// check for respawning
	if ( client->ps.stats[STAT_HEALTH] <= 0 ) {

		// DHM - Nerve
		if ( g_gametype.integer >= GT_WOLF ) {
			WolfFindMedic( ent );
		}
		// dhm - end

		// wait for the attack button to be pressed
		if ( level.time > client->respawnTime ) {
			// forcerespawn is to prevent users from waiting out powerups
			if ( ( g_gametype.integer != GT_SINGLE_PLAYER ) &&
				 ( g_forcerespawn.integer > 0 ) &&
				 ( ( level.time - client->respawnTime ) > g_forcerespawn.integer * 1000 )  &&
				 ( !( ent->client->ps.pm_flags & PMF_LIMBO ) ) ) { // JPW NERVE
				// JPW NERVE
				if ( g_gametype.integer >= GT_WOLF ) {
					limbo( ent, qtrue );
				} else {
					respawn( ent );
				}
				// jpw
				return;
			}

			// DHM - Nerve :: Single player game respawns immediately as before,
			//				  but in multiplayer, require button press before respawn
			if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
				respawn( ent );
			}
			// NERVE - SMF - we want to only respawn on jump button now
			else if ( ( ucmd->upmove > 0 ) &&
					  ( !( ent->client->ps.pm_flags & PMF_LIMBO ) ) ) { // JPW NERVE
				// JPW NERVE
				if ( g_gametype.integer >= GT_WOLF ) {
					limbo( ent, qtrue );
				} else {
					respawn( ent );
				}
				// jpw
			}
			// dhm - Nerve :: end
			// NERVE - SMF - we want to immediately go to limbo mode if gibbed
			else if ( client->ps.stats[STAT_HEALTH] <= GIB_HEALTH && !( ent->client->ps.pm_flags & PMF_LIMBO ) ) {
				if ( g_gametype.integer >= GT_WOLF ) {
					limbo( ent, qfalse );
				} else {
					respawn( ent );
				}
			}
			// -NERVE - SMF
		}
		return;
	}

	// perform once-a-second actions
	ClientTimerActions( ent, msec );
}
Exemple #25
0
void StartMenu::on_tool_launch_deskinfo_clicked(){
  LaunchItem("lumina-info",false);
}
Exemple #26
0
//Logout Buttons
void StartMenu::on_tool_lock_clicked(){
  LaunchItem("xscreensaver-command -lock", false);
}
Exemple #27
0
/*
================
LaunchItem

Spawns an item and tosses it forward
================
*/
gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity ) {
	gentity_t	*dropped;

	dropped = G_Spawn();

	dropped->s.eType = ET_ITEM;
	dropped->s.modelindex = item - bg_itemlist;	// store item number in modelindex
	dropped->s.modelindex2 = 1; // This is non-zero is it's a dropped item

	dropped->classname = item->classname;
	dropped->item = item;
	VectorSet (dropped->r.mins, -ITEM_RADIUS, -ITEM_RADIUS, -ITEM_RADIUS);
	VectorSet (dropped->r.maxs, ITEM_RADIUS, ITEM_RADIUS, ITEM_RADIUS);
	dropped->r.contents = CONTENTS_TRIGGER;

	dropped->touch = Touch_Item;

	G_SetOrigin( dropped, origin );
	dropped->s.pos.trType = TR_GRAVITY;
	dropped->s.pos.trTime = level.time;
	VectorCopy( velocity, dropped->s.pos.trDelta );

	dropped->s.eFlags |= EF_BOUNCE_HALF;
#ifdef MISSIONPACK
	if ((g_gametype.integer == GT_CTF || g_gametype.integer == GT_1FCTF)			&& item->giType == IT_TEAM) { // Special case for CTF flags
#else
	if (g_gametype.integer == GT_CTF && item->giType == IT_TEAM) { // Special case for CTF flags
#endif
		dropped->think = Team_DroppedFlagThink;
		dropped->nextthink = level.time + 30000;
		Team_CheckDroppedItem( dropped );
	} else { // auto-remove after 30 seconds
		dropped->think = G_FreeEntity;
		dropped->nextthink = level.time + 30000;
	}

	dropped->flags = FL_DROPPED_ITEM;

	trap_LinkEntity (dropped);

	return dropped;
}

/*
================
Drop_Item

Spawns an item and tosses it forward
================
*/
gentity_t *Drop_Item( gentity_t *ent, gitem_t *item, float angle ) {
	vec3_t	velocity;
	vec3_t	angles;

	VectorCopy( ent->s.apos.trBase, angles );
	angles[YAW] += angle;
	angles[PITCH] = 0;	// always forward

	AngleVectors( angles, velocity, NULL, NULL );
	VectorScale( velocity, 150, velocity );
	velocity[2] += 200 + crandom() * 50;

	return LaunchItem( item, ent->s.pos.trBase, velocity );
}
Exemple #28
0
void UserWidget::slotOpenDir(){
  LaunchItem(ui->label_home_dir->whatsThis());
}
Exemple #29
0
void misc_model_cargo_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod, int dFlags, int hitLoc )
{
	int		flags;
	vec3_t	org, temp;
	gitem_t *health = NULL, *shields = NULL, *bacta = NULL, *batteries = NULL;

	// copy these for later
	flags = self->spawnflags;
	VectorCopy( self->currentOrigin, org );

	// we already had spawn flags, but we don't care what they were...we just need to set up the flags we want for misc_model_breakable_die
	self->spawnflags = 8; // NO_DMODEL

	// pass through to get the effects and such
	misc_model_breakable_die( self, inflictor, attacker, damage, mod );

	// now that the model is broken, we can safely spawn these in it's place without them being in solid
	temp[2] = org[2] + 16;

	// annoying, but spawn each thing in its own little quadrant so that they don't end up on top of each other
	if (( flags & DROP_MEDPACK ))
	{
		health = FindItem( "item_medpak_instant" );

		if ( health )
		{
			temp[0] = org[0] + crandom() * 8 + 16;
			temp[1] = org[1] + crandom() * 8 + 16;

			LaunchItem( health, temp, vec3_origin, NULL );
		}
	}
	if (( flags & DROP_SHIELDS ))
	{
		shields = FindItem( "item_shield_sm_instant" );

		if ( shields )
		{
			temp[0] = org[0] + crandom() * 8 - 16;
			temp[1] = org[1] + crandom() * 8 + 16;

			LaunchItem( shields, temp, vec3_origin, NULL );
		}
	}

	if (( flags & DROP_BACTA ))
	{
		bacta = FindItem( "item_bacta" );

		if ( bacta )
		{
			temp[0] = org[0] + crandom() * 8 - 16;
			temp[1] = org[1] + crandom() * 8 - 16;

			LaunchItem( bacta, temp, vec3_origin, NULL );
		}
	}

	if (( flags & DROP_BATTERIES ))
	{
		batteries = FindItem( "item_battery" );

		if ( batteries )
		{
			temp[0] = org[0] + crandom() * 8 + 16;
			temp[1] = org[1] + crandom() * 8 - 16;

			LaunchItem( batteries, temp, vec3_origin, NULL );
		}
	}
}
Exemple #30
0
/**
* @brief Drop weapon.
*/
void G_DropWeapon(gentity_t *ent, weapon_t weapon)
{
	vec3_t    angles, velocity, org, offset, mins, maxs;
	gclient_t *client = ent->client;
	gentity_t *ent2;
	gitem_t   *item;
	trace_t   tr;

	if (!IS_VALID_WEAPON(weapon))
	{
		return;
	}

	item = BG_FindItemForWeapon(weapon);
	VectorCopy(client->ps.viewangles, angles);

	// clamp pitch
	if (angles[PITCH] < -30)
	{
		angles[PITCH] = -30;
	}
	else if (angles[PITCH] > 30)
	{
		angles[PITCH] = 30;
	}

	AngleVectors(angles, velocity, NULL, NULL);
	VectorScale(velocity, 64, offset);
	offset[2] += client->ps.viewheight / 2.f;
	VectorScale(velocity, 75, velocity);
	velocity[2] += 50 + random() * 35;

	VectorAdd(client->ps.origin, offset, org);

	VectorSet(mins, -ITEM_RADIUS, -ITEM_RADIUS, 0);
	VectorSet(maxs, ITEM_RADIUS, ITEM_RADIUS, 2 * ITEM_RADIUS);

	trap_Trace(&tr, client->ps.origin, mins, maxs, org, ent->s.number, MASK_SOLID);
	VectorCopy(tr.endpos, org);

	ent2 = LaunchItem(item, org, velocity, client->ps.clientNum);
	COM_BitClear(client->ps.weapons, weapon);

	switch (weapon)
	{
	case WP_KAR98:
		COM_BitClear(client->ps.weapons, WP_GPG40);
		break;
	case WP_CARBINE:
		COM_BitClear(client->ps.weapons, WP_M7);
		break;
	case WP_FG42:
		COM_BitClear(client->ps.weapons, WP_FG42SCOPE);
		break;
	case WP_K43:
		COM_BitClear(client->ps.weapons, WP_K43_SCOPE);
		break;
	case WP_GARAND:
		COM_BitClear(client->ps.weapons, WP_GARAND_SCOPE);
		break;
	case WP_MORTAR:
		COM_BitClear(client->ps.weapons, WP_MORTAR_SET);
		break;
	case WP_MORTAR2:
		COM_BitClear(client->ps.weapons, WP_MORTAR2_SET);
		break;
	case WP_MOBILE_MG42:
		COM_BitClear(client->ps.weapons, WP_MOBILE_MG42_SET);
		break;
	case WP_MOBILE_BROWNING:
		COM_BitClear(client->ps.weapons, WP_MOBILE_BROWNING_SET);
		break;
	default:
		break;
	}

	// Clear out empty weapon, change to next best weapon
	G_AddEvent(ent, EV_WEAPONSWITCHED, 0);

	if (weapon == client->ps.weapon)
	{
		client->ps.weapon = 0;
	}

	if (IS_MORTAR_WEAPON_SET(weapon))
	{
		ent2->count = client->ps.ammo[BG_FindAmmoForWeapon(weapon)] + client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
	}
	else
	{
		ent2->count = client->ps.ammoclip[BG_FindClipForWeapon(weapon)];
	}

	if (weapon == WP_KAR98 || weapon == WP_CARBINE)
	{
		ent2->delay = client->ps.ammo[BG_FindAmmoForWeapon(weaponTable[weapon].weapAlts)];
	}
	else
	{
		ent2->delay = 0;
	}

	//  ent2->item->quantity = client->ps.ammoclip[BG_FindClipForWeapon(weapon)]; // um, modifying an item is not a good idea
	client->ps.ammoclip[BG_FindClipForWeapon(weapon)] = 0;

#ifdef FEATURE_OMNIBOT
	Bot_Event_RemoveWeapon(client->ps.clientNum, Bot_WeaponGameToBot(weapon));
#endif
}