当前位置: 首页>>代码示例>>C++>>正文


C++ CG_PointContents函数代码示例

本文整理汇总了C++中CG_PointContents函数的典型用法代码示例。如果您正苦于以下问题:C++ CG_PointContents函数的具体用法?C++ CG_PointContents怎么用?C++ CG_PointContents使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了CG_PointContents函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: CG_ProjectileTrail

/*
* CG_ProjectileTrail
*/
void CG_ProjectileTrail( centity_t *cent )
{
	lentity_t	*le;
	float		len;
	vec3_t		vec;
	int			contents;
	int			trailTime;
	float		radius = 6.5f, alpha = 0.35f;
#if 0
	struct shader_s *shader = CG_MediaShader( cgs.media.shaderRocketTrailSmokePuff );
#else
	struct shader_s *shader = CG_MediaShader( cgs.media.shaderSmokePuff );
#endif
	CG_ProjectileFireTrail( cent ); // add fire trail

	if( !cg_projectileTrail->integer )
		return;

	// didn't move
	VectorSubtract( cent->ent.origin, cent->trailOrigin, vec );
	len = VectorNormalize( vec );
	if( !len )
		return;

	// density is found by quantity per second
	trailTime = (int)(1000.0f / cg_projectileTrail->value );
	if( trailTime < 1 ) trailTime = 1;

	// we don't add more than one sprite each frame. If frame
	// ratio is too slow, people will prefer having less sprites on screen
	if( cent->localEffects[LOCALEFFECT_ROCKETTRAIL_LAST_DROP] + trailTime < cg.time ) {
		cent->localEffects[LOCALEFFECT_ROCKETTRAIL_LAST_DROP] = cg.time;

		contents = ( CG_PointContents( cent->trailOrigin ) & CG_PointContents( cent->ent.origin ) );
		if( contents & MASK_WATER ) {
			shader = CG_MediaShader( cgs.media.shaderWaterBubble );
			radius = 3 + crandom();
			alpha = 1.0f;
		}

		// racesow
		if( cg_raceGhosts->integer && (unsigned int)cent->current.ownerNum != cg.predictedPlayerState.POVnum )
			alpha *= cg_raceGhostsAlpha->value;
		// !racesow

		clamp( alpha, 0.0f, 1.0f );
		le = CG_AllocSprite( LE_PUFF_SHRINK, cent->trailOrigin, radius, 20, 
			1.0f, 1.0f, 1.0f, alpha,
			0, 0, 0, 0, 
			shader );
		VectorSet( le->velocity, -vec[0] * 5 + crandom()*5, -vec[1] * 5 + crandom()*5, -vec[2] * 5 + crandom()*5 + 3 );
		le->ent.rotation = rand () % 360;
	}
}
开发者ID:QaleQ,项目名称:racemod,代码行数:57,代码来源:cg_lents.cpp

示例2: CG_NewBloodTrail

/*
* CG_NewBloodTrail
*/
void CG_NewBloodTrail( centity_t *cent )
{
	lentity_t *le;
	float len;
	vec3_t vec;
	int contents;
	int trailTime;
	float radius = 2.5f, alpha = cg_bloodTrailAlpha->value;
	struct shader_s *shader = CG_MediaShader( cgs.media.shaderBloodTrailPuff );

	if( !cg_showBloodTrail->integer )
		return;

	if( !cg_bloodTrail->integer )
		return;

	// didn't move
	VectorSubtract( cent->ent.origin, cent->trailOrigin, vec );
	len = VectorNormalize( vec );
	if( !len )
		return;

	// density is found by quantity per second
	trailTime = (int)( 1000.0f / cg_bloodTrail->value );
	if( trailTime < 1 ) trailTime = 1;

	// we don't add more than one sprite each frame. If frame
	// ratio is too slow, people will prefer having less sprites on screen
	if( cent->localEffects[LOCALEFFECT_BLOODTRAIL_LAST_DROP] + trailTime < cg.time )
	{
		cent->localEffects[LOCALEFFECT_BLOODTRAIL_LAST_DROP] = cg.time;

		contents = ( CG_PointContents( cent->trailOrigin ) & CG_PointContents( cent->ent.origin ) );
		if( contents & MASK_WATER )
		{
			shader = CG_MediaShader( cgs.media.shaderBloodTrailLiquidPuff );
			radius = 4 + crandom();
			alpha = 0.5f * cg_bloodTrailAlpha->value;
		}

		clamp( alpha, 0.0f, 1.0f );
		le = CG_AllocSprite( LE_SCALE_ALPHA_FADE, cent->trailOrigin, radius, 8,
			1.0f, 1.0f, 1.0f, alpha,
			0, 0, 0, 0,
			shader );
		VectorSet( le->velocity, -vec[0] * 5 + crandom()*5, -vec[1] * 5 + crandom()*5, -vec[2] * 5 + crandom()*5 + 3 );
		le->ent.rotation = rand() % 360;
	}
}
开发者ID:Kaperstone,项目名称:warsow,代码行数:52,代码来源:cg_lents.c

