forked from github/server
8823db9702
- Bugfix to P_BERSERK
202 lines
4.1 KiB
C
202 lines
4.1 KiB
C
/* vi: set ts=2:
|
|
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
|
| | Enno Rehling <enno@eressea-pbem.de>
|
|
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
|
| (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de>
|
|
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
|
|
+-------------------+ Stefan Reich <reich@halbling.de>
|
|
|
|
This program may not be used, modified or distributed
|
|
without prior permission by the authors of Eressea.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include "eressea.h"
|
|
|
|
/* kernel includes */
|
|
#include "unit.h"
|
|
#include "region.h"
|
|
#include "faction.h"
|
|
#include "ugroup.h"
|
|
|
|
/* attributes includes */
|
|
#include <attributes/ugroup.h>
|
|
|
|
/* libc includes */
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
/* TODO:
|
|
* - Anzeige (CR)
|
|
* - Speicherung
|
|
* - Evt. NACH (Betrete/Verlasse?) des Leaders vererben auf Members.
|
|
* - Routine zur automatischen Aufsplittung.
|
|
*/
|
|
|
|
/* Nur die erste Einheit in der Liste
|
|
(ugroup->unit_array[0] == u) kann NACH ausführen. */
|
|
|
|
#ifdef USE_UGROUPS
|
|
boolean
|
|
is_ugroupleader(const unit *u, const ugroup *ug)
|
|
{
|
|
if(ug->unit_array[0] == u) return true;
|
|
return false;
|
|
}
|
|
|
|
ugroup *
|
|
findugroupid(const faction *f, int id)
|
|
{
|
|
ugroup *ug;
|
|
|
|
for(ug=f->ugroups;ug; ug=ug->next) {
|
|
if(ug->id == id) return ug;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
ugroup *
|
|
findugroup(const unit *u)
|
|
{
|
|
attrib *a = a_find(u->attribs, &at_ugroup);
|
|
if(!a) return NULL;
|
|
return findugroupid(u->faction, a->data.i);
|
|
}
|
|
|
|
static int
|
|
ugroupfreeid(const ugroup *ug)
|
|
{
|
|
const ugroup *ug2 = ug;
|
|
int id = 0;
|
|
|
|
while(ug2) {
|
|
if(ug2->id == id) {
|
|
id++;
|
|
ug2 = ug;
|
|
} else {
|
|
ug2 = ug2->next;
|
|
}
|
|
}
|
|
return id;
|
|
}
|
|
|
|
ugroup *
|
|
createugroup(unit *uleader, unit *umember)
|
|
{
|
|
ugroup *ug = calloc(1,sizeof(ugroup));
|
|
|
|
ug->id = ugroupfreeid(uleader->faction->ugroups);
|
|
ug->members = 2;
|
|
ug->unit_array = malloc(2 * sizeof(unit *));
|
|
ug->unit_array[0] = uleader;
|
|
a_add(&uleader->attribs, a_new(&at_ugroup))->data.i = ug->id;
|
|
ug->unit_array[1] = umember;
|
|
a_add(&umember->attribs, a_new(&at_ugroup))->data.i = ug->id;
|
|
ug->next = uleader->faction->ugroups;
|
|
uleader->faction->ugroups = ug;
|
|
|
|
return ug;
|
|
}
|
|
|
|
void
|
|
join_ugroup(unit *u, strlist *order)
|
|
{
|
|
unit *u2;
|
|
ugroup *ug;
|
|
|
|
u2 = getunit(u->region, u->faction);
|
|
if(!u2 || cansee(u->faction, u->region, u2, 0) == false) {
|
|
cmistake(u, order->s, 63, MSG_EVENT);
|
|
return;
|
|
}
|
|
if(u2 == u) {
|
|
cmistake(u, order->s, 292, MSG_EVENT);
|
|
return;
|
|
}
|
|
if(u2->faction != u->faction) {
|
|
cmistake(u, order->s, 293, MSG_EVENT);
|
|
return;
|
|
}
|
|
if(u2->building != u->building || u2->ship != u->ship) {
|
|
cmistake(u, order->s, 294, MSG_EVENT);
|
|
return;
|
|
}
|
|
if(a_find(u->attribs, &at_ugroup)) {
|
|
cmistake(u, order->s, 290, MSG_EVENT);
|
|
return;
|
|
}
|
|
|
|
ug = findugroup(u2);
|
|
|
|
if(ug) {
|
|
ug->members++;
|
|
ug->unit_array = realloc(ug->unit_array,
|
|
ug->members * sizeof(unit *));
|
|
ug->unit_array[ug->members-1] = u;
|
|
a_add(&u->attribs, a_new(&at_ugroup))->data.i = ug->id;
|
|
} else {
|
|
createugroup(u2, u);
|
|
}
|
|
}
|
|
|
|
void
|
|
leave_ugroup(unit *u, strlist *order)
|
|
{
|
|
attrib *a = a_find(u->attribs, &at_ugroup);
|
|
ugroup *ug;
|
|
boolean found = false;
|
|
int i;
|
|
|
|
if(!a) {
|
|
cmistake(u, order->s, 286, MSG_EVENT);
|
|
return;
|
|
}
|
|
|
|
ug = findugroupid(u->faction, a->data.i);
|
|
for(i=0; i<ug->members; i++) {
|
|
if(found == true) {
|
|
ug->unit_array[i-1] = ug->unit_array[i];
|
|
} else if(ug->unit_array[i] == u) {
|
|
found = true;
|
|
}
|
|
}
|
|
ug->members--;
|
|
a_remove(&u->attribs, a);
|
|
|
|
if(ug->members == 1) {
|
|
a_remove(&ug->unit_array[0]->attribs, a);
|
|
free(ug->unit_array);
|
|
removelist(&u->faction->ugroups, ug);
|
|
} else {
|
|
ug->unit_array = realloc(ug->unit_array,
|
|
ug->members * sizeof(unit *));
|
|
}
|
|
}
|
|
|
|
void
|
|
ugroups(void)
|
|
{
|
|
region *r;
|
|
unit *u;
|
|
strlist *o;
|
|
|
|
for(r=regions; r; r=r->next) {
|
|
for(u=r->units; u; u=u->next) {
|
|
for(o = u->orders; o; o=o->next) {
|
|
if(igetkeyword(o->s, u->faction->locale) == K_LEAVEUGROUP) {
|
|
leave_ugroup(u, o);
|
|
}
|
|
}
|
|
}
|
|
for(u=r->units; u; u=u->next) {
|
|
for(o = u->orders; o; o=o->next) {
|
|
if(igetkeyword(o->s, u->faction->locale) == K_JOINUGROUP) {
|
|
join_ugroup(u, o);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif /* USE_UGROUPS */
|