예제 #1
0
/**
 * \brief Try to move push-wall.
 * \param[in] x coordinates in tile map.
 * \param[in] y coordinates in tile map.
 * \param[in] dir Direction in which push-wall is intended to move.
 * \return Returns true if push successful, otherwise false.
 * \note Called whenever someone tries to push a secret wall.
 */
PUBLIC _boolean PushWall_Push( int x, int y, dir4type dir )
{
	int dx, dy;


	if( PWall.active )
	{
		return false; // another PWall is moving [only one at a time!]
	}

	dx = dx4dir[ dir ];
	dy = dy4dir[ dir ];


	if( r_world->tilemap[ x + dx ][ y + dy ] & (SOLID_TILE | DOOR_TILE) )
	{ // noway (smth is blocking)
		return true;
	}

// remove secret flag & make everything needed when pushwall used!
	r_world->tilemap[ x ][ y ] &= (~SECRET_TILE);
	r_world->tilemap[ x ][ y ] &= (~WALL_TILE);
	r_world->tilemap[ x ][ y ] |= PUSHWALL_TILE;

	Com_Printf( "You have found a secret!\n" );

	levelstate.found_secrets++;

	if( g_version->value == SPEAROFDESTINY )
	{
		Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/030.wav" ), 1, ATTN_STATIC, 0 );
	}
	else
	{
		Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/034.wav" ), 1, ATTN_STATIC, 0 );
	}

// good way to avoid stuckness; [un]comment one more down!
// it makes a tile behind pushwall unpassable

	r_world->tilemap[ x + dx ][ y + dy ] |= PUSHWALL_TILE;
	r_world->wall_tex_x[ x + dx ][ y + dy ] = r_world->wall_tex_x[ x ][ y ];
	r_world->wall_tex_y[ x + dx ][ y + dy ] = r_world->wall_tex_y[ x ][ y ];

// write down PWall info
	PWall.active = true;
	PWall.PWtilesmoved = PWall.PWpointsmoved = 0;
	PWall.dir = dir;
	PWall.x = x; PWall.y = y;
	PWall.dx = dx; PWall.dy = dy;

	PWall.tex_x = r_world->wall_tex_x[ x ][ y ];
	PWall.tex_y = r_world->wall_tex_y[ x ][ y ];


	return true;
}
예제 #2
0
/*
-----------------------------------------------------------------------------
 Function: PushWall_Push() -Try to move push-wall. 
 
 Parameters: x, y -[in] Coordinates in tilemap.
			 dir -[in] Direction in which push-wall is intended to move.
 
 Returns: true if push successful, otherwise false.
 
 Notes: Called whenever someone tries to push a secret wall.

-----------------------------------------------------------------------------
*/
PUBLIC _boolean PushWall_Push( int x, int y, dir4type dir )
{
	int dx, dy;


	if( PWall.active ) 
	{
		return false; // another PWall is moving [only one at a time!]
	}

	dx = dx4dir[ dir ];
	dy = dy4dir[ dir ];

	if( r_world->tilemap[ x + dx ][ y + dy ] & (SOLID_TILE | DOOR_TILE) )
	{ // noway (smth is blocking)
		return true;
	}
	
// remove secret flag & make everything needed when pushwall used!
	r_world->tilemap[ x ][ y ] &= (~SECRET_TILE);
	r_world->tilemap[ x ][ y ] &= (~WALL_TILE);
	r_world->tilemap[ x ][ y ] |= PUSHWALL_TILE;
	
	if ( ++levelstate.found_secrets == levelstate.total_secrets ) {
		iphoneSetNotifyText( "You found the last secret!" );
	} else {
		iphoneSetNotifyText( "You found a secret!" );
	}

	if( g_version->value == SPEAROFDESTINY && currentMap.episode >= 6 && currentMap.episode < 9)//added the episode check... gsh ).. TODO: fix sfx and other media
	{
		Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/030.wav" ), 1, ATTN_STATIC, 0 );
	}
	else
	{
		Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/034.wav" ), 1, ATTN_STATIC, 0 );
	}

// good way to avoid stuckness; [un]comment one more down!
// it makes a tile behind pushwall unpassable
	r_world->tilemap[ x + dx ][ y + dy ] |= PUSHWALL_TILE;
	r_world->wall_tex_x[ x + dx ][ y + dy ] = r_world->wall_tex_x[ x ][ y ];
	r_world->wall_tex_y[ x + dx ][ y + dy ] = r_world->wall_tex_y[ x ][ y ];

// write down PWall info
	PWall.active = true;
	PWall.PWtilesmoved = PWall.PWpointsmoved = 0;
	PWall.dir = dir;
	PWall.x = x; PWall.y = y;
	PWall.dx = dx; PWall.dy = dy;
	PWall.tex_x = r_world->wall_tex_x[ x ][ y ];
	PWall.tex_y = r_world->wall_tex_y[ x ][ y ];

	return true;
}
예제 #3
0
/**
 * \brief Called when a player pressed the USE button
 * \param[in] self Player
 * \param[in] lvl Level data structure
 * \return true if player used something, otherwise false
 */