示例3: CG_Dash

void CG_Dash( entity_state_t *state )
{
	lentity_t *le;
	vec3_t pos, dvect, angle = { 0, 0, 0 };

	if( !(cg_cartoonEffects->integer & 4) )
		return;

	// KoFFiE: Calculate angle based on relative position of the previous origin state of the player entity
	VectorSubtract( state->origin, cg_entities[state->number].prev.origin, dvect );

	// ugly inline define -> Ignore when difference between 2 positions was less than this value.
#define IGNORE_DASH 6.0

	if( ( dvect[0] > -IGNORE_DASH ) && ( dvect[0] < IGNORE_DASH ) &&
		( dvect[1] > -IGNORE_DASH ) && ( dvect[1] < IGNORE_DASH ) )
		return;

	VecToAngles( dvect, angle );
	VectorCopy( state->origin, pos );
	angle[1] += 270; // Adjust angle
	pos[2] -= 24; // Adjust the position to ground height

	if( CG_PointContents( pos ) & MASK_WATER )
		return; // no smoke under water :)

	le = CG_AllocModel( LE_DASH_SCALE, pos, angle, 7, //5
		1.0, 1.0, 1.0, 1.0,
		0, 0, 0, 0,
		CG_MediaModel( cgs.media.modDash ),
		NULL
		);
	le->ent.scale = 0.01f;
	le->ent.axis[2][2] *= 2.0f;
}
开发者ID:Kaperstone,项目名称:warsow,代码行数:35,代码来源:cg_lents.c

示例4: CG_DustCircle

void CG_DustCircle( vec3_t pos, vec3_t dir, float radius, int count )
{
	vec3_t dir_per1;
	vec3_t dir_per2;
	vec3_t dir_temp = { 0.0f, 0.0f, 0.0f };
	int i;
	float angle;

	if( CG_PointContents( pos ) & MASK_WATER )
		return; // no smoke under water :)

	PerpendicularVector( dir_per2, dir );
	CrossProduct( dir, dir_per2, dir_per1 );

	VectorScale( dir_per1, VectorNormalize( dir_per1 ), dir_per1 );
	VectorScale( dir_per2, VectorNormalize( dir_per2 ), dir_per2 );

	for( i = 0; i < count; i++ )
	{
		angle = (float)( 6.2831f / count * i );
		VectorSet( dir_temp, 0.0f, 0.0f, 0.0f );
		VectorMA( dir_temp, sin( angle ), dir_per1, dir_temp );
		VectorMA( dir_temp, cos( angle ), dir_per2, dir_temp );
		//VectorScale(dir_temp, VectorNormalize(dir_temp),dir_temp );
		VectorScale( dir_temp, crandom()*10 + radius, dir_temp );
		CG_Explosion_Puff_2( pos, dir_temp, 10 );
	}
}
开发者ID:Kaperstone,项目名称:warsow,代码行数:28,代码来源:cg_lents.c

示例5: CG_CalcFov

