2001-01-25 10:37:55 +01:00
|
|
|
|
/* vi: set ts=2:
|
|
|
|
|
*
|
2001-04-16 16:34:19 +02:00
|
|
|
|
*
|
2001-01-25 10:37:55 +01:00
|
|
|
|
* Eressea PB(E)M host Copyright (C) 1998-2000
|
|
|
|
|
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
|
|
|
|
* Katja Zedel (katze@felidae.kn-bremen.de)
|
|
|
|
|
* Henning Peters (faroul@beyond.kn-bremen.de)
|
|
|
|
|
* Enno Rehling (enno@eressea-pbem.de)
|
|
|
|
|
* Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
|
|
|
|
|
*
|
|
|
|
|
* based on:
|
|
|
|
|
*
|
|
|
|
|
* Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace
|
|
|
|
|
* Atlantis v1.7 Copyright 1996 by Alex Schr<EFBFBD>der
|
|
|
|
|
*
|
|
|
|
|
* This program may not be used, modified or distributed without
|
|
|
|
|
* prior permission by the authors of Eressea.
|
|
|
|
|
* This program may not be sold or used commercially without prior written
|
|
|
|
|
* permission from the authors.
|
|
|
|
|
*/
|
|
|
|
|
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
#define TEACH_ALL 1
|
|
|
|
|
#define TEACH_FRIENDS 1
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <config.h>
|
|
|
|
|
#include "eressea.h"
|
|
|
|
|
|
|
|
|
|
#include "alchemy.h"
|
|
|
|
|
#include "item.h"
|
|
|
|
|
#include "faction.h"
|
|
|
|
|
#include "magic.h"
|
|
|
|
|
#include "building.h"
|
|
|
|
|
#include "race.h"
|
|
|
|
|
#include "pool.h"
|
|
|
|
|
#include "region.h"
|
|
|
|
|
#include "unit.h"
|
|
|
|
|
#include "skill.h"
|
|
|
|
|
#include "message.h"
|
|
|
|
|
#include "plane.h"
|
|
|
|
|
#include "karma.h"
|
2001-02-19 15:19:24 +01:00
|
|
|
|
#include "rand.h"
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* util includes */
|
|
|
|
|
#include <base36.h>
|
|
|
|
|
|
|
|
|
|
/* libc includes */
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <limits.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
|
|
#define TEACHNUMBER 10
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
static skill_t
|
2001-04-16 16:34:19 +02:00
|
|
|
|
getskill(const struct locale * lang)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2001-04-16 16:34:19 +02:00
|
|
|
|
return findskill(getstrtoken(), lang);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static magic_t
|
|
|
|
|
findmagicskill(const char *s)
|
|
|
|
|
{
|
|
|
|
|
return (char) findstr(magietypen, s, MAXMAGIETYP);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
magic_t
|
|
|
|
|
getmagicskill(void)
|
|
|
|
|
{
|
|
|
|
|
return findmagicskill(getstrtoken());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
2001-12-10 01:13:39 +01:00
|
|
|
|
/* Vertraute und Kr<4B>ten sind keine Migranten */
|
2001-02-11 10:42:58 +01:00
|
|
|
|
boolean
|
|
|
|
|
is_migrant(unit *u)
|
|
|
|
|
{
|
|
|
|
|
if (u->race == u->faction->race) return false;
|
|
|
|
|
|
|
|
|
|
if (is_familiar(u)) return false;
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (u->race == new_race[RC_TOAD]) return false;
|
2001-02-11 10:42:58 +01:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2001-05-20 08:48:34 +02:00
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
boolean
|
|
|
|
|
magic_lowskill(unit *u)
|
|
|
|
|
{
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (u->race == new_race[RC_TOAD]) return true;
|
2001-05-20 08:48:34 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2001-02-11 10:42:58 +01:00
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static int
|
|
|
|
|
study_cost(unit *u, int talent)
|
|
|
|
|
{
|
|
|
|
|
int stufe, k = 50;
|
|
|
|
|
|
|
|
|
|
switch (talent) {
|
|
|
|
|
case SK_SPY:
|
|
|
|
|
return 100;
|
|
|
|
|
break;
|
|
|
|
|
case SK_TACTICS:
|
|
|
|
|
case SK_HERBALISM:
|
|
|
|
|
case SK_ALCHEMY:
|
|
|
|
|
return 200;
|
|
|
|
|
break;
|
|
|
|
|
case SK_MAGIC: /* Die Magiekosten betragen 50+Summe(50*Stufe) */
|
|
|
|
|
/* 'Stufe' ist dabei die n<>chste zu erreichende Stufe */
|
2002-02-15 17:13:30 +01:00
|
|
|
|
stufe = 1 + get_level(u, SK_MAGIC);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return k*(1+((stufe+1)*stufe/2));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
2002-03-10 13:04:12 +01:00
|
|
|
|
typedef struct teaching_info {
|
|
|
|
|
unit * teacher;
|
|
|
|
|
int value;
|
|
|
|
|
} teaching_info;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
init_learning(struct attrib * a)
|
|
|
|
|
{
|
|
|
|
|
a->data.v = calloc(sizeof(teaching_info), 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
done_learning(struct attrib * a)
|
|
|
|
|
{
|
|
|
|
|
free(a->data.v);
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static const attrib_type at_learning = {
|
|
|
|
|
"learning",
|
2002-03-10 13:04:12 +01:00
|
|
|
|
init_learning, done_learning, NULL, NULL, NULL,
|
2001-01-25 10:37:55 +01:00
|
|
|
|
ATF_UNIQUE
|
|
|
|
|
};
|
|
|
|
|
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
static int
|
2002-03-10 13:04:12 +01:00
|
|
|
|
teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk,
|
2002-02-15 17:13:30 +01:00
|
|
|
|
boolean report, int * academy)
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
{
|
2002-03-10 13:04:12 +01:00
|
|
|
|
teaching_info * teach = NULL;
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
attrib * a;
|
|
|
|
|
int n;
|
|
|
|
|
|
|
|
|
|
/* learning sind die Tage, die sie schon durch andere Lehrer zugute
|
|
|
|
|
* geschrieben bekommen haben. Total darf dies nicht <EFBFBD>ber 30 Tage pro Mann
|
|
|
|
|
* steigen.
|
|
|
|
|
*
|
|
|
|
|
* n ist die Anzahl zus<EFBFBD>tzlich gelernter Tage. n darf max. die Differenz
|
|
|
|
|
* von schon gelernten Tagen zum max(30 Tage pro Mann) betragen. */
|
|
|
|
|
|
2001-05-20 09:57:52 +02:00
|
|
|
|
if (magic_lowskill(student)){
|
2001-05-27 10:37:56 +02:00
|
|
|
|
cmistake(teacher, teacher->thisorder, 292, MSG_EVENT);
|
2001-05-20 09:57:52 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
n = student->number * 30;
|
|
|
|
|
a = a_find(student->attribs, &at_learning);
|
2002-03-10 13:04:12 +01:00
|
|
|
|
if (a!=NULL) {
|
|
|
|
|
teach = (teaching_info*)a->data.v;
|
|
|
|
|
n -= teach->value;
|
|
|
|
|
}
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
|
2002-03-10 13:04:12 +01:00
|
|
|
|
n = min(n, nteaching);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
|
|
|
|
|
if (n != 0) {
|
|
|
|
|
struct building * b = inside_building(teacher);
|
|
|
|
|
const struct building_type * btype = b?b->type:NULL;
|
|
|
|
|
|
2002-03-10 13:04:12 +01:00
|
|
|
|
if (teach==NULL) {
|
|
|
|
|
a = a_add(&student->attribs, a_new(&at_learning));
|
|
|
|
|
teach = (teaching_info*)a->data.v;
|
|
|
|
|
}
|
|
|
|
|
teach->teacher = teacher;
|
|
|
|
|
teach->value += n;
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
|
2001-04-22 20:14:07 +02:00
|
|
|
|
/* Solange Akademien gr<67><72>enbeschr<68>nkt sind, sollte Lehrer und
|
|
|
|
|
* Student auch in unterschiedlichen Geb<EFBFBD>uden stehen d<EFBFBD>rfen */
|
2002-03-27 22:49:27 +01:00
|
|
|
|
if (btype == bt_find("academy")
|
|
|
|
|
&& student->building && student->building->type == bt_find("academy"))
|
2001-04-22 20:14:07 +02:00
|
|
|
|
{
|
2001-05-27 10:37:56 +02:00
|
|
|
|
int j = study_cost(student, sk);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
j = max(50, j * 2);
|
2001-05-27 10:37:56 +02:00
|
|
|
|
/* kann Einheit das zahlen? */
|
|
|
|
|
if (get_pooled(student, student->region, R_SILVER) >= j) {
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
/* Jeder Sch<63>ler zus<75>tzlich +10 Tage wenn in Uni. */
|
2002-03-10 13:04:12 +01:00
|
|
|
|
teach->value += (n / 30) * 10; /* learning erh<72>hen */
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
/* Lehrer zus<75>tzlich +1 Tag pro Sch<63>ler. */
|
2002-02-15 17:13:30 +01:00
|
|
|
|
if (academy) *academy += n;
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
} /* sonst nehmen sie nicht am Unterricht teil */
|
|
|
|
|
}
|
|
|
|
|
/* Teaching ist die Anzahl Leute, denen man noch was beibringen kann. Da
|
|
|
|
|
* hier nicht n verwendet wird, werden die Leute gez<EFBFBD>hlt und nicht die
|
|
|
|
|
* effektiv gelernten Tage. -> FALSCH ? (ENNO)
|
|
|
|
|
*
|
|
|
|
|
* Eine Einheit A von 11 Mann mit Talent 0 profitiert vom ersten Lehrer B
|
|
|
|
|
* also 10x30=300 tage, und der zweite Lehrer C lehrt f<EFBFBD>r nur noch 1x30=30
|
|
|
|
|
* Tage (damit das Maximum von 11x30=330 nicht <EFBFBD>berschritten wird).
|
|
|
|
|
*
|
|
|
|
|
* Damit es aber in der Ausf<EFBFBD>hrung nicht auf die Reihenfolge drauf ankommt,
|
|
|
|
|
* darf der zweite Lehrer C keine weiteren Einheiten D mehr lehren. Also
|
|
|
|
|
* wird student 30 Tage gutgeschrieben, aber teaching sinkt auf 0 (300-11x30 <=
|
|
|
|
|
* 0).
|
|
|
|
|
*
|
|
|
|
|
* Sonst tr<EFBFBD>te dies auf:
|
|
|
|
|
*
|
|
|
|
|
* A: lernt B: lehrt A C: lehrt A D D: lernt
|
|
|
|
|
*
|
|
|
|
|
* Wenn B vor C dran ist, lehrt C nur 30 Tage an A (wie oben) und
|
|
|
|
|
* 270 Tage an D.
|
|
|
|
|
*
|
|
|
|
|
* Ist C aber vor B dran, lehrt C 300 tage an A, und 0 tage an D,
|
|
|
|
|
* und B lehrt auch 0 tage an A.
|
|
|
|
|
*
|
|
|
|
|
* Deswegen darf C D nie lehren d<EFBFBD>rfen.
|
|
|
|
|
*
|
|
|
|
|
* -> Das ist wirr. wer hat das entworfen?
|
2001-04-16 16:34:19 +02:00
|
|
|
|
* Besser w<EFBFBD>re, man macht erst vorab alle zuordnungen, und dann
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
* die Talent<EFBFBD>nderung (enno).
|
|
|
|
|
*/
|
|
|
|
|
|
2002-03-10 13:04:12 +01:00
|
|
|
|
nteaching = max(0, nteaching - student->number * 30);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
|
|
|
|
teach(region * r, unit * u)
|
|
|
|
|
{
|
|
|
|
|
/* Parameter r gebraucht, um kontrollieren zu k<>nnen, da<64> die Ziel-Unit auch
|
|
|
|
|
* in der selben Region ist (getunit). Lehren vor lernen. */
|
|
|
|
|
static char order[BUFSIZE];
|
2002-02-15 17:13:30 +01:00
|
|
|
|
int teaching, i, j, count, academy=0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
unit *u2;
|
|
|
|
|
char *s;
|
|
|
|
|
skill_t sk;
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if ((u->race->flags & RCF_NOTEACH)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
cmistake(u, u->thisorder, 274, MSG_EVENT);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (r->planep && fval(r->planep, PFL_NOTEACH)) {
|
|
|
|
|
cmistake(u, u->thisorder, 273, MSG_EVENT);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
teaching = u->number * 30 * TEACHNUMBER;
|
|
|
|
|
|
|
|
|
|
if ((i = get_effect(u, oldpotiontype[P_FOOL])) > 0) { /* Trank "Dumpfbackenbrot" */
|
|
|
|
|
i = min(i, u->number * TEACHNUMBER);
|
|
|
|
|
/* Trank wirkt pro Sch<63>ler, nicht pro Lehrer */
|
|
|
|
|
teaching -= i * 30;
|
|
|
|
|
change_effect(u, oldpotiontype[P_FOOL], -i);
|
|
|
|
|
j = teaching / 30;
|
* möglichen Exploit beseitigt:
GIB xyz EINHEIT
GIB 0 ALLES SILBER
--> ALLE Befehle der übergebenen Einheit werden gelöscht.
* neue Funktion (convenience): ucansee(f, u1, u2)
liefert u1, wenn cansee(f,u1), sonst u2
* neue mistakes eingefügt uns übersetzt
* message bugfix:
u->htisorder kann gelöscht werden (z.b. NACH). Daher muss ein pointer auf
einen befehl in einer message immer auf den u->order Eintrag zeigen, damit er
zeit der auswertung noch existiert.
findorder(u, u->thisorder) tut das. Ist an mehreren Stellen nicht benutzt
worden. assert eingebaut, das das prüft.
* RESERVE_DONATIONS
Gegenstände, die von einer anderen Partei übergeben wurden, werden nicht
reserviert.
* TWOPASS_GIVE:
GIB Befehle werden zuerst an fremde Einheiten, danach in einem zweiten
Durchlauf an eigene Einheiten, ausgeführt.
* msg_message
An einigen messages ausprobiert, ob man die gleiche Message mehreren
Parteien einhängen kann - klappt, spart Speicher.
Allerdings fehlt dazu ein ordentliches memory-management (refcounter)
2001-05-10 07:50:52 +02:00
|
|
|
|
add_message(&u->faction->msgs, msg_message("teachdumb",
|
|
|
|
|
"teacher amount", u, j));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2002-02-15 17:13:30 +01:00
|
|
|
|
if (teaching == 0) return;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
strcpy(order, locale_string(u->faction->locale, keywords[K_TEACH]));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
u2 = 0;
|
|
|
|
|
count = 0;
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
#if TEACH_ALL
|
2001-04-16 16:34:19 +02:00
|
|
|
|
if (getparam(u->faction->locale)==P_ANY) {
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
unit * student = r->units;
|
|
|
|
|
skill_t teachskill[MAXSKILLS];
|
|
|
|
|
int i = 0;
|
|
|
|
|
do {
|
2001-04-16 16:34:19 +02:00
|
|
|
|
sk = getskill(u->faction->locale);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
teachskill[i++]=sk;
|
|
|
|
|
} while (sk!=NOSKILL);
|
|
|
|
|
while (teaching && student) {
|
2002-01-12 13:33:46 +01:00
|
|
|
|
if (student->faction == u->faction && !fval(student, FL_HUNGER)) {
|
2001-04-16 16:34:19 +02:00
|
|
|
|
if (igetkeyword(student->thisorder, student->faction->locale) == K_STUDY) {
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
/* Input ist nun von student->thisorder !! */
|
2001-04-16 16:34:19 +02:00
|
|
|
|
sk = getskill(student->faction->locale);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
if (sk!=NOSKILL && teachskill[0]!=NOSKILL) {
|
|
|
|
|
for (i=0;teachskill[i]!=NOSKILL;++i) if (sk==teachskill[i]) break;
|
|
|
|
|
sk = teachskill[i];
|
|
|
|
|
}
|
|
|
|
|
if (sk != NOSKILL && eff_skill(u, sk, r) > eff_skill(student, sk, r)) {
|
2002-02-15 17:13:30 +01:00
|
|
|
|
teaching -= teach_unit(u, student, teaching, sk, true, &academy);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
student = student->next;
|
|
|
|
|
}
|
|
|
|
|
#if TEACH_FRIENDS
|
|
|
|
|
while (teaching && student) {
|
2002-01-12 13:33:46 +01:00
|
|
|
|
if (student->faction != u->faction && !fval(student, FL_HUNGER) && allied(u, student->faction, HELP_GUARD)) {
|
2001-04-16 16:34:19 +02:00
|
|
|
|
if (igetkeyword(student->thisorder, student->faction->locale) == K_STUDY) {
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
/* Input ist nun von student->thisorder !! */
|
2001-04-16 16:34:19 +02:00
|
|
|
|
sk = getskill(student->faction->locale);
|
2002-03-10 16:43:00 +01:00
|
|
|
|
if (sk != NOSKILL && eff_skill(u, sk, r)-TEACHDIFFERENCE >= eff_skill(student, sk, r)) {
|
2002-02-15 17:13:30 +01:00
|
|
|
|
teaching -= teach_unit(u, student, teaching, sk, true, &academy);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
student = student->next;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2001-04-16 16:34:19 +02:00
|
|
|
|
}
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
else
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for (;;) {
|
|
|
|
|
/* Da sp<73>ter in der Schleife igetkeyword (u2->thisorder) verwendet wird,
|
|
|
|
|
* mu<EFBFBD> hier wieder von vorne gelesen werden. Also merken wir uns, an
|
|
|
|
|
* welcher Stelle wir hier waren...
|
|
|
|
|
*
|
|
|
|
|
* Beispiel count = 1: LEHRE 101 102 103
|
|
|
|
|
*
|
|
|
|
|
* LEHRE und 101 wird gelesen (und ignoriert), und dann wird
|
|
|
|
|
* getunit die einheit 102 zur<EFBFBD>ck liefern. */
|
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
igetkeyword(u->thisorder, u->faction->locale);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for (j = count; j; j--)
|
|
|
|
|
getstrtoken();
|
|
|
|
|
|
2001-04-26 19:41:06 +02:00
|
|
|
|
u2 = getunit(r, u->faction);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* Falls keine Unit gefunden, abbrechen - au<61>er es gibt <20>berhaupt keine
|
|
|
|
|
* Unit, dann gibt es zus<EFBFBD>tzlich noch einen Fehler */
|
|
|
|
|
|
|
|
|
|
if (!u2) {
|
|
|
|
|
|
|
|
|
|
/* Finde den string, der den Fehler verursacht hat */
|
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
igetkeyword(u->thisorder, u->faction->locale);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for (j = count; j; j--)
|
|
|
|
|
getstrtoken();
|
|
|
|
|
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
|
|
|
|
|
/* Falls es keinen String gibt, ist die Liste der Einheiten zuende */
|
|
|
|
|
|
|
|
|
|
if (!s[0])
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Beginne die Fehlermeldung */
|
|
|
|
|
|
|
|
|
|
strcpy(buf, "Die Einheit '");
|
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
if (findparam(s, u->faction->locale) == P_TEMP) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* F<>r: "Die Einheit 'TEMP ZET' wurde nicht gefunden" oder "Die Einheit
|
|
|
|
|
* 'TEMP' wurde nicht gefunden" */
|
|
|
|
|
|
|
|
|
|
scat(s);
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
if (s[0])
|
|
|
|
|
scat(" ");
|
|
|
|
|
|
|
|
|
|
/* Um nachher weiter einlesen zu koennen */
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
scat(s);
|
|
|
|
|
scat("' wurde nicht gefunden");
|
|
|
|
|
mistake(u, u->thisorder, buf, MSG_EVENT);
|
|
|
|
|
|
|
|
|
|
count++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
/* Defaultorder zusammenbauen. TEMP-Einheiten werden automatisch in
|
|
|
|
|
* ihre neuen Nummern <EFBFBD>bersetzt. */
|
|
|
|
|
strcat(order, " ");
|
|
|
|
|
strcat(order, unitid(u2));
|
|
|
|
|
set_string(&u->lastorder, order);
|
|
|
|
|
|
|
|
|
|
/* Wir m<>ssen nun hochz<68>hlen, wieviele Einheiten wir schon abgearbeitet
|
|
|
|
|
* haben, damit mit getstrtoken() die richtige Einheit geholt werden kann.
|
|
|
|
|
* Falls u2 ein Alias hat, ist sie neu, und es wurde ein TEMP verwendet, um
|
|
|
|
|
* sie zu beschreiben. */
|
|
|
|
|
|
|
|
|
|
count++;
|
|
|
|
|
if (ualias(u2))
|
|
|
|
|
count++;
|
|
|
|
|
|
|
|
|
|
if (!ucontact(u2, u)) {
|
|
|
|
|
sprintf(buf, "Einheit %s hat keinen Kontakt mit uns aufgenommen",
|
|
|
|
|
unitid(u2));
|
|
|
|
|
mistake(u, u->thisorder, buf, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2001-04-16 16:34:19 +02:00
|
|
|
|
i = igetkeyword(u2->thisorder, u2->faction->locale);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* Input ist nun von u2->thisorder !! */
|
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
if (i != K_STUDY || ((sk = getskill(u2->faction->locale)) == NOSKILL)) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
add_message(&u->faction->msgs,
|
|
|
|
|
msg_error(u, u->thisorder, "teach_nolearn", "student", u2));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2002-03-10 16:43:00 +01:00
|
|
|
|
/* u is teacher, u2 is student */
|
2002-03-10 16:50:11 +01:00
|
|
|
|
if (eff_skill(u2, sk, r) > eff_skill(u, sk, r)-TEACHDIFFERENCE) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
add_message(&u->faction->msgs,
|
|
|
|
|
msg_error(u, u->thisorder, "teach_asgood", "student", u2));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (sk == SK_MAGIC) {
|
|
|
|
|
/* ist der Magier schon spezialisiert, so versteht er nur noch
|
|
|
|
|
* Lehrer seines Gebietes */
|
|
|
|
|
if (find_magetype(u2) != 0
|
|
|
|
|
&& find_magetype(u) != find_magetype(u2))
|
|
|
|
|
{
|
|
|
|
|
sprintf(buf, "%s versteht unsere Art von Magie nicht", unitname(u2));
|
|
|
|
|
mistake(u, u->thisorder, buf, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-02-15 17:13:30 +01:00
|
|
|
|
teaching -= teach_unit(u, u2, teaching, sk, false, &academy);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2002-02-15 17:13:30 +01:00
|
|
|
|
if (academy) {
|
|
|
|
|
academy = academy/30;
|
|
|
|
|
learn_skill(u, sk, academy/30.0/TEACHNUMBER);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
#ifdef SKILLFIX_SAVE
|
|
|
|
|
extern void skillfix(struct unit *, skill_t, int, int, int);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
learn(void)
|
|
|
|
|
{
|
|
|
|
|
region *r;
|
|
|
|
|
unit *u;
|
|
|
|
|
int p;
|
|
|
|
|
magic_t mtyp;
|
2001-02-04 08:52:30 +01:00
|
|
|
|
int i, l;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
int warrior_skill;
|
|
|
|
|
int studycost;
|
|
|
|
|
|
|
|
|
|
/* lernen nach lehren */
|
|
|
|
|
|
2001-05-06 23:49:16 +02:00
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
2002-01-13 10:14:13 +01:00
|
|
|
|
int days;
|
2001-05-06 23:49:16 +02:00
|
|
|
|
if (rterrain(r) == T_OCEAN){
|
|
|
|
|
/* sonderbehandlung aller die auf Ozeanen lernen k<>nnen */
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (u->race != new_race[RC_AQUARIAN]
|
|
|
|
|
&& !(u->race->flags & RCF_SWIM)) {
|
2001-05-06 23:49:16 +02:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
if (igetkeyword(u->thisorder, u->faction->locale) == K_STUDY) {
|
|
|
|
|
double multi = 1.0;
|
|
|
|
|
attrib * a = NULL;
|
2002-03-10 13:04:12 +01:00
|
|
|
|
teaching_info * teach = NULL;
|
2001-05-06 23:49:16 +02:00
|
|
|
|
int money = 0;
|
|
|
|
|
int maxalchemy = 0;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (u->race == new_race[RC_INSECT] && r_insectstalled(r)
|
|
|
|
|
&& !is_cursed(u->attribs, C_KAELTESCHUTZ,0)) {
|
2001-05-06 23:49:16 +02:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (attacked(u)) {
|
|
|
|
|
cmistake(u, findorder(u, u->thisorder), 52, MSG_PRODUCE);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if ((u->race->flags & RCF_NOLEARN)) {
|
|
|
|
|
sprintf(buf, "%s k<>nnen nichts lernen", LOC(default_locale, rc_name(u->race, 1)));
|
|
|
|
|
mistake(u, u->thisorder, buf, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2001-05-06 23:49:16 +02:00
|
|
|
|
i = getskill(u->faction->locale);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-05-06 23:49:16 +02:00
|
|
|
|
if (i < 0) {
|
|
|
|
|
cmistake(u, findorder(u, u->thisorder), 77, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
/* Hack: Talente mit Malus -99 k<>nnen nicht gelernt werden */
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (u->race->bonus[i] == -99) {
|
2001-05-06 23:49:16 +02:00
|
|
|
|
cmistake(u, findorder(u, u->thisorder), 77, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2002-02-10 18:23:00 +01:00
|
|
|
|
/* snotlings k<>nnen Talente nur bis T8 lernen */
|
2002-02-10 21:02:23 +01:00
|
|
|
|
if (u->race == new_race[RC_SNOTLING]){
|
2002-02-23 12:27:19 +01:00
|
|
|
|
if (get_level(u, (skill_t)i) >= 8){
|
2002-02-10 18:23:00 +01:00
|
|
|
|
cmistake(u, findorder(u, u->thisorder), 308, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
p = studycost = study_cost(u,i);
|
|
|
|
|
a = a_find(u->attribs, &at_learning);
|
2002-03-10 13:04:12 +01:00
|
|
|
|
if (a!=NULL) {
|
|
|
|
|
teach = (teaching_info*)a->data.v;
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
/* keine kostenpflichtigen Talente f<>r Migranten. Vertraute sind
|
|
|
|
|
* keine Migranten, wird in is_migrant abgefangen. Vorsicht,
|
|
|
|
|
* studycost darf hier noch nicht durch Akademie erh<EFBFBD>ht sein */
|
|
|
|
|
if (is_migrant(u) && studycost > 0){
|
|
|
|
|
sprintf(buf, "Migranten k<>nnen keine kostenpflichtigen Talente lernen");
|
2001-05-06 23:49:16 +02:00
|
|
|
|
mistake(u, u->thisorder, buf, MSG_EVENT);
|
|
|
|
|
continue;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Akademie: */
|
|
|
|
|
{
|
2001-05-06 23:49:16 +02:00
|
|
|
|
struct building * b = inside_building(u);
|
|
|
|
|
const struct building_type * btype = b?b->type:NULL;
|
|
|
|
|
|
2002-03-27 22:49:27 +01:00
|
|
|
|
if (btype == bt_find("academy")) {
|
2001-05-06 23:49:16 +02:00
|
|
|
|
studycost = max(50, studycost * 2);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2001-05-06 23:49:16 +02:00
|
|
|
|
if (i == SK_MAGIC) {
|
|
|
|
|
if (u->number > 1){
|
|
|
|
|
cmistake(u, findorder(u, u->thisorder), 106, MSG_MAGIC);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
if (is_familiar(u)){
|
|
|
|
|
/* Vertraute z<>hlen nicht zu den Magiern einer Partei,
|
|
|
|
|
* k<EFBFBD>nnen aber nur Graue Magie lernen */
|
|
|
|
|
mtyp = M_GRAU;
|
2002-03-03 19:13:08 +01:00
|
|
|
|
if (!has_skill(u, SK_MAGIC)) {
|
2001-05-06 23:49:16 +02:00
|
|
|
|
create_mage(u, mtyp);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2002-03-03 19:13:08 +01:00
|
|
|
|
} else if (!has_skill(u, SK_MAGIC)){
|
2001-05-06 23:49:16 +02:00
|
|
|
|
/* Die Einheit ist noch kein Magier */
|
|
|
|
|
if (count_skill(u->faction, SK_MAGIC) + u->number >
|
|
|
|
|
max_skill(u->faction, SK_MAGIC))
|
|
|
|
|
{
|
|
|
|
|
sprintf(buf, "Es kann maximal %d Magier pro Partei geben",
|
|
|
|
|
max_skill(u->faction, SK_MAGIC));
|
|
|
|
|
mistake(u, u->thisorder, buf, MSG_EVENT);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
mtyp = getmagicskill();
|
|
|
|
|
if (mtyp == M_NONE || mtyp == M_GRAU) {
|
|
|
|
|
/* wurde kein Magiegebiet angegeben, wird davon
|
|
|
|
|
* ausgegangen, da<EFBFBD> das normal gelernt werden soll */
|
|
|
|
|
if(u->faction->magiegebiet != 0) {
|
|
|
|
|
mtyp = u->faction->magiegebiet;
|
|
|
|
|
} else {
|
|
|
|
|
/* Es wurde kein Magiegebiet angegeben und die Partei
|
|
|
|
|
* hat noch keins gew<EFBFBD>hlt. */
|
|
|
|
|
cmistake(u, findorder(u, u->thisorder), 178, MSG_MAGIC);
|
|
|
|
|
continue;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
}
|
|
|
|
|
if (mtyp != u->faction->magiegebiet){
|
|
|
|
|
/* Es wurde versucht, ein anderes Magiegebiet zu lernen
|
|
|
|
|
* als das der Partei */
|
|
|
|
|
if (u->faction->magiegebiet != 0){
|
|
|
|
|
cmistake(u, findorder(u, u->thisorder), 179, MSG_MAGIC);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
continue;
|
2001-05-06 23:49:16 +02:00
|
|
|
|
} else {
|
|
|
|
|
/* Lernt zum ersten mal Magie und legt damit das
|
|
|
|
|
* Magiegebiet der Partei fest */
|
|
|
|
|
u->faction->magiegebiet = mtyp;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
}
|
|
|
|
|
create_mage(u, mtyp);
|
|
|
|
|
} else {
|
|
|
|
|
/* ist schon ein Magier und kein Vertrauter */
|
|
|
|
|
if(u->faction->magiegebiet == 0){
|
|
|
|
|
/* die Partei hat noch kein Magiegebiet gew<65>hlt. */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
mtyp = getmagicskill();
|
2001-05-06 23:49:16 +02:00
|
|
|
|
if (mtyp == M_NONE){
|
|
|
|
|
cmistake(u, findorder(u, u->thisorder), 178, MSG_MAGIC);
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
/* Legt damit das Magiegebiet der Partei fest */
|
|
|
|
|
u->faction->magiegebiet = mtyp;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
}
|
|
|
|
|
if (i == SK_ALCHEMY) {
|
|
|
|
|
maxalchemy = eff_skill(u, SK_ALCHEMY, r);
|
2002-03-03 19:13:08 +01:00
|
|
|
|
if (has_skill(u, SK_ALCHEMY)==0
|
2001-05-06 23:49:16 +02:00
|
|
|
|
&& count_skill(u->faction, SK_ALCHEMY) + u->number >
|
|
|
|
|
max_skill(u->faction, SK_ALCHEMY)) {
|
|
|
|
|
sprintf(buf, "Es kann maximal %d Alchemisten pro Partei geben",
|
|
|
|
|
max_skill(u->faction, SK_ALCHEMY));
|
|
|
|
|
mistake(u, u->thisorder, buf, MSG_EVENT);
|
|
|
|
|
continue;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
}
|
|
|
|
|
if (studycost) {
|
|
|
|
|
money = get_pooled(u, r, R_SILVER);
|
|
|
|
|
money = min(money, studycost * u->number);
|
|
|
|
|
}
|
|
|
|
|
if (money < studycost * u->number) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
studycost = p; /* Ohne Univertreurung */
|
2001-05-06 23:49:16 +02:00
|
|
|
|
money = min(money, studycost);
|
|
|
|
|
if (p>0 && money < studycost * u->number) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#ifdef PARTIAL_STUDY
|
2001-05-06 23:49:16 +02:00
|
|
|
|
cmistake(u, findorder(u, u->thisorder), 65, MSG_EVENT);
|
|
|
|
|
multi = money / (double)(studycost * u->number);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#else
|
2001-05-06 23:49:16 +02:00
|
|
|
|
cmistake(u, findorder(u, u->thisorder), 65, MSG_EVENT);
|
|
|
|
|
continue; /* nein, Silber reicht auch so nicht */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#endif
|
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-03-10 13:04:12 +01:00
|
|
|
|
if (teach==NULL) {
|
|
|
|
|
a = a_add(&u->attribs, a_new(&at_learning));
|
|
|
|
|
teach = (teaching_info*)a->data.v;
|
|
|
|
|
teach->teacher = NULL;
|
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
if (money>0) {
|
|
|
|
|
use_pooled(u, r, R_SILVER, money);
|
* möglichen Exploit beseitigt:
GIB xyz EINHEIT
GIB 0 ALLES SILBER
--> ALLE Befehle der übergebenen Einheit werden gelöscht.
* neue Funktion (convenience): ucansee(f, u1, u2)
liefert u1, wenn cansee(f,u1), sonst u2
* neue mistakes eingefügt uns übersetzt
* message bugfix:
u->htisorder kann gelöscht werden (z.b. NACH). Daher muss ein pointer auf
einen befehl in einer message immer auf den u->order Eintrag zeigen, damit er
zeit der auswertung noch existiert.
findorder(u, u->thisorder) tut das. Ist an mehreren Stellen nicht benutzt
worden. assert eingebaut, das das prüft.
* RESERVE_DONATIONS
Gegenstände, die von einer anderen Partei übergeben wurden, werden nicht
reserviert.
* TWOPASS_GIVE:
GIB Befehle werden zuerst an fremde Einheiten, danach in einem zweiten
Durchlauf an eigene Einheiten, ausgeführt.
* msg_message
An einigen messages ausprobiert, ob man die gleiche Message mehreren
Parteien einhängen kann - klappt, spart Speicher.
Allerdings fehlt dazu ein ordentliches memory-management (refcounter)
2001-05-10 07:50:52 +02:00
|
|
|
|
add_message(&u->faction->msgs, msg_message("studycost",
|
|
|
|
|
"unit region cost skill", u, u->region, money, i));
|
2001-05-06 23:49:16 +02:00
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2001-05-06 23:49:16 +02:00
|
|
|
|
if (get_effect(u, oldpotiontype[P_WISE])) {
|
|
|
|
|
l = min(u->number, get_effect(u, oldpotiontype[P_WISE]));
|
2002-03-10 13:04:12 +01:00
|
|
|
|
teach->value += l * 10;
|
2001-05-06 23:49:16 +02:00
|
|
|
|
change_effect(u, oldpotiontype[P_WISE], -l);
|
|
|
|
|
}
|
|
|
|
|
if (get_effect(u, oldpotiontype[P_FOOL])) {
|
|
|
|
|
l = min(u->number, get_effect(u, oldpotiontype[P_FOOL]));
|
2002-03-10 13:04:12 +01:00
|
|
|
|
teach->value -= l * 30;
|
2001-05-06 23:49:16 +02:00
|
|
|
|
change_effect(u, oldpotiontype[P_FOOL], -l);
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2001-05-06 23:49:16 +02:00
|
|
|
|
warrior_skill = fspecial(u->faction, FS_WARRIOR);
|
|
|
|
|
if(warrior_skill > 0) {
|
|
|
|
|
if(i == SK_CROSSBOW || i == SK_LONGBOW
|
|
|
|
|
|| i == SK_CATAPULT || i == SK_SWORD || i == SK_SPEAR
|
|
|
|
|
|| i == SK_AUSDAUER || i == SK_WEAPONLESS)
|
|
|
|
|
{
|
2002-03-10 13:04:12 +01:00
|
|
|
|
teach->value += u->number * (5+warrior_skill*5);
|
2001-05-06 23:49:16 +02:00
|
|
|
|
} else {
|
2002-03-10 13:04:12 +01:00
|
|
|
|
teach->value -= u->number * (5+warrior_skill*5);
|
|
|
|
|
teach->value = max(0, teach->value);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2001-05-06 23:49:16 +02:00
|
|
|
|
if (p != studycost) {
|
|
|
|
|
/* ist_in_gebaeude(r, u, BT_UNIVERSITAET) == 1) { */
|
|
|
|
|
/* p ist Kosten ohne Uni, studycost mit; wenn
|
|
|
|
|
* p!=studycost, ist die Einheit zwangsweise
|
|
|
|
|
* in einer Uni */
|
2002-03-10 13:04:12 +01:00
|
|
|
|
teach->value += u->number * 10;
|
2001-05-06 23:49:16 +02:00
|
|
|
|
}
|
|
|
|
|
if (is_cursed(r->attribs,C_BADLEARN,0)) {
|
2002-03-10 13:04:12 +01:00
|
|
|
|
teach->value -= u->number * 10;
|
2001-05-06 23:49:16 +02:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#ifdef SKILLFIX_SAVE
|
2002-03-10 13:04:12 +01:00
|
|
|
|
if (teach && teach->value) {
|
2001-05-06 23:49:16 +02:00
|
|
|
|
int skill = get_skill(u, (skill_t)i);
|
|
|
|
|
skillfix(u, (skill_t)i, skill,
|
2002-03-10 13:04:12 +01:00
|
|
|
|
(int)(u->number * 30 * multi), teach->value);
|
2001-05-06 23:49:16 +02:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#endif
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2002-03-10 13:04:12 +01:00
|
|
|
|
days = (int)((u->number * 30 + teach->value) * multi);
|
2002-01-13 11:42:56 +01:00
|
|
|
|
if (fval(u, FL_HUNGER)) days = days / 2;
|
2002-02-15 17:13:30 +01:00
|
|
|
|
while (days) {
|
2002-02-16 11:37:18 +01:00
|
|
|
|
if (days>=u->number*30) {
|
2002-02-15 17:13:30 +01:00
|
|
|
|
learn_skill(u, (skill_t)i, 1.0);
|
|
|
|
|
days -= u->number*30;
|
|
|
|
|
} else {
|
|
|
|
|
double chance = (double)days/u->number/30;
|
|
|
|
|
learn_skill(u, (skill_t)i, chance);
|
2002-02-16 11:37:18 +01:00
|
|
|
|
days = 0;
|
2002-02-15 17:13:30 +01:00
|
|
|
|
}
|
2002-02-10 18:23:00 +01:00
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
if (a) {
|
2002-03-10 13:04:12 +01:00
|
|
|
|
if (teach && teach->teacher) {
|
|
|
|
|
unit * teacher = teach->teacher;
|
|
|
|
|
if (teacher->faction != u->faction) {
|
|
|
|
|
add_message(&u->faction->msgs, msg_message("teach_student",
|
|
|
|
|
"teacher student skill", teacher, u, (skill_t)i));
|
|
|
|
|
add_message(&teacher->faction->msgs, msg_message("teach_teacher",
|
|
|
|
|
"teacher student skill level", teacher, u, (skill_t)i,
|
|
|
|
|
effskill(u, (skill_t)i)));
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
a_remove(&u->attribs, a);
|
|
|
|
|
a = NULL;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-05-06 23:49:16 +02:00
|
|
|
|
/* Anzeigen neuer Tr<54>nke */
|
|
|
|
|
/* Spruchlistenaktualiesierung ist in Regeneration */
|
|
|
|
|
|
|
|
|
|
if (i == SK_ALCHEMY) {
|
|
|
|
|
const potion_type * ptype;
|
|
|
|
|
faction * f = u->faction;
|
|
|
|
|
int skill = eff_skill(u, SK_ALCHEMY, r);
|
|
|
|
|
if (skill>maxalchemy) {
|
|
|
|
|
for (ptype=potiontypes; ptype; ptype=ptype->next) {
|
|
|
|
|
if (skill == ptype->level * 2) {
|
|
|
|
|
attrib * a = a_find(f->attribs, &at_showitem);
|
|
|
|
|
while (a && a->data.v != ptype) a=a->nexttype;
|
|
|
|
|
if (!a) {
|
|
|
|
|
a = a_add(&f->attribs, a_new(&at_showitem));
|
|
|
|
|
a->data.v = (void*) ptype->itype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-05-06 23:49:16 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
teaching(void)
|
|
|
|
|
{
|
|
|
|
|
region *r;
|
|
|
|
|
unit *u;
|
|
|
|
|
/* das sind alles befehle, die 30 tage brauchen, und die in thisorder
|
|
|
|
|
* stehen! von allen 30-tage befehlen wird einfach der letzte verwendet
|
|
|
|
|
* (dosetdefaults).
|
|
|
|
|
*
|
|
|
|
|
* lehren vor lernen. */
|
|
|
|
|
|
|
|
|
|
for (r = regions; r; r = r->next) {
|
|
|
|
|
|
|
|
|
|
for (u = r->units; u; u = u->next) {
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (u->race == new_race[RC_SPELL] || fval(u, FL_LONGACTION))
|
2001-01-25 10:37:55 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (rterrain(r) == T_OCEAN
|
|
|
|
|
&& u->race != new_race[RC_AQUARIAN]
|
|
|
|
|
&& !(u->race->flags & RCF_SWIM))
|
2001-05-06 23:49:16 +02:00
|
|
|
|
continue;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (u->race == new_race[RC_INSECT] && r_insectstalled(r)
|
|
|
|
|
&& !is_cursed(u->attribs, C_KAELTESCHUTZ,0)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
continue;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
switch (igetkeyword(u->thisorder, u->faction->locale)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
case K_TEACH:
|
|
|
|
|
if (attacked(u)){
|
|
|
|
|
cmistake(u, findorder(u, u->thisorder), 52, MSG_PRODUCE);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
teach(r, u);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|