PRIVATE _boolean PL_Use( player_t *self, LevelData_t *lvl )
{
	int x, y, dir;

    dir = Get4dir( self->position.angle );
	x = self->tilex + dx4dir[ dir ];
	y = self->tiley + dy4dir[ dir ];

	if( lvl->tilemap[ x ][ y ] & DOOR_TILE )
	{
        Door_Use( &lvl->Doors.DoorMap[ x ][ y ], Player.items );
		return true;
	}

	if( lvl->tilemap[ x ][ y ] & SECRET_TILE )
	{
		return PushWall_Push( x, y, dir );
	}

	if( lvl->tilemap[ x ][ y ] & ELEVATOR_TILE )
	{
		int newtex;

		switch( dir )
		{
			case dir4_east:
			case dir4_west:
				newtex = lvl->wall_tex_x[ x ][ y ] += 2;
				break;

			case dir4_north:
			case dir4_south:
				return false; // don't allow to press elevator rails
		}

		if( lvl->tilemap[ self->tilex ][ self->tiley ] & SECRETLEVEL_TILE )
		{
			self->playstate = ex_secretlevel;
            elevatorSwitchTime = ClientStatic.realtime;
		}
		else
		{
			self->playstate = ex_complete;
            elevatorSwitchTime = ClientStatic.realtime;
		}
		Sound_StartSound( NULL, 0, CHAN_BODY, Sound_RegisterSound( "lsfx/040.wav" ), 1, ATTN_NORM, 0 );

		return true;
	}

	//Sound_StartSound( NULL, 0, CHAN_BODY, Sound_RegisterSound( "lsfx/020.wav" ), 1, ATTN_NORM, 0 );
	return false;
}
예제 #4
0
/*
-----------------------------------------------------------------------------
 Function: 
 
 Parameters:
 
 Returns:
 
 Notes: 

-----------------------------------------------------------------------------
*/
PUBLIC void fire_hit( player_t *self )
{
	entity_t *closest;
	int dist, d1, n, shot_dist, damage;

	Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "lsfx/023.wav" ), 1, ATTN_NORM, 0 );

