2006-03-20 16:43:15 +00:00
/*
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ( " PARALLAX " ) . PARALLAX , IN DISTRIBUTING THE CODE TO
END - USERS , AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN , GRANTS A
ROYALTY - FREE , PERPETUAL LICENSE TO SUCH END - USERS FOR USE BY SUCH END - USERS
IN USING , DISPLAYING , AND CREATING DERIVATIVE WORKS THEREOF , SO LONG AS
SUCH USE , DISPLAY OR CREATION IS FOR NON - COMMERCIAL , ROYALTY OR REVENUE
FREE PURPOSES . IN NO EVENT SHALL THE END - USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE - BEARING PURPOSES . THE END - USER UNDERSTANDS
2010-07-27 11:41:43 +00:00
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE .
2006-03-20 16:43:15 +00:00
COPYRIGHT 1993 - 1998 PARALLAX SOFTWARE CORPORATION . ALL RIGHTS RESERVED .
*/
2008-04-06 20:23:28 +00:00
2006-03-20 16:43:15 +00:00
/*
*
2008-04-06 20:23:28 +00:00
* New Triggers and Switches .
2006-03-20 16:43:15 +00:00
*
*/
# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# include <string.h>
# include "gauges.h"
# include "game.h"
# include "switch.h"
# include "inferno.h"
# include "segment.h"
2012-07-07 18:35:06 +00:00
# include "dxxerror.h"
2006-03-20 16:43:15 +00:00
# include "gameseg.h"
# include "wall.h"
# include "texmap.h"
# include "fuelcen.h"
2010-07-27 11:41:43 +00:00
# include "cntrlcen.h"
2006-03-20 16:43:15 +00:00
# include "newdemo.h"
# include "player.h"
# include "endlevel.h"
# include "gameseq.h"
# include "multi.h"
# include "palette.h"
2009-10-05 02:51:37 +00:00
# include "byteswap.h"
2006-03-20 16:43:15 +00:00
2010-07-27 11:41:43 +00:00
# ifdef EDITOR
# include "editor/editor.h"
# endif
2006-03-20 16:43:15 +00:00
trigger Triggers [ MAX_TRIGGERS ] ;
int Num_triggers ;
//link Links[MAX_WALL_LINKS];
//int Num_links;
# ifdef EDITOR
fix trigger_time_count = F1_0 ;
//-----------------------------------------------------------------
// Initializes all the switches.
void trigger_init ( )
{
int i ;
Num_triggers = 0 ;
// Num_links = 0;
for ( i = 0 ; i < MAX_TRIGGERS ; i + + )
{
Triggers [ i ] . type = 0 ;
Triggers [ i ] . flags = 0 ;
Triggers [ i ] . value = 0 ;
Triggers [ i ] . link_num = - 1 ;
Triggers [ i ] . time = - 1 ;
}
// for (i=0;i<MAX_WALL_LINKS;i++)
// Links[i].num_walls = 0;
}
# endif
//-----------------------------------------------------------------
// Executes a link, attached to a trigger.
// Toggles all walls linked to the switch.
// Opens doors, Blasts blast walls, turns off illusions.
2006-10-06 14:41:31 +00:00
void do_link ( sbyte trigger_num )
2006-03-20 16:43:15 +00:00
{
int i ;
if ( trigger_num ! = - 1 ) {
for ( i = 0 ; i < Triggers [ trigger_num ] . num_links ; i + + ) {
2013-02-21 00:20:26 +00:00
wall_toggle ( Triggers [ trigger_num ] . seg [ i ] , Triggers [ trigger_num ] . side [ i ] ) ;
2006-03-20 16:43:15 +00:00
}
}
}
2006-10-06 14:41:31 +00:00
void do_matcen ( sbyte trigger_num )
2006-03-20 16:43:15 +00:00
{
int i ;
if ( trigger_num ! = - 1 ) {
for ( i = 0 ; i < Triggers [ trigger_num ] . num_links ; i + + ) {
2013-02-21 00:20:26 +00:00
trigger_matcen ( Triggers [ trigger_num ] . seg [ i ] ) ;
2006-03-20 16:43:15 +00:00
}
}
}
2013-02-21 00:20:26 +00:00
2006-10-06 14:41:31 +00:00
void do_il_on ( sbyte trigger_num )
2006-03-20 16:43:15 +00:00
{
int i ;
if ( trigger_num ! = - 1 ) {
for ( i = 0 ; i < Triggers [ trigger_num ] . num_links ; i + + ) {
2013-02-21 00:20:26 +00:00
wall_illusion_on ( & Segments [ Triggers [ trigger_num ] . seg [ i ] ] , Triggers [ trigger_num ] . side [ i ] ) ;
2006-03-20 16:43:15 +00:00
}
}
}
2006-10-06 14:41:31 +00:00
void do_il_off ( sbyte trigger_num )
2006-03-20 16:43:15 +00:00
{
int i ;
2013-02-21 00:20:26 +00:00
2006-03-20 16:43:15 +00:00
if ( trigger_num ! = - 1 ) {
for ( i = 0 ; i < Triggers [ trigger_num ] . num_links ; i + + ) {
wall_illusion_off ( & Segments [ Triggers [ trigger_num ] . seg [ i ] ] , Triggers [ trigger_num ] . side [ i ] ) ;
}
}
}
int check_trigger_sub ( int trigger_num , int pnum )
{
2012-05-25 10:14:22 +00:00
if ( pnum < 0 | | pnum > MAX_PLAYERS )
return 1 ;
if ( ( Game_mode & GM_MULTI ) & & ( Players [ pnum ] . connected ! = CONNECT_PLAYING ) ) // as a host we may want to handle triggers for our clients. to do that properly we must check wether we (host) or client is actually playing.
return 1 ;
2006-03-20 16:43:15 +00:00
if ( pnum = = Player_num ) {
if ( Triggers [ trigger_num ] . flags & TRIGGER_SHIELD_DAMAGE ) {
Players [ Player_num ] . shields - = Triggers [ trigger_num ] . value ;
}
if ( Triggers [ trigger_num ] . flags & TRIGGER_EXIT ) {
start_endlevel_sequence ( ) ;
}
if ( Triggers [ trigger_num ] . flags & TRIGGER_SECRET_EXIT ) {
if ( Newdemo_state = = ND_STATE_RECORDING ) // stop demo recording
Newdemo_state = ND_STATE_PAUSED ;
2013-02-21 00:20:26 +00:00
# ifdef NETWORK
2006-03-20 16:43:15 +00:00
if ( Game_mode & GM_MULTI )
multi_send_endlevel_start ( 1 ) ;
2013-02-21 00:20:26 +00:00
# endif
2006-03-20 16:43:15 +00:00
# ifdef NETWORK
if ( Game_mode & GM_NETWORK )
2009-03-20 12:10:38 +00:00
multi_do_protocol_frame ( 1 , 1 ) ;
2006-03-20 16:43:15 +00:00
# endif
PlayerFinishedLevel ( 1 ) ; //1 means go to secret level
2011-06-27 16:17:04 +00:00
Control_center_destroyed = 0 ;
2006-03-20 16:43:15 +00:00
return 1 ;
}
if ( Triggers [ trigger_num ] . flags & TRIGGER_ENERGY_DRAIN ) {
Players [ Player_num ] . energy - = Triggers [ trigger_num ] . value ;
}
}
if ( Triggers [ trigger_num ] . flags & TRIGGER_CONTROL_DOORS ) {
do_link ( trigger_num ) ;
}
if ( Triggers [ trigger_num ] . flags & TRIGGER_MATCEN ) {
if ( ! ( Game_mode & GM_MULTI ) | | ( Game_mode & GM_MULTI_ROBOTS ) )
do_matcen ( trigger_num ) ;
}
if ( Triggers [ trigger_num ] . flags & TRIGGER_ILLUSION_ON ) {
do_il_on ( trigger_num ) ;
}
if ( Triggers [ trigger_num ] . flags & TRIGGER_ILLUSION_OFF ) {
do_il_off ( trigger_num ) ;
}
return 0 ;
}
//-----------------------------------------------------------------
// Checks for a trigger whenever an object hits a trigger side.
void check_trigger ( segment * seg , short side , short objnum )
{
int wall_num , trigger_num , ctrigger_num ;
segment * csegp ;
short cside ;
2012-05-25 10:14:22 +00:00
if ( ( Game_mode & GM_MULTI ) & & ( Players [ Player_num ] . connected ! = CONNECT_PLAYING ) ) // as a host we may want to handle triggers for our clients. so this function may be called when we are not playing.
return ;
2006-03-20 16:43:15 +00:00
if ( objnum = = Players [ Player_num ] . objnum ) {
// if ( Newdemo_state == ND_STATE_RECORDING )
// newdemo_record_trigger( seg-Segments, side, objnum );
if ( Newdemo_state = = ND_STATE_PLAYBACK )
return ;
wall_num = seg - > sides [ side ] . wall_num ;
if ( wall_num = = - 1 ) return ;
2013-02-21 00:20:26 +00:00
2006-03-20 16:43:15 +00:00
trigger_num = Walls [ wall_num ] . trigger ;
if ( trigger_num = = - 1 )
return ;
if ( check_trigger_sub ( trigger_num , Player_num ) )
return ;
if ( Triggers [ trigger_num ] . flags & TRIGGER_ONE_SHOT ) {
Triggers [ trigger_num ] . flags & = ~ TRIGGER_ON ;
csegp = & Segments [ seg - > children [ side ] ] ;
cside = find_connect_side ( seg , csegp ) ;
Assert ( cside ! = - 1 ) ;
wall_num = csegp - > sides [ cside ] . wall_num ;
if ( wall_num = = - 1 ) return ;
ctrigger_num = Walls [ wall_num ] . trigger ;
Triggers [ ctrigger_num ] . flags & = ~ TRIGGER_ON ;
}
# ifndef SHAREWARE
# ifdef NETWORK
if ( Game_mode & GM_MULTI )
multi_send_trigger ( trigger_num ) ;
# endif
# endif
}
}
2013-02-21 00:20:26 +00:00
2006-03-20 16:43:15 +00:00
void triggers_frame_process ( )
{
int i ;
for ( i = 0 ; i < Num_triggers ; i + + )
if ( Triggers [ i ] . time > = 0 )
Triggers [ i ] . time - = FrameTime ;
}
2008-01-13 00:58:49 +00:00
/*
2011-06-01 07:59:51 +00:00
* reads a v29_trigger structure from a PHYSFS_file
2008-01-13 00:58:49 +00:00
*/
2011-06-01 07:59:51 +00:00
extern void trigger_read ( trigger * t , PHYSFS_file * fp )
2008-01-13 00:58:49 +00:00
{
int i ;
2013-02-21 00:20:26 +00:00
2011-06-01 07:59:51 +00:00
t - > type = PHYSFSX_readByte ( fp ) ;
t - > flags = PHYSFSX_readShort ( fp ) ;
t - > value = PHYSFSX_readFix ( fp ) ;
t - > time = PHYSFSX_readFix ( fp ) ;
t - > link_num = PHYSFSX_readByte ( fp ) ;
t - > num_links = PHYSFSX_readShort ( fp ) ;
2008-01-13 00:58:49 +00:00
for ( i = 0 ; i < MAX_WALLS_PER_LINK ; i + + )
2011-06-01 07:59:51 +00:00
t - > seg [ i ] = PHYSFSX_readShort ( fp ) ;
2008-01-13 00:58:49 +00:00
for ( i = 0 ; i < MAX_WALLS_PER_LINK ; i + + )
2011-06-01 07:59:51 +00:00
t - > side [ i ] = PHYSFSX_readShort ( fp ) ;
2008-01-13 00:58:49 +00:00
}
2009-10-05 02:51:37 +00:00
void trigger_swap ( trigger * t , int swap )
{
int i ;
2013-02-21 00:20:26 +00:00
2009-10-05 02:51:37 +00:00
if ( ! swap )
return ;
2013-02-21 00:20:26 +00:00
2009-10-05 02:51:37 +00:00
t - > flags = SWAPSHORT ( t - > flags ) ;
t - > value = SWAPINT ( t - > value ) ;
t - > time = SWAPINT ( t - > time ) ;
t - > num_links = SWAPSHORT ( t - > num_links ) ;
for ( i = 0 ; i < MAX_WALLS_PER_LINK ; i + + )
t - > seg [ i ] = SWAPSHORT ( t - > seg [ i ] ) ;
for ( i = 0 ; i < MAX_WALLS_PER_LINK ; i + + )
t - > side [ i ] = SWAPSHORT ( t - > side [ i ] ) ;
}
/*
2011-06-01 07:59:51 +00:00
* reads n trigger structs from a PHYSFS_file and swaps if specified
2009-10-05 02:51:37 +00:00
*/
2011-06-01 07:59:51 +00:00
void trigger_read_n_swap ( trigger * t , int n , int swap , PHYSFS_file * fp )
2009-10-05 02:51:37 +00:00
{
int i ;
2013-02-21 00:20:26 +00:00
2009-10-05 02:51:37 +00:00
PHYSFS_read ( fp , t , sizeof ( trigger ) , n ) ;
2013-02-21 00:20:26 +00:00
2009-10-05 02:51:37 +00:00
if ( swap )
for ( i = 0 ; i < n ; i + + )
trigger_swap ( & t [ i ] , swap ) ;
}
2010-12-24 04:26:24 +00:00
void trigger_write ( trigger * t , short version , PHYSFS_file * fp )
{
int i ;
if ( version < = 29 )
2013-02-21 00:20:26 +00:00
PHYSFSX_writeU8 ( fp , 0 ) ; // unused 'type'
2010-12-24 04:26:24 +00:00
else if ( version > = 31 )
{
if ( t - > flags & TRIGGER_CONTROL_DOORS )
PHYSFSX_writeU8 ( fp , 0 ) ; // door
else if ( t - > flags & TRIGGER_MATCEN )
PHYSFSX_writeU8 ( fp , 2 ) ; // matcen
else if ( t - > flags & TRIGGER_EXIT )
PHYSFSX_writeU8 ( fp , 3 ) ; // exit
else if ( t - > flags & TRIGGER_SECRET_EXIT )
PHYSFSX_writeU8 ( fp , 4 ) ; // secret exit
else if ( t - > flags & TRIGGER_ILLUSION_OFF )
PHYSFSX_writeU8 ( fp , 5 ) ; // illusion off
else if ( t - > flags & TRIGGER_ILLUSION_ON )
PHYSFSX_writeU8 ( fp , 6 ) ; // illusion on
}
if ( version < = 30 )
PHYSFS_writeSLE16 ( fp , t - > flags ) ;
else
PHYSFSX_writeU8 ( fp , ( t - > flags & TRIGGER_ONE_SHOT ) ? 2 : 0 ) ; // flags
2013-02-21 00:20:26 +00:00
2010-12-24 04:26:24 +00:00
if ( version > = 30 )
{
PHYSFSX_writeU8 ( fp , t - > num_links ) ;
PHYSFSX_writeU8 ( fp , 0 ) ; // t->pad
}
2013-02-21 00:20:26 +00:00
2010-12-24 04:26:24 +00:00
PHYSFSX_writeFix ( fp , t - > value ) ;
PHYSFSX_writeFix ( fp , t - > time ) ;
2013-02-21 00:20:26 +00:00
2010-12-24 04:26:24 +00:00
if ( version < = 29 )
{
PHYSFSX_writeU8 ( fp , t - > link_num ) ;
PHYSFS_writeSLE16 ( fp , t - > num_links ) ;
}
2013-02-21 00:20:26 +00:00
2010-12-24 04:26:24 +00:00
for ( i = 0 ; i < MAX_WALLS_PER_LINK ; i + + )
PHYSFS_writeSLE16 ( fp , t - > seg [ i ] ) ;
for ( i = 0 ; i < MAX_WALLS_PER_LINK ; i + + )
PHYSFS_writeSLE16 ( fp , t - > side [ i ] ) ;
}