fireplace.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. class Fireplace extends FireplaceBase
  2. {
  3. bool m_ContactEventProcessing = false;
  4. protected bool m_ContactDeletionProcessing = false;
  5. void Fireplace()
  6. {
  7. //Particles - default for FireplaceBase
  8. PARTICLE_FIRE_START = ParticleList.CAMP_FIRE_START;
  9. PARTICLE_SMALL_FIRE = ParticleList.CAMP_SMALL_FIRE;
  10. PARTICLE_NORMAL_FIRE = ParticleList.CAMP_NORMAL_FIRE;
  11. PARTICLE_SMALL_SMOKE = ParticleList.CAMP_SMALL_SMOKE;
  12. PARTICLE_NORMAL_SMOKE = ParticleList.CAMP_NORMAL_SMOKE;
  13. PARTICLE_FIRE_END = ParticleList.CAMP_FIRE_END;
  14. PARTICLE_STEAM_END = ParticleList.CAMP_STEAM_2END;
  15. SetEventMask( EntityEvent.CONTACT | EntityEvent.TOUCH );
  16. //! universal temperature sources overrides
  17. m_UTSSettings.m_TemperatureItemCap = GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE;
  18. m_UTSSettings.m_TemperatureCap = 20;
  19. m_ThawnSurfaceUnderSupport = true;
  20. }
  21. override protected void InitializeTemperatureSources()
  22. {
  23. m_UTSLFireplace = new UniversalTemperatureSourceLambdaFireplace();
  24. m_UTSLFireplace.SetSmallFireplaceTemperatureMax(PARAM_SMALL_FIRE_TEMPERATURE);
  25. m_UTSLFireplace.SetNormalFireplaceTemperatureMax(PARAM_OUTDOOR_FIRE_TEMPERATURE);
  26. m_UTSource = new UniversalTemperatureSource(this, m_UTSSettings, m_UTSLFireplace);
  27. }
  28. override bool IsBaseFireplace()
  29. {
  30. return true;
  31. }
  32. override bool CanObstruct()
  33. {
  34. return IsOven();
  35. }
  36. override bool CanProxyObstruct()
  37. {
  38. return IsOven();
  39. }
  40. override void EOnTouch( IEntity other, int extra )
  41. {
  42. ContactEvent( other, GetPosition() );
  43. }
  44. override void EOnContact( IEntity other, Contact extra )
  45. {
  46. ContactEvent( other, extra.Position );
  47. }
  48. void ContactEvent( IEntity other, vector position )
  49. {
  50. if (GetGame().IsServer() && !m_ContactEventProcessing && dBodyIsActive(this) && !IsSetForDeletion())
  51. m_ContactEventProcessing = true;
  52. }
  53. override protected void EOnPostSimulate(IEntity other, float timeSlice)
  54. {
  55. super.EOnPostSimulate(other,timeSlice);
  56. if (m_ContactEventProcessing && !m_ContactDeletionProcessing)
  57. {
  58. MiscGameplayFunctions.ThrowAllItemsInInventory(this, 0);
  59. CheckForDestroy();
  60. m_ContactDeletionProcessing = true;
  61. }
  62. }
  63. //attachments
  64. override bool CanReceiveAttachment( EntityAI attachment, int slotId )
  65. {
  66. if ( !super.CanReceiveAttachment(attachment, slotId) )
  67. return false;
  68. ItemBase item = ItemBase.Cast( attachment );
  69. //cookware
  70. if ( ( item.Type() == ATTACHMENT_CAULDRON ) || ( item.Type() == ATTACHMENT_COOKING_POT ) )
  71. {
  72. if ( FindAttachmentBySlotName( "CookingTripod" ) || IsOven() )
  73. return true;
  74. return false;
  75. }
  76. if ( item.Type() == ATTACHMENT_FRYING_PAN )
  77. {
  78. if ( IsOven() )
  79. return true;
  80. return false;
  81. }
  82. // food on direct cooking slots
  83. if ( item.IsKindOf( "Edible_Base" ) )
  84. {
  85. if ( IsOven() )
  86. return true;
  87. return false;
  88. }
  89. //tripod
  90. if ( item.IsInherited(TripodBase) )
  91. {
  92. if (!IsOven() && !GetHierarchyParent())
  93. return true;
  94. return false;
  95. }
  96. //stones
  97. if ( item.Type() == ATTACHMENT_STONES )
  98. {
  99. if ( !GetHierarchyParent() && !IsBurning() )
  100. return true;
  101. return false;
  102. }
  103. return true;
  104. }
  105. override bool CanDisplayAttachmentSlot( int slot_id )
  106. {
  107. string slot_name = InventorySlots.GetSlotName(slot_id);
  108. if ( super.CanDisplayAttachmentSlot(slot_id) )
  109. {
  110. if ( slot_name != "CookingEquipment" || FindAttachmentBySlotName( "CookingTripod" ) )
  111. return true;
  112. }
  113. return false;
  114. }
  115. override bool CanLoadAttachment( EntityAI attachment )
  116. {
  117. if ( !super.CanLoadAttachment(attachment) )
  118. return false;
  119. ItemBase item = ItemBase.Cast( attachment );
  120. //cookware
  121. if ( ( item.Type() == ATTACHMENT_CAULDRON ) || ( item.Type() == ATTACHMENT_COOKING_POT ) )
  122. {
  123. //if ( IsItemTypeAttached( ATTACHMENT_TRIPOD ) /*|| IsOven()*/ )
  124. return true;
  125. }
  126. if ( item.Type() == ATTACHMENT_FRYING_PAN )
  127. {
  128. //if ( IsOven() )
  129. return true;
  130. }
  131. // food on direct cooking slots
  132. //if ( IsOven() )
  133. //{
  134. if ( item.IsKindOf( "Edible_Base" ) )
  135. return true;
  136. //}
  137. //tripod
  138. if ( item.Type() == ATTACHMENT_TRIPOD )
  139. {
  140. if ( /*!IsOven() &&*/ GetHierarchyParent() == NULL )
  141. return true;
  142. }
  143. //stones
  144. if ( item.Type() == ATTACHMENT_STONES )
  145. {
  146. if ( GetHierarchyParent() /*|| IsBurning()*/ )
  147. return false;
  148. return true;
  149. }
  150. return true;
  151. }
  152. override bool CanReleaseAttachment( EntityAI attachment )
  153. {
  154. if (!super.CanReleaseAttachment(attachment))
  155. {
  156. return false;
  157. }
  158. ItemBase item = ItemBase.Cast(attachment);
  159. //stones
  160. if (item.Type() == ATTACHMENT_STONES)
  161. {
  162. if (IsBurning())
  163. {
  164. return false;
  165. }
  166. int stone_quantity = item.GetQuantity();
  167. if (HasStoneCircle() && stone_quantity <= 8)
  168. {
  169. return false;
  170. }
  171. if (IsOven())
  172. {
  173. return false;
  174. }
  175. }
  176. return true;
  177. }
  178. override void EEItemAttached(EntityAI item, string slot_name)
  179. {
  180. super.EEItemAttached(item, slot_name);
  181. ItemBase item_base = ItemBase.Cast(item);
  182. if (IsKindling(item_base) || IsFuel(item_base))
  183. {
  184. AddToFireConsumables(item_base);
  185. }
  186. //cookware
  187. if (item_base.IsCookware())
  188. SetCookingEquipment(item_base);
  189. if (GetGame().IsServer() && !IsOven())
  190. {
  191. if (item_base.Type() == ATTACHMENT_COOKING_POT)
  192. item_base.SetAnimationPhase(ANIMATION_COOKWARE_HANDLE, 0);
  193. if (item.Type() == ATTACHMENT_CAULDRON)
  194. item_base.SetAnimationPhase(ANIMATION_CAULDRON_HANDLE, 0);
  195. }
  196. // direct cooking/smoking slots
  197. bool edible_base_attached = false;
  198. switch (slot_name)
  199. {
  200. case "DirectCookingA":
  201. m_DirectCookingSlots[0] = item_base;
  202. edible_base_attached = true;
  203. break;
  204. case "DirectCookingB":
  205. m_DirectCookingSlots[1] = item_base;
  206. edible_base_attached = true;
  207. break;
  208. case "DirectCookingC":
  209. m_DirectCookingSlots[2] = item_base;
  210. edible_base_attached = true;
  211. break;
  212. case "SmokingA":
  213. m_SmokingSlots[0] = item_base;
  214. edible_base_attached = true;
  215. break;
  216. case "SmokingB":
  217. m_SmokingSlots[1] = item_base;
  218. edible_base_attached = true;
  219. break;
  220. case "SmokingC":
  221. m_SmokingSlots[2] = item_base;
  222. edible_base_attached = true;
  223. break;
  224. case "SmokingD":
  225. m_SmokingSlots[3] = item_base;
  226. edible_base_attached = true;
  227. break;
  228. }
  229. //TODO
  230. //add SetViewIndex when attaching various attachments
  231. RefreshFireplaceVisuals();
  232. }
  233. override void EEItemDetached(EntityAI item, string slot_name)
  234. {
  235. super.EEItemDetached(item, slot_name);
  236. ItemBase item_base = ItemBase.Cast(item);
  237. if (IsKindling(item_base) || IsFuel(item_base))
  238. {
  239. RemoveFromFireConsumables(GetFireConsumableByItem(item_base));
  240. }
  241. //cookware
  242. if (item_base.IsCookware())
  243. {
  244. ClearCookingEquipment(item_base);
  245. item_base.RemoveAudioVisualsOnClient();
  246. }
  247. if (item_base.IsLiquidContainer()) //boiling bottle effects stop
  248. item_base.RemoveAudioVisualsOnClient();
  249. if (GetGame().IsServer())
  250. {
  251. if (item_base.Type() == ATTACHMENT_COOKING_POT)
  252. item_base.SetAnimationPhase(ANIMATION_COOKWARE_HANDLE, 1);
  253. if (item_base.Type() == ATTACHMENT_CAULDRON)
  254. item_base.SetAnimationPhase(ANIMATION_CAULDRON_HANDLE, 1);
  255. }
  256. // direct cooking/smoking slots
  257. switch (slot_name)
  258. {
  259. case "DirectCookingA":
  260. m_DirectCookingSlots[0] = null;
  261. break;
  262. case "DirectCookingB":
  263. m_DirectCookingSlots[1] = null;
  264. break;
  265. case "DirectCookingC":
  266. m_DirectCookingSlots[2] = null;
  267. break;
  268. case "SmokingA":
  269. m_SmokingSlots[0] = null;
  270. break;
  271. case "SmokingB":
  272. m_SmokingSlots[1] = null;
  273. break;
  274. case "SmokingC":
  275. m_SmokingSlots[2] = null;
  276. break;
  277. case "SmokingD":
  278. m_SmokingSlots[3] = null;
  279. break;
  280. }
  281. //no attachments left, no cargo items & no ashes are present
  282. CheckForDestroy();
  283. RefreshFireplaceVisuals();
  284. }
  285. override void SetCookingEquipment(ItemBase equipment)
  286. {
  287. super.SetCookingEquipment(equipment);
  288. TripodBase stand = TripodBase.Cast(FindAttachmentBySlotName("CookingTripod"));
  289. if (stand)
  290. {
  291. if (equipment)
  292. stand.LockToParent();
  293. else
  294. stand.UnlockFromParent();
  295. }
  296. }
  297. override void OnBeforeTryDelete()
  298. {
  299. super.OnBeforeTryDelete();
  300. MiscGameplayFunctions.DropAllItemsInInventoryInBounds(this, m_HalfExtents);
  301. }
  302. override bool IsPrepareToDelete()
  303. {
  304. return GetInventory().AttachmentCount() == 0 && !IsBurning() && !HasAshes();
  305. }
  306. //CONDITIONS
  307. //this into/outo parent.Cargo
  308. override bool CanPutInCargo(EntityAI parent)
  309. {
  310. if (!super.CanPutInCargo(parent))
  311. {
  312. return false;
  313. }
  314. if (HasAshes() || IsBurning() || HasStones() || HasStoneCircle() || IsOven() || !IsCargoEmpty() || HasCookingStand())
  315. {
  316. return false;
  317. }
  318. return true;
  319. }
  320. override bool CanRemoveFromCargo( EntityAI parent )
  321. {
  322. return true;
  323. }
  324. //cargo item into/outo this.Cargo
  325. override bool CanReceiveItemIntoCargo( EntityAI item )
  326. {
  327. if ( GetHierarchyParent() )
  328. return false;
  329. return super.CanReceiveItemIntoCargo( item );
  330. }
  331. override bool CanLoadItemIntoCargo( EntityAI item )
  332. {
  333. if (!super.CanLoadItemIntoCargo( item ))
  334. return false;
  335. if ( GetHierarchyParent() )
  336. return false;
  337. return true;
  338. }
  339. //hands
  340. override bool CanPutIntoHands(EntityAI parent)
  341. {
  342. if (!super.CanPutIntoHands(parent))
  343. {
  344. return false;
  345. }
  346. if (HasAshes() || IsBurning() || HasStones() || HasStoneCircle() || IsOven() || !IsCargoEmpty() || HasCookingStand())
  347. {
  348. return false;
  349. }
  350. return true;
  351. }
  352. override bool CanDisplayAttachmentCategory( string category_name )
  353. {
  354. if ( !super.CanDisplayAttachmentCategory( category_name ) )
  355. return false;
  356. if ( IsOven() )
  357. {
  358. if ( category_name == "CookingEquipment" )
  359. return false;
  360. if ( ( category_name == "DirectCooking" ) || ( category_name == "Smoking" ) )
  361. return true;
  362. }
  363. else
  364. {
  365. if ( category_name == "CookingEquipment" )
  366. return true;
  367. if ( ( category_name == "DirectCooking" ) || ( category_name == "Smoking" ) )
  368. return false;
  369. }
  370. return true;
  371. }
  372. override bool CanAssignAttachmentsToQuickbar()
  373. {
  374. return false;
  375. }
  376. override float HeightStartCheckOverride()
  377. {
  378. return 0.5;
  379. }
  380. //particles
  381. override bool CanShowSmoke()
  382. {
  383. return !IsOven();
  384. }
  385. void DestroyClutterCutter( Object clutter_cutter )
  386. {
  387. GetGame().ObjectDelete( clutter_cutter );
  388. }
  389. override void RefreshPhysics()
  390. {
  391. super.RefreshPhysics();
  392. //Oven
  393. if ( IsOven() )
  394. {
  395. RemoveProxyPhysics( ANIMATION_OVEN );
  396. AddProxyPhysics( ANIMATION_OVEN );
  397. }
  398. else
  399. {
  400. RemoveProxyPhysics( ANIMATION_OVEN );
  401. }
  402. //Tripod
  403. if ( IsItemTypeAttached( ATTACHMENT_TRIPOD ) )
  404. {
  405. RemoveProxyPhysics( ANIMATION_TRIPOD );
  406. AddProxyPhysics( ANIMATION_TRIPOD );
  407. }
  408. else
  409. {
  410. RemoveProxyPhysics( ANIMATION_TRIPOD );
  411. }
  412. }
  413. override void RefreshFireplacePhysics()
  414. {
  415. RefreshPhysics();
  416. }
  417. //on store save/load
  418. override void OnStoreSave( ParamsWriteContext ctx )
  419. {
  420. super.OnStoreSave(ctx);
  421. if ( GetGame().SaveVersion() >= 110 )
  422. {
  423. // save stone circle state
  424. ctx.Write( m_HasStoneCircle );
  425. // save stone oven state
  426. ctx.Write( m_IsOven );
  427. }
  428. }
  429. override bool OnStoreLoad( ParamsReadContext ctx, int version )
  430. {
  431. if ( !super.OnStoreLoad(ctx, version) )
  432. return false;
  433. if ( version >= 110 )
  434. {
  435. // read stone circle state
  436. if ( !ctx.Read( m_HasStoneCircle ) )
  437. {
  438. m_HasStoneCircle = false;
  439. return false;
  440. }
  441. // read stone oven state
  442. if ( !ctx.Read( m_IsOven ) )
  443. {
  444. m_IsOven = false;
  445. return false;
  446. }
  447. }
  448. return true;
  449. }
  450. override void AfterStoreLoad()
  451. {
  452. super.AfterStoreLoad();
  453. if ( IsBurning() )
  454. {
  455. if ( !m_ClutterCutter )
  456. {
  457. m_ClutterCutter = GetGame().CreateObjectEx( OBJECT_CLUTTER_CUTTER, GetPosition(), ECE_PLACE_ON_SURFACE );
  458. m_ClutterCutter.SetOrientation( GetOrientation() );
  459. }
  460. }
  461. }
  462. //================================================================
  463. // IGNITION ACTION
  464. //================================================================
  465. // Item-to-item fire distribution
  466. override bool HasFlammableMaterial()
  467. {
  468. return true;
  469. }
  470. override bool CanBeIgnitedBy(EntityAI igniter = NULL)
  471. {
  472. return HasAnyKindling() && !IsBurning() && !GetHierarchyParent();
  473. }
  474. override bool CanIgniteItem(EntityAI ignite_target = NULL)
  475. {
  476. return IsBurning();
  477. }
  478. override bool IsIgnited()
  479. {
  480. return IsBurning();
  481. }
  482. override void OnIgnitedTarget( EntityAI target_item )
  483. {
  484. }
  485. override void OnIgnitedThis( EntityAI fire_source )
  486. {
  487. //remove grass
  488. Object cc_object = GetGame().CreateObjectEx( OBJECT_CLUTTER_CUTTER , GetPosition(), ECE_PLACE_ON_SURFACE );
  489. cc_object.SetOrientation ( GetOrientation() );
  490. GetGame().GetCallQueue( CALL_CATEGORY_GAMEPLAY ).CallLater( DestroyClutterCutter, 200, false, cc_object );
  491. //start fire
  492. StartFire();
  493. if ( fire_source )
  494. {
  495. Man player = fire_source.GetHierarchyRootPlayer();
  496. if ( player )
  497. {
  498. EFireIgniteType ignate_type = EFireIgniteType.Unknow;
  499. if ( fire_source.ClassName() == "Matchbox" )
  500. {
  501. ignate_type = EFireIgniteType.Matchbox;
  502. }
  503. else if ( fire_source.ClassName() == "Roadflare" )
  504. {
  505. ignate_type = EFireIgniteType.Roadflare;
  506. }
  507. else if ( fire_source.ClassName() == "HandDrillKit" )
  508. {
  509. ignate_type = EFireIgniteType.HandDrill;
  510. }
  511. SyncEvents.SendPlayerIgnatedFireplace( player, ignate_type );
  512. }
  513. }
  514. }
  515. override bool IsThisIgnitionSuccessful( EntityAI item_source = NULL )
  516. {
  517. SetIgniteFailure( false );
  518. Param1<bool> failure;
  519. //check kindling
  520. if ( !HasAnyKindling() )
  521. {
  522. return false;
  523. }
  524. //check roof
  525. if ( !IsOven() )
  526. {
  527. if ( !IsCeilingHighEnoughForSmoke() && IsOnInteriorSurface() )
  528. {
  529. return false;
  530. }
  531. }
  532. //check surface
  533. if ( IsOnWaterSurface() )
  534. {
  535. return false;
  536. }
  537. //check wetness
  538. if ( IsWet() )
  539. {
  540. SetIgniteFailure( true );
  541. failure = new Param1<bool>( GetIgniteFailure() );
  542. GetGame().RPCSingleParam( this, FirePlaceFailure.WET, failure, true );
  543. return false;
  544. }
  545. // check if the fireplace isnt below a roof
  546. // excluding this check whein oven stage
  547. CheckForRoofLimited(0);
  548. if ( !IsOven() && !IsRoofAbove() )
  549. {
  550. // if not, check if there is strong rain or wind
  551. if ( IsRainingAbove() )
  552. {
  553. SetIgniteFailure( true );
  554. failure = new Param1<bool>( GetIgniteFailure() );
  555. GetGame().RPCSingleParam( this, FirePlaceFailure.WET, failure, true );
  556. return false;
  557. }
  558. if ( IsWindy() )
  559. {
  560. SetIgniteFailure( true );
  561. failure = new Param1<bool>( GetIgniteFailure() );
  562. GetGame().RPCSingleParam( this, FirePlaceFailure.WIND, failure, true );
  563. return false;
  564. }
  565. }
  566. return true;
  567. }
  568. //================================================================
  569. // FIREPLACE ENTITY
  570. //================================================================
  571. static Fireplace IgniteEntityAsFireplace( notnull EntityAI entity, notnull EntityAI fire_source )
  572. {
  573. //get player
  574. PlayerBase player = PlayerBase.Cast( fire_source.GetHierarchyRootPlayer() );
  575. //create fireplace
  576. Fireplace fireplace = Fireplace.Cast( GetGame().CreateObjectEx( "Fireplace" , entity.GetPosition(), ECE_PLACE_ON_SURFACE ) );
  577. //attach
  578. if ( !GetGame().IsMultiplayer() ) //clear inventory reservation (single player)
  579. {
  580. InventoryLocation loc = new InventoryLocation;
  581. entity.GetInventory().GetCurrentInventoryLocation( loc );
  582. player.GetInventory().ClearInventoryReservationEx( entity, loc );
  583. }
  584. if ( GetGame().IsServer() && GetGame().IsMultiplayer() )
  585. {
  586. player.ServerTakeEntityToTargetAttachment( fireplace, entity ); // multiplayer server side
  587. }
  588. else
  589. {
  590. player.LocalTakeEntityToTargetAttachment( fireplace, entity ); // single player or multiplayer client side
  591. }
  592. //start fire
  593. fireplace.StartFire();
  594. fireplace.OnIgnitedThis(fire_source);
  595. return fireplace;
  596. }
  597. static bool CanIgniteEntityAsFireplace(notnull EntityAI entity)
  598. {
  599. //check surface
  600. if (FireplaceBase.IsEntityOnWaterSurface(entity))
  601. {
  602. return false;
  603. }
  604. entity.CheckForRoofLimited(); //TODO: limit more severely? Should update at least once during UATimeSpent.FIREPLACE_IGNITE
  605. if (!entity.IsRoofAbove())
  606. return !FireplaceBase.IsRainingAboveEntity(entity);
  607. //check ceiling (enough space for smoke)
  608. if (IsEntityOnInteriorSurface(entity) && MiscGameplayFunctions.IsUnderRoof(entity, FireplaceBase.MIN_CEILING_HEIGHT))
  609. {
  610. return false;
  611. }
  612. return true;
  613. }
  614. //================================================================
  615. // ADVANCED PLACEMENT
  616. //================================================================
  617. override void SetActions()
  618. {
  619. super.SetActions();
  620. AddAction(ActionPlaceFireplaceIntoBarrel);
  621. AddAction(ActionPlaceFireplaceIndoor);
  622. AddAction(ActionPlaceOvenIndoor);
  623. AddAction(ActionTogglePlaceObject);
  624. AddAction(ActionPlaceObject);
  625. AddAction(ActionBuildOven);
  626. AddAction(ActionDismantleOven);
  627. AddAction(ActionBuildStoneCircle);
  628. AddAction(ActionDismantleStoneCircle);
  629. }
  630. }