// actually fire
	dist = 0x7fffffff;
	closest = NULL;

	for( n = 0 ; n < NumGuards ; ++n )
	{
		if( Guards[ n ].flags & FL_SHOOTABLE ) // && Guards[n].flags&FL_VISABLE
		{
			shot_dist = Point2LineDist( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
			
			if( shot_dist > (2 * TILEGLOBAL / 3) ) 
			{
				continue; // miss
			}
			
			d1 = LineLen2Point( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
			
			if( d1 < 0 || d1 > dist ) 
			{
				continue;
			}
			
			if( ! Level_CheckLine( Guards[ n ].x, Guards[ n ].y, Player.position.origin[0], Player.position.origin[1], r_world ) )
			{
			//if( ! CheckLine( &Guards[ n ] ) ) 
				continue; // obscured
			}

			dist = d1;
			closest = &Guards[ n ];
		}
	}

	if( ! closest || dist > TILE2POS( 1 ) ) 
	{
		return; // missed if further than 1.5 tiles
	}

	damage = US_RndT() >> 4;

	A_DamageActor( closest, damage ); // hit something
}
예제 #5
0
파일: sound.c 프로젝트: damajor/play-dune
/**
 * Start speech.
 * Start a new speech fragment if possible.
 * @return Sound is produced.
 */
bool Sound_StartSpeech()
{
    if (g_gameConfig.sounds == 0) return false;

    if (Driver_Voice_IsPlaying()) return true;

    s_variable_4060 = 0;

    if (s_spokenWords[0] == 0xFFFF) return false;

    Sound_StartSound(s_spokenWords[0]);
    /* Move speech parts one place. */
    memmove(&s_spokenWords[0], &s_spokenWords[1], sizeof(s_spokenWords) - sizeof(s_spokenWords[0]));
    s_spokenWords[lengthof(s_spokenWords) - 1] = 0xFFFF;

    return true;
}
예제 #6
0
/**
 * Handles Click event for unit commands button.
 *
 * @param w The widget.
 * @return True, always.
 */
bool GUI_Widget_TextButton_Click(Widget *w)
{
	const UnitInfo *ui;
	const ActionInfo *ai;
	const uint16 *actions;
	ActionType action;
	Unit *u;
	uint16 *found;
	ActionType unitAction;

	u = g_unitSelected;
	ui = &g_table_unitInfo[u->o.type];

	actions = ui->o.actionsPlayer;
	if (Unit_GetHouseID(u) != g_playerHouseID && u->o.type != UNIT_HARVESTER) {
		actions = g_table_actionsAI;
	}

	action = actions[w->index - 8];

	unitAction = u->nextActionID;
	if (unitAction == ACTION_INVALID) {
		unitAction = u->actionID;
	}

	if (u->deviated != 0) {
		Unit_Deviation_Decrease(u, 5);
		if (u->deviated == 0) {
			GUI_Widget_MakeNormal(w, false);
			return true;
		}
	}

	GUI_Widget_MakeSelected(w, false);

	ai = &g_table_actionInfo[action];

	if (ai->selectionType != g_selectionType) {
		g_unitActive = g_unitSelected;
		g_activeAction = action;
		GUI_ChangeSelectionType(ai->selectionType);

		return true;
	}

	Object_Script_Variable4_Clear(&u->o);
	u->targetAttack = 0;
	u->targetMove = 0;
	u->route[0] = 0xFF;

	Unit_SetAction(u, action);

	if (ui->movementType == MOVEMENT_FOOT) Sound_StartSound(ai->soundID);

	if (unitAction == action) return true;

	found = memchr(actions, unitAction, 4);
	if (found == NULL) return true;

	GUI_Widget_MakeNormal(GUI_Widget_Get_ByIndex(g_widgetLinkedListHead, found - actions + 8), false);

	return true;
}
예제 #7
0
/*
-----------------------------------------------------------------------------
 Function: 
 
 Parameters:
 
 Returns: 1 if powerup is picked up, otherwise 0.
 
 Notes: 

-----------------------------------------------------------------------------
*/
PRIVATE int Pow_Give( pow_t type )
{
	static const char *keynames[] = { "Gold", "Silver", "?", "?" };

	switch( type )
	{
//
// Keys
//
		case pow_key1:
		case pow_key2:
		case pow_key3:
		case pow_key4:
			type -= pow_key1;
			PL_GiveKey( &Player, type );
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/012.wav" ), 1, ATTN_NORM, 0 );
			iphoneSetNotifyText( "%s key\n", keynames[ type ] );
			break;
//
// Treasure
//
		case pow_cross:
			PL_GiveHealth( &Player, 1, 150 );	// iphone -- trasure acts as health crumbs
			PL_GivePoints( &Player, 100 );
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/035.wav" ), 1, ATTN_NORM, 0 );
			if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
				iphoneSetNotifyText( "You found the last treasure!" );
			}
			break;

		case pow_chalice:
			PL_GiveHealth( &Player, 1, 150 );	// iphone -- trasure acts as health crumbs
			PL_GivePoints( &Player, 500 );
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/036.wav" ), 1, ATTN_NORM, 0 );
			if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
				iphoneSetNotifyText( "You found the last treasure!" );
			}
			break;

		case pow_bible:
			PL_GiveHealth( &Player, 1, 150 );	// iphone -- trasure acts as health crumbs
			PL_GivePoints( &Player, 1000 );
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/037.wav" ), 1, ATTN_NORM, 0 );
			if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
				iphoneSetNotifyText( "You found the last treasure!" );
			}
			break;

		case pow_crown:
			PL_GiveHealth( &Player, 1, 150 );	// iphone -- trasure acts as health crumbs
			PL_GivePoints( &Player, 5000 );
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/045.wav" ), 1, ATTN_NORM, 0 );
			if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
				iphoneSetNotifyText( "You found the last treasure!" );
			}
			break;

