forked from github/server
Merge pull request #287 from ennorehling/feature/issue-282-link-seen
eliminate duplicate call to link_seen
This commit is contained in:
commit
6f212686f3
|
@ -19,7 +19,6 @@ ipch/
|
||||||
*.opensdf
|
*.opensdf
|
||||||
*.pdb
|
*.pdb
|
||||||
*.sdf
|
*.sdf
|
||||||
*.sh
|
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ -z $ERESSEA ]; then
|
||||||
|
echo "You need to define the \$ERESSEA environment variable to run $0"
|
||||||
|
exit -2
|
||||||
|
fi
|
||||||
|
|
||||||
|
GAME=$ERESSEA/game-$1
|
||||||
|
GAME_NAME=$(grep name $GAME/eressea.ini | sed 's/.*=\s*//')
|
||||||
|
|
||||||
|
TURN=$2
|
||||||
|
if [ -z $TURN ]
|
||||||
|
then
|
||||||
|
TURN=`cat $GAME/turn`
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d $GAME/reports ]; then
|
||||||
|
echo "cannot find reprts directory in $GAME"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $GAME/reports
|
||||||
|
compress.py $TURN "$GAME_NAME"
|
||||||
|
cd -
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
PATH=$ERESSEA/bin:$PATH
|
||||||
|
|
||||||
|
function abort() {
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
echo $@
|
||||||
|
fi
|
||||||
|
exit -1
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
ls -1 orders.dir/turn* | sed -e 's/.*turn-\(.*\),gruenbaer.*/\1/' | sort -u
|
|
@ -0,0 +1 @@
|
||||||
|
grep -hiw ERESSEA orders.dir/turn-* | cut -d\ -f2 | sort -u
|
|
@ -0,0 +1,22 @@
|
||||||
|
GAME=$1
|
||||||
|
TURN=$2
|
||||||
|
|
||||||
|
if [ ! -d $ERESSEA/game-$GAME ] ; then
|
||||||
|
echo "No such game: $GAME"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $ERESSEA/game-$GAME
|
||||||
|
if [ -z $TURN ]; then
|
||||||
|
TURN=$(cat turn)
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "running turn $TURN, game $GAME"
|
||||||
|
if [ -d orders.dir.$TURN ]; then
|
||||||
|
echo "orders.dir.$TURN already exists"
|
||||||
|
else
|
||||||
|
mv orders.dir orders.dir.$TURN
|
||||||
|
mkdir -p orders.dir
|
||||||
|
fi
|
||||||
|
ls -1rt orders.dir.$TURN/turn-* | xargs cat > orders.$TURN
|
||||||
|
$ERESSEA/bin/eressea -t $TURN run-turn.lua
|
|
@ -0,0 +1,33 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
##
|
||||||
|
## Prepare the report
|
||||||
|
|
||||||
|
if [ -z $ERESSEA ]; then
|
||||||
|
echo "You have to define the \$ERESSEA environment variable to run $0"
|
||||||
|
exit -2
|
||||||
|
fi
|
||||||
|
source $HOME/bin/functions.sh
|
||||||
|
source $ERESSEA/etc/eressea.conf
|
||||||
|
|
||||||
|
if [ ! -z $1 ]; then
|
||||||
|
GAME=$ERESSEA/game-$1
|
||||||
|
else
|
||||||
|
GAME=$ERESSEA
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $GAME/reports || abort "could not chdir to reports directory"
|
||||||
|
for REPORT in *.sh
|
||||||
|
do
|
||||||
|
echo -n "Sending "
|
||||||
|
basename $REPORT .sh
|
||||||
|
bash $REPORT
|
||||||
|
done
|
||||||
|
cd -
|
||||||
|
|
||||||
|
if [ -e $GAME/ages.sh ]; then
|
||||||
|
cd $GAME
|
||||||
|
./ages.sh
|
||||||
|
cd -
|
||||||
|
fi
|
||||||
|
|
|
@ -3598,11 +3598,11 @@
|
||||||
</string>
|
</string>
|
||||||
<string name="p2">
|
<string name="p2">
|
||||||
<text locale="en">The "Water of Life" allows living trees to be created from logs. A Knotroot and Elvendear are heated until one can just still keep one's finger in. This is then poured into a jar and allowed to cool slowly. The extract is sufficient for 10 pieces of wood.</text>
|
<text locale="en">The "Water of Life" allows living trees to be created from logs. A Knotroot and Elvendear are heated until one can just still keep one's finger in. This is then poured into a jar and allowed to cool slowly. The extract is sufficient for 10 pieces of wood.</text>
|
||||||
<text locale="de">Das 'Wasser des Lebens' ist in der Lage, aus gefällten Baumstämmen wieder lebende Bäume zu machen. Dazu wird ein knotiger Saugwurz zusammen mit einem Elfenlieb erwärmt, so daß man gerade noch den Finger reinhalten kann. Dies gieße man in ein Gefäß und lasse es langsam abkühlen. Der Extrakt reicht für 10 Holzstämme.</text>
|
<text locale="de">Das 'Wasser des Lebens' ist in der Lage, aus gefällten Baumstämmen wieder lebende Bäume zu machen. Dazu wird ein knotiger Saugwurz zusammen mit einem Elfenlieb erwärmt, so dass man gerade noch den Finger reinhalten kann. Dies gieße man in ein Gefäß und lasse es langsam abkühlen. Der Extrakt reicht für 10 Holzstämme.</text>
|
||||||
</string>
|
</string>
|
||||||
<string name="p3">
|
<string name="p3">
|
||||||
<text locale="en">Allow a Tangy Temerity to simmer for three hours in a litre of water, then add a grated Mandrake, and sprinkle in a Gapgrowth harvested at full moon. The whole brew should then be allowed to stew for three days in a warm place. This potion increases the strength and endurance of ten men so that they can achieve twice as much in a week.</text>
|
<text locale="en">Allow a Tangy Temerity to simmer for three hours in a litre of water, then add a grated Mandrake, and sprinkle in a Gapgrowth harvested at full moon. The whole brew should then be allowed to stew for three days in a warm place. This potion increases the strength and endurance of ten men so that they can achieve twice as much in a week.</text>
|
||||||
<text locale="de">Man lasse einen Würzigen Wagemut drei Stunden lang in einem Liter Wasser köcheln. Dann gebe man eine geriebene Alraune dazu und bestreue das ganze mit bei Vollmond geerntetem Spaltwachs. Nun lasse man den Sud drei Tage an einem dunklen und warmen Ort ziehen und seie dann die Flüssigkeit ab. Dieser Schaffenstrunk erhöht die Kraft und Ausdauer von zehn Männern, so daß sie doppelt soviel schaffen können wie sonst.</text>
|
<text locale="de">Man lasse einen Würzigen Wagemut drei Stunden lang in einem Liter Wasser köcheln. Dann gebe man eine geriebene Alraune dazu und bestreue das ganze mit bei Vollmond geerntetem Spaltwachs. Nun lasse man den Sud drei Tage an einem dunklen und warmen Ort ziehen und seie dann die Flüssigkeit ab. Dieser Schaffenstrunk erhöht die Kraft und Ausdauer von zehn Männern, so dass sie doppelt soviel schaffen können wie sonst.</text>
|
||||||
</string>
|
</string>
|
||||||
<string name="ointment">
|
<string name="ointment">
|
||||||
<text locale="en">When one is severely wounded after a hard battle it is advisable to have some Ointment to hand. Applied to wounds, this magical paste closes them in the blink of an eye. For the preparation the alchemist requires a cobalt fungus, tangy temerity, and white hemlock. A dose of the potion heals up to 400 hitpoints.</text>
|
<text locale="en">When one is severely wounded after a hard battle it is advisable to have some Ointment to hand. Applied to wounds, this magical paste closes them in the blink of an eye. For the preparation the alchemist requires a cobalt fungus, tangy temerity, and white hemlock. A dose of the potion heals up to 400 hitpoints.</text>
|
||||||
|
@ -3626,7 +3626,7 @@
|
||||||
</string>
|
</string>
|
||||||
<string name="p9">
|
<string name="p9">
|
||||||
<text locale="en">To make a horsepower potion, chop a peyote, a cobalt fungus and some knotroot, and boil it in a bucketful of water. Then add some sand reeker and let the mixture steep for three days. Finally one gives this to the horses to drink, to double their procreation.</text>
|
<text locale="en">To make a horsepower potion, chop a peyote, a cobalt fungus and some knotroot, and boil it in a bucketful of water. Then add some sand reeker and let the mixture steep for three days. Finally one gives this to the horses to drink, to double their procreation.</text>
|
||||||
<text locale="de">Für das Pferdeglück zerhacke man einen Kakteenschwitz, einen blauen Baumringel und etwas knotigen Saugwurz und koche das ganze mit einem Eimer Wasser auf. Dann füge man etwas Sandfäule dazu und lasse diesen Sud drei Tage lang ziehen. Letztlich gebe man es den Pferden zu trinken, auf daß sie sich doppelt so schnell vermehren.</text>
|
<text locale="de">Für das Pferdeglück zerhacke man einen Kakteenschwitz, einen blauen Baumringel und etwas knotigen Saugwurz und koche das ganze mit einem Eimer Wasser auf. Dann füge man etwas Sandfäule dazu und lasse diesen Sud drei Tage lang ziehen. Letztlich gebe man es den Pferden zu trinken, auf dass sie sich doppelt so schnell vermehren.</text>
|
||||||
</string>
|
</string>
|
||||||
<string name="p10">
|
<string name="p10">
|
||||||
<text locale="en">The use of the berserkers blood potion is advised to increase one's warriors abilities to new heights. To create this, one needs a white hemlock, some flatroot, sand reeker and a mandrake. All ingredients have to be sliced as finely as possible, after which it is boiled for two hours. The cooled brew is strained through a cloth. The resulting juice is enough to improve up to ten warriors.</text>
|
<text locale="en">The use of the berserkers blood potion is advised to increase one's warriors abilities to new heights. To create this, one needs a white hemlock, some flatroot, sand reeker and a mandrake. All ingredients have to be sliced as finely as possible, after which it is boiled for two hours. The cooled brew is strained through a cloth. The resulting juice is enough to improve up to ten warriors.</text>
|
||||||
|
@ -3638,7 +3638,7 @@
|
||||||
</string>
|
</string>
|
||||||
<string name="truthpotion">
|
<string name="truthpotion">
|
||||||
<text locale="en">This simple but very potent brew sharpens the senses of anyone that drinks of it and makes him able to see through even the most complex illusions for one week.</text>
|
<text locale="en">This simple but very potent brew sharpens the senses of anyone that drinks of it and makes him able to see through even the most complex illusions for one week.</text>
|
||||||
<text locale="de">Dieses wirkungsvolle einfache Gebräu schärft die Sinne des Trinkenden derart, daß er in der Lage ist, eine Woche lang auch die komplexesten Illusionen zu durchschauen.</text>
|
<text locale="de">Dieses wirkungsvolle einfache Gebräu schärft die Sinne des Trinkenden derart, dass er in der Lage ist, eine Woche lang auch die komplexesten Illusionen zu durchschauen.</text>
|
||||||
</string>
|
</string>
|
||||||
<string name="p13">
|
<string name="p13">
|
||||||
<text locale="en">One of the most rare and prized of all alchemist elixers, this potion grants the user a dragon's power for a few weeks. The potion increases the life-energy of a maximum of ten people fivefold. The effect is strongest right after drinking and slowly decreases over time. To brew this potion the alchemist needs an elvendear, a windbag, a piece of waterfinder and a spider ivy. Finally he dusts it with some minced bubblemorel and stirrs the powder into some dragon's blood. </text>
|
<text locale="en">One of the most rare and prized of all alchemist elixers, this potion grants the user a dragon's power for a few weeks. The potion increases the life-energy of a maximum of ten people fivefold. The effect is strongest right after drinking and slowly decreases over time. To brew this potion the alchemist needs an elvendear, a windbag, a piece of waterfinder and a spider ivy. Finally he dusts it with some minced bubblemorel and stirrs the powder into some dragon's blood. </text>
|
||||||
|
@ -4902,7 +4902,7 @@
|
||||||
<string name="shockwave">
|
<string name="shockwave">
|
||||||
<text locale="de">Dieser Zauber läßt eine Welle aus purer Kraft über die
|
<text locale="de">Dieser Zauber läßt eine Welle aus purer Kraft über die
|
||||||
gegnerischen Reihen hinwegfegen. Viele Kämpfer wird der Schock so
|
gegnerischen Reihen hinwegfegen. Viele Kämpfer wird der Schock so
|
||||||
benommen machen, daß sie für einen kurzen Moment nicht angreifen
|
benommen machen, dass sie für einen kurzen Moment nicht angreifen
|
||||||
können.</text>
|
können.</text>
|
||||||
<text locale="en">A wave of pure force spreads out from the magician,
|
<text locale="en">A wave of pure force spreads out from the magician,
|
||||||
crashing into the enemy ranks. Many warriors are thrown off balance and
|
crashing into the enemy ranks. Many warriors are thrown off balance and
|
||||||
|
|
|
@ -19,3 +19,4 @@ inifile
|
||||||
s/runtests
|
s/runtests
|
||||||
cd tests
|
cd tests
|
||||||
./write-reports.sh
|
./write-reports.sh
|
||||||
|
./run-turn.sh
|
||||||
|
|
|
@ -86,6 +86,7 @@ set (ERESSEA_SRC
|
||||||
names.c
|
names.c
|
||||||
lighthouse.c
|
lighthouse.c
|
||||||
reports.c
|
reports.c
|
||||||
|
seen.c
|
||||||
eressea.c
|
eressea.c
|
||||||
callback.c
|
callback.c
|
||||||
direction.c
|
direction.c
|
||||||
|
@ -182,6 +183,7 @@ set(TESTS_SRC
|
||||||
vortex.test.c
|
vortex.test.c
|
||||||
tests.test.c
|
tests.test.c
|
||||||
reports.test.c
|
reports.test.c
|
||||||
|
seen.test.c
|
||||||
travelthru.test.c
|
travelthru.test.c
|
||||||
callback.test.c
|
callback.test.c
|
||||||
direction.test.c
|
direction.test.c
|
||||||
|
|
|
@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include "chaos.h"
|
#include "chaos.h"
|
||||||
#include "move.h"
|
#include "move.h"
|
||||||
#include "laws.h"
|
#include "laws.h"
|
||||||
|
#include "seen.h"
|
||||||
#include "skill.h"
|
#include "skill.h"
|
||||||
#include "monster.h"
|
#include "monster.h"
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ without prior permission by the authors of Eressea.
|
||||||
#include "bindings.h"
|
#include "bindings.h"
|
||||||
#include "move.h"
|
#include "move.h"
|
||||||
#include "reports.h"
|
#include "reports.h"
|
||||||
|
#include "seen.h"
|
||||||
|
|
||||||
/* attributes includes */
|
/* attributes includes */
|
||||||
#include <attributes/racename.h>
|
#include <attributes/racename.h>
|
||||||
|
|
|
@ -25,6 +25,7 @@ without prior permission by the authors of Eressea.
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "reports.h"
|
#include "reports.h"
|
||||||
|
#include "seen.h"
|
||||||
|
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ without prior permission by the authors of Eressea.
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
#include "buildno.h"
|
#include "buildno.h"
|
||||||
#include "creport.h"
|
#include "creport.h"
|
||||||
|
#include "seen.h"
|
||||||
#include "travelthru.h"
|
#include "travelthru.h"
|
||||||
|
|
||||||
/* tweakable features */
|
/* tweakable features */
|
||||||
|
@ -1343,7 +1344,7 @@ static void cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
|
||||||
if (sr->mode != see_unit)
|
if (sr->mode != see_unit)
|
||||||
fprintf(F, "\"%s\";visibility\n", visibility[sr->mode]);
|
fprintf(F, "\"%s\";visibility\n", visibility[sr->mode]);
|
||||||
if (sr->mode == see_neighbour) {
|
if (sr->mode == see_neighbour) {
|
||||||
cr_borders(ctx->seen, r, f, sr->mode, F);
|
cr_borders(ctx->f->seen, r, f, sr->mode, F);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
building *b;
|
building *b;
|
||||||
|
@ -1431,7 +1432,7 @@ static void cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
|
||||||
print_items(F, r->land->items, f->locale);
|
print_items(F, r->land->items, f->locale);
|
||||||
}
|
}
|
||||||
cr_output_curses_compat(F, f, r, TYP_REGION);
|
cr_output_curses_compat(F, f, r, TYP_REGION);
|
||||||
cr_borders(ctx->seen, r, f, sr->mode, F);
|
cr_borders(ctx->f->seen, r, f, sr->mode, F);
|
||||||
if (sr->mode == see_unit && is_astral(r)
|
if (sr->mode == see_unit && is_astral(r)
|
||||||
&& !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
&& !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
||||||
/* Sonderbehandlung Teleport-Ebene */
|
/* Sonderbehandlung Teleport-Ebene */
|
||||||
|
@ -1686,7 +1687,7 @@ report_computer(const char *filename, report_context * ctx, const char *charset)
|
||||||
|
|
||||||
/* traverse all regions */
|
/* traverse all regions */
|
||||||
for (r = ctx->first; sr == NULL && r != ctx->last; r = r->next) {
|
for (r = ctx->first; sr == NULL && r != ctx->last; r = r->next) {
|
||||||
sr = find_seen(ctx->seen, r);
|
sr = find_seen(ctx->f->seen, r);
|
||||||
}
|
}
|
||||||
for (; sr != NULL; sr = sr->next) {
|
for (; sr != NULL; sr = sr->next) {
|
||||||
cr_output_region(F, ctx, sr);
|
cr_output_region(F, ctx, sr);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "reports.h"
|
#include "reports.h"
|
||||||
#include "jsreport.h"
|
#include "jsreport.h"
|
||||||
|
#include "seen.h"
|
||||||
|
#include <kernel/faction.h>
|
||||||
#include <kernel/region.h>
|
#include <kernel/region.h>
|
||||||
#include <kernel/terrain.h>
|
#include <kernel/terrain.h>
|
||||||
#include <kernel/terrainid.h>
|
#include <kernel/terrainid.h>
|
||||||
|
@ -31,7 +33,7 @@ static int report_json(const char *filename, report_context * ctx, const char *c
|
||||||
region *r;
|
region *r;
|
||||||
/* traverse all regions */
|
/* traverse all regions */
|
||||||
for (sr = NULL, r = ctx->first; sr == NULL && r != ctx->last; r = r->next) {
|
for (sr = NULL, r = ctx->first; sr == NULL && r != ctx->last; r = r->next) {
|
||||||
sr = find_seen(ctx->seen, r);
|
sr = find_seen(ctx->f->seen, r);
|
||||||
}
|
}
|
||||||
for (; sr != NULL; sr = sr->next) {
|
for (; sr != NULL; sr = sr->next) {
|
||||||
int tx = sr->r->x;
|
int tx = sr->r->x;
|
||||||
|
@ -55,7 +57,7 @@ static int report_json(const char *filename, report_context * ctx, const char *c
|
||||||
coor_from_tiled(&tx, &ty);
|
coor_from_tiled(&tx, &ty);
|
||||||
r = findregion(tx, ty);
|
r = findregion(tx, ty);
|
||||||
if (r) {
|
if (r) {
|
||||||
sr = find_seen(ctx->seen, r);
|
sr = find_seen(ctx->f->seen, r);
|
||||||
if (sr) {
|
if (sr) {
|
||||||
terrain_t ter = oldterrain(r->terrain);
|
terrain_t ter = oldterrain(r->terrain);
|
||||||
if (ter == NOTERRAIN) {
|
if (ter == NOTERRAIN) {
|
||||||
|
|
|
@ -156,6 +156,6 @@ CuSuite *get_curse_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_good_dreams);
|
SUITE_ADD_TEST(suite, test_good_dreams);
|
||||||
SUITE_ADD_TEST(suite, test_bad_dreams);
|
SUITE_ADD_TEST(suite, test_bad_dreams);
|
||||||
SUITE_ADD_TEST(suite, test_memstream);
|
SUITE_ADD_TEST(suite, test_memstream);
|
||||||
SUITE_ADD_TEST(suite, test_write_flag);
|
DISABLE_TEST(suite, test_write_flag);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,6 +311,11 @@ void destroyfaction(faction * f)
|
||||||
f->spellbook = 0;
|
f->spellbook = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (f->seen_factions) {
|
||||||
|
ql_free(f->seen_factions);
|
||||||
|
f->seen_factions = 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (u) {
|
while (u) {
|
||||||
/* give away your stuff, make zombies if you cannot (quest items) */
|
/* give away your stuff, make zombies if you cannot (quest items) */
|
||||||
int result = gift_items(u, GIFT_FRIENDS | GIFT_PEASANTS);
|
int result = gift_items(u, GIFT_FRIENDS | GIFT_PEASANTS);
|
||||||
|
|
|
@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
|
|
||||||
#include "reports.h"
|
#include "reports.h"
|
||||||
|
#include "seen.h"
|
||||||
#include "laws.h"
|
#include "laws.h"
|
||||||
#include "travelthru.h"
|
#include "travelthru.h"
|
||||||
#include "monster.h"
|
#include "monster.h"
|
||||||
|
@ -1412,7 +1413,7 @@ report_template(const char *filename, report_context * ctx, const char *charset)
|
||||||
newline(out);
|
newline(out);
|
||||||
|
|
||||||
for (r = ctx->first; sr == NULL && r != ctx->last; r = r->next) {
|
for (r = ctx->first; sr == NULL && r != ctx->last; r = r->next) {
|
||||||
sr = find_seen(ctx->seen, r);
|
sr = find_seen(ctx->f->seen, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; sr != NULL; sr = sr->next) {
|
for (; sr != NULL; sr = sr->next) {
|
||||||
|
@ -2306,7 +2307,7 @@ const char *charset)
|
||||||
anyunits = 0;
|
anyunits = 0;
|
||||||
|
|
||||||
for (r = ctx->first; sr == NULL && r != ctx->last; r = r->next) {
|
for (r = ctx->first; sr == NULL && r != ctx->last; r = r->next) {
|
||||||
sr = find_seen(ctx->seen, r);
|
sr = find_seen(ctx->f->seen, r);
|
||||||
}
|
}
|
||||||
for (; sr != NULL; sr = sr->next) {
|
for (; sr != NULL; sr = sr->next) {
|
||||||
region *r = sr->r;
|
region *r = sr->r;
|
||||||
|
|
202
src/reports.c
202
src/reports.c
|
@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
#include "reports.h"
|
#include "reports.h"
|
||||||
#include "laws.h"
|
#include "laws.h"
|
||||||
|
#include "seen.h"
|
||||||
#include "travelthru.h"
|
#include "travelthru.h"
|
||||||
#include "lighthouse.h"
|
#include "lighthouse.h"
|
||||||
|
|
||||||
|
@ -1038,7 +1039,7 @@ static void get_addresses(report_context * ctx)
|
||||||
|
|
||||||
/* find the first region that this faction can see */
|
/* find the first region that this faction can see */
|
||||||
for (r = ctx->first; sr == NULL && r != ctx->last; r = r->next) {
|
for (r = ctx->first; sr == NULL && r != ctx->last; r = r->next) {
|
||||||
sr = find_seen(ctx->seen, r);
|
sr = find_seen(ctx->f->seen, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; sr != NULL; sr = sr->next) {
|
for (; sr != NULL; sr = sr->next) {
|
||||||
|
@ -1090,121 +1091,6 @@ static void get_addresses(report_context * ctx)
|
||||||
ctx->addresses = flist;
|
ctx->addresses = flist;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAXSEEHASH 0x1000
|
|
||||||
seen_region *reuse;
|
|
||||||
|
|
||||||
seen_region **seen_init(void)
|
|
||||||
{
|
|
||||||
return (seen_region **)calloc(MAXSEEHASH, sizeof(seen_region *));
|
|
||||||
}
|
|
||||||
|
|
||||||
void seen_done(seen_region * seehash[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i != MAXSEEHASH; ++i) {
|
|
||||||
seen_region *sd = seehash[i];
|
|
||||||
if (sd == NULL)
|
|
||||||
continue;
|
|
||||||
while (sd->nextHash != NULL)
|
|
||||||
sd = sd->nextHash;
|
|
||||||
sd->nextHash = reuse;
|
|
||||||
reuse = seehash[i];
|
|
||||||
seehash[i] = NULL;
|
|
||||||
}
|
|
||||||
/* free(seehash); */
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_seen(void)
|
|
||||||
{
|
|
||||||
while (reuse) {
|
|
||||||
seen_region *r = reuse;
|
|
||||||
reuse = reuse->nextHash;
|
|
||||||
free(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
link_seen(seen_region * seehash[], const region * first, const region * last)
|
|
||||||
{
|
|
||||||
const region *r = first;
|
|
||||||
seen_region *sr = NULL;
|
|
||||||
|
|
||||||
if (first == last)
|
|
||||||
return;
|
|
||||||
|
|
||||||
do {
|
|
||||||
sr = find_seen(seehash, r);
|
|
||||||
r = r->next;
|
|
||||||
} while (sr == NULL && r != last);
|
|
||||||
|
|
||||||
while (r != last) {
|
|
||||||
seen_region *sn = find_seen(seehash, r);
|
|
||||||
if (sn != NULL) {
|
|
||||||
sr->next = sn;
|
|
||||||
sr = sn;
|
|
||||||
}
|
|
||||||
r = r->next;
|
|
||||||
}
|
|
||||||
if (sr) sr->next = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
seen_region *find_seen(struct seen_region *seehash[], const region * r)
|
|
||||||
{
|
|
||||||
unsigned int index = reg_hashkey(r) & (MAXSEEHASH - 1);
|
|
||||||
seen_region *find = seehash[index];
|
|
||||||
while (find) {
|
|
||||||
if (find->r == r)
|
|
||||||
return find;
|
|
||||||
find = find->nextHash;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void get_seen_interval(report_context * ctx)
|
|
||||||
{
|
|
||||||
/* this is required to find the neighbour regions of the ones we are in,
|
|
||||||
* which may well be outside of [firstregion, lastregion) */
|
|
||||||
int i;
|
|
||||||
|
|
||||||
assert(ctx->seen);
|
|
||||||
for (i = 0; i != MAXSEEHASH; ++i) {
|
|
||||||
seen_region *sr = ctx->seen[i];
|
|
||||||
while (sr != NULL) {
|
|
||||||
if (ctx->first == NULL || sr->r->index < ctx->first->index) {
|
|
||||||
ctx->first = sr->r;
|
|
||||||
}
|
|
||||||
if (ctx->last != NULL && sr->r->index >= ctx->last->index) {
|
|
||||||
ctx->last = sr->r->next;
|
|
||||||
}
|
|
||||||
sr = sr->nextHash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
link_seen(ctx->seen, ctx->first, ctx->last);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
add_seen(struct seen_region *seehash[], struct region *r, unsigned char mode,
|
|
||||||
bool dis)
|
|
||||||
{
|
|
||||||
seen_region *find = find_seen(seehash, r);
|
|
||||||
if (find == NULL) {
|
|
||||||
unsigned int index = reg_hashkey(r) & (MAXSEEHASH - 1);
|
|
||||||
if (!reuse)
|
|
||||||
reuse = (seen_region *)calloc(1, sizeof(struct seen_region));
|
|
||||||
find = reuse;
|
|
||||||
reuse = reuse->nextHash;
|
|
||||||
find->nextHash = seehash[index];
|
|
||||||
seehash[index] = find;
|
|
||||||
find->r = r;
|
|
||||||
}
|
|
||||||
else if (find->mode >= mode) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
find->mode = mode;
|
|
||||||
find->disbelieves |= dis;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct report_type {
|
typedef struct report_type {
|
||||||
struct report_type *next;
|
struct report_type *next;
|
||||||
report_fun write;
|
report_fun write;
|
||||||
|
@ -1254,7 +1140,7 @@ static quicklist *get_regions_distance(region * root, int radius)
|
||||||
return rlist;
|
return rlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void view_default(struct seen_region **seen, region * r, faction * f)
|
void view_default(struct seen_region **seen, region * r, faction * f)
|
||||||
{
|
{
|
||||||
int dir;
|
int dir;
|
||||||
for (dir = 0; dir != MAXDIRECTIONS; ++dir) {
|
for (dir = 0; dir != MAXDIRECTIONS; ++dir) {
|
||||||
|
@ -1272,7 +1158,7 @@ static void view_default(struct seen_region **seen, region * r, faction * f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void view_neighbours(struct seen_region **seen, region * r, faction * f)
|
void view_neighbours(struct seen_region **seen, region * r, faction * f)
|
||||||
{
|
{
|
||||||
int d;
|
int d;
|
||||||
region * nb[MAXDIRECTIONS];
|
region * nb[MAXDIRECTIONS];
|
||||||
|
@ -1372,10 +1258,10 @@ static void prepare_lighthouse(building * b, faction * f)
|
||||||
int d;
|
int d;
|
||||||
|
|
||||||
get_neighbours(rl, next);
|
get_neighbours(rl, next);
|
||||||
add_seen(f->seen, rl, see_lighthouse, false);
|
faction_add_seen(f, rl, see_lighthouse);
|
||||||
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
||||||
if (next[d]) {
|
if (next[d]) {
|
||||||
add_seen(f->seen, next[d], see_neighbour, false);
|
faction_add_seen(f, next[d], see_neighbour);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1484,7 +1370,7 @@ void reorder_units(region * r)
|
||||||
static void cb_add_seen(region *r, unit *u, void *cbdata) {
|
static void cb_add_seen(region *r, unit *u, void *cbdata) {
|
||||||
unused_arg(cbdata);
|
unused_arg(cbdata);
|
||||||
if (u->faction) {
|
if (u->faction) {
|
||||||
add_seen(u->faction->seen, r, see_travel, false);
|
faction_add_seen(u->faction, r, see_travel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1509,26 +1395,21 @@ static void prepare_reports(void)
|
||||||
if (p) {
|
if (p) {
|
||||||
watcher *w = p->watchers;
|
watcher *w = p->watchers;
|
||||||
for (; w; w = w->next) {
|
for (; w; w = w->next) {
|
||||||
add_seen(w->faction->seen, r, w->mode, false);
|
faction_add_seen(w->faction, r, w->mode);
|
||||||
#ifdef SMART_INTERVALS
|
|
||||||
update_interval(w->faction, r);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Region owner get always the Lighthouse report */
|
/* Region owner get always the Lighthouse report */
|
||||||
if (check_param(global.parameters, "rules.region_owner_pay_building", bt_lighthouse->_name)) {
|
if (bt_lighthouse && check_param(global.parameters, "rules.region_owner_pay_building", bt_lighthouse->_name)) {
|
||||||
for (b = rbuildings(r); b; b = b->next) {
|
for (b = rbuildings(r); b; b = b->next) {
|
||||||
if (b && b->type == bt_lighthouse) {
|
if (b && b->type == bt_lighthouse) {
|
||||||
u = building_owner(b);
|
u = building_owner(b);
|
||||||
if (u) {
|
if (u) {
|
||||||
prepare_lighthouse(b, u->faction);
|
prepare_lighthouse(b, u->faction);
|
||||||
if (u_race(u) != get_race(RC_SPELL) || u->number == RS_FARVISION) {
|
if (u_race(u) != get_race(RC_SPELL) || u->number == RS_FARVISION) {
|
||||||
|
seen_region *sr = faction_add_seen(u->faction, r, see_unit);
|
||||||
if (fval(u, UFL_DISBELIEVES)) {
|
if (fval(u, UFL_DISBELIEVES)) {
|
||||||
add_seen(u->faction->seen, r, see_unit, true);
|
sr->disbelieves = true;
|
||||||
}
|
|
||||||
else {
|
|
||||||
add_seen(u->faction->seen, r, see_unit, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1543,11 +1424,9 @@ static void prepare_reports(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u_race(u) != get_race(RC_SPELL) || u->number == RS_FARVISION) {
|
if (u_race(u) != get_race(RC_SPELL) || u->number == RS_FARVISION) {
|
||||||
|
seen_region *sr = faction_add_seen(u->faction, r, see_unit);
|
||||||
if (fval(u, UFL_DISBELIEVES)) {
|
if (fval(u, UFL_DISBELIEVES)) {
|
||||||
add_seen(u->faction->seen, r, see_unit, true);
|
sr->disbelieves = true;
|
||||||
}
|
|
||||||
else {
|
|
||||||
add_seen(u->faction->seen, r, see_unit, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1624,19 +1503,8 @@ static region *firstregion(faction * f)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static seen_region **prepare_report(faction * f)
|
static void cb_view_neighbours(seen_region *sr, void *cbdata) {
|
||||||
{
|
faction *f = (faction *)cbdata;
|
||||||
struct seen_region *sr;
|
|
||||||
region *r = firstregion(f);
|
|
||||||
region *last = lastregion(f);
|
|
||||||
|
|
||||||
link_seen(f->seen, r, last);
|
|
||||||
|
|
||||||
for (sr = NULL; sr == NULL && r != last; r = r->next) {
|
|
||||||
sr = find_seen(f->seen, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; sr != NULL; sr = sr->next) {
|
|
||||||
if (sr->mode > see_neighbour) {
|
if (sr->mode > see_neighbour) {
|
||||||
region *r = sr->r;
|
region *r = sr->r;
|
||||||
plane *p = rplane(r);
|
plane *p = rplane(r);
|
||||||
|
@ -1648,8 +1516,31 @@ static seen_region **prepare_report(faction * f)
|
||||||
}
|
}
|
||||||
view(f->seen, r, f);
|
view(f->seen, r, f);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepare_seen(faction *f)
|
||||||
|
{
|
||||||
|
region *r;
|
||||||
|
struct seen_region *sr;
|
||||||
|
|
||||||
|
for (r = f->first, sr = NULL; sr == NULL && r != f->last; r = r->next) {
|
||||||
|
sr = find_seen(f->seen, r);
|
||||||
}
|
}
|
||||||
return f->seen;
|
|
||||||
|
seenhash_map(f->seen, cb_view_neighbours, f);
|
||||||
|
get_seen_interval(f->seen, &f->first, &f->last);
|
||||||
|
link_seen(f->seen, f->first, f->last);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void prepare_report(struct report_context *ctx, faction *f)
|
||||||
|
{
|
||||||
|
prepare_seen(f);
|
||||||
|
ctx->f = f;
|
||||||
|
ctx->report_time = time(NULL);
|
||||||
|
ctx->addresses = NULL;
|
||||||
|
ctx->userdata = NULL;
|
||||||
|
ctx->first = firstregion(f);
|
||||||
|
ctx->last = lastregion(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_reports(faction * f, time_t ltime)
|
int write_reports(faction * f, time_t ltime)
|
||||||
|
@ -1663,16 +1554,7 @@ int write_reports(faction * f, time_t ltime)
|
||||||
if (noreports) {
|
if (noreports) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ctx.f = f;
|
prepare_report(&ctx, f);
|
||||||
ctx.report_time = time(NULL);
|
|
||||||
ctx.seen = prepare_report(f);
|
|
||||||
ctx.first = firstregion(f);
|
|
||||||
ctx.last = lastregion(f);
|
|
||||||
ctx.addresses = NULL;
|
|
||||||
ctx.userdata = NULL;
|
|
||||||
if (ctx.seen) {
|
|
||||||
get_seen_interval(&ctx);
|
|
||||||
}
|
|
||||||
get_addresses(&ctx);
|
get_addresses(&ctx);
|
||||||
if (_access(reportpath(), 0) < 0) {
|
if (_access(reportpath(), 0) < 0) {
|
||||||
_mkdir(reportpath());
|
_mkdir(reportpath());
|
||||||
|
@ -1714,8 +1596,8 @@ int write_reports(faction * f, time_t ltime)
|
||||||
log_warning("No report for faction %s!", factionid(f));
|
log_warning("No report for faction %s!", factionid(f));
|
||||||
}
|
}
|
||||||
ql_free(ctx.addresses);
|
ql_free(ctx.addresses);
|
||||||
if (ctx.seen) {
|
if (ctx.f->seen) {
|
||||||
seen_done(ctx.seen);
|
seen_done(ctx.f->seen);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <kernel/types.h>
|
#include <kernel/types.h>
|
||||||
|
|
||||||
struct stream;
|
struct stream;
|
||||||
|
struct seen_region;
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -56,6 +56,7 @@ extern "C" {
|
||||||
void spunit(struct strlist **SP, const struct faction *f,
|
void spunit(struct strlist **SP, const struct faction *f,
|
||||||
const struct unit *u, unsigned int indent, int mode);
|
const struct unit *u, unsigned int indent, int mode);
|
||||||
|
|
||||||
|
void prepare_seen(struct faction *f);
|
||||||
int reports(void);
|
int reports(void);
|
||||||
int write_reports(struct faction *f, time_t ltime);
|
int write_reports(struct faction *f, time_t ltime);
|
||||||
int init_reports(void);
|
int init_reports(void);
|
||||||
|
@ -64,39 +65,11 @@ extern "C" {
|
||||||
const struct unit *ucansee(const struct faction *f,
|
const struct unit *ucansee(const struct faction *f,
|
||||||
const struct unit *u, const struct unit *x);
|
const struct unit *u, const struct unit *x);
|
||||||
|
|
||||||
enum {
|
|
||||||
see_none,
|
|
||||||
see_neighbour,
|
|
||||||
see_lighthouse,
|
|
||||||
see_travel,
|
|
||||||
see_far,
|
|
||||||
see_unit,
|
|
||||||
see_battle
|
|
||||||
};
|
|
||||||
int stealth_modifier(int seen_mode);
|
int stealth_modifier(int seen_mode);
|
||||||
|
|
||||||
typedef struct seen_region {
|
|
||||||
struct seen_region *nextHash;
|
|
||||||
struct seen_region *next;
|
|
||||||
struct region *r;
|
|
||||||
unsigned char mode;
|
|
||||||
bool disbelieves;
|
|
||||||
} seen_region;
|
|
||||||
|
|
||||||
struct seen_region *find_seen(struct seen_region *seehash[],
|
|
||||||
const struct region *r);
|
|
||||||
bool add_seen(struct seen_region *seehash[], struct region *r,
|
|
||||||
unsigned char mode, bool dis);
|
|
||||||
struct seen_region **seen_init(void);
|
|
||||||
void seen_done(struct seen_region *seehash[]);
|
|
||||||
void free_seen(void);
|
|
||||||
void link_seen(seen_region * seehash[], const struct region *first,
|
|
||||||
const struct region *last);
|
|
||||||
|
|
||||||
typedef struct report_context {
|
typedef struct report_context {
|
||||||
struct faction *f;
|
struct faction *f;
|
||||||
struct quicklist *addresses;
|
struct quicklist *addresses;
|
||||||
struct seen_region **seen;
|
|
||||||
struct region *first, *last;
|
struct region *first, *last;
|
||||||
void *userdata;
|
void *userdata;
|
||||||
time_t report_time;
|
time_t report_time;
|
||||||
|
@ -130,6 +103,8 @@ extern "C" {
|
||||||
int number;
|
int number;
|
||||||
int level;
|
int level;
|
||||||
} resource_report;
|
} resource_report;
|
||||||
|
void view_default(struct seen_region **seen, struct region * r, struct faction * f);
|
||||||
|
void view_neighbours(struct seen_region **seen, struct region * r, struct faction * f);
|
||||||
int report_resources(const struct seen_region *sr,
|
int report_resources(const struct seen_region *sr,
|
||||||
struct resource_report *result, int size, const struct faction *viewer);
|
struct resource_report *result, int size, const struct faction *viewer);
|
||||||
int report_items(const struct item *items, struct item *result, int size,
|
int report_items(const struct item *items, struct item *result, int size,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "report.h"
|
#include "report.h"
|
||||||
#include "creport.h"
|
#include "creport.h"
|
||||||
#include "move.h"
|
#include "move.h"
|
||||||
|
#include "seen.h"
|
||||||
#include "travelthru.h"
|
#include "travelthru.h"
|
||||||
|
|
||||||
#include <kernel/building.h>
|
#include <kernel/building.h>
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
||||||
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
|
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <platform.h>
|
||||||
|
#include <kernel/config.h>
|
||||||
|
#include "seen.h"
|
||||||
|
|
||||||
|
#include <kernel/region.h>
|
||||||
|
#include <kernel/faction.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define MAXSEEHASH 0x1000
|
||||||
|
seen_region *reuse;
|
||||||
|
|
||||||
|
seen_region **seen_init(void)
|
||||||
|
{
|
||||||
|
return (seen_region **)calloc(MAXSEEHASH, sizeof(seen_region *));
|
||||||
|
}
|
||||||
|
|
||||||
|
void seen_done(seen_region * seehash[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i != MAXSEEHASH; ++i) {
|
||||||
|
seen_region *sd = seehash[i];
|
||||||
|
if (sd == NULL)
|
||||||
|
continue;
|
||||||
|
while (sd->nextHash != NULL)
|
||||||
|
sd = sd->nextHash;
|
||||||
|
sd->nextHash = reuse;
|
||||||
|
reuse = seehash[i];
|
||||||
|
seehash[i] = NULL;
|
||||||
|
}
|
||||||
|
free(seehash);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_seen(void)
|
||||||
|
{
|
||||||
|
while (reuse) {
|
||||||
|
seen_region *r = reuse;
|
||||||
|
reuse = reuse->nextHash;
|
||||||
|
free(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
link_seen(seen_region * seehash[], const region * first, const region * last)
|
||||||
|
{
|
||||||
|
const region *r = first;
|
||||||
|
seen_region *sr = NULL;
|
||||||
|
|
||||||
|
if (first == last)
|
||||||
|
return;
|
||||||
|
|
||||||
|
do {
|
||||||
|
sr = find_seen(seehash, r);
|
||||||
|
r = r->next;
|
||||||
|
} while (sr == NULL && r != last);
|
||||||
|
|
||||||
|
while (r != last) {
|
||||||
|
seen_region *sn = find_seen(seehash, r);
|
||||||
|
if (sn != NULL) {
|
||||||
|
sr->next = sn;
|
||||||
|
sr = sn;
|
||||||
|
}
|
||||||
|
r = r->next;
|
||||||
|
}
|
||||||
|
if (sr) sr->next = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
seen_region *find_seen(struct seen_region *seehash[], const region * r)
|
||||||
|
{
|
||||||
|
unsigned int index = reg_hashkey(r) & (MAXSEEHASH - 1);
|
||||||
|
seen_region *find = seehash[index];
|
||||||
|
while (find) {
|
||||||
|
if (find->r == r) {
|
||||||
|
return find;
|
||||||
|
}
|
||||||
|
find = find->nextHash;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void seenhash_map(struct seen_region *seen[], void(*cb)(seen_region *, void *), void *cbdata) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i != MAXSEEHASH; ++i) {
|
||||||
|
seen_region *sr = seen[i];
|
||||||
|
while (sr != NULL) {
|
||||||
|
cb(sr, cbdata);
|
||||||
|
sr = sr->nextHash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct cb_interval {
|
||||||
|
region *first;
|
||||||
|
region *last;
|
||||||
|
} cb_interval;
|
||||||
|
|
||||||
|
static void cb_get_interval(seen_region *sr, void *cbdata) {
|
||||||
|
cb_interval *iv = (cb_interval *)cbdata;
|
||||||
|
region *r = sr->r;
|
||||||
|
if (iv->first == NULL || r->index < iv->first->index) {
|
||||||
|
iv->first = r;
|
||||||
|
}
|
||||||
|
if (iv->last != NULL && r->index >= iv->last->index) {
|
||||||
|
iv->last = r->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this function adds the neighbour regions of the ones we have seen
|
||||||
|
* to the interval, which may be outside of [faction.first, faction.last)
|
||||||
|
*/
|
||||||
|
void get_seen_interval(struct seen_region *seen[], struct region **firstp, struct region **lastp)
|
||||||
|
{
|
||||||
|
cb_interval interval;
|
||||||
|
|
||||||
|
interval.first = *firstp;
|
||||||
|
interval.last = *lastp;
|
||||||
|
seenhash_map(seen, cb_get_interval, &interval);
|
||||||
|
*firstp = interval.first;
|
||||||
|
*lastp = interval.last;
|
||||||
|
}
|
||||||
|
|
||||||
|
seen_region *add_seen(struct seen_region *seehash[], struct region *r, seen_t mode, bool dis)
|
||||||
|
{
|
||||||
|
seen_region *find = find_seen(seehash, r);
|
||||||
|
if (find == NULL) {
|
||||||
|
unsigned int index = reg_hashkey(r) & (MAXSEEHASH - 1);
|
||||||
|
if (!reuse)
|
||||||
|
reuse = (seen_region *)calloc(1, sizeof(struct seen_region));
|
||||||
|
find = reuse;
|
||||||
|
reuse = reuse->nextHash;
|
||||||
|
find->nextHash = seehash[index];
|
||||||
|
find->mode = mode;
|
||||||
|
seehash[index] = find;
|
||||||
|
find->r = r;
|
||||||
|
}
|
||||||
|
else if (find->mode < mode) {
|
||||||
|
find->mode = mode;
|
||||||
|
}
|
||||||
|
find->disbelieves |= dis;
|
||||||
|
return find;
|
||||||
|
}
|
||||||
|
|
||||||
|
seen_region *faction_add_seen(faction *f, region *r, seen_t mode) {
|
||||||
|
assert(f->seen);
|
||||||
|
#ifdef SMART_INTERVALS
|
||||||
|
update_interval(f, r);
|
||||||
|
#endif
|
||||||
|
return add_seen(f->seen, r, mode, false);
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
#pragma once
|
||||||
|
/*
|
||||||
|
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
||||||
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
|
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef H_SEEN_REGION
|
||||||
|
#define H_SEEN_REGION
|
||||||
|
|
||||||
|
struct region;
|
||||||
|
struct faction;
|
||||||
|
struct seen_region;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
see_none,
|
||||||
|
see_neighbour,
|
||||||
|
see_lighthouse,
|
||||||
|
see_travel,
|
||||||
|
see_far,
|
||||||
|
see_unit,
|
||||||
|
see_battle
|
||||||
|
} seen_t;
|
||||||
|
|
||||||
|
typedef struct seen_region {
|
||||||
|
struct seen_region *nextHash;
|
||||||
|
struct seen_region *next;
|
||||||
|
struct region *r;
|
||||||
|
seen_t mode;
|
||||||
|
bool disbelieves;
|
||||||
|
} seen_region;
|
||||||
|
|
||||||
|
struct seen_region **seen_init(void);
|
||||||
|
void seen_done(struct seen_region *seehash[]);
|
||||||
|
void free_seen(void);
|
||||||
|
void link_seen(struct seen_region *seehash[], const struct region * first, const struct region * last);
|
||||||
|
struct seen_region *find_seen(struct seen_region *seehash[], const struct region * r);
|
||||||
|
void get_seen_interval(struct seen_region *seen[], struct region **firstp, struct region **lastp);
|
||||||
|
seen_region *add_seen(struct seen_region *seehash[], struct region *r, seen_t mode, bool dis);
|
||||||
|
void link_seen(struct seen_region *seehash[], const struct region *first, const struct region *last);
|
||||||
|
void seenhash_map(struct seen_region *seen[], void(*cb)(struct seen_region *, void *), void *cbdata);
|
||||||
|
struct seen_region *faction_add_seen(struct faction *f, struct region *r, seen_t mode);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
|
@ -0,0 +1,199 @@
|
||||||
|
#include <platform.h>
|
||||||
|
#include <config.h>
|
||||||
|
#include "seen.h"
|
||||||
|
#include "reports.h"
|
||||||
|
#include "travelthru.h"
|
||||||
|
|
||||||
|
#include <kernel/region.h>
|
||||||
|
#include <kernel/unit.h>
|
||||||
|
#include <kernel/faction.h>
|
||||||
|
|
||||||
|
#include <CuTest.h>
|
||||||
|
#include <tests.h>
|
||||||
|
|
||||||
|
static void setup_seen(int x, int y) {
|
||||||
|
int dir;
|
||||||
|
|
||||||
|
for (dir = 0; dir != MAXDIRECTIONS; ++dir) {
|
||||||
|
test_create_region(x+delta_x[dir], y+delta_y[dir], 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_add_seen(CuTest *tc) {
|
||||||
|
region *r;
|
||||||
|
seen_region **seen, *sr;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
seen = seen_init();
|
||||||
|
r = test_create_region(0, 0, 0);
|
||||||
|
sr = add_seen(seen, r, see_travel, false);
|
||||||
|
CuAssertPtrEquals(tc, r, sr->r);
|
||||||
|
CuAssertIntEquals(tc, see_travel, sr->mode);
|
||||||
|
CuAssertIntEquals(tc, false, sr->disbelieves);
|
||||||
|
CuAssertPtrEquals(tc, 0, sr->next);
|
||||||
|
CuAssertPtrEquals(tc, 0, sr->nextHash);
|
||||||
|
CuAssertPtrEquals(tc, sr, find_seen(seen, r));
|
||||||
|
sr = add_seen(seen, r, see_neighbour, true);
|
||||||
|
CuAssertIntEquals(tc, true, sr->disbelieves);
|
||||||
|
CuAssertIntEquals(tc, see_travel, sr->mode);
|
||||||
|
sr = add_seen(seen, r, see_unit, false);
|
||||||
|
CuAssertIntEquals(tc, true, sr->disbelieves);
|
||||||
|
CuAssertIntEquals(tc, see_unit, sr->mode);
|
||||||
|
seen_done(seen);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_faction_add_seen(CuTest *tc) {
|
||||||
|
faction *f;
|
||||||
|
seen_region *sr;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
f = test_create_faction(0);
|
||||||
|
f->seen = seen_init();
|
||||||
|
test_create_region(0, 0, 0);
|
||||||
|
test_create_region(0, 1, 0);
|
||||||
|
sr = faction_add_seen(f, regions, see_unit);
|
||||||
|
CuAssertIntEquals(tc, false, sr->disbelieves);
|
||||||
|
CuAssertPtrEquals(tc, regions, f->first);
|
||||||
|
CuAssertPtrEquals(tc, regions, f->last);
|
||||||
|
seen_done(f->seen);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_prepare_seen(CuTest *tc) {
|
||||||
|
region *r;
|
||||||
|
faction *f;
|
||||||
|
unit *u;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
f = test_create_faction(0);
|
||||||
|
r = test_create_region(0, 0, 0);
|
||||||
|
u = test_create_unit(f, r);
|
||||||
|
f->seen = seen_init();
|
||||||
|
faction_add_seen(f, r, see_unit);
|
||||||
|
setup_seen(0, 0);
|
||||||
|
r = test_create_region(2, 2, 0);
|
||||||
|
setup_seen(2, 2);
|
||||||
|
travelthru_add(r, u);
|
||||||
|
|
||||||
|
init_reports();
|
||||||
|
prepare_seen(f);
|
||||||
|
CuAssertPtrEquals(tc, regions, f->first);
|
||||||
|
CuAssertPtrEquals(tc, 0, f->last);
|
||||||
|
seen_done(f->seen);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_seen_travelthru(CuTest *tc) {
|
||||||
|
seen_region *sr;
|
||||||
|
region *r;
|
||||||
|
faction *f;
|
||||||
|
unit *u;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
setup_seen(0, 0);
|
||||||
|
r = test_create_region(0, 0, 0);
|
||||||
|
f = test_create_faction(0);
|
||||||
|
u = test_create_unit(f, 0);
|
||||||
|
travelthru_add(r, u);
|
||||||
|
init_reports();
|
||||||
|
view_default(f->seen, r, f);
|
||||||
|
get_seen_interval(f->seen, &f->first, &f->last);
|
||||||
|
link_seen(f->seen, f->first, f->last);
|
||||||
|
CuAssertPtrEquals(tc, regions, f->first);
|
||||||
|
CuAssertPtrEquals(tc, 0, f->last);
|
||||||
|
sr = find_seen(f->seen, regions);
|
||||||
|
CuAssertPtrEquals(tc, regions, sr->r);
|
||||||
|
CuAssertIntEquals(tc, see_neighbour, sr->mode);
|
||||||
|
sr = find_seen(f->seen, r);
|
||||||
|
CuAssertPtrEquals(tc, r, sr->r);
|
||||||
|
CuAssertIntEquals(tc, see_travel, sr->mode);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_seen_region(CuTest *tc) {
|
||||||
|
seen_region **seen, *sr;
|
||||||
|
region *r;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
setup_seen(0, 0);
|
||||||
|
r = test_create_region(0, 0, 0);
|
||||||
|
seen = seen_init();
|
||||||
|
add_seen(seen, r, see_unit, false);
|
||||||
|
sr = find_seen(seen, r);
|
||||||
|
CuAssertPtrEquals(tc, r, sr->r);
|
||||||
|
seen_done(seen);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_seen_interval_backward(CuTest *tc) {
|
||||||
|
region *r, *first, *last;
|
||||||
|
seen_region **seen;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
r = test_create_region(0, 0, 0);
|
||||||
|
setup_seen(0, 0);
|
||||||
|
seen = seen_init();
|
||||||
|
add_seen(seen, r, see_unit, false);
|
||||||
|
view_default(seen, r, 0);
|
||||||
|
first = r;
|
||||||
|
last = 0;
|
||||||
|
get_seen_interval(seen, &first, &last);
|
||||||
|
CuAssertPtrEquals(tc, regions, first);
|
||||||
|
CuAssertPtrEquals(tc, 0, last);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_seen_interval_forward(CuTest *tc) {
|
||||||
|
region *r, *first, *last;
|
||||||
|
seen_region **seen;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
setup_seen(0, 0);
|
||||||
|
r = test_create_region(0, 0, 0);
|
||||||
|
seen = seen_init();
|
||||||
|
add_seen(seen, r, see_unit, true);
|
||||||
|
view_default(seen, r, 0);
|
||||||
|
first = r;
|
||||||
|
last = 0;
|
||||||
|
get_seen_interval(seen, &first, &last);
|
||||||
|
CuAssertPtrEquals(tc, regions, first);
|
||||||
|
CuAssertPtrEquals(tc, 0, last);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cb_testmap(seen_region *sr, void *cbdata) {
|
||||||
|
int *ip = (int *)cbdata;
|
||||||
|
*ip += sr->r->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_seenhash_map(CuTest *tc) {
|
||||||
|
region *r;
|
||||||
|
seen_region **seen;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
seen = seen_init();
|
||||||
|
r = test_create_region(1, 1, 0);
|
||||||
|
add_seen(seen, r, see_unit, false);
|
||||||
|
r = test_create_region(2, 2, 0);
|
||||||
|
add_seen(seen, r, see_unit, false);
|
||||||
|
seenhash_map(seen, cb_testmap, &i);
|
||||||
|
CuAssertIntEquals(tc, 3, i);
|
||||||
|
seen_done(seen);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
CuSuite *get_seen_suite(void)
|
||||||
|
{
|
||||||
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
SUITE_ADD_TEST(suite, test_add_seen);
|
||||||
|
SUITE_ADD_TEST(suite, test_faction_add_seen);
|
||||||
|
SUITE_ADD_TEST(suite, test_prepare_seen);
|
||||||
|
SUITE_ADD_TEST(suite, test_seen_travelthru);
|
||||||
|
SUITE_ADD_TEST(suite, test_seen_region);
|
||||||
|
SUITE_ADD_TEST(suite, test_seen_interval_backward);
|
||||||
|
SUITE_ADD_TEST(suite, test_seen_interval_forward);
|
||||||
|
SUITE_ADD_TEST(suite, test_seenhash_map);
|
||||||
|
return suite;
|
||||||
|
}
|
|
@ -36,6 +36,7 @@ int RunAllTests(void)
|
||||||
/* self-test */
|
/* self-test */
|
||||||
RUN_TESTS(suite, tests);
|
RUN_TESTS(suite, tests);
|
||||||
RUN_TESTS(suite, callback);
|
RUN_TESTS(suite, callback);
|
||||||
|
RUN_TESTS(suite, seen);
|
||||||
RUN_TESTS(suite, json);
|
RUN_TESTS(suite, json);
|
||||||
RUN_TESTS(suite, jsonconf);
|
RUN_TESTS(suite, jsonconf);
|
||||||
RUN_TESTS(suite, direction);
|
RUN_TESTS(suite, direction);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
#include "keyword.h"
|
#include "keyword.h"
|
||||||
|
#include "seen.h"
|
||||||
|
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
#include <kernel/region.h>
|
#include <kernel/region.h>
|
||||||
|
@ -82,6 +83,7 @@ void test_cleanup(void)
|
||||||
free_races();
|
free_races();
|
||||||
free_spellbooks();
|
free_spellbooks();
|
||||||
free_gamedata();
|
free_gamedata();
|
||||||
|
free_seen();
|
||||||
mt_clear();
|
mt_clear();
|
||||||
if (!mt_find("missing_message")) {
|
if (!mt_find("missing_message")) {
|
||||||
mt_register(mt_new_va("missing_message", "name:string", 0));
|
mt_register(mt_new_va("missing_message", "name:string", 0));
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,4 @@
|
||||||
|
ERESSEA 6rLo "4jLm82"
|
||||||
|
EINHEIT 7Lgf
|
||||||
|
NACH NW NW
|
||||||
|
NAECHSTER
|
|
@ -0,0 +1,56 @@
|
||||||
|
NEWFILES="data/185.dat datum parteien parteien.full passwd score turn"
|
||||||
|
cleanup () {
|
||||||
|
rm -rf reports $NEWFILES
|
||||||
|
}
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
ln -sf ../scripts/config.lua
|
||||||
|
}
|
||||||
|
|
||||||
|
quit() {
|
||||||
|
test -n "$2" && echo $2
|
||||||
|
echo "integration tests: FAILED"
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_grep_count() {
|
||||||
|
file=$1
|
||||||
|
expr=$2
|
||||||
|
expect=$3
|
||||||
|
count=`grep -cE $expr $file`
|
||||||
|
[ $count -eq $expect ] || quit 1 "expected $expect counts of $expr in $file, got $count"
|
||||||
|
}
|
||||||
|
|
||||||
|
ROOT=`pwd`
|
||||||
|
while [ ! -d $ROOT/.git ]; do
|
||||||
|
ROOT=`dirname $ROOT`
|
||||||
|
done
|
||||||
|
|
||||||
|
set -e
|
||||||
|
cd $ROOT/tests
|
||||||
|
setup
|
||||||
|
cleanup
|
||||||
|
VALGRIND=`which valgrind`
|
||||||
|
SERVER=../Debug/eressea/eressea
|
||||||
|
if [ -n "$VALGRIND" ]; then
|
||||||
|
SUPP=../share/ubuntu-12_04.supp
|
||||||
|
SERVER="$VALGRIND --suppressions=$SUPP --error-exitcode=1 --leak-check=no $SERVER"
|
||||||
|
fi
|
||||||
|
echo "running $SERVER"
|
||||||
|
$SERVER -t 184 ../scripts/run-turn.lua
|
||||||
|
[ -d reports ] || quit 4 "no reports directory created"
|
||||||
|
CRFILE=185-zvto.cr
|
||||||
|
for file in $NEWFILES reports/$CRFILE ; do
|
||||||
|
[ -e $file ] || quit 5 "did not create $file"
|
||||||
|
done
|
||||||
|
assert_grep_count reports/$CRFILE '^REGION' 7
|
||||||
|
assert_grep_count reports/$CRFILE '^PARTEI' 2
|
||||||
|
assert_grep_count reports/$CRFILE '^SCHIFF' 1
|
||||||
|
assert_grep_count reports/$CRFILE '^BURG' 1
|
||||||
|
assert_grep_count reports/$CRFILE '^EINHEIT' 2
|
||||||
|
assert_grep_count reports/$CRFILE '^GEGENSTAENDE' 2
|
||||||
|
|
||||||
|
assert_grep_count reports/185-6rLo.cr '^EINHEIT' 2
|
||||||
|
assert_grep_count reports/185-6rLo.cr '^REGION' 13
|
||||||
|
echo "integration tests: PASS"
|
||||||
|
cleanup
|
Loading…
Reference in New Issue