1 package ru
.deadsoftware
.cavedroid
.game
.mobs
;
3 import com
.badlogic
.gdx
.graphics
.g2d
.Sprite
;
4 import com
.badlogic
.gdx
.graphics
.g2d
.SpriteBatch
;
5 import com
.badlogic
.gdx
.math
.MathUtils
;
6 import com
.badlogic
.gdx
.math
.Vector2
;
7 import ru
.deadsoftware
.cavedroid
.game
.GameItemsHolder
;
8 import ru
.deadsoftware
.cavedroid
.game
.model
.block
.Block
;
9 import ru
.deadsoftware
.cavedroid
.game
.model
.item
.InventoryItem
;
10 import ru
.deadsoftware
.cavedroid
.game
.model
.item
.Item
;
11 import ru
.deadsoftware
.cavedroid
.game
.objects
.Drop
;
12 import ru
.deadsoftware
.cavedroid
.game
.world
.GameWorld
;
13 import ru
.deadsoftware
.cavedroid
.misc
.Assets
;
14 import ru
.deadsoftware
.cavedroid
.misc
.utils
.SpriteOrigin
;
15 import ru
.deadsoftware
.cavedroid
.misc
.utils
.SpriteUtilsKt
;
17 import javax
.annotation
.CheckForNull
;
19 public class Player
extends Mob
{
21 private static final float SPEED
= 69.072f;
22 private static final float JUMP_VELOCITY
= -133.332f;
23 private static final int MAX_HEALTH
= 20;
25 private boolean hitting
= false, hittingWithDamage
= false;
26 private float hitAnim
= 0f;
27 private float hitAnimDelta
= ANIMATION_SPEED
;
29 public final InventoryItem
[] inventory
;
33 public float headRotation
= 0f;
35 public float blockDamage
= 0f;
36 public int cursorX
= 0;
37 public int cursorY
= 0;
39 public ControlMode controlMode
= ControlMode
.WALK
;
41 public enum ControlMode
{
46 public Player(GameItemsHolder gameItemsHolder
) {
47 super(0, 0, 4, 30, randomDir(), Type
.MOB
, MAX_HEALTH
);
48 inventory
= new InventoryItem
[36];
49 for (int i
= 0; i
< inventory
.length
; i
++) {
50 inventory
[i
] = gameItemsHolder
.getFallbackItem().toInventoryItem();
55 public void initInventory(GameItemsHolder gameItemsHolder
) {
56 for (InventoryItem invItem
: inventory
) {
57 invItem
.init(gameItemsHolder
);
62 public Item
inventory(int i
) {
63 return inventory
[i
].getItem();
66 public void respawn(GameWorld gameWorld
, GameItemsHolder itemsHolder
) {
67 Vector2 pos
= getSpawnPoint(gameWorld
, itemsHolder
);
75 public void decreaseCurrentItemCount(GameItemsHolder gameItemsHolder
) {
79 getCurrentItem().setAmount(getCurrentItem().getAmount() - 1);
80 if (getCurrentItem().getAmount() <= 0) {
81 setCurrentInventorySlotItem(gameItemsHolder
.getFallbackItem());
85 public InventoryItem
getCurrentItem() {
86 return inventory
[slot
];
89 public void pickUpDrop(Drop drop
) {
90 for (InventoryItem invItem
: inventory
) {
91 if (!invItem
.getItem().isTool()
92 && invItem
.getItem() == drop
.getItem()
93 && invItem
.getAmount() < invItem
.getItem().getParams().getMaxStack()) {
94 invItem
.setAmount(invItem
.getAmount() + 1);
95 drop
.setPickedUp(true);
100 for (int i
= 0; i
< inventory
.length
; i
++) {
101 if (inventory(i
) == null || inventory(i
).getParams().getKey().equals(GameItemsHolder
.FALLBACK_ITEM_KEY
)) {
102 inventory
[i
] = drop
.getItem().toInventoryItem();
103 drop
.setPickedUp(true);
109 private Vector2
getSpawnPoint(GameWorld gameWorld
, GameItemsHolder itemsHolder
) {
111 for (y
= 0; y
< gameWorld
.getHeight(); y
++) {
112 if (y
== gameWorld
.getHeight() - 1) {
114 gameWorld
.setForeMap(0, y
, itemsHolder
.getBlock("grass"));
117 if (gameWorld
.hasForeAt(0, y
) && gameWorld
.getForeMap(0, y
).hasCollision()) {
121 return new Vector2(8 - getWidth() / 2, (float) y
* 16 - getHeight());
124 public void setDir(Direction dir
) {
125 if (dir
!= getDirection()) {
130 public void setCurrentInventorySlotItem(Item item
) {
131 inventory
[slot
] = item
.toInventoryItem();
135 public float getSpeed() {
141 mVelocity
.y
= JUMP_VELOCITY
;
144 private void hitBlock(GameWorld gameWorld
, GameItemsHolder gameItemsHolder
) {
145 if (!hitting
|| !hittingWithDamage
) {
149 final Block foregroundBlock
= gameWorld
.getForeMap(cursorX
, cursorY
);
150 final Block backgroundBlock
= gameWorld
.getBackMap(cursorX
, cursorY
);
152 if ((!foregroundBlock
.isNone() && foregroundBlock
.getParams().getHitPoints() >= 0) ||
153 (foregroundBlock
.isNone() && !backgroundBlock
.isNone() && backgroundBlock
.getParams().getHitPoints() >= 0)) {
155 if (!foregroundBlock
.isNone() && blockDamage
>= foregroundBlock
.getParams().getHitPoints()) {
156 gameWorld
.destroyForeMap(cursorX
, cursorY
);
158 } else if (!backgroundBlock
.isNone() && blockDamage
>= backgroundBlock
.getParams().getHitPoints()) {
159 gameWorld
.destroyBackMap(cursorX
, cursorY
);
163 if (!foregroundBlock
.isNone()) {
164 gameWorld
.placeToForeground(cursorX
, cursorY
, gameItemsHolder
.getFallbackBlock());
165 } else if (!backgroundBlock
.isNone()) {
166 gameWorld
.placeToBackground(cursorX
, cursorY
, gameItemsHolder
.getFallbackBlock());
176 public void ai(GameWorld gameWorld
, GameItemsHolder gameItemsHolder
, float delta
) {
177 updateAnimation(delta
);
178 hitBlock(gameWorld
, gameItemsHolder
);
184 final Block foregroundBlock
= gameWorld
.getForeMap(cursorX
, cursorY
);
185 final Block backgroundBlock
= gameWorld
.getBackMap(cursorX
, cursorY
);
186 @CheckForNull final Block target
;
188 if (!foregroundBlock
.isNone() && foregroundBlock
.getParams().getHitPoints() >= 0) {
189 target
= foregroundBlock
;
190 } else if (!backgroundBlock
.isNone() && backgroundBlock
.getParams().getHitPoints() >= 0) {
191 target
= backgroundBlock
;
196 final boolean canHitBlock
= target
!= null;
198 float multiplier
= 1f;
199 final Item currentItem
= inventory
[slot
].getItem();
200 if (currentItem
instanceof Item
.Tool
&& canHitBlock
) {
201 if (target
.getParams().getToolType() == currentItem
.getClass()
202 && ((Item
.Tool
)currentItem
).getLevel() >= target
.getParams().getToolLevel()) {
203 multiplier
= 2f * ((Item
.Tool
)currentItem
).getLevel();
205 multiplier
*= ((Item
.Tool
)currentItem
).getBlockDamageMultiplier();
208 if (hitting
&& hittingWithDamage
&& canHitBlock
) {
209 blockDamage
+= 60f * delta
* multiplier
;
216 public void changeDir() {
220 public void damage(int damage
) {
226 getVelocity().y
+= JUMP_VELOCITY
/ 3f;
229 super.damage(damage
);
233 public void heal(int heal
) {
240 private void drawItem(SpriteBatch spriteBatch
, float x
, float y
, float anim
) {
241 final Item item
= inventory(slot
);
243 if (item
== null || item
.isNone()) {
247 final Sprite sprite
= item
.getSprite();
248 final boolean smallSprite
= !item
.isTool() || item
.isShears();
251 sprite
.setSize(Drop
.DROP_SIZE
, Drop
.DROP_SIZE
);
254 final float handLength
= Assets
.playerSprite
[0][2].getHeight();
256 final SpriteOrigin spriteOrigin
= item
.getParams().getInHandSpriteOrigin();
257 final int handMultiplier
= -getDirection().getBasis();
258 final float xOffset
= (-1 + getDirection().getIndex()) * sprite
.getWidth() + 4 + handMultiplier
* (sprite
.getWidth() * spriteOrigin
.getX());
259 final float yOffset
= !smallSprite ?
-sprite
.getHeight() / 2 : 0;
261 float rotate
= anim
+ 30;
264 sprite
.rotate90(looksLeft());
267 final float itemX
= x
+ handLength
* MathUtils
.sin(handMultiplier
* anim
* MathUtils
.degRad
) + xOffset
;
268 final float itemY
= y
+ handLength
* MathUtils
.cos(handMultiplier
* anim
* MathUtils
.degRad
) + yOffset
;
271 sprite
.setFlip(!item
.isTool(), sprite
.isFlipY());
272 SpriteUtilsKt
.applyOrigin(sprite
, spriteOrigin
.getFlipped(true, false));
274 sprite
.setFlip(item
.isTool(), sprite
.isFlipY());
275 SpriteUtilsKt
.applyOrigin(sprite
, spriteOrigin
);
278 SpriteUtilsKt
.drawSprite(spriteBatch
, sprite
, itemX
, itemY
, -handMultiplier
* rotate
);
280 // dont forget to reset
281 sprite
.setFlip(false, sprite
.isFlipY());
282 sprite
.setRotation(0);
283 sprite
.setOriginCenter();
285 sprite
.rotate90(looksRight());
289 public void startHitting(boolean withDamage
) {
295 hittingWithDamage
= withDamage
;
297 hitAnimDelta
= ANIMATION_SPEED
;
300 public void startHitting() {
304 public void stopHitting() {
309 private float getRightHandAnim(float delta
) {
310 hitAnim
-= hitAnimDelta
* delta
;
312 if (hitAnim
< 30f || hitAnim
> 90f) {
314 hitAnim
= MathUtils
.clamp(hitAnim
, 30f, 90f);
315 hitAnimDelta
= -hitAnimDelta
;
317 hitAnimDelta
= ANIMATION_SPEED
;
322 if (hitAnim
< hitAnimDelta
* delta
) {
333 public void draw(SpriteBatch spriteBatch
, float x
, float y
, float delta
) {
334 final Sprite backHand
= Assets
.playerSprite
[1][2];
335 final Sprite backLeg
= Assets
.playerSprite
[1][3];
336 final Sprite frontLeg
= Assets
.playerSprite
[0][3];
337 final Sprite head
= Assets
.playerSprite
[getDirection().getIndex()][0];
338 final Sprite body
= Assets
.playerSprite
[getDirection().getIndex()][1];
339 final Sprite frontHand
= Assets
.playerSprite
[0][2];
341 float backHandAnim
, frontHandAnim
;
343 final float rightHandAnim
= getRightHandAnim(delta
);
346 backHandAnim
= rightHandAnim
;
347 frontHandAnim
= mAnim
;
349 backHandAnim
= -mAnim
;
350 frontHandAnim
= -rightHandAnim
;
353 SpriteUtilsKt
.drawSprite(spriteBatch
, backHand
, x
+ 2, y
+ 8, backHandAnim
);
356 drawItem(spriteBatch
, x
, y
, -backHandAnim
);
359 SpriteUtilsKt
.drawSprite(spriteBatch
, backLeg
, x
+ 2, y
+ 20, mAnim
);
360 SpriteUtilsKt
.drawSprite(spriteBatch
, frontLeg
, x
+ 2, y
+ 20, -mAnim
);
361 SpriteUtilsKt
.drawSprite(spriteBatch
, head
, x
, y
, headRotation
);
362 SpriteUtilsKt
.drawSprite(spriteBatch
, body
, x
+ 2, y
+ 8);
365 drawItem(spriteBatch
, x
, y
, frontHandAnim
);
368 SpriteUtilsKt
.drawSprite(spriteBatch
, frontHand
, x
+ 2, y
+ 8, frontHandAnim
);