Skip to content

Commit

Permalink
added wepon state check for Lara;
Browse files Browse the repository at this point in the history
added AVL tree to core for internal usage;
  • Loading branch information
TeslaRus committed Jan 30, 2018
1 parent d199c8f commit 56cd054
Show file tree
Hide file tree
Showing 6 changed files with 470 additions and 83 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ add_subdirectory(extern/freetype2)
add_subdirectory(extern/lua)

set(OPENTOMB_SRCS
src/core/avl.c
src/core/avl.h
src/core/base_types.c
src/core/base_types.h
src/core/console.c
Expand Down
3 changes: 2 additions & 1 deletion src/character_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ void Character_Update(struct entity_s *ent)
if(mask == (ent->state_flags & mask))
{
bool is_player = (World_GetPlayer() == ent);
if(ent->character->cmd.action && (ent->type_flags & ENTITY_TYPE_TRIGGER_ACTIVATOR))
if(ent->character->cmd.action && (ent->type_flags & ENTITY_TYPE_TRIGGER_ACTIVATOR) &&
(ent->character->weapon_state == WEAPON_STATE_HIDE))
{
Entity_CheckActivators(ent);
}
Expand Down
315 changes: 315 additions & 0 deletions src/core/avl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
#include <stdio.h>
#include <stdlib.h>
#include "avl.h"


static avl_node_p RotateRight(avl_node_p node);
static avl_node_p RotateLeft(avl_node_p node);
static avl_node_p BalanceNode(avl_node_p node);
static void BalanceTree(avl_header_p header, avl_node_p p);

#define AVL_UPDATE_NODE_HEIGHT(node, t) \
(node)->height = ((node)->left) ? ((node)->left->height) : 0;\
(t) = ((node)->right) ? ((node)->right->height) : 0;\
(node)->height = ((t) > (node)->height) ? (t) : (node)->height;\
++(node)->height;\

#define AVL_GET_NODE_FACTOR(node, t) \
t = (node->right) ? (node->right->height) : (0);\
t -= ((node->left) ? (node->left->height) : (0));\

avl_header_p AVL_Init()
{
avl_header_p p = (avl_header_p)malloc(sizeof(struct avl_header_s));
if(p == NULL)
{
return NULL;
}

p->free_data = NULL;
p->root = NULL;
p->list = NULL;
p->nodes_count = 0;

return p;
}


void AVL_Free(avl_header_p p)
{
AVL_MakeEmpty(p);
free(p);
}


void AVL_MakeEmpty(avl_header_p header)
{
if(header)
{
for(avl_node_p p = header->list; p; )
{
avl_node_p next = p->next;
if(header->free_data)
{
header->free_data(p->data);
}
free(p);
p = next;
}
header->nodes_count = 0;
header->list = NULL;
header->root = NULL;
}
}


avl_node_p AVL_NewNode(uint32_t key, void *data)
{
avl_node_p ret = (avl_node_p)malloc(sizeof(avl_node_t));
ret->left = NULL;
ret->right = NULL;
ret->parent = NULL;
ret->next = NULL;
ret->prev = NULL;
ret->height = 1;
ret->data = data;
ret->key = key;
return ret;
}

// This method search the tree for key, and
// returns the node on success, otherwise NULL.
avl_node_p AVL_SearchNode(avl_header_p header, uint32_t key)
{
avl_node_p current = header->root;
while(current && (key != current->key))
{
current = (key < current->key) ? current->left : current->right;
}
return current;
}


avl_node_p RotateRight(avl_node_p node)
{
avl_node_p t = node->left;
int32_t h;
node->left = t->right;
if(node->left)
{
node->left->parent = node;
}

t->right = node;
t->parent = node->parent;
node->parent = t;
AVL_UPDATE_NODE_HEIGHT(node, h)
AVL_UPDATE_NODE_HEIGHT(t, h)

return t;
}


avl_node_p RotateLeft(avl_node_p node)
{
avl_node_p t = node->right;
int32_t h;
node->right = t->left;
if(node->right)
{
node->right->parent = node;
}

t->left = node;
t->parent = node->parent;
node->parent = t;
AVL_UPDATE_NODE_HEIGHT(node, h)
AVL_UPDATE_NODE_HEIGHT(t, h)

return t;
}


avl_node_p BalanceNode(avl_node_p node)
{
int32_t t;
AVL_UPDATE_NODE_HEIGHT(node, t)
AVL_GET_NODE_FACTOR(node, t)
if(t == 2)
{
AVL_GET_NODE_FACTOR(node->right, t)
if(t < 0)
{
node->right = RotateRight(node->right);
node->right->parent = node;
}
return RotateLeft(node);
}
if(t == -2)
{
AVL_GET_NODE_FACTOR(node->left, t)
if(t > 0)
{
node->left = RotateLeft(node->left);
node->left->parent = node;
}
return RotateRight(node);
}
return node;
}


void BalanceTree(avl_header_p header, avl_node_p p)
{
while(p)
{
avl_node_p pp = p->parent;
if(pp)
{
avl_node_p *p_ins = (p == pp->left) ? (&pp->left) : (&pp->right);
avl_node_p bn = BalanceNode(p);
if(bn != p)
{
*p_ins = bn;
bn->parent = pp;
}
}
else
{
header->root = BalanceNode(p);
header->root->parent = NULL;
}
p = pp;
}
}


avl_node_p AVL_InsertReplace(avl_header_p header, uint32_t key, void *data)
{
avl_node_p p = header->root;
avl_node_p i = NULL;

if(!header->root)
{
header->list = header->root = AVL_NewNode(key, data);
++header->nodes_count;
return header->root;
}

while(p)
{
if(key < p->key)
{
if(!p->left)
{
i = p->left = AVL_NewNode(key, data);
++header->nodes_count;
p->left->parent = p;
break;
}
p = p->left;
}
else if(p->key < key)
{
if(!p->right)
{
i = p->right = AVL_NewNode(key, data);
++header->nodes_count;
p->right->parent = p;
break;
}
p = p->right;
}
else
{
i = p;
header->free_data(i->data);
i->data = data;
i->key = key;
return i;
}
}

i->next = header->list;
header->list->prev = i;
header->list = i;
BalanceTree(header, p);

return i;
}


void AVL_DeleteNode(avl_header_p header, avl_node_p node)
{
if(node)
{
int32_t t;
avl_node_p parent = node->parent;
avl_node_p *p_ins = &header->root;
if(parent)
{
p_ins = (node == parent->left) ? (&parent->left) : (&parent->right);
}

if(node->prev)
{
node->prev->next = node->next;
}
else
{
header->list = node->next;
}
if(node->next)
{
node->next->prev = node->prev;
}

if(!node->right || !node->left)
{
*p_ins = (node->right) ? (node->right) : (node->left);
if(*p_ins)
{
(*p_ins)->parent = parent;
AVL_UPDATE_NODE_HEIGHT(*p_ins, t)
}
}
else if(!node->right->left)
{
node->left->parent = node->right;
node->right->left = node->left;
AVL_UPDATE_NODE_HEIGHT(node->right, t)
*p_ins = node->right;
(*p_ins)->parent = parent;
}
else
{
avl_node_p min = node->right;
while(min->left)
{
min = min->left;
}

min->parent->left = min->right;
if(min->right)
{
min->right->parent = min->parent;
}
AVL_UPDATE_NODE_HEIGHT(min->parent, t)

min->left = node->left;
min->left->parent = min;
min->right = node->right;
min->right->parent = min;

min->parent = parent;
*p_ins = min;
parent = min;
AVL_UPDATE_NODE_HEIGHT(min, t)
}

--header->nodes_count;
header->free_data(node->data);
free(node);
BalanceTree(header, parent);
}
}
47 changes: 47 additions & 0 deletions src/core/avl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef AVL_TREE_H
#define AVL_TREE_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdlib.h>
#include <stdint.h>


typedef struct avl_node_s
{
struct avl_node_s *parent;
struct avl_node_s *left;
struct avl_node_s *right;
struct avl_node_s *next;
struct avl_node_s *prev;
int32_t height;
uint32_t key;
void *data;
} avl_node_t, *avl_node_p;

typedef struct avl_header_s
{
struct avl_node_s *root; /* header pointer */
struct avl_node_s *list;
uint32_t nodes_count; /* node count in tree */
void (*free_data)(void *data);
} avl_header_t, *avl_header_p;

avl_header_p AVL_Init();
void AVL_Free(avl_header_p p);

avl_node_p AVL_NewNode(uint32_t key, void *data);
avl_node_p AVL_SearchNode(avl_header_p header, uint32_t key);
avl_node_p AVL_InsertReplace(avl_header_p header, uint32_t key, void *data);
void AVL_DeleteNode(avl_header_p header, avl_node_p node);
void AVL_MakeEmpty(avl_header_p header);

#endif /* AVL_TREE_H */

#ifdef __cplusplus
}
#endif

/* END */
Loading

0 comments on commit 56cd054

Please sign in to comment.