1- namespace XSharp . Engine . Entities . Enemies . DigLabour ;
1+ using SharpDX ;
22
3- public class DigLabour : Enemy
3+ using XSharp . Engine . Graphics ;
4+ using XSharp . Math ;
5+ using XSharp . Math . Geometry ;
6+
7+ using static XSharp . Engine . Consts ;
8+
9+ namespace XSharp . Engine . Entities . Enemies . DigLabour ;
10+
11+ public enum DigLabourState
412{
13+ IDLE ,
14+ ATTACKING ,
15+ LAUGHING
16+ }
17+
18+ public class DigLabour : Enemy , IStateEntity < DigLabourState >
19+ {
20+ #region StaticFields
21+ public static readonly Color [ ] PALETTE = new Color [ ]
22+ {
23+ Color . Transparent , // 0
24+ Color . FromBgra ( 0xFF406830 ) , // 1
25+ Color . FromBgra ( 0xFF70B888 ) , // 2
26+ Color . FromBgra ( 0xFFD0E0B0 ) , // 3
27+ Color . FromBgra ( 0xFFB85820 ) , // 4
28+ Color . FromBgra ( 0xFFE8A040 ) , // 5
29+ Color . FromBgra ( 0xFFF8D888 ) , // 6
30+ Color . FromBgra ( 0xFF405880 ) , // 7
31+ Color . FromBgra ( 0xFF6098C8 ) , // 8
32+ Color . FromBgra ( 0xFFA0D8F8 ) , // 9
33+ Color . FromBgra ( 0xFF705870 ) , // A
34+ Color . FromBgra ( 0xFFA090A0 ) , // B
35+ Color . FromBgra ( 0xFFE0D0E0 ) , // C
36+ Color . FromBgra ( 0xFF783830 ) , // D
37+ Color . FromBgra ( 0xFFF87858 ) , // E
38+ Color . FromBgra ( 0xFF302020 ) // F
39+ } ;
40+
41+ public const int HEALTH = 8 ;
42+ public static readonly FixedSingle CONTACT_DAMAGE = 2 ;
43+ public static readonly Box HITBOX = ( ( 0 , 1 ) , ( - 11 , - 17 ) , ( 11 , 17 ) ) ;
44+ public static readonly Box COLLISION_BOX = ( ( 0 , 0 ) , ( - 11 , - 17 ) , ( 11 , 17 ) ) ;
45+
46+ public const int IDLE_AFTER_ATTACKING_FRAMES = 90 ;
47+ public const int IDLE_AFTER_LAUGHING_FRAMES = 50 ;
48+ public const int ATTACKING_FRAMES = 38 ;
49+ public const int LAUGHING_FRAMES = 80 ;
50+ public const int FRAME_TO_THROW_PICKAXE = 18 ;
51+
52+ public static readonly FixedSingle PICKAXE_INITIAL_SPEED = 1536 / 256.0 ;
53+ public static readonly Box PICKAXE_HITBOX = ( ( 0 , 0 ) , ( - 11 , - 12 ) , ( 11 , 12 ) ) ;
54+ public const int PICKAXE_DAMAGE = 2 ;
55+ public static readonly FixedSingle PICKAXE_SPAWN_OFFSET_X = 20 ;
56+ public static readonly FixedSingle PICKAXE_SPAWN_OFFSET_Y = - 12 ;
57+ #endregion
58+
59+ #region Precache
60+ [ Precache ]
61+ new internal static void Precache ( )
62+ {
63+ var palette = Engine . PrecachePalette ( "DigLabourPalette" , PALETTE ) ;
64+ var spriteSheet = Engine . CreateSpriteSheet ( "DigLabour" , true , true ) ;
65+
66+ spriteSheet . CurrentTexture = Engine . CreateImageTextureFromEmbeddedResource ( "Sprites.Enemies.X1.Dig Labour.png" ) ;
67+ spriteSheet . CurrentPalette = palette ;
68+
69+ var sequence = spriteSheet . AddFrameSquence ( "Idle" ) ;
70+ sequence . OriginOffset = - HITBOX . Origin - HITBOX . Mins ;
71+ sequence . Hitbox = HITBOX ;
72+ sequence . AddFrame ( 4 , 2 , 4 , 13 , 32 , 37 , 1 , true ) ;
73+
74+ sequence = spriteSheet . AddFrameSquence ( "Attacking" ) ;
75+ sequence . OriginOffset = - HITBOX . Origin - HITBOX . Mins ;
76+ sequence . Hitbox = HITBOX ;
77+ sequence . AddFrame ( 4 , 2 , 4 , 13 , 32 , 37 , 4 ) ;
78+ sequence . AddFrame ( 3 , 2 , 150 , 14 , 32 , 37 , 5 ) ;
79+ sequence . AddFrame ( 2 , 2 , 199 , 13 , 34 , 37 , 4 ) ;
80+ sequence . AddFrame ( 6 , 3 , 247 , 13 , 38 , 38 , 4 ) ;
81+ sequence . AddFrame ( 9 , 4 , 296 , 12 , 40 , 39 , 4 ) ;
82+ sequence . AddFrame ( 13 , 2 , 345 , 13 , 41 , 37 , 17 ) ; // pickaxe spawn here, total of 38 frames
83+
84+ sequence = spriteSheet . AddFrameSquence ( "Laughing" ) ;
85+ sequence . OriginOffset = - HITBOX . Origin - HITBOX . Mins ;
86+ sequence . Hitbox = HITBOX ;
87+ sequence . AddFrame ( 4 , 2 , 4 , 13 , 32 , 37 , 4 , true ) ;
88+ sequence . AddFrame ( 4 , 2 , 54 , 13 , 32 , 37 , 4 ) ;
89+ sequence . AddFrame ( 5 , 3 , 104 , 13 , 32 , 38 , 4 ) ;
90+ sequence . AddFrame ( 4 , 2 , 54 , 13 , 32 , 37 , 4 ) ; // this cycle is repeated 5 times, totalizing 80 frames
91+
92+ sequence = spriteSheet . AddFrameSquence ( "Pickaxe" ) ;
93+ sequence . OriginOffset = - PICKAXE_HITBOX . Origin - PICKAXE_HITBOX . Mins ;
94+ sequence . Hitbox = PICKAXE_HITBOX ;
95+ sequence . AddFrame ( 1 , 0 , 403 , 34 , 24 , 24 , 3 , true ) ;
96+ sequence . AddFrame ( 2 , - 2 , 456 , 9 , 21 , 20 , 3 ) ;
97+ sequence . AddFrame ( 1 , - 2 , 481 , 7 , 24 , 24 , 3 ) ;
98+ sequence . AddFrame ( 1 , - 4 , 431 , 9 , 21 , 20 , 3 ) ;
99+ sequence . AddFrame ( 1 , - 1 , 403 , 7 , 24 , 24 , 3 ) ;
100+ sequence . AddFrame ( - 1 , - 4 , 431 , 36 , 21 , 20 , 3 ) ;
101+ sequence . AddFrame ( 1 , - 2 , 481 , 34 , 24 , 24 , 3 ) ;
102+ sequence . AddFrame ( - 3 , - 2 , 456 , 36 , 21 , 20 , 3 ) ;
103+
104+ spriteSheet . ReleaseCurrentTexture ( ) ;
105+ }
106+ #endregion
107+
108+ private int idleFrames ;
109+
110+ public DigLabourState State
111+ {
112+ get => GetState < DigLabourState > ( ) ;
113+ set => SetState ( value ) ;
114+ }
115+
116+ public DigLabour ( )
117+ {
118+ }
119+
120+ protected override void OnCreate ( )
121+ {
122+ base . OnCreate ( ) ;
123+
124+ DefaultDirection = Direction . LEFT ;
125+ SpawnFacedToPlayer = true ;
126+ AlwaysFaceToPlayer = true ;
127+
128+ PaletteName = "DigLabourPalette" ;
129+ SpriteSheetName = "DigLabour" ;
130+
131+ SetAnimationNames ( "Idle" , "Attacking" , "Laughing" ) ;
132+
133+ SetupStateArray < DigLabourState > ( ) ;
134+ RegisterState ( DigLabourState . IDLE , OnIdle , "Idle" ) ;
135+ RegisterState ( DigLabourState . ATTACKING , OnAttacking , "Attacking" ) ;
136+ RegisterState ( DigLabourState . LAUGHING , OnLaughing , "Laughing" ) ;
137+ }
138+
139+ private void OnIdle ( EntityState state , long frameCounter )
140+ {
141+ if ( frameCounter >= idleFrames )
142+ State = DigLabourState . ATTACKING ;
143+ }
144+
145+ private void OnAttacking ( EntityState state , long frameCounter )
146+ {
147+ if ( frameCounter == FRAME_TO_THROW_PICKAXE )
148+ {
149+ ThrowPickaxe ( ) ;
150+ }
151+ else if ( frameCounter >= ATTACKING_FRAMES )
152+ {
153+ idleFrames = IDLE_AFTER_ATTACKING_FRAMES ;
154+ State = DigLabourState . IDLE ;
155+ }
156+ }
157+
158+ private void OnLaughing ( EntityState state , long frameCounter )
159+ {
160+ if ( frameCounter >= LAUGHING_FRAMES )
161+ {
162+ idleFrames = IDLE_AFTER_LAUGHING_FRAMES ;
163+ State = DigLabourState . IDLE ;
164+ }
165+ }
166+
167+ private EntityReference < DigLabourPickaxe > ThrowPickaxe ( )
168+ {
169+ var player = Engine . Player ;
170+ if ( player == null )
171+ return null ;
172+
173+ var throwOrigin = Origin + ( PICKAXE_SPAWN_OFFSET_X * Direction . GetHorizontalSignal ( ) , PICKAXE_SPAWN_OFFSET_Y ) ;
174+
175+ double v = PICKAXE_INITIAL_SPEED ;
176+ double v2 = v * v ;
177+ double g = GRAVITY ;
178+ double dx = player . Origin . X - throwOrigin . X ;
179+ int dxs = System . Math . Sign ( dx ) ;
180+ double dy = player . Origin . Y - throwOrigin . Y ;
181+ double alpha = v / ( g * dx ) ;
182+ double alpha2 = alpha * alpha ;
183+ double delta = v2 + 2 * g * dy - 1 / alpha2 ;
184+
185+ if ( delta < 0 )
186+ delta = 0 ;
187+
188+ double tanTheta = alpha * ( - v - System . Math . Sqrt ( delta ) ) ;
189+ double theta = System . Math . Atan ( tanTheta ) ;
190+
191+ FixedSingle vx = dxs * v * System . Math . Cos ( theta ) ;
192+ FixedSingle vy = dxs * v * System . Math . Sin ( theta ) ;
193+
194+ DigLabourPickaxe pickaxe = Engine . Entities . Create < DigLabourPickaxe > ( new
195+ {
196+ Origin = throwOrigin ,
197+ Velocity = ( vx . TruncFracPart ( ) , vy . TruncFracPart ( ) ) ,
198+ Direction
199+ } ) ;
200+
201+ pickaxe . pitcher = this ;
202+ pickaxe . Spawn ( ) ;
203+ return pickaxe ;
204+ }
205+
206+ protected override Box GetHitbox ( )
207+ {
208+ return HITBOX ;
209+ }
210+
211+ protected override Box GetCollisionBox ( )
212+ {
213+ return COLLISION_BOX ;
214+ }
215+
216+ protected override void OnSpawn ( )
217+ {
218+ base . OnSpawn ( ) ;
219+
220+ Health = HEALTH ;
221+ ContactDamage = CONTACT_DAMAGE ;
222+
223+ NothingDropOdd = 9000 ; // 90%
224+ SmallHealthDropOdd = 300 ; // 3%
225+ BigHealthDropOdd = 100 ; // 1%
226+ SmallAmmoDropOdd = 400 ; // 4%
227+ BigAmmoDropOdd = 175 ; // 1.75%
228+ LifeUpDropOdd = 25 ; // 0.25%
229+
230+ idleFrames = IDLE_AFTER_ATTACKING_FRAMES ;
231+ State = DigLabourState . IDLE ;
232+ }
233+
234+ internal void NotifyPlayerDamagedByPickaxe ( )
235+ {
236+ State = DigLabourState . LAUGHING ;
237+ }
5238}
0 commit comments