C_BaseEntity *ClientClassFactory( boost::python::object cls_type, int entnum, int serialNum ) { C_BaseEntity *pResult = NULL; try { // Spawn and initialize the entity boost::python::object inst = cls_type(); pResult = boost::python::extract<C_BaseEntity *>( inst ); if( !pResult ) { Warning("Invalid client entity\n" ); return NULL; } pResult->SetPyInstance( inst ); pResult->Init( entnum, serialNum ); } catch(boost::python::error_already_set &) { Warning( "Failed to create python client side entity, falling back to base c++ class\n" ); PyErr_Print(); } return pResult; }
IClientNetworkable *ClientClassFactory( int iType, boost::python::object cls_type, int entnum, int serialNum ) { try { // Safety check. The base implementations must be match, otherwise it can result in incorrect behavior (crashes) int iNetworkType = boost::python::extract<int>(cls_type.attr("GetPyNetworkType")()); if( iNetworkType != iType ) { char buf[512]; Q_snprintf( buf, sizeof(buf), "Network type does not match client %d != server %d", iNetworkType, iType ); PyErr_SetString(PyExc_Exception, buf ); throw boost::python::error_already_set(); } // Spawn and initialize the entity boost::python::object inst = cls_type(); C_BaseEntity *pRet = boost::python::extract<C_BaseEntity *>(inst); if( !pRet ) { Warning("Invalid client entity\n" ); return NULL; } pRet->SetPyInstance( inst ); pRet->Init( entnum, serialNum ); return pRet; } catch(boost::python::error_already_set &) { Warning("Failed to create python client side entity, falling back to base c++ class\n"); PyErr_Print(); PyErr_Clear(); // Call the correct fallback factory IClientNetworkable *pResult = NULL; switch( iType ) { case PN_BASEENTITY: pResult = CALL_FALLBACK_FACTORY( C_BaseEntity, entnum, serialNum ); break; case PN_BASEANIMATING: pResult = CALL_FALLBACK_FACTORY( C_BaseAnimating, entnum, serialNum ); break; case PN_BASEANIMATINGOVERLAY: pResult = CALL_FALLBACK_FACTORY( C_BaseAnimatingOverlay, entnum, serialNum ); break; case PN_BASEFLEX: pResult = CALL_FALLBACK_FACTORY( C_BaseFlex, entnum, serialNum ); break; case PN_BASECOMBATCHARACTER: pResult = CALL_FALLBACK_FACTORY( C_BaseCombatCharacter, entnum, serialNum ); break; case PN_BASEPLAYER: pResult = CALL_FALLBACK_FACTORY( C_BasePlayer, entnum, serialNum ); break; case PN_BASEPROJECTILE: pResult = CALL_FALLBACK_FACTORY( C_BaseProjectile, entnum, serialNum ); break; case PN_BASEGRENADE: pResult = CALL_FALLBACK_FACTORY( C_BaseGrenade, entnum, serialNum ); break; case PN_BASECOMBATWEAPON: pResult = CALL_FALLBACK_FACTORY( C_BaseCombatWeapon, entnum, serialNum ); break; case PN_BREAKABLEPROP: pResult = CALL_FALLBACK_FACTORY( C_BreakableProp, entnum, serialNum ); break; case PN_BASETOGGLE: pResult = CALL_FALLBACK_FACTORY( C_BaseToggle, entnum, serialNum ); break; case PN_BASETRIGGER: pResult = CALL_FALLBACK_FACTORY( C_BaseTrigger, entnum, serialNum ); break; case PN_UNITBASE: pResult = CALL_FALLBACK_FACTORY( C_UnitBase, entnum, serialNum ); break; case PN_SPRITE: pResult = CALL_FALLBACK_FACTORY( C_Sprite, entnum, serialNum ); break; case PN_BEAM: pResult = CALL_FALLBACK_FACTORY( C_Beam, entnum, serialNum ); break; case PN_HL2WARSPLAYER: pResult = CALL_FALLBACK_FACTORY( C_HL2WarsPlayer, entnum, serialNum ); break; case PN_WARSWEAPON: pResult = CALL_FALLBACK_FACTORY( C_WarsWeapon, entnum, serialNum ); break; case PN_FUNCUNIT: pResult = CALL_FALLBACK_FACTORY( C_FuncUnit, entnum, serialNum ); break; default: Warning( "No default fallback for networktype %d. Warn a dev.\n", iType ); pResult = CALL_FALLBACK_FACTORY( C_BaseEntity, entnum, serialNum ); break; } return pResult; } }