/** * \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; }
/* ----------------------------------------------------------------------------- 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; }
/** * \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; }
/* ----------------------------------------------------------------------------- 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 }
/** * 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; }
/** * 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; }
/* ----------------------------------------------------------------------------- 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; }
/** * \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 }
/** * 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; }
/* ----------------------------------------------------------------------------- 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 ); }
/* ----------------------------------------------------------------------------- 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 ); }