2016-03-01 15:47:10 +00:00
/*
* * thingdef . cpp
* *
* * Actor definitions
* *
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* * Copyright 2002 - 2008 Christoph Oelckers
* * Copyright 2004 - 2008 Randy Heit
* * All rights reserved .
* *
* * Redistribution and use in source and binary forms , with or without
* * modification , are permitted provided that the following conditions
* * are met :
* *
* * 1. Redistributions of source code must retain the above copyright
* * notice , this list of conditions and the following disclaimer .
* * 2. Redistributions in binary form must reproduce the above copyright
* * notice , this list of conditions and the following disclaimer in the
* * documentation and / or other materials provided with the distribution .
* * 3. The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission .
* * 4. When not used as part of ZDoom or a ZDoom derivative , this code will be
* * covered by the terms of the GNU General Public License as published by
* * the Free Software Foundation ; either version 2 of the License , or ( at
* * your option ) any later version .
* *
* * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* * IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* * INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* * NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* * DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* * THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* * THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* *
*/
# include "gi.h"
# include "actor.h"
# include "info.h"
# include "sc_man.h"
# include "tarray.h"
# include "w_wad.h"
# include "templates.h"
# include "r_defs.h"
# include "a_pickups.h"
# include "s_sound.h"
# include "cmdlib.h"
# include "p_lnspec.h"
# include "a_action.h"
# include "decallib.h"
# include "m_random.h"
# include "i_system.h"
# include "m_argv.h"
# include "p_local.h"
# include "doomerrors.h"
# include "a_weaponpiece.h"
# include "p_conversation.h"
# include "v_text.h"
# include "thingdef.h"
2016-10-15 08:43:02 +00:00
# include "codegeneration/codegen.h"
2016-03-01 15:47:10 +00:00
# include "a_sharedglobal.h"
# include "vmbuilder.h"
# include "stats.h"
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
void InitThingdef ( ) ;
// STATIC FUNCTION PROTOTYPES --------------------------------------------
PClassActor * QuestItemClasses [ 31 ] ;
//==========================================================================
//
2016-10-12 22:53:59 +00:00
// SetImplicitArgs
//
// Adds the parameters implied by the function flags.
2016-03-01 15:47:10 +00:00
//
//==========================================================================
2016-10-15 12:36:08 +00:00
void SetImplicitArgs ( TArray < PType * > * args , TArray < DWORD > * argflags , TArray < FName > * argnames , PClass * cls , DWORD funcflags )
2016-03-01 15:47:10 +00:00
{
2016-10-12 22:53:59 +00:00
// Must be called before adding any other arguments.
2016-10-15 12:36:08 +00:00
assert ( args = = nullptr | | args - > Size ( ) = = 0 ) ;
assert ( argflags = = nullptr | | argflags - > Size ( ) = = 0 ) ;
2016-03-01 15:47:10 +00:00
2016-10-12 22:53:59 +00:00
if ( funcflags & VARF_Method )
2016-03-01 15:47:10 +00:00
{
2016-10-12 22:53:59 +00:00
// implied self pointer
2016-10-15 15:40:27 +00:00
if ( args ! = nullptr ) args - > Push ( NewPointer ( cls ) ) ;
2016-10-15 12:36:08 +00:00
if ( argflags ! = nullptr ) argflags - > Push ( VARF_Implicit ) ;
if ( argnames ! = nullptr ) argnames - > Push ( NAME_self ) ;
2016-03-01 15:47:10 +00:00
}
2016-10-12 22:53:59 +00:00
if ( funcflags & VARF_Action )
2016-03-01 15:47:10 +00:00
{
2016-10-12 22:53:59 +00:00
// implied caller and callingstate pointers
2016-10-15 12:36:08 +00:00
if ( args ! = nullptr )
2016-03-01 15:47:10 +00:00
{
2016-10-15 12:36:08 +00:00
// Special treatment for weapons and CustomInventorys: 'self' is not the defining class but the actual user of the item, so this pointer must be of type 'Actor'
2016-10-15 13:10:48 +00:00
if ( cls - > IsDescendantOf ( RUNTIME_CLASS ( AStateProvider ) ) )
2016-10-15 12:36:08 +00:00
{
2016-10-15 15:40:27 +00:00
args - > Insert ( 0 , NewPointer ( RUNTIME_CLASS ( AActor ) ) ) ; // this must go in before the real pointer to the containing class.
2016-10-15 12:36:08 +00:00
}
2016-10-15 13:10:48 +00:00
else
2016-10-15 12:36:08 +00:00
{
2016-10-15 15:40:27 +00:00
args - > Push ( NewPointer ( cls ) ) ;
2016-10-15 12:36:08 +00:00
}
args - > Push ( TypeState /*Info*/ ) ; // fixme: TypeState is not the correct type here!!!
2016-03-01 15:47:10 +00:00
}
2016-10-15 12:36:08 +00:00
if ( argflags ! = nullptr )
2016-03-01 15:47:10 +00:00
{
2016-10-12 22:53:59 +00:00
argflags - > Push ( VARF_Implicit ) ;
argflags - > Push ( VARF_Implicit ) ;
2016-03-01 15:47:10 +00:00
}
2016-10-15 12:36:08 +00:00
if ( argnames ! = nullptr )
{
argnames - > Push ( NAME_invoker ) ;
argnames - > Push ( NAME_stateinfo ) ;
}
2016-03-01 15:47:10 +00:00
}
}
2016-10-15 12:36:08 +00:00
//==========================================================================
//
// CreateAnonymousFunction
//
// Creates a function symbol for an anonymous function
// This contains actual info about the implied variables which is needed
// during code generation.
//
//==========================================================================
PFunction * CreateAnonymousFunction ( PClass * containingclass , PType * returntype , int flags )
{
TArray < PType * > rets ( 1 ) ;
TArray < PType * > args ;
TArray < uint32_t > argflags ;
TArray < FName > argnames ;
rets [ 0 ] = returntype ! = nullptr ? returntype : TypeError ; // Use TypeError as placeholder if we do not know the return type yet.
SetImplicitArgs ( & args , & argflags , & argnames , containingclass , flags ) ;
2016-10-15 13:50:45 +00:00
PFunction * sym = new PFunction ( containingclass , NAME_None ) ; // anonymous functions do not have names.
sym - > AddVariant ( NewPrototype ( rets , args ) , argflags , argnames , nullptr , VARF_Action | VARF_Method ) ;
2016-10-15 12:36:08 +00:00
return sym ;
}
2016-03-01 15:47:10 +00:00
//==========================================================================
//
// LoadActors
//
// Called from FActor::StaticInit()
//
//==========================================================================
2016-10-07 23:05:27 +00:00
void ParseScripts ( ) ;
2016-10-12 22:53:59 +00:00
void ParseAllDecorate ( ) ;
2016-03-01 15:47:10 +00:00
void LoadActors ( )
{
cycle_t timer ;
timer . Reset ( ) ; timer . Clock ( ) ;
2016-10-12 22:53:59 +00:00
FScriptPosition : : ResetErrorCounter ( ) ;
2016-03-01 15:47:10 +00:00
InitThingdef ( ) ;
2016-10-07 23:05:27 +00:00
ParseScripts ( ) ;
2016-10-15 10:15:25 +00:00
2016-10-12 22:53:59 +00:00
ParseAllDecorate ( ) ;
FunctionBuildList . Build ( ) ;
2016-10-12 18:42:41 +00:00
2016-03-01 15:47:10 +00:00
if ( FScriptPosition : : ErrorCounter > 0 )
{
I_Error ( " %d errors while parsing DECORATE scripts " , FScriptPosition : : ErrorCounter ) ;
}
2016-10-12 22:53:59 +00:00
int errorcount = 0 ;
for ( auto ti : PClassActor : : AllActorClasses )
{
if ( ti - > Size = = TentativeClass )
{
Printf ( TEXTCOLOR_RED " Class %s referenced but not defined \n " , ti - > TypeName . GetChars ( ) ) ;
errorcount + + ;
continue ;
}
if ( GetDefaultByType ( ti ) = = nullptr )
{
Printf ( TEXTCOLOR_RED " No ActorInfo defined for class '%s' \n " , ti - > TypeName . GetChars ( ) ) ;
errorcount + + ;
continue ;
}
}
if ( errorcount > 0 )
{
I_Error ( " %d errors during actor postprocessing " , errorcount ) ;
}
2016-03-01 15:47:10 +00:00
timer . Unclock ( ) ;
if ( ! batchrun ) Printf ( " DECORATE parsing took %.2f ms \n " , timer . TimeMS ( ) ) ;
// Base time: ~52 ms
2016-10-12 18:42:41 +00:00
// Since these are defined in DECORATE now the table has to be initialized here.
for ( int i = 0 ; i < 31 ; i + + )
{
char fmt [ 20 ] ;
mysnprintf ( fmt , countof ( fmt ) , " QuestItem%d " , i + 1 ) ;
QuestItemClasses [ i ] = PClass : : FindActor ( fmt ) ;
}
2016-03-01 15:47:10 +00:00
}