static int CG_CalcFov( void ) {
	float fov;
	int contents;

	// check if underwater
	contents = CG_PointContents( cg.refdef.vieworg, -1 );
	if ( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ){
		cg.refdef.rdflags |= RDF_UNDERWATER;
	}
	else {
		cg.refdef.rdflags &= ~RDF_UNDERWATER;
	}

	// set world fov
	fov = cg_fov.value;
	CG_CalcFov2( &cg.refdef, &fov, &cg.refdef.fov_x, &cg.refdef.fov_y );

	// set view weapon fov
	cg.viewWeaponFov = cg_weaponFov.value ? cg_weaponFov.value : cg_fov.value;
	CG_CalcFov2( &cg.refdef, &cg.viewWeaponFov, &cg.refdef.weapon_fov_x, &cg.refdef.weapon_fov_y );

	if ( !cg.cur_lc->zoomed ) {
		cg.cur_lc->zoomSensitivity = 1;
	} else {
		cg.cur_lc->zoomSensitivity = cg.refdef.fov_y / 75.0;
	}

	return (cg.refdef.rdflags & RDF_UNDERWATER);
}
开发者ID:zturtleman,项目名称:mint-arena,代码行数:29,代码来源:cg_view.c

示例6: CG_ImpactSmokePuff

/*
* CG_ImpactSmokePuff
*/
void CG_ImpactSmokePuff( vec3_t origin, vec3_t dir, float radius, float alpha, int time, int speed )
{
#define SMOKEPUFF_MAXVIEWDIST 700
	lentity_t *le;
	struct shader_s *shader = CG_MediaShader( cgs.media.shaderSmokePuff );

	if( CG_PointContents( origin ) & MASK_WATER )
	{
		return;
	}

	if( DistanceFast( origin, cg.view.origin ) * cg.view.fracDistFOV > SMOKEPUFF_MAXVIEWDIST )
		return;

	if( !VectorLength( dir ) )
	{
		VectorCopy( cg.view.axis[FORWARD], dir );
		VectorInverse( dir );
	}
	VectorNormalize( dir );
	//offset the origin by half of the radius
	VectorMA( origin, radius*0.5f, dir, origin );

	le = CG_AllocSprite( LE_SCALE_ALPHA_FADE, origin, radius + crandom(), time,
		1, 1, 1, alpha, 0, 0, 0, 0, shader );

	le->ent.rotation = rand() % 360;
	VectorScale( dir, speed, le->velocity );
}
开发者ID:Kaperstone,项目名称:warsow,代码行数:32,代码来源:cg_lents.c

示例7: CG_RainParticleGenerate

static qboolean CG_RainParticleGenerate(cg_atmosphericParticle_t * particle, vec3_t currvec, float currweight)
{
	// Attempt to 'spot' a raindrop somewhere below a sky texture.

	float angle, distance, origz;
	vec3_t testpoint, testend;
	trace_t tr;

	angle = random() * 2 * M_PI;
	distance = 20 + MAX_ATMOSPHERIC_DISTANCE * random();

	testpoint[0] = testend[0] = cg.refdef.vieworg[0] + sin(angle) * distance;
	testpoint[1] = testend[1] = cg.refdef.vieworg[1] + cos(angle) * distance;
	testpoint[2] = origz = cg.refdef.vieworg[2];
	testend[2] = testpoint[2] + MAX_ATMOSPHERIC_HEIGHT;

	while (1) {
		if (testpoint[2] >= MAX_ATMOSPHERIC_HEIGHT)
			return (qfalse);
		if (testend[2] >= MAX_ATMOSPHERIC_HEIGHT)
			testend[2] = MAX_ATMOSPHERIC_HEIGHT - 1;
		CG_Trace(&tr, testpoint, NULL, NULL, testend, ENTITYNUM_NONE, MASK_SOLID | MASK_WATER);
		if (tr.startsolid)	// Stuck in something, skip over it.
		{
			testpoint[2] += 64;
			testend[2] = testpoint[2] + MAX_ATMOSPHERIC_HEIGHT;
		} else if (tr.fraction == 1)	// Didn't hit anything, we're (probably) outside the world
			return (qfalse);
		else if (tr.surfaceFlags & SURF_SKY)	// Hit sky, this is where we start.
			break;
		else
			return (qfalse);
	}

	particle->active = qtrue;
	particle->colour[0] = 0.6 + 0.2 * random();
	particle->colour[1] = 0.6 + 0.2 * random();
	particle->colour[2] = 0.6 + 0.2 * random();
	VectorCopy(tr.endpos, particle->pos);
	VectorCopy(currvec, particle->delta);
	particle->delta[2] += crandom() * 100;
	VectorNormalize2(particle->delta, particle->deltaNormalized);
	particle->height = ATMOSPHERIC_RAIN_HEIGHT + crandom() * 100;
	particle->weight = currweight;
	particle->effectshader = &cg_atmFx.effectshaders[0];

	distance = ((float) (tr.endpos[2] - MIN_ATMOSPHERIC_HEIGHT)) / -particle->delta[2];
	VectorMA(tr.endpos, distance, particle->delta, testend);

	CG_Trace(&tr, particle->pos, NULL, NULL, testend, ENTITYNUM_NONE, MASK_SOLID | MASK_WATER);
	particle->minz = tr.endpos[2];
	tr.endpos[2]--;
	VectorCopy(tr.plane.normal, particle->surfacenormal);
	particle->surface = tr.surfaceFlags;
	particle->contents = CG_PointContents(tr.endpos, ENTITYNUM_NONE);

	return (qtrue);
}
开发者ID:Zekom,项目名称:reaction,代码行数:58,代码来源:cg_atmospheric.c

