12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307 |
- //BASE BUILDING BASE
- class BaseBuildingBase extends ItemBase
- {
- const string ANIMATION_DEPLOYED = "Deployed";
-
- float m_ConstructionKitHealth; //stored health value for used construction kit
- ref Construction m_Construction;
-
- bool m_HasBase;
- //variables for synchronization of base building parts (2x31 is the current limit)
- int m_SyncParts01; //synchronization for already built parts (31 parts)
- int m_SyncParts02; //synchronization for already built parts (+31 parts)
- int m_SyncParts03; //synchronization for already built parts (+31 parts)
- int m_InteractedPartId; //construction part id that an action was performed on
- int m_PerformedActionId; //action id that was performed on a construction part
-
- //Sounds
- //build
- const string SOUND_BUILD_WOOD_LOG = "putDown_WoodLog_SoundSet";
- const string SOUND_BUILD_WOOD_PLANK = "putDown_WoodPlank_SoundSet";
- const string SOUND_BUILD_WOOD_STAIRS = "putDown_WoodStairs_SoundSet";
- const string SOUND_BUILD_METAL = "putDown_MetalPlank_SoundSet";
- const string SOUND_BUILD_WIRE = "putDown_BarbedWire_SoundSet";
- //dismantle
- const string SOUND_DISMANTLE_WOOD_LOG = "Crash_WoodPlank_SoundSet";
- const string SOUND_DISMANTLE_WOOD_PLANK = "Crash_WoodPlank_SoundSet";
- const string SOUND_DISMANTLE_WOOD_STAIRS = "Crash_WoodPlank_SoundSet";
- const string SOUND_DISMANTLE_METAL = "Crash_MetalPlank_SoundSet";
- const string SOUND_DISMANTLE_WIRE = "putDown_BarbedWire_SoundSet";
-
- protected EffectSound m_Sound;
-
- ref map<string, ref AreaDamageManager> m_DamageTriggers;
- ref array<string> m_HybridAttachments;
- ref array<string> m_Mountables;
-
- // Constructor
- void BaseBuildingBase()
- {
- m_DamageTriggers = new ref map<string, ref AreaDamageManager>;
-
- //synchronized variables
- RegisterNetSyncVariableInt( "m_SyncParts01" );
- RegisterNetSyncVariableInt( "m_SyncParts02" );
- RegisterNetSyncVariableInt( "m_SyncParts03" );
- RegisterNetSyncVariableInt( "m_InteractedPartId" );
- RegisterNetSyncVariableInt( "m_PerformedActionId" );
- RegisterNetSyncVariableBool( "m_HasBase" );
-
- //Construction init
- ConstructionInit();
-
- if (ConfigIsExisting("hybridAttachments"))
- {
- m_HybridAttachments = new array<string>;
- ConfigGetTextArray("hybridAttachments", m_HybridAttachments);
- }
- if (ConfigIsExisting("mountables"))
- {
- m_Mountables = new array<string>;
- ConfigGetTextArray("mountables", m_Mountables);
- }
-
- ProcessInvulnerabilityCheck(GetInvulnerabilityTypeString());
- }
-
- override void EEDelete(EntityAI parent)
- {
- super.EEDelete(parent);
- foreach (AreaDamageManager areaDamage : m_DamageTriggers)
- {
- areaDamage.Destroy();
- }
-
- }
-
- override string GetInvulnerabilityTypeString()
- {
- return "disableBaseDamage";
- }
-
- override bool CanObstruct()
- {
- return true;
- }
-
- override int GetHideIconMask()
- {
- return EInventoryIconVisibility.HIDE_VICINITY;
- }
- // --- SYNCHRONIZATION
- void SynchronizeBaseState()
- {
- if ( GetGame().IsServer() )
- {
- SetSynchDirty();
- }
- }
- override void OnVariablesSynchronized()
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + " OnVariablesSynchronized");
- super.OnVariablesSynchronized();
- GetGame().GetCallQueue( CALL_CATEGORY_GAMEPLAY ).CallLater( OnSynchronizedClient, 100, false );
- }
-
- protected void OnSynchronizedClient()
- {
- //update parts
- SetPartsFromSyncData();
-
- //update action on part
- SetActionFromSyncData();
-
- //update visuals (client)
- UpdateVisuals();
- }
-
- //parts synchronization
- void RegisterPartForSync( int part_id )
- {
- //part_id must starts from index = 1
- int offset;
- int mask;
-
- if ( part_id >= 1 && part_id <= 31 ) //<1,31> (31 parts)
- {
- offset = part_id - 1;
- mask = 1 << offset;
-
- m_SyncParts01 = m_SyncParts01 | mask;
- }
- else if ( part_id >= 32 && part_id <= 62 ) //<32,62> (31 parts)
- {
- offset = ( part_id % 32 );
- mask = 1 << offset;
-
- m_SyncParts02 = m_SyncParts02 | mask;
- }
- else if ( part_id >= 63 && part_id <= 93 ) //<63,93> (31 parts)
- {
- offset = ( part_id % 63 );
- mask = 1 << offset;
-
- m_SyncParts03 = m_SyncParts03 | mask;
- }
- }
-
- void UnregisterPartForSync( int part_id )
- {
- //part_id must starts from index = 1
- int offset;
- int mask;
-
- if ( part_id >= 1 && part_id <= 31 ) //<1,31> (31 parts)
- {
- offset = part_id - 1;
- mask = 1 << offset;
-
- m_SyncParts01 = m_SyncParts01 & ~mask;
- }
- else if ( part_id >= 32 && part_id <= 62 ) //<32,62> (31 parts)
- {
- offset = ( part_id % 32 );
- mask = 1 << offset;
-
- m_SyncParts02 = m_SyncParts02 & ~mask;
- }
- else if ( part_id >= 63 && part_id <= 93 ) //<63,93> (31 parts)
- {
- offset = ( part_id % 63 );
- mask = 1 << offset;
-
- m_SyncParts03 = m_SyncParts03 & ~mask;
- }
- }
-
- bool IsPartBuildInSyncData( int part_id )
- {
- //part_id must starts from index = 1
- int offset;
- int mask;
-
- if ( part_id >= 1 && part_id <= 31 ) //<1,31> (31 parts)
- {
- offset = part_id - 1;
- mask = 1 << offset;
-
- if ( ( m_SyncParts01 & mask ) > 0 )
- {
- return true;
- }
- }
- else if ( part_id >= 32 && part_id <= 62 ) //<32,62> (31 parts)
- {
- offset = ( part_id % 32 );
- mask = 1 << offset;
-
- if ( ( m_SyncParts02 & mask ) > 0 )
- {
- return true;
- }
- }
- else if ( part_id >= 63 && part_id <= 93 ) //<63,93> (31 parts)
- {
- offset = ( part_id % 63 );
- mask = 1 << offset;
-
- if ( ( m_SyncParts03 & mask ) > 0 )
- {
- return true;
- }
- }
-
- return false;
- }
- protected void RegisterActionForSync( int part_id, int action_id )
- {
- m_InteractedPartId = part_id;
- m_PerformedActionId = action_id;
- }
-
- protected void ResetActionSyncData()
- {
- //reset data
- m_InteractedPartId = -1;
- m_PerformedActionId = -1;
- }
-
- protected void SetActionFromSyncData()
- {
- if ( m_InteractedPartId > -1 && m_PerformedActionId > -1 )
- {
- ConstructionPart constrution_part = GetConstructionPartById( m_InteractedPartId );
- int build_action_id = m_PerformedActionId;
-
- switch( build_action_id )
- {
- case AT_BUILD_PART : OnPartBuiltClient( constrution_part.GetPartName(), build_action_id ); break;
- case AT_DISMANTLE_PART : OnPartDismantledClient( constrution_part.GetPartName(), build_action_id ); break;
- case AT_DESTROY_PART : OnPartDestroyedClient( constrution_part.GetPartName(), build_action_id ); break;
- }
- }
- }
- //------
-
- void SetPartFromSyncData( ConstructionPart part )
- {
- string key = part.m_PartName;
- bool is_base = part.IsBase();
- bool is_part_built_sync = IsPartBuildInSyncData( part.GetId() );
- bsbDebugSpam("[bsb] " + GetDebugName(this) + " SetPartFromSyncData try to sync: built=" + is_part_built_sync + " key=" + key + " part=" + part.GetPartName() + " part_built=" + part.IsBuilt());
- if ( is_part_built_sync )
- {
- if ( !part.IsBuilt() )
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + " SetPartsFromSyncData +++ " + key);
- GetConstruction().AddToConstructedParts( key );
- GetConstruction().ShowConstructionPartPhysics(part.GetPartName());
-
- if (is_base)
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + ANIMATION_DEPLOYED + " RM");
- RemoveProxyPhysics( ANIMATION_DEPLOYED );
- }
- }
- }
- else
- {
- if ( part.IsBuilt() )
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + " SetPartsFromSyncData --- " + key);
- GetConstruction().RemoveFromConstructedParts( key );
- GetConstruction().HideConstructionPartPhysics(part.GetPartName());
-
- if (is_base)
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + ANIMATION_DEPLOYED + " ADD");
- AddProxyPhysics( ANIMATION_DEPLOYED );
- }
- }
- }
- //check slot lock for material attachments
- GetConstruction().SetLockOnAttachedMaterials( part.GetPartName(), part.IsBuilt() ); //failsafe for corrupted sync/storage data
- }
-
- //set construction parts based on synchronized data
- void SetPartsFromSyncData()
- {
- Construction construction = GetConstruction();
- map<string, ref ConstructionPart> construction_parts = construction.GetConstructionParts();
-
- for ( int i = 0; i < construction_parts.Count(); ++i )
- {
- string key = construction_parts.GetKey( i );
- ConstructionPart value = construction_parts.Get( key );
- SetPartFromSyncData(value);
- }
-
- //regenerate navmesh
- UpdateNavmesh();
- }
-
- protected ConstructionPart GetConstructionPartById( int id )
- {
- Construction construction = GetConstruction();
- map<string, ref ConstructionPart> construction_parts = construction.GetConstructionParts();
-
- for ( int i = 0; i < construction_parts.Count(); ++i )
- {
- string key = construction_parts.GetKey( i );
- ConstructionPart value = construction_parts.Get( key );
-
- if ( value.GetId() == id )
- {
- return value;
- }
- }
-
- return NULL;
- }
- //
-
- //Base
- bool HasBase()
- {
- return m_HasBase;
- }
-
- void SetBaseState( bool has_base )
- {
- m_HasBase = has_base;
- }
-
- override bool IsDeployable()
- {
- return true;
- }
-
- bool IsOpened()
- {
- return false;
- }
-
- //--- CONSTRUCTION KIT
- ItemBase CreateConstructionKit()
- {
- ItemBase construction_kit = ItemBase.Cast( GetGame().CreateObjectEx( GetConstructionKitType(), GetKitSpawnPosition(), ECE_PLACE_ON_SURFACE ) );
- if ( m_ConstructionKitHealth > 0 )
- {
- construction_kit.SetHealth( m_ConstructionKitHealth );
- }
-
- return construction_kit;
- }
-
- void CreateConstructionKitInHands(notnull PlayerBase player)
- {
- ItemBase construction_kit = ItemBase.Cast(player.GetHumanInventory().CreateInHands(GetConstructionKitType()));
- if ( m_ConstructionKitHealth > 0 )
- {
- construction_kit.SetHealth( m_ConstructionKitHealth );
- }
- }
-
- protected vector GetKitSpawnPosition()
- {
- return GetPosition();
- }
-
- protected string GetConstructionKitType()
- {
- return "";
- }
-
- void DestroyConstructionKit( ItemBase construction_kit )
- {
- m_ConstructionKitHealth = construction_kit.GetHealth();
- GetGame().ObjectDelete( construction_kit );
- }
-
- //--- CONSTRUCTION
- void DestroyConstruction()
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + " DestroyConstruction");
- GetGame().ObjectDelete( this );
- }
-
- // --- EVENTS
- override void OnStoreSave( ParamsWriteContext ctx )
- {
- super.OnStoreSave( ctx );
-
- //sync parts 01
- ctx.Write( m_SyncParts01 );
- ctx.Write( m_SyncParts02 );
- ctx.Write( m_SyncParts03 );
-
- ctx.Write( m_HasBase );
- }
-
- override bool OnStoreLoad( ParamsReadContext ctx, int version )
- {
- if ( !super.OnStoreLoad( ctx, version ) )
- return false;
-
- //--- Base building data ---
- //Restore synced parts data
- if ( !ctx.Read( m_SyncParts01 ) )
- {
- m_SyncParts01 = 0; //set default
- return false;
- }
- if ( !ctx.Read( m_SyncParts02 ) )
- {
- m_SyncParts02 = 0; //set default
- return false;
- }
- if ( !ctx.Read( m_SyncParts03 ) )
- {
- m_SyncParts03 = 0; //set default
- return false;
- }
-
- //has base
- if ( !ctx.Read( m_HasBase ) )
- {
- m_HasBase = false;
- return false;
- }
- //---
- return true;
- }
-
- override void AfterStoreLoad()
- {
- super.AfterStoreLoad();
-
- if (!m_FixDamageSystemInit)
- {
- SetPartsAfterStoreLoad();
- }
- }
-
- void SetPartsAfterStoreLoad()
- {
- //update server data
- SetPartsFromSyncData();
-
- //set base state
- ConstructionPart construction_part = GetConstruction().GetBaseConstructionPart();
- SetBaseState( construction_part.IsBuilt() ) ;
-
- //synchronize after load
- SynchronizeBaseState();
- }
-
- override void OnCreatePhysics()
- {
- super.OnCreatePhysics();
- ConstructionInit();
- SetPartsAfterStoreLoad();
- }
-
- override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
- {
- if (m_FixDamageSystemInit)
- return;
-
- super.EEHealthLevelChanged(oldLevel,newLevel,zone);
-
- if (GetGame().IsMultiplayer() && !GetGame().IsServer())
- return;
-
- Construction construction = GetConstruction();
- string part_name = zone;
- part_name.ToLower();
-
- if ( newLevel == GameConstants.STATE_RUINED )
- {
- ConstructionPart construction_part = construction.GetConstructionPart( part_name );
-
- if ( construction_part && construction.IsPartConstructed( part_name ) )
- {
- construction.DestroyPartServer( null, part_name, AT_DESTROY_PART );
- construction.DestroyConnectedParts(part_name);
- }
-
- //barbed wire handling (hack-ish)
- if ( part_name.Contains("barbed") )
- {
- BarbedWire barbed_wire = BarbedWire.Cast( FindAttachmentBySlotName( zone ) );
- if (barbed_wire)
- barbed_wire.SetMountedState( false );
- }
- }
- }
-
- override void EEOnAfterLoad()
- {
- if (m_FixDamageSystemInit)
- {
- GetGame().GetCallQueue( CALL_CATEGORY_GAMEPLAY ).CallLater( SetPartsAfterStoreLoad, 500, false, this );
- }
-
- super.EEOnAfterLoad();
- }
-
- override void EEInit()
- {
- super.EEInit();
-
- // init visuals and physics
- InitBaseState();
-
- //debug
- #ifdef DEVELOPER
- DebugCustomState();
- #endif
- }
- override void EEItemAttached( EntityAI item, string slot_name )
- {
- super.EEItemAttached( item, slot_name );
-
- CheckForHybridAttachments( item, slot_name );
- UpdateVisuals();
- UpdateAttachmentPhysics( slot_name, false );
- }
-
- override void EEItemDetached( EntityAI item, string slot_name )
- {
- super.EEItemDetached( item, slot_name );
- UpdateVisuals();
- UpdateAttachmentPhysics( slot_name, false );
- }
-
- protected void OnSetSlotLock( int slotId, bool locked, bool was_locked )
- {
- string slot_name = InventorySlots.GetSlotName( slotId );
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint( "inv: OnSetSlotLock " + GetDebugName( this ) + " slot=" + slot_name + " locked=" + locked + " was_locked=" + was_locked );
- UpdateAttachmentVisuals( slot_name, locked );
- UpdateAttachmentPhysics( slot_name, locked );
- }
-
- //ignore out of reach condition
- override bool IgnoreOutOfReachCondition()
- {
- return true;
- }
-
- //CONSTRUCTION EVENTS
- //Build
- void OnPartBuiltServer(notnull Man player, string part_name, int action_id)
- {
- ConstructionPart construtionPart = GetConstruction().GetConstructionPart(part_name);
-
- //check base state
- if (construtionPart.IsBase())
- {
- SetBaseState(true);
- //spawn kit
- CreateConstructionKit();
- }
-
- //register constructed parts for synchronization
- RegisterPartForSync(construtionPart.GetId());
-
- //register action that was performed on part
- RegisterActionForSync(construtionPart.GetId(), action_id);
-
- //synchronize
- SynchronizeBaseState();
- SetPartFromSyncData(construtionPart); // server part of sync, client will be synced from SetPartsFromSyncData
-
- UpdateNavmesh();
-
- //update visuals
- UpdateVisuals();
-
- //reset action sync data
- GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(ResetActionSyncData, 100, false, this);
- }
-
- void OnPartBuiltClient(string part_name, int action_id)
- {
- //play sound
- SoundBuildStart( part_name );
- }
-
- //Dismantle
- void OnPartDismantledServer(notnull Man player, string part_name, int action_id)
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + " OnPartDismantledServer " + part_name);
- ConstructionPart construtionPart = GetConstruction().GetConstructionPart(part_name);
-
- //register constructed parts for synchronization
- UnregisterPartForSync(construtionPart.GetId());
-
- //register action that was performed on part
- RegisterActionForSync(construtionPart.GetId(), action_id);
-
- //synchronize
- SynchronizeBaseState();
- // server part of sync, client will be synced from SetPartsFromSyncData
- SetPartFromSyncData(construtionPart);
-
- UpdateNavmesh();
-
- //update visuals
- UpdateVisuals();
-
- //reset action sync data
- GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(ResetActionSyncData, 100, false, this);
-
- //check base state
- if (construtionPart.IsBase())
- {
- //Destroy construction
- GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(DestroyConstruction, 200, false, this);
- }
-
- if (GetGame().IsServer())
- HandleItemFalling(construtionPart);
- }
-
- void OnPartDismantledClient( string part_name, int action_id )
- {
- //play sound
- SoundDismantleStart( part_name );
- }
-
- //Destroy
- void OnPartDestroyedServer(Man player, string part_name, int action_id, bool destroyed_by_connected_part = false)
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + " OnPartDestroyedServer " + part_name);
- ConstructionPart construtionPart = GetConstruction().GetConstructionPart(part_name);
-
- //register constructed parts for synchronization
- UnregisterPartForSync(construtionPart.GetId());
-
- //register action that was performed on part
- RegisterActionForSync(construtionPart.GetId(), action_id);
-
- //synchronize
- SynchronizeBaseState();
-
- // server part of sync, client will be synced from SetPartsFromSyncData
- SetPartFromSyncData(construtionPart);
-
- UpdateNavmesh();
-
- //update visuals
- UpdateVisuals();
-
- //reset action sync data
- GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(ResetActionSyncData, 100, false, this);
-
- //check base state
- if (construtionPart.IsBase())
- {
- //Destroy construction
- GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(DestroyConstruction, 200, false, this);
- }
-
- if (GetGame().IsServer())
- HandleItemFalling(construtionPart);
- }
-
- void OnPartDestroyedClient( string part_name, int action_id )
- {
- //play sound
- SoundDestroyStart( part_name );
- }
-
- protected void HandleItemFalling(ConstructionPart part)
- {
- bool process = false;
-
- //TODO: add a parameter to parts' config classes?
- process |= part.m_PartName.Contains("_roof");
- process |= part.m_PartName.Contains("_platform");
- process |= part.m_PartName.Contains("_stair");
-
- if (process)
- {
- if (!MemoryPointExists(part.m_PartName + "_min") || !MemoryPointExists(part.m_PartName + "_max"))
- {
- Debug.Log("min/max memory points do not exist for part: " + part.m_PartName);
- return;
- }
-
- vector mins, maxs;
- mins = ModelToWorld(GetMemoryPointPos(part.m_PartName + "_min"));
- maxs = ModelToWorld(GetMemoryPointPos(part.m_PartName + "_max"));
-
- //sanitize minmaxs
- vector minTmp, maxTmp;
- minTmp[0] = Math.Min(mins[0],maxs[0]);
- maxTmp[0] = Math.Max(mins[0],maxs[0]);
- minTmp[1] = Math.Min(mins[1],maxs[1]);
- maxTmp[1] = Math.Max(mins[1],maxs[1]);
- minTmp[2] = Math.Min(mins[2],maxs[2]);
- maxTmp[2] = Math.Max(mins[2],maxs[2]);
- mins = minTmp;
- maxs = maxTmp;
-
- maxs[1] = maxs[1] + 0.35; //reach a little above..
-
- ItemFall(mins,maxs);
- }
- }
-
- protected void ItemFall(vector min, vector max)
- {
- array<EntityAI> foundEntities = new array<EntityAI>();
- DayZPlayerUtils.PhysicsGetEntitiesInBox(min,max,foundEntities);
-
- //filtering
- ItemBase item;
- foreach (EntityAI entity : foundEntities)
- {
- if (Class.CastTo(item,entity) && !item.CanUseConstruction()) //BB items?
- item.ThrowPhysically(null,vector.Zero);
- }
- }
-
- // --- UPDATE
- void InitBaseState()
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + " BaseBuildingBase::InitBaseState ");
- InitVisuals();
- UpdateNavmesh(); //regenerate navmesh
- GetConstruction().InitBaseState();
- }
-
- void InitVisuals()
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + " InitVisuals");
- //check base
- if ( !HasBase() )
- {
- SetAnimationPhase( ANIMATION_DEPLOYED, 0 );
- }
- else
- {
- SetAnimationPhase( ANIMATION_DEPLOYED, 1 );
- }
-
- GetConstruction().UpdateVisuals();
- }
- void UpdateVisuals()
- {
- array<string> attachmentSlots = new array<string>;
- GetAttachmentSlots(this, attachmentSlots);
- foreach (string slotName : attachmentSlots)
- {
- UpdateAttachmentVisuals(slotName, IsAttachmentSlotLocked(slotName));
- }
-
- //check base
- if (!HasBase())
- SetAnimationPhase(ANIMATION_DEPLOYED, 0);
- else
- SetAnimationPhase(ANIMATION_DEPLOYED, 1);
-
- GetConstruction().UpdateVisuals();
- }
-
- void UpdateAttachmentVisuals(string slot_name, bool is_locked)
- {
- string slotNameMounted = slot_name + "_Mounted";
- EntityAI attachment = FindAttachmentBySlotName(slot_name);
-
- if (attachment)
- {
- BarbedWire barbedWire = BarbedWire.Cast(attachment);
- if (barbedWire && barbedWire.IsMounted())
- CreateAreaDamage(slotNameMounted);
- else
- DestroyAreaDamage(slotNameMounted);
-
- if (is_locked)
- {
- SetAnimationPhase(slotNameMounted, 0);
- SetAnimationPhase(slot_name, 1);
- }
- else
- {
- SetAnimationPhase(slotNameMounted, 1);
- SetAnimationPhase(slot_name, 0);
- }
- }
- else
- {
- SetAnimationPhase(slotNameMounted, 1);
- SetAnimationPhase(slot_name, 1);
-
- DestroyAreaDamage(slotNameMounted);
- }
- }
-
- // avoid calling this function on frequent occasions, it's a massive performance hit
- void UpdatePhysics()
- {
- if (LogManager.IsBaseBuildingLogEnable())
- bsbDebugPrint("[bsb] " + GetDebugName(this) + " BaseBuildingBase::UpdatePhysics");
-
- array<string> attachmentSlots = new array<string>;
- GetAttachmentSlots(this, attachmentSlots);
- if (LogManager.IsBaseBuildingLogEnable())
- bsbDebugPrint("[bsb] " + GetDebugName(this) + " att_cnt=" + attachmentSlots.Count());
- foreach (string slotName : attachmentSlots)
- {
- UpdateAttachmentPhysics(slotName, IsAttachmentSlotLocked(slotName));
- }
-
- //check base
- if (!HasBase())
- {
- if (LogManager.IsBaseBuildingLogEnable())
- bsbDebugPrint("[bsb] " + GetDebugName(this) + ANIMATION_DEPLOYED + " ADD");
- AddProxyPhysics(ANIMATION_DEPLOYED);
- }
- else
- {
- if (LogManager.IsBaseBuildingLogEnable())
- bsbDebugPrint("[bsb] " + GetDebugName(this) + ANIMATION_DEPLOYED + " RM");
- RemoveProxyPhysics(ANIMATION_DEPLOYED);
- }
-
- GetConstruction().UpdatePhysics();
- UpdateNavmesh();
- }
-
- void UpdateAttachmentPhysics( string slot_name, bool is_locked )
- {
- //checks for invalid appends; hotfix
- if ( !m_Mountables || m_Mountables.Find(slot_name) == -1 )
- return;
- //----------------------------------
- string slot_name_mounted = slot_name + "_Mounted";
- EntityAI attachment = FindAttachmentBySlotName( slot_name );
-
- //remove proxy physics
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + " Removing ATT SLOT=" + slot_name + " RM / RM");
- RemoveProxyPhysics( slot_name_mounted );
- RemoveProxyPhysics( slot_name );
-
- if ( attachment )
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + " Adding ATT=" + Object.GetDebugName(attachment));
- if ( is_locked )
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + " RM / RM");
- AddProxyPhysics( slot_name_mounted );
- }
- else
- {
- if (LogManager.IsBaseBuildingLogEnable()) bsbDebugPrint("[bsb] " + GetDebugName(this) + " ADD");
- AddProxyPhysics( slot_name );
- }
- }
- }
-
- protected void UpdateNavmesh()
- {
- SetAffectPathgraph( true, false );
- GetGame().GetCallQueue( CALL_CATEGORY_SYSTEM ).CallLater( GetGame().UpdatePathgraphRegionByObject, 100, false, this );
- }
-
- override bool CanUseConstruction()
- {
- return true;
- }
-
- override bool CanUseConstructionBuild()
- {
- return true;
- }
- protected bool IsAttachmentSlotLocked( EntityAI attachment )
- {
- if ( attachment )
- {
- InventoryLocation inventory_location = new InventoryLocation;
- attachment.GetInventory().GetCurrentInventoryLocation( inventory_location );
-
- return GetInventory().GetSlotLock( inventory_location.GetSlot() );
- }
-
- return false;
- }
-
- protected bool IsAttachmentSlotLocked( string slot_name )
- {
- return GetInventory().GetSlotLock( InventorySlots.GetSlotIdFromString( slot_name ) );
- }
-
- //--- ATTACHMENT SLOTS
- void GetAttachmentSlots( EntityAI entity, out array<string> attachment_slots )
- {
- string config_path = "CfgVehicles" + " " + entity.GetType() + " " + "attachments";
- if ( GetGame().ConfigIsExisting( config_path ) )
- {
- GetGame().ConfigGetTextArray( config_path, attachment_slots );
- }
- }
- bool CheckSlotVerticalDistance( int slot_id, PlayerBase player )
- {
- return true;
- }
-
- protected bool CheckMemoryPointVerticalDistance( float max_dist, string selection, PlayerBase player )
- {
- return true;
- }
-
- protected bool CheckLevelVerticalDistance( float max_dist, string selection, PlayerBase player )
- {
- return true;
- }
-
- // --- INIT
- void ConstructionInit()
- {
- if ( !m_Construction )
- {
- m_Construction = new Construction( this );
- }
-
- GetConstruction().Init();
- }
-
- Construction GetConstruction()
- {
- return m_Construction;
- }
-
- //--- INVENTORY/ATTACHMENTS CONDITIONS
- //attachments
- override bool CanReceiveAttachment( EntityAI attachment, int slotId )
- {
- return super.CanReceiveAttachment(attachment, slotId);
- }
-
- bool HasAttachmentsBesidesBase()
- {
- int attachment_count = GetInventory().AttachmentCount();
- if ( attachment_count > 0 )
- {
- if ( HasBase() && attachment_count == 1 )
- {
- return false;
- }
-
- return true;
- }
-
- return false;
- }
-
- override bool ShowZonesHealth()
- {
- return true;
- }
-
- override bool IsTakeable()
- {
- return false;
- }
-
- //this into/outo parent.Cargo
- override bool CanPutInCargo( EntityAI parent )
- {
- return false;
- }
-
- override bool CanRemoveFromCargo( EntityAI parent )
- {
- return false;
- }
- //hands
- override bool CanPutIntoHands( EntityAI parent )
- {
- return false;
- }
-
- //--- ACTION CONDITIONS
- //direction
- override bool IsFacingPlayer( PlayerBase player, string selection )
- {
- return true;
- }
-
- override bool IsPlayerInside( PlayerBase player, string selection )
- {
- return true;
- }
-
- //! Some buildings can only be built from outside
- bool MustBeBuiltFromOutside()
- {
- return false;
- }
-
- //camera direction check
- bool IsFacingCamera( string selection )
- {
- return true;
- }
-
- //roof check
- bool PerformRoofCheckForBase( string partName, PlayerBase player, out bool result )
- {
- return false;
- }
-
- //selection->player distance check
- bool HasProperDistance( string selection, PlayerBase player )
- {
- return true;
- }
-
- //folding
- bool CanFoldBaseBuildingObject()
- {
- if ( HasBase() || GetInventory().AttachmentCount() > 0 )
- {
- return false;
- }
-
- return true;
- }
-
- ItemBase FoldBaseBuildingObject()
- {
- ItemBase item = CreateConstructionKit();
- DestroyConstruction();
- return item;
- }
-
- //Damage triggers (barbed wire)
- void CreateAreaDamage( string slot_name, float rotation_angle = 0 )
- {
- if ( GetGame() && GetGame().IsServer() )
- {
- //destroy area damage if some already exists
- DestroyAreaDamage( slot_name );
-
- //create new area damage
- AreaDamageLoopedDeferred_NoVehicle areaDamage = new AreaDamageLoopedDeferred_NoVehicle( this );
- areaDamage.SetDamageComponentType(AreaDamageComponentTypes.HITZONE);
-
- vector min_max[2];
- if ( MemoryPointExists( slot_name + "_min" ) )
- {
- min_max[0] = GetMemoryPointPos( slot_name + "_min" );
- }
- if ( MemoryPointExists( slot_name + "_max" ) )
- {
- min_max[1] = GetMemoryPointPos( slot_name + "_max" );
- }
-
- //get proper trigger extents (min<max)
- vector extents[2];
- GetConstruction().GetTriggerExtents( min_max, extents );
-
- //get box center
- vector center;
- center = GetConstruction().GetBoxCenter( min_max );
- center = ModelToWorld( center );
-
- //rotate center if needed
- vector orientation = GetOrientation();;
- CalcDamageAreaRotation( rotation_angle, center, orientation );
-
- areaDamage.SetExtents( extents[0], extents[1] );
- areaDamage.SetAreaPosition( center );
- areaDamage.SetAreaOrientation( orientation );
- areaDamage.SetLoopInterval( 1.0 );
- areaDamage.SetDeferDuration( 0.2 );
- areaDamage.SetHitZones( { "Torso","LeftHand","LeftLeg","LeftFoot","RightHand","RightLeg","RightFoot" } );
- areaDamage.SetAmmoName( "BarbedWireHit" );
- areaDamage.Spawn();
-
- m_DamageTriggers.Insert( slot_name, areaDamage );
- }
- }
-
- void CalcDamageAreaRotation( float angle_deg, out vector center, out vector orientation )
- {
- if ( angle_deg != 0 )
- {
- //orientation
- orientation[0] = orientation[0] - angle_deg;
-
- //center
- vector rotate_axis;
- if ( MemoryPointExists( "rotate_axis" ) )
- {
- rotate_axis = ModelToWorld( GetMemoryPointPos( "rotate_axis" ) );
- }
- float r_center_x = ( Math.Cos( angle_deg * Math.DEG2RAD ) * ( center[0] - rotate_axis[0] ) ) - ( Math.Sin( angle_deg * Math.DEG2RAD ) * ( center[2] - rotate_axis[2] ) ) + rotate_axis[0];
- float r_center_z = ( Math.Sin( angle_deg * Math.DEG2RAD ) * ( center[0] - rotate_axis[0] ) ) + ( Math.Cos( angle_deg * Math.DEG2RAD ) * ( center[2] - rotate_axis[2] ) ) + rotate_axis[2];
- center[0] = r_center_x;
- center[2] = r_center_z;
- }
- }
-
- void DestroyAreaDamage( string slot_name )
- {
- if (GetGame() && GetGame().IsServer())
- {
- AreaDamageLoopedDeferred_NoVehicle areaDamage;
- if (m_DamageTriggers.Find(slot_name, areaDamage))
- {
- if (areaDamage)
- {
- areaDamage.Destroy();
- }
-
- m_DamageTriggers.Remove( slot_name );
- }
- }
- }
-
- override bool IsIgnoredByConstruction()
- {
- return true;
- }
-
- //================================================================
- // SOUNDS
- //================================================================
- protected void SoundBuildStart( string part_name )
- {
- PlaySoundSet( m_Sound, GetBuildSoundByMaterial( part_name ), 0.1, 0.1 );
- }
- protected void SoundDismantleStart( string part_name )
- {
- PlaySoundSet( m_Sound, GetDismantleSoundByMaterial( part_name ), 0.1, 0.1 );
- }
-
- protected void SoundDestroyStart( string part_name )
- {
- PlaySoundSet( m_Sound, GetDismantleSoundByMaterial( part_name ), 0.1, 0.1 );
- }
-
- protected string GetBuildSoundByMaterial( string part_name )
- {
- ConstructionMaterialType material_type = GetConstruction().GetMaterialType( part_name );
-
- switch ( material_type )
- {
- case ConstructionMaterialType.MATERIAL_LOG: return SOUND_BUILD_WOOD_LOG;
- case ConstructionMaterialType.MATERIAL_WOOD: return SOUND_BUILD_WOOD_PLANK;
- case ConstructionMaterialType.MATERIAL_STAIRS: return SOUND_BUILD_WOOD_STAIRS;
- case ConstructionMaterialType.MATERIAL_METAL: return SOUND_BUILD_METAL;
- case ConstructionMaterialType.MATERIAL_WIRE: return SOUND_BUILD_WIRE;
- }
-
- return "";
- }
-
- protected string GetDismantleSoundByMaterial( string part_name )
- {
- ConstructionMaterialType material_type = GetConstruction().GetMaterialType( part_name );
-
- switch ( material_type )
- {
- case ConstructionMaterialType.MATERIAL_LOG: return SOUND_DISMANTLE_WOOD_LOG;
- case ConstructionMaterialType.MATERIAL_WOOD: return SOUND_DISMANTLE_WOOD_PLANK;
- case ConstructionMaterialType.MATERIAL_STAIRS: return SOUND_DISMANTLE_WOOD_STAIRS;
- case ConstructionMaterialType.MATERIAL_METAL: return SOUND_DISMANTLE_METAL;
- case ConstructionMaterialType.MATERIAL_WIRE: return SOUND_DISMANTLE_WIRE;
- }
-
- return "";
- }
-
- //misc
- void CheckForHybridAttachments( EntityAI item, string slot_name )
- {
- if (!GetGame().IsMultiplayer() || GetGame().IsServer())
- {
- //if this is a hybrid attachment, set damage of appropriate damage zone. Zone name must match slot name...WIP
- if (m_HybridAttachments && m_HybridAttachments.Find(slot_name) != -1)
- {
- SetHealth(slot_name,"Health",item.GetHealth());
- }
- }
- }
-
- override int GetDamageSystemVersionChange()
- {
- return 111;
- }
-
- override void SetActions()
- {
- super.SetActions();
-
- AddAction(ActionDetachFromTarget);
- RemoveAction(ActionTakeItem);
- RemoveAction(ActionTakeItemToHands);
- }
-
- //================================================================
- // DEBUG
- //================================================================
- protected void DebugCustomState()
- {
- }
-
- //! Excludes certain parts from being built by OnDebugSpawn, uses Contains to compare
- array<string> OnDebugSpawnBuildExcludes()
- {
- return null;
- }
-
- override void OnDebugSpawn()
- {
- FullyBuild();
- }
-
- void FullyBuild()
- {
- array<string> excludes = OnDebugSpawnBuildExcludes();
- array<ConstructionPart> parts = GetConstruction().GetConstructionParts().GetValueArray();
-
- Man p;
-
- #ifdef SERVER
- array<Man> players = new array<Man>;
- GetGame().GetWorld().GetPlayerList(players);
- if (players.Count())
- p = players[0];
- #else
- p = GetGame().GetPlayer();
- #endif
-
- foreach (ConstructionPart part : parts)
- {
- bool excluded = false;
- string partName = part.GetPartName();
- if (excludes)
- {
- foreach (string exclude : excludes)
- {
- if (partName.Contains(exclude))
- {
- excluded = true;
- break;
- }
- }
- }
-
- if (!excluded)
- {
- OnPartBuiltServer(p, partName, AT_BUILD_PART);
- }
- }
-
- GetConstruction().UpdateVisuals();
- }
- }
- void bsbDebugPrint (string s)
- {
- #ifdef BSB_DEBUG
- PrintToRPT("" + s); // comment/uncomment to hide/see debug logs
- #else
- //Print("" + s); // comment/uncomment to hide/see debug logs
- #endif
- }
- void bsbDebugSpam (string s)
- {
- #ifdef BSB_DEBUG_SPAM
- PrintToRPT("" + s); // comment/uncomment to hide/see debug logs
- #else
- //Print("" + s); // comment/uncomment to hide/see debug logs
- #endif
- }
|