//
// Health
//
		case pow_gibs:
			if( ! PL_GiveHealth( &Player, 1, 11 ) )
			{
				return 0;
			}
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/061.wav" ), 1, ATTN_NORM, 0 );
			break;

		case pow_alpo:
			if( ! PL_GiveHealth( &Player, 4, 0 ) )
			{
				return 0;
			}
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/033.wav" ), 1, ATTN_NORM, 0 );
			break;

		case pow_food:
			if( ! PL_GiveHealth( &Player, 10, 0 ) ) 
			{
				return 0;
			}
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/033.wav" ), 1, ATTN_NORM, 0 );
			break;

		case pow_firstaid:
			if( ! PL_GiveHealth( &Player, 25, 0 ) )
			{
				return 0;
			}
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/034.wav" ), 1, ATTN_NORM, 0 );
			break;

//
// Weapon & Ammo
//
		case pow_clip:
			if( ! PL_GiveAmmo( &Player, AMMO_BULLETS, 8 ) ) 
			{
				return 0;
			}
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/031.wav" ), 1, ATTN_NORM, 0 );
			break;

		case pow_clip2:
			if( ! PL_GiveAmmo( &Player, AMMO_BULLETS, 4 ) ) 
			{
				return 0;
			}
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/031.wav" ), 1, ATTN_NORM, 0 );
			break;

		case pow_25clip:
			if( ! PL_GiveAmmo( &Player, AMMO_BULLETS, 25 ) ) 
			{
				return 0;
			}
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/064.wav" ), 1, ATTN_NORM, 0 );
			break;

		case pow_machinegun:
			PL_GiveWeapon( &Player, WEAPON_AUTO );
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/030.wav" ), 1, ATTN_NORM, 0 );
			iphoneSetNotifyText( "Machinegun" );
			break;

		case pow_chaingun:
			PL_GiveWeapon( &Player, WEAPON_CHAIN );
			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/038.wav" ), 1, ATTN_NORM, 0 );
			iphoneSetNotifyText( "Chaingun" );

			Player.facecount = -100;
			Player.face_gotgun = true;
			break;

//
// Artifacts
//
		case pow_fullheal:
			PL_GiveHealth( &Player, 999, 0 );
			PL_GiveAmmo( &Player, AMMO_BULLETS, 25 );
			PL_GiveLife( &Player );
			if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
				iphoneSetNotifyText( "You found the last treasure!" );
			} else {
				iphoneSetNotifyText( "Full Heal" );
			}
			// no extra lives on iPhone			Com_Printf( "Extra life!\n" );
			break;

		case pow_spear:
			{
			char szTextMsg[ 256 ];

			Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "sodsfx/109.wav" ), 1, ATTN_NORM, 0 );
			iphoneSetNotifyText( "Spear of Destiny" );

			my_snprintf( szTextMsg, sizeof( szTextMsg ), 
				"loading ; map s%.2d.map\n", 20 );
			Cbuf_AddText( szTextMsg );
			}
			break;

		default:
			Com_DPrintf( "Warning: Unknown item type: %d\n", type );
			break;
	}

	iphoneStartBonusFlash();
	
	return 1;
}
예제 #8
0
/**
 * \brief Doors to process
 * \param[in] lvldoors Doors to process
 * \param[in] t_tk Clock tics
 */
