You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
7.8 KiB

#include "list.h"
#include <stdio.h>
#include <stdlib.h>
#include "../sprite.h"
#include "raylib.h"
#include "raymath.h"
#include "../Textures/textureIDs.h"
Node * ListCreateNode(Sprite *data){
Node *new = malloc(sizeof(Node));
new->data = data;
new->next = 0;
new->prev = 0;
return new;
}
void ListPrintForward(List *list){
Node *current = list->head;
printf("\n[\n");
while(current != 0){
printf("%f,\n", current->data->depth);
current = current->next;
}
printf("]\n");
}
void ListInsertBefore(List *list, Node *new, Node *current){
new->next = current;
new->prev = current->prev;
current->prev = new;
if(current == list->head){
list->head = new;
}
else{
new->prev->next = new;
}
}
void ListInsertAfter(List *list, Node *new, Node *current){
new->prev = current;
new->next = current->next;
current->next = new;
if(current == list->tail){
list->tail = new;
}
else{
new->next->prev = new;
}
}
void ListInsert(List *list, Sprite *data){
Node *new = ListCreateNode(data);
if(list->head == 0){
list->head = new;
list->tail = new;
}
else{
Node *current = list->head;
while(current != 0){
if(new->data->depth < current->data->depth){
ListInsertBefore(list, new, current);
return;
}
current = current->next;
}
ListInsertAfter(list, new, list->tail);
}
}
void ListSpriteChanged(List *list, Node *changed){
if(changed != list->tail && changed->data->depth > changed->next->data->depth){
//Nach rechts
Node *current = changed->next;
ListRemove(list, changed);
while(current != 0){
if(changed->data->depth < current->data->depth){
ListInsertBefore(list, changed, current);
return;
}
current = current->next;
}
ListInsertAfter(list, changed, list->tail);
}
else if(changed != list->head && changed->data->depth < changed->prev->data->depth){
//Nach links
Node *current = changed->prev;
ListRemove(list, changed);
while(current != 0){
if(changed->data->depth > current->data->depth){
ListInsertAfter(list, changed, current);
return;
}
current = current->prev;
}
ListInsertBefore(list, changed, list->head);
}
}
void ListRemove(List *list, Node *remove){
if(remove == 0){
printf("WARNING: TRIED TO REMOVE NULLPOINTER\n");
}
else if(list->head == remove && list->tail == remove){
list->head = 0;
list->tail = 0;
}
else if(list->head == remove){
remove->next->prev = 0;
list->head = remove->next;
}
else if(list->tail == remove){
remove->prev->next = 0;
list->tail = remove->prev;
}
else{
remove->prev->next = remove->next;
remove->next->prev = remove->prev;
}
remove->next = 0;
remove->prev = 0;
}
List * ListInit(){
List *newList = malloc(sizeof(List));
newList->head = 0;
newList->tail = 0;
return newList;
}
// iterates over all Sprites in the list and draws them to the world
void ListDrawAllSprites(List *list, IsometricMap **map, Camera2D *camera){
Node *current = list->head;
// Only drawing the Sprites which are within Camera view
Vector2 topleft = {0, 0};
IsometricMapProject(map[0], camera, topleft.x, topleft.y, &topleft);
Vector2 topright = {GetScreenWidth(), 0};
IsometricMapProject(map[0], camera, topright.x, topright.y, &topright);
Vector2 botleft = {0, GetScreenHeight()};
IsometricMapProject(map[0], camera, botleft.x, botleft.y, &botleft);
Vector2 botright = {GetScreenWidth(), GetScreenHeight()};
IsometricMapProject(map[0], camera, botright.x, botright.y, &botright);
int extraPixels = 0;
int itmp, jtmp, maxI, maxJ;
itmp = (int)(topleft.x) - extraPixels;
jtmp = (int)(topright.y) - extraPixels;
maxI = (int)(botright.x) + extraPixels;
maxJ = (int)(botleft.y) + extraPixels;
while(current != 0){
// drawing some extra corner pixels
// if extraPixels == 0 you can see flickering in the corners
// Only drawing the Sprites which are within Camera view
if( current->data->x > itmp &&
current->data->y > jtmp &&
current->data->x < maxI &&
current->data->y < maxJ){
DrawSpriteToWorld(current->data, map, camera);
}
current = current->next;
}
}
// iterates over all Sprites in the list and does their acting (moving etc)
void ListActAllSprites(Game *game){
ListPrintForward(game->sprites);
// Sprites move towards their destination
float movementSpeed = 150.0f * GetFrameTime();
Node *current = game->sprites->head;
int counter = 0;
while (current != 0){
current->data->depth = current->data->x + current->data->y + current->data->z;
ListSpriteChanged(game->sprites, current);
counter ++;
if(current->data->hasDestination == 1){
Vector2 movement = {
current->data->destX - current->data->x,
current->data->destY - current->data->y
};
if(Vector2Length(movement) < movementSpeed){
current->data->hasDestination = 0;
current->data->x = current->data->destX;
current->data->y = current->data->destY;
}
else{
movement = Vector2Normalize(movement);
movement = Vector2Scale(movement, movementSpeed);
current->data->x += movement.x;
current->data->y += movement.y;
// Change sprite according to direction
Vector2 nullvektor = {0,0};
float angle = Vector2Angle(movement, nullvektor);
angle = angle * RAD2DEG;
angle -= 35.26;
if(angle <= 22.5 && angle >= -22.5){
// E
AnimationChangeAnimation(current->data->animationHandler, E);
}
else if(angle > 0 && angle <= 67.5){
// NE
AnimationChangeAnimation(current->data->animationHandler, NE);
}
else if(angle > 0 && angle <= 112.5){
// N
AnimationChangeAnimation(current->data->animationHandler, N);
}
else if(angle > 0 && angle <= 157.5){
// NW
AnimationChangeAnimation(current->data->animationHandler, NW);
}
else if(angle < 0 && angle >= -67.5){
// SE
AnimationChangeAnimation(current->data->animationHandler, SE);
}
else if(angle < 0 && angle >= -112.5){
// S
AnimationChangeAnimation(current->data->animationHandler, S);
}
else if(angle < 0 && angle >= -157.5){
// SW
AnimationChangeAnimation(current->data->animationHandler, SW);
}
else{
// W
AnimationChangeAnimation(current->data->animationHandler, W);
}
}
}
SpriteUpdateAnimation(current->data);
// updating z-position according to the tile the sprite stands on
Tile *floorTile = IsometricMapGetTileFromWorldCoordinates(game->layers, current->data->x, current->data->y, 0);
Tile *topTile = IsometricMapGetMostUpperTile(game->layers, floorTile);
current->data->z = topTile->z;
current = current->next;
}
}