示例8: CG_WaterLevel

/*
================
CG_WaterLevel

Returns waterlevel for entity origin
================
*/
int CG_WaterLevel(centity_t *cent) {
	vec3_t point;
	int contents, sample1, sample2, anim, waterlevel;
	int viewheight;

	anim = cent->currentState.legsAnim & ~ANIM_TOGGLEBIT;

	if (anim == LEGS_WALKCR || anim == LEGS_IDLECR) {
		viewheight = CROUCH_VIEWHEIGHT;
	} else {
		viewheight = DEFAULT_VIEWHEIGHT;
	}

	//
	// get waterlevel, accounting for ducking
	//
	waterlevel = 0;

	point[0] = cent->lerpOrigin[0];
	point[1] = cent->lerpOrigin[1];
	point[2] = cent->lerpOrigin[2] + MINS_Z + 1;
	contents = CG_PointContents(point, -1);

	if (contents & MASK_WATER) {
		sample2 = viewheight - MINS_Z;
		sample1 = sample2 / 2;
		waterlevel = 1;
		point[2] = cent->lerpOrigin[2] + MINS_Z + sample1;
		contents = CG_PointContents(point, -1);

		if (contents & MASK_WATER) {
			waterlevel = 2;
			point[2] = cent->lerpOrigin[2] + MINS_Z + sample2;
			contents = CG_PointContents(point, -1);

			if (contents & MASK_WATER) {
				waterlevel = 3;
			}
		}
	}

	return waterlevel;
}
开发者ID:Hasimir,项目名称:ioq3,代码行数:50,代码来源:cg_event.c

示例9: CG_RenderFlags

/*
* CG_RenderFlags
*/
static int CG_RenderFlags( void )
{
	int rdflags, contents;

	rdflags = 0;

	// set the RDF_UNDERWATER and RDF_CROSSINGWATER bitflags
	contents = CG_PointContents( cg.view.origin );
	if( contents & MASK_WATER )
	{
		rdflags |= RDF_UNDERWATER;

		// undewater, check above
		contents = CG_PointContents( tv( cg.view.origin[0], cg.view.origin[1], cg.view.origin[2] + 9 ) );
		if( !(contents & MASK_WATER) )
			rdflags |= RDF_CROSSINGWATER;
	}
	else
	{
		// look down a bit
		contents = CG_PointContents( tv( cg.view.origin[0], cg.view.origin[1], cg.view.origin[2] - 9 ) );
		if( contents & MASK_WATER )
			rdflags |= RDF_CROSSINGWATER;
	}

	if( cg.oldAreabits )
		rdflags |= RDF_OLDAREABITS;

	if( cg.portalInView )
		rdflags |= RDF_PORTALINVIEW;

	if( cg_outlineWorld->integer )
		rdflags |= RDF_WORLDOUTLINES;

	if( cg.view.flipped )
		rdflags |= RDF_FLIPPED;

	rdflags |= CG_SkyPortal();

	return rdflags;
}
开发者ID:MaryJaneInChain,项目名称:qfusion,代码行数:44,代码来源:cg_view.cpp