PUBLIC void Door_Process( LevelDoors_t *lvldoors, int t_tk )
{
	int n;

	for( n = 0 ; n < lvldoors->doornum ; ++n )
	{
		switch( lvldoors->Doors[ n ]->action )
		{
			case dr_closed: // this door is closed!
				continue;

			case dr_opening:
				if( lvldoors->Doors[ n ]->ticcount >= DOOR_FULLOPEN ) // door fully opened!
				{
					lvldoors->Doors[ n ]->action = dr_open;
					lvldoors->Doors[ n ]->ticcount = 0;
				}
				else // opening!
				{
					if( lvldoors->Doors[ n ]->ticcount == 0 )
					{ // door is just starting to open, so connect the areas
						Areas_Join( lvldoors->Doors[ n ]->area1, lvldoors->Doors[ n ]->area2 );
						Areas_Connect( Player.areanumber );
						if( areabyplayer[ lvldoors->Doors[ n ]->area1 ] ) // Door Opening sound!
						{
							Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/010.wav" ), 1, ATTN_STATIC, 0 );
						}
					}

					lvldoors->Doors[n]->ticcount += t_tk;

					if( lvldoors->Doors[ n ]->ticcount > DOOR_FULLOPEN )
					{
						lvldoors->Doors[ n ]->ticcount = DOOR_FULLOPEN;
					}
				}
				break;

			case dr_closing:
				if( lvldoors->Doors[ n ]->ticcount <= 0 ) // door fully closed! disconnect areas!
				{
					Areas_Disconnect( lvldoors->Doors[ n ]->area1, lvldoors->Doors[ n ]->area2 );
					Areas_Connect( Player.areanumber );
					lvldoors->Doors[ n ]->ticcount = 0;
					lvldoors->Doors[ n ]->action = dr_closed;
				}
				else // closing!
				{
					if( lvldoors->Doors[ n ]->ticcount == DOOR_FULLOPEN )
					{
						if( areabyplayer[ lvldoors->Doors[ n ]->area1 ] ) // Door Closing sound!
						{
							Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/007.wav" ), 1, ATTN_STATIC, 0 );
						}
					}
					lvldoors->Doors[ n ]->ticcount -= t_tk;
					if( lvldoors->Doors[ n ]->ticcount < 0 )
					{
						lvldoors->Doors[ n ]->ticcount = 0;
					}
				}
				break;

			case dr_open:
				if( lvldoors->Doors[ n ]->ticcount > DOOR_MINOPEN )
				{ // If player or something is in door do not close it!
					if( ! CanCloseDoor( lvldoors->Doors[ n ]->tilex, lvldoors->Doors[ n ]->tiley, lvldoors->Doors[ n ]->vertical ) )
					{
						lvldoors->Doors[ n ]->ticcount = DOOR_MINOPEN; // do not close door immediately!
					}
				}
				if( lvldoors->Doors[ n ]->ticcount >= DOOR_TIMEOUT )
				{ // Door timeout, time to close it!
					lvldoors->Doors[ n ]->action = dr_closing;
					lvldoors->Doors[ n ]->ticcount = DOOR_FULLOPEN;
				}
				else
				{ // Increase timeout!
					lvldoors->Doors[ n ]->ticcount += t_tk;
				}
				break;

		} // End switch lvldoors->Doors[ n ].action

	} // End for n = 0 ; n < lvldoors->doornum ; ++n

}
예제 #9
0
파일: viewport.c 프로젝트: 166MMX/OpenDUNE
/**
 * Handles the Click events for the Viewport widget.
 *
 * @param w The widget.
 */
