/*
hm_gameserver - hearthmod gameserver
Copyright (C) 2016 Filip Pancik
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
void flags_diff(struct flags_s *old, struct flags_s *new,
struct flag_pr_s ***src_added, int *nsrc_added,
struct flag_pr_s ***src_removed, int *nsrc_removed,
struct card_s *card)
{
int i, j;
unsigned long long t;
for(i = 0; i < MAX_FLAGS_ARRAY; i++) {
for(j = 0; j < LL_BITS; j++) {
t = 1;
t <<= j;
#define FFILL(f_s, f_n, f_t)\
*f_s = realloc(*f_s, ++(*f_n) * sizeof(void *));\
(*f_s)[*f_n - 1] = malloc(sizeof(***f_s));\
(*f_s)[*f_n - 1]->flag = (i * LL_BITS + j);\
if(card->priority_override > 0) {\
(*f_s)[*f_n - 1]->priority = card->priority_override;\
} else {\
(*f_s)[*f_n - 1]->priority = flag_defs[(i * LL_BITS + j)];\
}\
(*f_s)[*f_n - 1]->type = f_t;\
(*f_s)[*f_n - 1]->parent_card = card;
if((old->nibble[i] & t) == t && (new->nibble[i] & t) == 0) {
FFILL(src_removed, nsrc_removed, F_REMOVED)
} else if((old->nibble[i] & t) == 0 && (new->nibble[i] & t) == t) {
FFILL(src_added, nsrc_added, F_ADDED)
}
}
}
}
int flags_copy(struct flags_s *dst, const struct flags_s *src)
{
int i, j;
unsigned long long t;
for(i = 0; i < MAX_FLAGS_ARRAY; i++) {
for(j = 0; j < LL_BITS; j++) {
t = 1;
t <<= j;
if((src->nibble[i] & t) == t) {
dst->nibble[i] |= t;
}
}
}
return 0;
}
int flag_get(struct flags_s *flags, int **f)
{
assert(flags);
if(flags == NULL) {
return -1;
}
int i, j, c = 0;
unsigned long long t;
for(i = 0; i < MAX_FLAGS_ARRAY; i++) {
for(j = 0; j < LL_BITS; j++) {
t = 1;
t <<= j;
if((flags->nibble[i] & t) == t) {
*f = realloc(*f, ++c * sizeof(int));
(*f)[c - 1] = i * LL_BITS + j;
}
}
}
return c;
}
int flag(struct flags_s *flags, enum flags_e src, enum flags_action_e action)
{
int index;
unsigned long long mod = 1;
assert(flags);
if(flags == NULL) {
return -1;
}
if(action == FLAG_DUMP && src == -1) {
int i, j;
unsigned long long t;
for(i = 0; i < MAX_FLAGS_ARRAY; i++) {
for(j = 0; j < LL_BITS; j++) {
t = 1;
t <<= j;
if((flags->nibble[i] & t) == t) {
hm_log(LOG_DEBUG, lg, "flag %p set: %d", flags, i * LL_BITS + j);
}
}
}
return 0;
}
if(src > (MAX_FLAGS_ARRAY * LL_BITS) || src < 0) return -1;
index = src / LL_BITS;
mod <<= (src % LL_BITS);
if(action == FLAG_SET) flags->nibble[index] |= mod;
else if(action == FLAG_UNSET) flags->nibble[index] &= ~(mod);
else if(action == FLAG_ISSET) {
if((flags->nibble[index] & mod) == mod) return 1;
else return 0;
} else return -1;
return 0;
}