示例10: CG_WaterLevel

/*
================
CG_WaterLevel

Returns waterlevel for entity origin
================
*/
int CG_WaterLevel(centity_t *cent) {
	vec3_t point;
	int contents, sample1, sample2, anim, waterlevel;

	// get waterlevel, accounting for ducking
	waterlevel = 0;
	VectorCopy(cent->lerpOrigin, point);
	point[2] += MINS_Z + 1;
	anim = cent->currentState.legsAnim & ~ANIM_TOGGLEBIT;

	if (anim == LEGS_WALKCR || anim == LEGS_IDLECR) {
		point[2] += CROUCH_VIEWHEIGHT;
	} else {
		point[2] += DEFAULT_VIEWHEIGHT;
	}

	contents = CG_PointContents(point, -1);

	if (contents & MASK_WATER) {
		sample2 = point[2] - MINS_Z;
		sample1 = sample2 / 2;
		waterlevel = 1;
		point[2] = cent->lerpOrigin[2] + MINS_Z + sample1;
		contents = CG_PointContents(point, -1);

		if (contents & MASK_WATER) {
			waterlevel = 2;
			point[2] = cent->lerpOrigin[2] + MINS_Z + sample2;
			contents = CG_PointContents(point, -1);

			if (contents & MASK_WATER) {
				waterlevel = 3;
			}
		}
	}

	return waterlevel;
}
开发者ID:mecwerks,项目名称:revamp,代码行数:45,代码来源:cg_event.c

示例11: CG_BloodDamageEffect

/*
* CG_BloodDamageEffect
*/
void CG_BloodDamageEffect( const vec3_t origin, const vec3_t dir, int damage )
{
	lentity_t *le;
	int count, i;
	float radius = 5.0f, alpha = cg_bloodTrailAlpha->value;
	int time = 8;
	struct shader_s *shader = CG_MediaShader( cgs.media.shaderBloodImpactPuff );
	vec3_t local_dir;

	if( !cg_showBloodTrail->integer )
		return;

	if( !cg_bloodTrail->integer )
		return;

	count = (int)( damage * 0.25f );
	clamp( count, 1, 10 );

	if( CG_PointContents( origin ) & MASK_WATER )
	{
		shader = CG_MediaShader( cgs.media.shaderBloodTrailLiquidPuff );
		radius += ( 1 + crandom() );
		alpha = 0.5f * cg_bloodTrailAlpha->value;
	}

	if( !VectorLength( dir ) )
	{
		VectorNegate( &cg.view.axis[AXIS_FORWARD], local_dir );
	}
	else
	{
		VectorNormalize2( dir, local_dir );
	}

	for( i = 0; i < count; i++ )
	{
		le = CG_AllocSprite( LE_PUFF_SHRINK, origin, radius + crandom(), time,
			1, 1, 1, alpha, 0, 0, 0, 0, shader );

		le->ent.rotation = rand() % 360;

		// randomize dir
		VectorSet( le->velocity,
			-local_dir[0] * 5 + crandom()*5,
			-local_dir[1] * 5 + crandom()*5,
			-local_dir[2] * 5 + crandom()*5 + 3 );
		VectorMA( local_dir, min( 6, count ), le->velocity, le->velocity );
	}
}
开发者ID:QaleQ,项目名称:racemod,代码行数:52,代码来源:cg_lents.cpp

示例12: CG_CalcViewBob