bool GUI_Widget_Viewport_Click(Widget *w)
{
	uint16 direction;
	uint16 x, y;
	uint16 spriteID;
	uint16 packed;
	bool click, drag;

	spriteID = g_cursorSpriteID;
	switch (w->index) {
		default: break;
		case 39: spriteID = 1; break;
		case 40: spriteID = 2; break;
		case 41: spriteID = 4; break;
		case 42: spriteID = 3; break;
		case 43: spriteID = g_cursorDefaultSpriteID; break;
		case 44: spriteID = g_cursorDefaultSpriteID; break;
		case 45: spriteID = 0; break;
	}

	if (spriteID != g_cursorSpriteID) {
		/* HotSpots for different cursor types. */
		static const XYPosition cursorHotSpots[6] = {{0, 0}, {5, 0}, {8, 5}, {5, 8}, {0, 5}, {8, 8}};

		s_tickCursor = g_timerGame;

		Sprites_SetMouseSprite(cursorHotSpots[spriteID].x, cursorHotSpots[spriteID].y, g_sprites[spriteID]);

		g_cursorSpriteID = spriteID;
	}

	if (w->index == 45) return true;

	click = false;
	drag = false;

	if ((w->state.buttonState & 0x11) != 0) {
		click = true;
		g_var_37B8 = false;
	} else if ((w->state.buttonState & 0x22) != 0 && !g_var_37B8) {
		drag = true;
	}

	/* ENHANCEMENT -- Dune2 depends on slow CPUs to limit the rate mouse clicks are handled. */
	if (g_dune2_enhanced && (click || drag)) {
		if (s_tickClick + 2 >= g_timerGame) return true;
		s_tickClick = g_timerGame;
	}

	direction = 0xFFFF;
	switch (w->index) {
		default: break;
		case 39: direction = 0; break;
		case 40: direction = 2; break;
		case 41: direction = 6; break;
		case 42: direction = 4; break;
	}

	if (direction != 0xFFFF) {
		/* Always scroll if we have a click or a drag */
		if (!click && !drag) {
			/* Wait for either one of the timers */
			if (s_tickMapScroll + 10 >= g_timerGame || s_tickCursor + 20 >= g_timerGame) return true;
			/* Don't scroll if we have a structure/unit selected and don't want to autoscroll */
			if (g_gameConfig.autoScroll == 0 && (g_selectionType == SELECTIONTYPE_STRUCTURE || g_selectionType == SELECTIONTYPE_UNIT)) return true;
		}

		s_tickMapScroll = g_timerGame;

		Map_MoveDirection(direction);
		return true;
	}

	if (click) {
		x = g_mouseClickX;
		y = g_mouseClickY;
	} else {
		x = g_mouseX;
		y = g_mouseY;
	}

	if (w->index == 43) {
		x =  x / 16 + Tile_GetPackedX(g_minimapPosition);
		y = (y - 40) / 16 + Tile_GetPackedY(g_minimapPosition);
	} else if (w->index == 44) {
		uint16 mapScale;
		const MapInfo *mapInfo;

		mapScale = g_scenario.mapScale;
		mapInfo = &g_mapInfos[mapScale];

		x = min((max(x, 256) - 256) / (mapScale + 1), mapInfo->sizeX - 1) + mapInfo->minX;
		y = min((max(y, 136) - 136) / (mapScale + 1), mapInfo->sizeY - 1) + mapInfo->minY;
	}

	packed = Tile_PackXY(x, y);

	if (click && g_selectionType == SELECTIONTYPE_TARGET) {
		Unit *u;
		ActionType action;
		uint16 encoded;

		GUI_DisplayText(NULL, -1);

		if (g_unitHouseMissile != NULL) {
			Unit_LaunchHouseMissile(packed);
			return true;
		}

		u = g_unitActive;

		action = g_activeAction;

		Object_Script_Variable4_Clear(&u->o);
		u->targetAttack   = 0;
		u->targetMove     = 0;
		u->route[0] = 0xFF;

		if (action != ACTION_MOVE && action != ACTION_HARVEST) {
			encoded = Tools_Index_Encode(Unit_FindTargetAround(packed), IT_TILE);
		} else {
			encoded = Tools_Index_Encode(packed, IT_TILE);
		}

		Unit_SetAction(u, action);

		if (action == ACTION_MOVE) {
			Unit_SetDestination(u, encoded);
		} else if (action == ACTION_HARVEST) {
			u->targetMove = encoded;
		} else {
			Unit *target;

			Unit_SetTarget(u, encoded);
			target = Tools_Index_GetUnit(u->targetAttack);
			if (target != NULL) target->blinkCounter = 8;
		}

		if (g_enableVoices == 0) {
			Driver_Sound_Play(36, 0xFF);
		} else if (g_table_unitInfo[u->o.type].movementType == MOVEMENT_FOOT) {
			Sound_StartSound(g_table_actionInfo[action].soundID);
		} else {
			Sound_StartSound(((Tools_Random_256() & 0x1) == 0) ? 20 : 17);
		}

		g_unitActive   = NULL;
		g_activeAction = 0xFFFF;

		GUI_ChangeSelectionType(SELECTIONTYPE_UNIT);
		return true;
	}

	if (click && g_selectionType == SELECTIONTYPE_PLACE) {
		const StructureInfo *si;
		Structure *s;
		House *h;

		s = g_structureActive;
		si = &g_table_structureInfo[g_structureActiveType];
		h = g_playerHouse;

		if (Structure_Place(s, g_selectionPosition)) {
			Voice_Play(20);

			if (s->o.type == STRUCTURE_PALACE) House_Get_ByIndex(s->o.houseID)->palacePosition = s->o.position;

			if (g_structureActiveType == STRUCTURE_REFINERY && g_validateStrictIfZero == 0) {
				Unit *u;

				g_validateStrictIfZero++;
				u = Unit_CreateWrapper(g_playerHouseID, UNIT_HARVESTER, Tools_Index_Encode(s->o.index, IT_STRUCTURE));
				g_validateStrictIfZero--;

				if (u == NULL) {
					h->harvestersIncoming++;
				} else {
					u->originEncoded = Tools_Index_Encode(s->o.index, IT_STRUCTURE);
				}
			}

			GUI_ChangeSelectionType(SELECTIONTYPE_STRUCTURE);

			s = Structure_Get_ByPackedTile(g_structureActivePosition);
			if (s != NULL) {
				if ((Structure_GetBuildable(s) & (1 << s->objectType)) == 0) Structure_BuildObject(s, 0xFFFE);
			}

			g_structureActiveType = 0xFFFF;
			g_structureActive     = NULL;
			g_selectionState      = 0; /* Invalid. */

			GUI_DisplayHint(si->o.hintStringID, si->o.spriteID);

			House_UpdateRadarState(h);

			if (h->powerProduction < h->powerUsage) {
				if ((h->structuresBuilt & (1 << STRUCTURE_OUTPOST)) != 0) {
					GUI_DisplayText(String_Get_ByIndex(STR_NOT_ENOUGH_POWER_FOR_RADAR_BUILD_WINDTRAPS), 3);
				}
			}
			return true;
		}

		Voice_Play(47);

		if (g_structureActiveType == STRUCTURE_SLAB_1x1 || g_structureActiveType == STRUCTURE_SLAB_2x2) {
			GUI_DisplayText(String_Get_ByIndex(STR_CAN_NOT_PLACE_FOUNDATION_HERE), 2);
		} else {
			GUI_DisplayHint(STR_STRUCTURES_MUST_BE_PLACED_ON_CLEAR_ROCK_OR_CONCRETE_AND_ADJACENT_TO_ANOTHER_FRIENDLY_STRUCTURE, 0xFFFF);
			GUI_DisplayText(String_Get_ByIndex(STR_CAN_NOT_PLACE_S_HERE), 2, String_Get_ByIndex(si->o.stringID_abbrev));
		}
		return true;
	}

	if (click && w->index == 43) {
		uint16 position;

		if (g_debugScenario) {
			position = packed;
		} else {
			position = Unit_FindTargetAround(packed);
		}

		if (g_map[position].overlaySpriteID != g_veiledSpriteID || g_debugScenario) {
			if (Object_GetByPackedTile(position) != NULL || g_debugScenario) {
				Map_SetSelection(position);
				Unit_DisplayStatusText(g_unitSelected);
			}
		}

		if ((w->state.buttonState & 0x10) != 0) Map_SetViewportPosition(packed);

		return true;
	}

	if ((click || drag) && w->index == 44) {
		Map_SetViewportPosition(packed);
		return true;
	}

	if (g_selectionType == SELECTIONTYPE_TARGET) {
		Map_SetSelection(Unit_FindTargetAround(packed));
	} else if (g_selectionType == SELECTIONTYPE_PLACE) {
		Map_SetSelection(packed);
	}

	return true;
}
예제 #10
0
/*
-----------------------------------------------------------------------------
 Function: 
 
 Parameters:
 
 Returns:
 
 Notes: 

-----------------------------------------------------------------------------
*/
PUBLIC void fire_lead( player_t *self )
{
	entity_t *closest;
	int damage;
	int dx, dy, dist;
	int d1, shot_dist, n;

	switch( self->weapon )
	{
		case WEAPON_PISTOL:
			Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/012.wav" ), 1, ATTN_NORM, 0 );
			break;

		case WEAPON_AUTO:
			Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/011.wav" ), 1, ATTN_NORM, 0 );
			break;

		case WEAPON_CHAIN:
			Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/013.wav" ), 1, ATTN_NORM, 0 );
			break;
	}
	self->madenoise = true;

	dist = 0x7fffffffl;
	closest = NULL;

	for( n = 0 ; n < NumGuards; ++n )
	{
		if( Guards[ n ].flags & FL_SHOOTABLE ) // && Guards[n].flags&FL_VISABLE
		{
			shot_dist = Point2LineDist( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );			
			if( shot_dist > (2 * TILEGLOBAL / 3) )
			{
				continue; // miss
			}

			d1 = LineLen2Point( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
			if( d1 < 0 || d1 > dist )
			{
				continue;
			}
			
			if( ! Level_CheckLine( Guards[ n ].x, Guards[ n ].y, Player.position.origin[0], Player.position.origin[1], r_world ) )
			{
			//if( ! CheckLine( &Guards[ n ] ) )
				continue; // obscured
			}

			dist = d1;
			closest = &Guards[ n ];
		}
	}

	if( ! closest ) // missed
	{
		r_trace_t trace;

		trace.a = NormalizeAngle( self->position.angle - DEG2FINE( 2 ) + rand() % (DEG2FINE( 4 ) ) );
		trace.x = self->position.origin[ 0 ];
		trace.y = self->position.origin[ 1 ];
		trace.flags = TRACE_BULLET;
		trace.tile_vis = NULL;
		R_Trace( &trace, r_world );

		if( trace.flags & TRACE_HIT_DOOR )
		{
			Sound_StartSound( NULL, 0, CHAN_AUTO, Sound_RegisterSound( "lsfx/028.wav" ), 1, ATTN_NORM, 0 );
		}
		return;
	}

// hit something
	dx = ABS( closest->tilex - self->tilex );
	dy = ABS( closest->tiley - self->tiley );
	dist = max_of_2( dx, dy );

	if( dist < 2 )
	{
		damage = US_RndT() / 4;
	}
	else if( dist < 4 )
	{
		damage = US_RndT() / 6;
	}
	else
	{
		if( US_RndT() / 12 < dist ) 
		{
			return; // missed
		}

		damage = US_RndT() / 6;
	}

	A_DamageActor( closest, damage );
}
예제 #11
0
파일: wolf_bj.c 프로젝트: Anters/Wolf3D-iOS
/*
-----------------------------------------------------------------------------
 Function: 
 
 Parameters:
 
 Returns:
 
 Notes: 

-----------------------------------------------------------------------------
*/
void T_BJYell( entity_t *Guard )
{
	Sound_StartSound( NULL, 0, CHAN_VOICE, Sound_RegisterSound( "sfx/082.wav" ), 1, ATTN_NORM, 0 );
}