/*
* CG_CalcViewBob
*/
static void CG_CalcViewBob( void )
{
	float bobMove, bobTime, bobScale;

	if( !cg.view.drawWeapon )
		return;

	// calculate speed and cycle to be used for all cyclic walking effects
	cg.xyspeed = sqrt( cg.predictedPlayerState.pmove.velocity[0]*cg.predictedPlayerState.pmove.velocity[0] + cg.predictedPlayerState.pmove.velocity[1]*cg.predictedPlayerState.pmove.velocity[1] );

	bobScale = 0;
	if( cg.xyspeed < 5 )
		cg.oldBobTime = 0;  // start at beginning of cycle again
	else if( cg_gunbob->integer )
	{
		if( !ISVIEWERENTITY( cg.view.POVent ) )
			bobScale = 0.0f;
		else if( CG_PointContents( cg.view.origin ) & MASK_WATER )
			bobScale =  0.75f;
		else
		{
			centity_t *cent;
			vec3_t mins, maxs;
			trace_t	trace;

			cent = &cg_entities[cg.view.POVent];
			GS_BBoxForEntityState( &cent->current, mins, maxs );
			maxs[2] = mins[2];
			mins[2] -= ( 1.6f*STEPSIZE );

			CG_Trace( &trace, cg.predictedPlayerState.pmove.origin, mins, maxs, cg.predictedPlayerState.pmove.origin, cg.view.POVent, MASK_PLAYERSOLID );
			if( trace.startsolid || trace.allsolid )
			{
				if( cg.predictedPlayerState.pmove.stats[PM_STAT_CROUCHTIME] )
					bobScale = 1.5f;
				else
					bobScale = 2.5f;
			}
		}
	}

	bobMove = cg.frameTime * bobScale;
	bobTime = ( cg.oldBobTime += bobMove );

	cg.bobCycle = (int)bobTime;
	cg.bobFracSin = fabs( sin( bobTime*M_PI ) );
}
开发者ID:MaryJaneInChain,项目名称:qfusion,代码行数:50,代码来源:cg_view.cpp

示例13: Player_GetUnderwater

	static int Player_GetUnderwater( lua_State *L, jpluaEntity_t *ent ) {
		qboolean underwater = qfalse;
	#if defined(PROJECT_GAME)
		if ( ent->waterlevel == 3 ) {
			underwater = qtrue;
		}
	#elif defined(PROJECT_CGAME)
		const vector3 *pos = ((int)(ent - ents) == cg.clientNum)
			? &cg.predictedPlayerState.origin
			: &ent->currentState.pos.trBase; // not cent->lerpOrigin?
		if ( CG_PointContents( pos, -1 ) & (CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA) ) {
			underwater = qtrue;
		}
	#endif
		lua_pushboolean( L, underwater );
		return 1;
	}
开发者ID:Mauii,项目名称:japp,代码行数:17,代码来源:bg_luaplayer.cpp

示例14: CG_LeadBubbleTrail

/*
* CG_LeadBubbleTrail
*/
static void CG_LeadBubbleTrail( trace_t *tr, vec3_t water_start )
{
	// if went through water, determine where the end and make a bubble trail
	vec3_t dir, pos;

	VectorSubtract( tr->endpos, water_start, dir );
	VectorNormalize( dir );
	VectorMA( tr->endpos, -2, dir, pos );

	if( CG_PointContents( pos ) & MASK_WATER )
		VectorCopy( pos, tr->endpos );
	else
		CG_Trace( tr, pos, vec3_origin, vec3_origin, water_start, tr->ent ? cg_entities[tr->ent].current.number : 0, MASK_WATER );

	VectorAdd( water_start, tr->endpos, pos );
	VectorScale( pos, 0.5, pos );

	CG_BubbleTrail( water_start, tr->endpos, 32 );
}
开发者ID:hettoo,项目名称:racesow,代码行数:22,代码来源:cg_events.c

示例15: CG_BubbleThink

/*
=======================================================================================================================================
CG_BubbleThink
=======================================================================================================================================
*/
void CG_BubbleThink(localEntity_t *le) {
	int contents;
	vec3_t newOrigin;
	trace_t trace;

	// calculate new position
	BG_EvaluateTrajectory(&le->pos, cg.time, newOrigin);
	// trace a line from previous position to new position
	CG_Trace(&trace, le->refEntity.origin, NULL, NULL, newOrigin, -1, CONTENTS_SOLID);

	contents = CG_PointContents(trace.endpos, -1);

	if (!(contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA))) {
		// bubble isn't in liquid anymore, remove it
		CG_FreeLocalEntity(le);
		return;
	}

	CG_AddMoveScaleFade(le);
}
开发者ID:KuehnhammerTobias,项目名称:ioqw,代码行数:25,代码来源:cg_localents.c


注:本文中的CG_PointContents函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。