forked from github/server
Merge pull request #745 from ennorehling/develop
Orders in temporary database, bugfixes, tests. For future 3.15 release.
This commit is contained in:
commit
ffc39a303f
|
@ -14,6 +14,7 @@ addons:
|
|||
- libxml2-dev
|
||||
- valgrind
|
||||
- cppcheck
|
||||
- shellcheck
|
||||
os:
|
||||
- linux
|
||||
notifications:
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
SCRIPTS=compress.sh send-bz2-report send-zip-report create-orders \
|
||||
run-turn sendreports.sh
|
||||
IGNORE=sendreport.sh
|
||||
|
||||
shellcheck: $(SCRIPTS)
|
||||
shellcheck $(SCRIPTS)
|
|
@ -1,24 +1,25 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z $ERESSEA ]; then
|
||||
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 -w name $GAME/eressea.ini | sed 's/.*=\s*//')
|
||||
GAME="$ERESSEA/game-$1"
|
||||
GAME_NAME=$(grep -w name "$GAME/eressea.ini" | sed 's/.*=\s*//')
|
||||
|
||||
TURN=$2
|
||||
if [ -z $TURN ]
|
||||
if [ -z "$TURN" ]
|
||||
then
|
||||
TURN=`cat $GAME/turn`
|
||||
TURN=$(cat "$GAME/turn")
|
||||
fi
|
||||
|
||||
if [ ! -d $GAME/reports ]; then
|
||||
if [ ! -d "$GAME/reports" ]; then
|
||||
echo "cannot find reports directory in $GAME"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
cd $GAME/reports
|
||||
$ERESSEA/server/bin/compress.py $TURN "$GAME_NAME"
|
||||
cd -
|
||||
cd "$GAME/reports" || exit
|
||||
"$ERESSEA/server/bin/compress.py" "$TURN" "$GAME_NAME"
|
||||
cd - || exit
|
||||
|
||||
|
|
|
@ -3,24 +3,25 @@
|
|||
GAME=$1
|
||||
TURN=$2
|
||||
|
||||
if [ ! -d $ERESSEA/game-$GAME ] ; then
|
||||
if [ ! -d "$ERESSEA/game-$GAME" ] ; then
|
||||
echo "No such game: $GAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $ERESSEA/game-$GAME
|
||||
cd "$ERESSEA/game-$GAME" || exit
|
||||
|
||||
if [ -d orders.dir.$TURN ]; then
|
||||
if [ -d "orders.dir.$TURN" ]; then
|
||||
echo "orders.dir.$TURN already exists"
|
||||
else
|
||||
mv orders.dir orders.dir.$TURN
|
||||
mv orders.dir "orders.dir.$TURN"
|
||||
mkdir -p orders.dir
|
||||
fi
|
||||
ls -1rt orders.dir.$TURN/turn-* | xargs cat > orders.$TURN
|
||||
#shellcheck disable=2011
|
||||
ls -1rt "orders.dir.$TURN/turn-*" | xargs cat > "orders.$TURN"
|
||||
|
||||
lockfile -r3 -l120 orders.queue.lock
|
||||
if [ -e orders.queue ] ; then
|
||||
mv orders.queue orders.dir.$TURN/orders.queue
|
||||
mv orders.queue "orders.dir.$TURN/orders.queue"
|
||||
fi
|
||||
rm -f orders.queue.lock
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#!/bin/sh
|
||||
|
||||
GAME=$1
|
||||
TURN=$2
|
||||
GAME="$1"
|
||||
TURN="$2"
|
||||
|
||||
if [ ! -d $ERESSEA/game-$GAME ] ; then
|
||||
if [ ! -d "$ERESSEA/game-$GAME" ] ; then
|
||||
echo "No such game: $GAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $ERESSEA/game-$GAME
|
||||
cd "$ERESSEA/game-$GAME" || exit
|
||||
|
||||
echo "running turn $TURN, game $GAME"
|
||||
$ERESSEA/server/bin/eressea -v3 -t $TURN run-turn.lua
|
||||
"$ERESSEA/server/bin/eressea" -t "$TURN" run-turn.lua
|
||||
mkdir -p log
|
||||
ln -f eressea.log log/eressea.log.$TURN
|
||||
ln -f eressea.log "log/eressea.log.$TURN"
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
#!/bin/bash
|
||||
if [ -z $ERESSEA ]; then
|
||||
ERESSEA=`echo $PWD |sed -e 's/\/game.*//'`
|
||||
if [ -z "$ERESSEA" ]; then
|
||||
ERESSEA=$(echo "$PWD" |sed -e 's/\/game.*//')
|
||||
echo "Assuming that ERESSEA=$ERESSEA"
|
||||
fi
|
||||
if [ ! -f reports.txt ]; then
|
||||
echo "need to run $0 from the report direcory"
|
||||
exit -2
|
||||
fi
|
||||
source $HOME/bin/functions.sh
|
||||
|
||||
TEMPLATE=report-mail.txt
|
||||
if [ "$1" == "-Lde" ]
|
||||
|
@ -26,4 +25,6 @@ addr=$1
|
|||
subj=$2
|
||||
shift 2
|
||||
|
||||
cat $ERESSEA/server/etc/$TEMPLATE | mutt -F $ERESSEA/etc/muttrc -s "$subj" -a $* -- $addr
|
||||
mutt -F "$ERESSEA/etc/muttrc" -s "$subj" -a "$@" -- "$addr" \
|
||||
< "$ERESSEA/server/etc/$TEMPLATE"
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#!/bin/bash
|
||||
if [ -z $ERESSEA ]; then
|
||||
ERESSEA=`echo $PWD |sed -e 's/\/game.*//'`
|
||||
|
||||
if [ -z "$ERESSEA" ]; then
|
||||
ERESSEA=$(echo "$PWD" |sed -e 's/\/game.*//')
|
||||
echo "Assuming that ERESSEA=$ERESSEA"
|
||||
fi
|
||||
if [ ! -f reports.txt ]; then
|
||||
|
@ -9,7 +10,7 @@ if [ ! -f reports.txt ]; then
|
|||
fi
|
||||
|
||||
PWD=$(pwd)
|
||||
GAME=$(dirname $PWD)
|
||||
GAME=$(dirname "$PWD")
|
||||
|
||||
TEMPLATE=report-mail.txt
|
||||
if [ "$1" == "-Lde" ]
|
||||
|
@ -24,13 +25,13 @@ then
|
|||
shift
|
||||
fi
|
||||
|
||||
if [ -e $GAME/$TEMPLATE ]; then
|
||||
TEMPLATE=$GAME/$TEMPLATE
|
||||
if [ -e "$GAME/$TEMPLATE" ]; then
|
||||
TEMPLATE="$GAME/$TEMPLATE"
|
||||
else
|
||||
TEMPLATE=$ERESSEA/server/etc/$TEMPLATE
|
||||
TEMPLATE="$ERESSEA/server/etc/$TEMPLATE"
|
||||
fi
|
||||
|
||||
if [ ! -e $TEMPLATE ]; then
|
||||
if [ ! -e "$TEMPLATE" ]; then
|
||||
echo "no such email template: $TEMPLATE"
|
||||
exit -3
|
||||
fi
|
||||
|
@ -42,8 +43,7 @@ done
|
|||
addr=$1
|
||||
subject=$2
|
||||
shift 2
|
||||
mutt -F $ERESSEA/etc/muttrc -s "$subject" -a $* -- $addr < $TEMPLATE
|
||||
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "Sending failed for email/report: $2/$3"
|
||||
fi
|
||||
mutt -F "$ERESSEA/etc/muttrc" -s "$subject" -a "$@" -- "$addr" \
|
||||
< "$TEMPLATE" || echo "Sending failed for email/report: $2/$3"
|
||||
|
||||
|
|
|
@ -3,30 +3,23 @@
|
|||
##
|
||||
## Prepare the report
|
||||
|
||||
if [ -z $ERESSEA ]; then
|
||||
if [ -z "$ERESSEA" ]; then
|
||||
echo "You have to define the \$ERESSEA environment variable to run $0"
|
||||
exit -2
|
||||
fi
|
||||
source $HOME/bin/functions.sh
|
||||
|
||||
if [ ! -z $1 ]; then
|
||||
GAME=$ERESSEA/game-$1
|
||||
if [ ! -z "$1" ]; then
|
||||
GAME="$ERESSEA/game-$1"
|
||||
else
|
||||
GAME=$ERESSEA
|
||||
fi
|
||||
|
||||
cd $GAME/reports || abort "could not chdir to reports directory"
|
||||
cd "$GAME/reports" || exit
|
||||
for REPORT in *.sh
|
||||
do
|
||||
echo -n "Sending "
|
||||
basename $REPORT .sh
|
||||
bash $REPORT
|
||||
basename "$REPORT" .sh
|
||||
bash "$REPORT"
|
||||
done
|
||||
cd -
|
||||
|
||||
if [ -e $GAME/ages.sh ]; then
|
||||
cd $GAME
|
||||
./ages.sh
|
||||
cd -
|
||||
fi
|
||||
cd - || exit
|
||||
|
||||
|
|
|
@ -19,11 +19,12 @@ cd tests
|
|||
set -e
|
||||
[ -z $BUILD ] && BUILD=Debug ; export BUILD
|
||||
s/cmake-init
|
||||
cppcheck --version
|
||||
cppcheck --quiet -Isrc -Iclibs -Istorage -IcJSON --error-exitcode=1 src
|
||||
s/build
|
||||
cd process
|
||||
make
|
||||
cd $ROOT
|
||||
inifile
|
||||
cppcheck --version
|
||||
cppcheck --quiet --error-exitcode=1 src
|
||||
s/runtests -V
|
||||
integration_tests
|
||||
|
||||
|
|
|
@ -121,9 +121,11 @@ function test_fleeing_units_can_be_transported()
|
|||
u1.number = 100
|
||||
u1:add_order("ATTACKIEREN " .. itoa36(u2.id))
|
||||
u2.number = 100
|
||||
u2.name = 'Passagier'
|
||||
u2:add_order("FAHREN " .. itoa36(u3.id))
|
||||
u2:add_order("KAEMPFE FLIEHE")
|
||||
u3.number = 100
|
||||
u3.name = 'Transporter'
|
||||
u3:add_order("KAEMPFE FLIEHE")
|
||||
u3:add_order("TRANSPORT " .. itoa36(u2.id))
|
||||
u3:add_order("NACH O ")
|
||||
|
@ -131,8 +133,8 @@ function test_fleeing_units_can_be_transported()
|
|||
u3:add_item("horse", u2.number)
|
||||
u3:add_order("KAEMPFE FLIEHE")
|
||||
process_orders()
|
||||
assert_equal(u3.region.id, r1.id, "transporter did not move")
|
||||
assert_equal(u2.region.id, r1.id, "transported unit did not move")
|
||||
assert_equal(u3.region, r1, "transporter did not move")
|
||||
assert_equal(u2.region, r1, "transported unit did not move")
|
||||
end
|
||||
|
||||
function test_plane()
|
||||
|
|
|
@ -10,6 +10,7 @@ require 'tests.e2.destroy'
|
|||
require 'tests.e2.guard'
|
||||
require 'tests.e2.stealth'
|
||||
require 'tests.e2.items'
|
||||
-- require 'tests.e2.ships'
|
||||
require 'tests.items'
|
||||
require 'tests.economy'
|
||||
require 'tests.orders'
|
||||
|
|
|
@ -76,3 +76,29 @@ function test_dwarf_mining_bonus()
|
|||
assert_equal(20, u:get_item('iron'))
|
||||
assert_equal(84, r:get_resource('iron'))
|
||||
end
|
||||
|
||||
function test_build_boat_low_skill()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create("human", "build@example.com")
|
||||
local u = unit.create(f, r, 1)
|
||||
u:set_skill("shipcraft", 3) -- humans get +1
|
||||
u:add_item("log", 10)
|
||||
u:add_order("MACHE BOOT")
|
||||
process_orders()
|
||||
assert_not_equal(nil, u.ship)
|
||||
assert_equal(4, u.ship.size)
|
||||
assert_equal(6, u:get_item('log'))
|
||||
end
|
||||
|
||||
function test_build_boat_high_skill()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create("human", "build@example.com")
|
||||
local u = unit.create(f, r, 1)
|
||||
u:set_skill("shipcraft", 5) -- humans get +1
|
||||
u:add_item("log", 10)
|
||||
u:add_order("MACHE BOOT")
|
||||
process_orders()
|
||||
assert_not_equal(nil, u.ship)
|
||||
assert_equal(5, u.ship.size)
|
||||
assert_equal(5, u:get_item('log'))
|
||||
end
|
||||
|
|
|
@ -10,7 +10,9 @@ end
|
|||
|
||||
function test_ship_requires_skill()
|
||||
local r1 = region.create(0, 0, "ocean")
|
||||
assert_not_nil(r1)
|
||||
local r2 = region.create(1, 0, "ocean")
|
||||
assert_not_nil(r2)
|
||||
local f = faction.create("human", "fake@eressea.de", "de")
|
||||
local u1 = unit.create(f, r1, 1)
|
||||
u1.name = "fake"
|
||||
|
@ -22,7 +24,7 @@ function test_ship_requires_skill()
|
|||
assert_equal(r1, u1.region)
|
||||
end
|
||||
|
||||
function no_test_ship_happy_case()
|
||||
function test_ship_happy_case()
|
||||
local r1 = region.create(0, 0, "ocean")
|
||||
local r2 = region.create(1, 0, "ocean")
|
||||
local f = faction.create("human", "hodor@eressea.de", "de")
|
||||
|
@ -39,4 +41,3 @@ function no_test_ship_happy_case()
|
|||
assert_equal(r2, u1.region)
|
||||
assert_equal(r2, u2.region)
|
||||
end
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ function setup()
|
|||
eressea.settings.set("NewbieImmunity", "0")
|
||||
eressea.settings.set("rules.food.flags", "4")
|
||||
eressea.settings.set("rules.peasants.growth.factor", "0")
|
||||
eressea.settings.set("magic.fumble.enable", "0")
|
||||
end
|
||||
|
||||
function test_shapeshift()
|
||||
|
|
|
@ -81,3 +81,25 @@ function test_create_dreameye()
|
|||
assert_equal(amax - 5, u.aura_max)
|
||||
end
|
||||
|
||||
function test_appeasement()
|
||||
local u1, u2, r1, r2, uno
|
||||
r1 = region.create(0, 0, 'plain')
|
||||
r2 = region.create(1, 0, 'plain')
|
||||
u2 = unit.create(faction.create('human'), r1, 1)
|
||||
u2.race = 'elf'
|
||||
u2.name = 'Angsthase'
|
||||
u2.magic = 'gwyrrd'
|
||||
u2:set_skill('magic', 5)
|
||||
u2.aura = 10
|
||||
u2:add_spell('appeasement')
|
||||
u2:add_order('NACH O')
|
||||
u2:add_order('KAMPFZAUBER STUFE 1 Friedenslied')
|
||||
uno = u2.id
|
||||
u1 = unit.create(faction.create('human'), r1, 1)
|
||||
u1:set_skill('polearm', 5)
|
||||
u1:add_order('ATTACKIERE ' .. itoa36(uno))
|
||||
process_orders()
|
||||
u2 = get_unit(uno)
|
||||
assert_not_nil(u2)
|
||||
assert_equal(r2, u2.region)
|
||||
end
|
||||
|
|
|
@ -109,6 +109,7 @@ set (ERESSEA_SRC
|
|||
json.c
|
||||
creport.c
|
||||
report.c
|
||||
steal.c
|
||||
economy.c
|
||||
give.c
|
||||
items.c
|
||||
|
@ -140,7 +141,6 @@ set (ERESSEA_SRC
|
|||
|
||||
set(SERVER_SRC
|
||||
main.c
|
||||
building_action.c
|
||||
console.c
|
||||
helpers.c
|
||||
bind_tolua.c
|
||||
|
@ -293,5 +293,4 @@ include_directories (${LIBXML2_INCLUDE_DIR})
|
|||
target_link_libraries(eressea ${LIBXML2_LIBRARIES})
|
||||
target_link_libraries(convert ${LIBXML2_LIBRARIES})
|
||||
target_link_libraries(test_eressea ${LIBXML2_LIBRARIES})
|
||||
add_definitions(-DUSE_LIBXML2)
|
||||
endif (LIBXML2_FOUND)
|
||||
|
|
|
@ -41,11 +41,7 @@ extern "C" {
|
|||
/* Stufe 3 */
|
||||
P_WISE, /* 6 */
|
||||
P_FOOL,
|
||||
#ifdef INSECT_POTION
|
||||
P_WARMTH,
|
||||
#else
|
||||
P_STEEL,
|
||||
#endif
|
||||
P_HORSE,
|
||||
P_BERSERK, /* 10 */
|
||||
/* Stufe 4 */
|
||||
|
|
37
src/battle.c
37
src/battle.c
|
@ -1009,7 +1009,7 @@ int natural_armor(unit * du)
|
|||
static int rc_specialdamage(const unit *au, const unit *du, const struct weapon_type *wtype)
|
||||
{
|
||||
const race *ar = u_race(au);
|
||||
int m, modifier = 0;
|
||||
int modifier = 0;
|
||||
if (wtype != NULL) {
|
||||
if (fval(u_race(du), RCF_DRAGON)) {
|
||||
static int cache;
|
||||
|
@ -1022,6 +1022,7 @@ static int rc_specialdamage(const unit *au, const unit *du, const struct weapon_
|
|||
}
|
||||
}
|
||||
if (wtype->modifiers != NULL) {
|
||||
int m;
|
||||
for (m = 0; wtype->modifiers[m].value; ++m) {
|
||||
/* weapon damage for this weapon, possibly by race */
|
||||
if (wtype->modifiers[m].flags & WMF_DAMAGE) {
|
||||
|
@ -2009,11 +2010,6 @@ void dazzle(battle * b, troop * td)
|
|||
{
|
||||
UNUSED_ARG(b);
|
||||
/* Nicht kumulativ ! */
|
||||
#ifdef TODO_RUNESWORD
|
||||
if (td->fighter->weapon[WP_RUNESWORD].count > td->index) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (td->fighter->person[td->index].flags & (FL_COURAGE|FL_DAZZLED)) {
|
||||
return;
|
||||
}
|
||||
|
@ -2285,21 +2281,6 @@ void do_attack(fighter * af)
|
|||
}
|
||||
}
|
||||
|
||||
void do_regenerate(fighter * af)
|
||||
{
|
||||
troop ta;
|
||||
unit *au = af->unit;
|
||||
|
||||
ta.fighter = af;
|
||||
ta.index = af->fighting;
|
||||
|
||||
while (ta.index--) {
|
||||
struct person *p = af->person + ta.index;
|
||||
p->hp += effskill(au, SK_STAMINA, 0);
|
||||
p->hp = MIN(unit_max_hp(au), p->hp);
|
||||
}
|
||||
}
|
||||
|
||||
static void add_tactics(tactics * ta, fighter * fig, int value)
|
||||
{
|
||||
if (value == 0 || value < ta->value)
|
||||
|
@ -2655,14 +2636,14 @@ static void aftermath(battle * b)
|
|||
}
|
||||
}
|
||||
snumber += du->number;
|
||||
if (relevant) {
|
||||
flags = UFL_LONGACTION | UFL_NOTMOVING;
|
||||
if (du->status == ST_FLEE) {
|
||||
flags -= UFL_NOTMOVING;
|
||||
}
|
||||
}
|
||||
if (df->alive == 0) {
|
||||
flags |= UFL_DEAD;
|
||||
flags = UFL_DEAD;
|
||||
}
|
||||
else if (relevant) {
|
||||
flags = UFL_LONGACTION;
|
||||
if ((du->status != ST_FLEE) && (df->run.hp <= 0)) {
|
||||
flags |= UFL_NOTMOVING;
|
||||
}
|
||||
}
|
||||
if (flags) {
|
||||
fset(du, flags);
|
||||
|
|
|
@ -45,28 +45,35 @@ int tolua_shiplist_next(lua_State * L)
|
|||
|
||||
static int tolua_ship_get_id(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, self->no);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_name(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
tolua_pushstring(L, ship_getname(self));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_size(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, self->size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_display(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
tolua_pushstring(L, self->display);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_region(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
if (self) {
|
||||
tolua_pushusertype(L, self->region, TOLUA_CAST "region");
|
||||
return 1;
|
||||
|
@ -76,8 +83,8 @@ static int tolua_ship_get_region(lua_State * L)
|
|||
|
||||
static int tolua_ship_set_region(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
region *r = (region *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
region *r = (region *)tolua_tousertype(L, 2, NULL);
|
||||
if (self) {
|
||||
move_ship(self, self->region, r, NULL);
|
||||
}
|
||||
|
@ -86,22 +93,29 @@ static int tolua_ship_set_region(lua_State * L)
|
|||
|
||||
static int tolua_ship_set_name(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship_setname(self, tolua_tostring(L, 2, 0));
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
ship_setname(self, tolua_tostring(L, 2, NULL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_set_size(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
self->size = lua_tointeger(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_set_display(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
free(self->display);
|
||||
self->display = strdup(tolua_tostring(L, 2, 0));
|
||||
self->display = strdup(tolua_tostring(L, 2, NULL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_units(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
unit **unit_ptr = (unit **)lua_newuserdata(L, sizeof(unit *));
|
||||
unit *u = self->region->units;
|
||||
|
||||
|
@ -118,8 +132,8 @@ static int tolua_ship_get_units(lua_State * L)
|
|||
|
||||
static int tolua_ship_create(lua_State * L)
|
||||
{
|
||||
region *r = (region *)tolua_tousertype(L, 1, 0);
|
||||
const char *sname = tolua_tostring(L, 2, 0);
|
||||
region *r = (region *)tolua_tousertype(L, 1, NULL);
|
||||
const char *sname = tolua_tostring(L, 2, NULL);
|
||||
if (sname) {
|
||||
const ship_type *stype = st_find(sname);
|
||||
if (stype) {
|
||||
|
@ -138,40 +152,40 @@ static int tolua_ship_create(lua_State * L)
|
|||
static int
|
||||
tolua_ship_tostring(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushstring(L, shipname(self));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_flags(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, self->flags);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_set_flags(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
self->flags = (int)tolua_tonumber(L, 2, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
self->flags = (int)lua_tointeger(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_set_coast(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
if (lua_isnil(L, 2)) {
|
||||
self->coast = NODIRECTION;
|
||||
}
|
||||
else if (lua_isnumber(L, 2)) {
|
||||
self->coast = (direction_t)tolua_tonumber(L, 2, 0);
|
||||
self->coast = (direction_t)lua_tointeger(L, 2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_coast(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
if (self->coast) {
|
||||
lua_pushinteger(L, self->coast);
|
||||
return 1;
|
||||
|
@ -181,28 +195,28 @@ static int tolua_ship_get_coast(lua_State * L)
|
|||
|
||||
static int tolua_ship_get_type(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
tolua_pushstring(L, self->type->_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_damage(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
lua_pushinteger(L, self->damage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_ship_set_damage(lua_State * L)
|
||||
{
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
self->damage = (int)tolua_tonumber(L, 2, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
self->damage = (int)lua_tointeger(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_ship_get_curse(lua_State *L) {
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
const char *name = tolua_tostring(L, 2, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
const char *name = tolua_tostring(L, 2, NULL);
|
||||
if (self->attribs) {
|
||||
curse * c = get_curse(self->attribs, ct_find(name));
|
||||
if (c) {
|
||||
|
@ -214,8 +228,8 @@ static int tolua_ship_get_curse(lua_State *L) {
|
|||
}
|
||||
|
||||
static int tolua_ship_has_attrib(lua_State *L) {
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, 0);
|
||||
const char *name = tolua_tostring(L, 2, 0);
|
||||
ship *self = (ship *)tolua_tousertype(L, 1, NULL);
|
||||
const char *name = tolua_tostring(L, 2, NULL);
|
||||
attrib * a = a_find(self->attribs, at_find(name));
|
||||
lua_pushboolean(L, a != NULL);
|
||||
return 1;
|
||||
|
@ -236,6 +250,8 @@ void tolua_ship_open(lua_State * L)
|
|||
tolua_variable(L, TOLUA_CAST "id", tolua_ship_get_id, NULL);
|
||||
tolua_variable(L, TOLUA_CAST "name", tolua_ship_get_name,
|
||||
tolua_ship_set_name);
|
||||
tolua_variable(L, TOLUA_CAST "size", tolua_ship_get_size,
|
||||
tolua_ship_set_size);
|
||||
tolua_variable(L, TOLUA_CAST "info", tolua_ship_get_display,
|
||||
tolua_ship_set_display);
|
||||
tolua_variable(L, TOLUA_CAST "units", tolua_ship_get_units, NULL);
|
||||
|
|
|
@ -286,7 +286,7 @@ static int tolua_unit_get_magic(lua_State * L)
|
|||
|
||||
static void unit_setmagic(unit * u, const char *type)
|
||||
{
|
||||
sc_mage *mage = get_mage_depr(u);
|
||||
sc_mage *mage = get_mage(u);
|
||||
int mtype;
|
||||
for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) {
|
||||
if (strcmp(magic_school[mtype], type) == 0)
|
||||
|
@ -763,38 +763,6 @@ static int tolua_unit_get_spells(lua_State * L)
|
|||
return tolua_selist_push(L, "spellbook", "spell_entry", slist);
|
||||
}
|
||||
|
||||
#ifdef TOLUA_ORDERS_CLOSURE
|
||||
/* TODO: this requires that the locale for write_order is included in the closure */
|
||||
static int tolua_orderlist_next(lua_State * L)
|
||||
{
|
||||
order **order_ptr = (order **)lua_touserdata(L, lua_upvalueindex(1));
|
||||
order *ord = *order_ptr;
|
||||
if (ord != NULL) {
|
||||
char cmd[8192];
|
||||
write_order(ord, cmd, sizeof(cmd));
|
||||
tolua_pushstring(L, cmd);
|
||||
*order_ptr = ord->next;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_unit_get_orders(lua_State * L)
|
||||
{
|
||||
unit *self = (unit *)tolua_tousertype(L, 1, 0);
|
||||
|
||||
order **order_ptr = (order **)lua_newuserdata(L, sizeof(order *));
|
||||
|
||||
luaL_getmetatable(L, TOLUA_CAST "order");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*order_ptr = self->orders;
|
||||
|
||||
lua_pushcclosure(L, tolua_orderlist_next, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
static int tolua_unit_get_curse(lua_State *L) {
|
||||
unit *self = (unit *)tolua_tousertype(L, 1, 0);
|
||||
const char *name = tolua_tostring(L, 2, 0);
|
||||
|
@ -1006,9 +974,6 @@ void tolua_unit_open(lua_State * L)
|
|||
|
||||
tolua_function(L, TOLUA_CAST "add_order", tolua_unit_add_order);
|
||||
tolua_function(L, TOLUA_CAST "clear_orders", tolua_unit_clear_orders);
|
||||
#ifdef TOLUA_ORDERS_CLOSURE
|
||||
tolua_variable(L, TOLUA_CAST "orders", tolua_unit_get_orders, 0);
|
||||
#endif
|
||||
tolua_function(L, TOLUA_CAST "get_curse", tolua_unit_get_curse);
|
||||
tolua_function(L, TOLUA_CAST "has_attrib", tolua_unit_has_attrib);
|
||||
|
||||
|
|
|
@ -710,7 +710,6 @@ static int config_get_resource(lua_State * L)
|
|||
lua_settable(L, -3);
|
||||
}
|
||||
if (itype->construction) {
|
||||
int i;
|
||||
lua_pushstring(L, "build_skill_min");
|
||||
lua_pushinteger(L, itype->construction->minskill);
|
||||
lua_settable(L, -3);
|
||||
|
@ -718,6 +717,7 @@ static int config_get_resource(lua_State * L)
|
|||
lua_pushstring(L, skillnames[itype->construction->skill]);
|
||||
lua_settable(L, -3);
|
||||
if (itype->construction->materials) {
|
||||
int i;
|
||||
lua_pushstring(L, "materials");
|
||||
lua_newtable(L);
|
||||
for (i = 0; itype->construction->materials[i].number; ++i) {
|
||||
|
@ -774,7 +774,6 @@ static int config_get_btype(lua_State * L)
|
|||
lua_settable(L, -3);
|
||||
}
|
||||
if (btype->construction) {
|
||||
int i;
|
||||
lua_pushstring(L, "build_skill_min");
|
||||
lua_pushinteger(L, btype->construction->minskill);
|
||||
lua_settable(L, -3);
|
||||
|
@ -782,6 +781,7 @@ static int config_get_btype(lua_State * L)
|
|||
lua_pushstring(L, skillnames[btype->construction->skill]);
|
||||
lua_settable(L, -3);
|
||||
if (btype->construction->materials) {
|
||||
int i;
|
||||
lua_pushstring(L, "materials");
|
||||
lua_newtable(L);
|
||||
for (i = 0; btype->construction->materials[i].number; ++i) {
|
||||
|
@ -840,7 +840,6 @@ static int config_get_stype(lua_State * L)
|
|||
}
|
||||
}
|
||||
if (stype->construction) {
|
||||
int i;
|
||||
lua_pushstring(L, "build_skill_min");
|
||||
lua_pushinteger(L, stype->construction->minskill);
|
||||
lua_settable(L, -3);
|
||||
|
@ -848,6 +847,7 @@ static int config_get_stype(lua_State * L)
|
|||
lua_pushstring(L, skillnames[stype->construction->skill]);
|
||||
lua_settable(L, -3);
|
||||
if (stype->construction->materials) {
|
||||
int i;
|
||||
lua_pushstring(L, "materials");
|
||||
lua_newtable(L);
|
||||
for (i = 0; stype->construction->materials[i].number; ++i) {
|
||||
|
@ -922,12 +922,6 @@ int tolua_read_xml(lua_State * L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
typedef struct event_args {
|
||||
int hfunction;
|
||||
int hargs;
|
||||
const char *sendertype;
|
||||
} event_args;
|
||||
|
||||
static int tolua_report_unit(lua_State * L)
|
||||
{
|
||||
char buffer[512];
|
||||
|
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
+-------------------+
|
||||
| | Enno Rehling <enno@eressea.de>
|
||||
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
|
||||
| | Henning Peters <faroul@beyond.kn-bremen.de>
|
||||
+-------------------+
|
||||
|
||||
This program may not be used, modified or distributed
|
||||
without prior permission by the authors of Eressea.
|
||||
*/
|
||||
|
||||
#include <platform.h>
|
||||
#include <kernel/config.h>
|
||||
#include <kernel/building.h>
|
||||
#include <util/attrib.h>
|
||||
#include <util/gamedata.h>
|
||||
#include <util/log.h>
|
||||
#include <util/resolve.h>
|
||||
|
||||
#include <storage.h>
|
||||
|
||||
#include <tolua.h>
|
||||
#include <lua.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct building_action {
|
||||
char *fname;
|
||||
char *param;
|
||||
} building_action;
|
||||
|
||||
static int lc_age(struct attrib *a, void *owner)
|
||||
{
|
||||
building_action *data = (building_action *)a->data.v;
|
||||
const char *fname = data->fname;
|
||||
const char *fparam = data->param;
|
||||
building *b = (building *)owner;
|
||||
int result = -1;
|
||||
|
||||
assert(b != NULL);
|
||||
if (fname != NULL) {
|
||||
lua_State *L = (lua_State *)global.vm_state;
|
||||
|
||||
lua_getglobal(L, fname);
|
||||
if (lua_isfunction(L, -1)) {
|
||||
tolua_pushusertype(L, (void *)b, TOLUA_CAST "building");
|
||||
if (fparam) {
|
||||
tolua_pushstring(L, fparam);
|
||||
}
|
||||
|
||||
if (lua_pcall(L, fparam ? 2 : 1, 1, 0) != 0) {
|
||||
const char *error = lua_tostring(L, -1);
|
||||
log_error("lc_age(%s) calling '%s': %s.\n", buildingname(b), fname, error);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else {
|
||||
result = (int)lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_error("lc_age(%s) calling '%s': not a function.\n", buildingname(b), fname);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
return (result != 0) ? AT_AGE_KEEP : AT_AGE_REMOVE;
|
||||
}
|
||||
|
||||
static const char *NULLSTRING = "(null)";
|
||||
|
||||
static void lc_init(struct attrib *a)
|
||||
{
|
||||
a->data.v = calloc(1, sizeof(building_action));
|
||||
}
|
||||
|
||||
static void lc_done(struct attrib *a)
|
||||
{
|
||||
building_action *data = (building_action *)a->data.v;
|
||||
if (data->fname)
|
||||
free(data->fname);
|
||||
if (data->param)
|
||||
free(data->param);
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void lc_write(const struct attrib *a, const void *owner, struct storage *store)
|
||||
{
|
||||
building_action *data = (building_action *)a->data.v;
|
||||
const char *fname = data->fname;
|
||||
const char *fparam = data->param;
|
||||
|
||||
UNUSED_ARG(owner);
|
||||
WRITE_TOK(store, fname);
|
||||
WRITE_TOK(store, fparam ? fparam : NULLSTRING);
|
||||
}
|
||||
|
||||
static int lc_read(struct attrib *a, void *owner, gamedata *data)
|
||||
{
|
||||
struct storage *store = data->store;
|
||||
char name[NAMESIZE];
|
||||
building_action *bd = (building_action *)a->data.v;
|
||||
building *b = (building *)owner;
|
||||
int result = 0;
|
||||
if (data->version < ATTRIBOWNER_VERSION) {
|
||||
READ_INT(data->store, NULL);
|
||||
}
|
||||
READ_TOK(store, name, sizeof(name));
|
||||
if (strcmp(name, "tunnel_action") == 0) {
|
||||
/* E2: Weltentor has a new module, doesn't need this any longer */
|
||||
result = 0;
|
||||
b = 0;
|
||||
}
|
||||
else {
|
||||
bd->fname = strdup(name);
|
||||
}
|
||||
READ_TOK(store, name, sizeof(name));
|
||||
if (strcmp(name, "tnnL") == 0) {
|
||||
/* tunnel_action was the old Weltentore, their code has changed. ignore this object */
|
||||
result = 0;
|
||||
b = 0;
|
||||
}
|
||||
if (strcmp(name, NULLSTRING) == 0)
|
||||
bd->param = 0;
|
||||
else {
|
||||
bd->param = strdup(name);
|
||||
}
|
||||
if (result == 0 && !b) {
|
||||
return AT_READ_FAIL;
|
||||
}
|
||||
return AT_READ_OK;
|
||||
}
|
||||
|
||||
attrib_type at_building_action = {
|
||||
"lcbuilding",
|
||||
lc_init, lc_done,
|
||||
lc_age,
|
||||
lc_write, lc_read
|
||||
};
|
||||
|
||||
void building_addaction(building * b, const char *fname, const char *param)
|
||||
{
|
||||
attrib *a = a_add(&b->attribs, a_new(&at_building_action));
|
||||
building_action *data = (building_action *)a->data.v;
|
||||
data->fname = strdup(fname);
|
||||
if (param) {
|
||||
data->param = strdup(param);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,8 @@
|
|||
#include <platform.h>
|
||||
|
||||
|
||||
#ifdef USE_LIBXML2
|
||||
#include <kernel/xmlreader.h>
|
||||
#include <util/xml.h>
|
||||
#endif
|
||||
#include <kernel/race.h>
|
||||
#include <kernel/rules.h>
|
||||
#include <races/races.h>
|
||||
|
@ -21,12 +19,9 @@ int main(int argc, char **argv) {
|
|||
const char *mode;
|
||||
|
||||
register_races();
|
||||
#ifdef USE_LIBXML2
|
||||
register_xmlreader();
|
||||
#endif
|
||||
if (argc < 2) return usage();
|
||||
mode = argv[1];
|
||||
#ifdef USE_LIBXML2
|
||||
if (strcmp(mode, "rules")==0) {
|
||||
const char *xmlfile, *catalog;
|
||||
if (argc < 4) return usage();
|
||||
|
@ -36,7 +31,6 @@ int main(int argc, char **argv) {
|
|||
write_rules("rules.dat");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (strcmp(mode, "po")==0) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -723,18 +723,6 @@ static void cr_output_ship_compat(FILE *F, const ship *sh, const unit *u,
|
|||
cr_output_ship(&strm, sh, u, fcaptain, f, r);
|
||||
}
|
||||
|
||||
static int stream_order(stream *out, const struct order *ord, const struct locale *lang) {
|
||||
const char *str;
|
||||
char ebuf[1025];
|
||||
char obuf[1024];
|
||||
write_order(ord, lang, obuf, sizeof(obuf));
|
||||
str = escape_string(obuf, ebuf, sizeof(ebuf));
|
||||
if (str == ebuf) {
|
||||
ebuf[1024] = 0;
|
||||
}
|
||||
return stream_printf(out, "\"%s\"\n", str);
|
||||
}
|
||||
|
||||
static void cr_output_spells(stream *out, const unit * u, int maxlevel)
|
||||
{
|
||||
spellbook * book = unit_get_spellbook(u);
|
||||
|
@ -925,7 +913,9 @@ void cr_output_unit(stream *out, const region * r, const faction * f,
|
|||
for (ord = u->old_orders; ord; ord = ord->next) {
|
||||
/* this new order will replace the old defaults */
|
||||
if (is_persistent(ord)) {
|
||||
stream_order(out, ord, lang);
|
||||
swrite("\"", 1, 1, out);
|
||||
stream_order(out, ord, lang, true);
|
||||
swrite("\"\n", 1, 2, out);
|
||||
}
|
||||
}
|
||||
for (ord = u->orders; ord; ord = ord->next) {
|
||||
|
@ -933,7 +923,9 @@ void cr_output_unit(stream *out, const region * r, const faction * f,
|
|||
if (u->old_orders && is_repeated(kwd))
|
||||
continue; /* unit has defaults */
|
||||
if (is_persistent(ord)) {
|
||||
stream_order(out, ord, lang);
|
||||
swrite("\"", 1, 1, out);
|
||||
stream_order(out, ord, lang, true);
|
||||
swrite("\"\n", 1, 2, out);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1388,7 +1380,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r)
|
|||
else {
|
||||
fprintf(F, "%d;Rekruten\n", rpeasants(r) / RECRUITFRACTION);
|
||||
}
|
||||
if (production(r)) {
|
||||
if (max_production(r)) {
|
||||
int p_wage = wage(r, NULL, NULL, turn + 1);
|
||||
fprintf(F, "%d;Lohn\n", p_wage);
|
||||
if (is_mourning(r, turn + 1)) {
|
||||
|
|
329
src/economy.c
329
src/economy.c
|
@ -81,26 +81,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
typedef struct request {
|
||||
struct request *next;
|
||||
struct unit *unit;
|
||||
struct order *ord;
|
||||
int qty;
|
||||
int no;
|
||||
union {
|
||||
bool goblin; /* stealing */
|
||||
const struct luxury_type *ltype; /* trading */
|
||||
} type;
|
||||
} request;
|
||||
|
||||
static int working;
|
||||
|
||||
static request entertainers[1024];
|
||||
static request *nextentertainer;
|
||||
static econ_request entertainers[1024];
|
||||
static econ_request *nextentertainer;
|
||||
static int entertaining;
|
||||
|
||||
static unsigned int norders;
|
||||
static request *g_requests;
|
||||
static econ_request *g_requests;
|
||||
|
||||
#define RECRUIT_MERGE 1
|
||||
static int rules_recruit = -1;
|
||||
|
@ -153,19 +141,18 @@ static void scramble(void *data, unsigned int n, size_t width)
|
|||
}
|
||||
}
|
||||
|
||||
static void expandorders(region * r, request * requests)
|
||||
unsigned int expand_production(region * r, econ_request * requests, econ_request **results)
|
||||
{
|
||||
unit *u;
|
||||
request *o;
|
||||
econ_request *o;
|
||||
unsigned int norders = 0;
|
||||
|
||||
/* Alle Units ohne request haben ein -1, alle units mit orders haben ein
|
||||
/* Alle Units ohne production haben ein -1, alle units mit orders haben ein
|
||||
* 0 hier stehen */
|
||||
|
||||
for (u = r->units; u; u = u->next)
|
||||
u->n = -1;
|
||||
|
||||
norders = 0;
|
||||
|
||||
for (o = requests; o; o = o->next) {
|
||||
if (o->qty > 0) {
|
||||
norders += o->qty;
|
||||
|
@ -174,28 +161,35 @@ static void expandorders(region * r, request * requests)
|
|||
|
||||
if (norders > 0) {
|
||||
int i = 0;
|
||||
g_requests = (request *)calloc(norders, sizeof(request));
|
||||
econ_request *split;
|
||||
split = (econ_request *)calloc(norders, sizeof(econ_request));
|
||||
for (o = requests; o; o = o->next) {
|
||||
if (o->qty > 0) {
|
||||
unsigned int j;
|
||||
for (j = o->qty; j; j--) {
|
||||
g_requests[i] = *o;
|
||||
g_requests[i].unit->n = 0;
|
||||
split[i] = *o;
|
||||
split[i].unit->n = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
scramble(g_requests, norders, sizeof(request));
|
||||
scramble(split, norders, sizeof(econ_request));
|
||||
*results = split;
|
||||
}
|
||||
else {
|
||||
g_requests = NULL;
|
||||
*results = NULL;
|
||||
}
|
||||
while (requests) {
|
||||
request *o = requests->next;
|
||||
econ_request *o = requests->next;
|
||||
free_order(requests->ord);
|
||||
free(requests);
|
||||
requests = o;
|
||||
}
|
||||
return norders;
|
||||
}
|
||||
|
||||
static void expandorders(region * r, econ_request * requests) {
|
||||
norders = expand_production(r, requests, &g_requests);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
@ -203,21 +197,21 @@ static void expandorders(region * r, request * requests)
|
|||
typedef struct recruitment {
|
||||
struct recruitment *next;
|
||||
faction *f;
|
||||
request *requests;
|
||||
econ_request *requests;
|
||||
int total, assigned;
|
||||
} recruitment;
|
||||
|
||||
/** Creates a list of recruitment structs, one for each faction. Adds every quantifyable request
|
||||
/** Creates a list of recruitment structs, one for each faction. Adds every quantifyable production
|
||||
* to the faction's struct and to total.
|
||||
*/
|
||||
static recruitment *select_recruitment(request ** rop,
|
||||
static recruitment *select_recruitment(econ_request ** rop,
|
||||
int(*quantify) (const struct race *, int), int *total)
|
||||
{
|
||||
recruitment *recruits = NULL;
|
||||
|
||||
while (*rop) {
|
||||
recruitment *rec = recruits;
|
||||
request *ro = *rop;
|
||||
econ_request *ro = *rop;
|
||||
unit *u = ro->unit;
|
||||
const race *rc = u_race(u);
|
||||
int qty = quantify(rc, ro->qty);
|
||||
|
@ -294,7 +288,7 @@ static int do_recruiting(recruitment * recruits, int available)
|
|||
int n = 0;
|
||||
int rest, mintotal = INT_MAX;
|
||||
|
||||
/* find smallest request */
|
||||
/* find smallest production */
|
||||
for (rec = recruits; rec != NULL; rec = rec->next) {
|
||||
int want = rec->total - rec->assigned;
|
||||
if (want > 0) {
|
||||
|
@ -310,7 +304,7 @@ static int do_recruiting(recruitment * recruits, int available)
|
|||
}
|
||||
rest = available - mintotal * n;
|
||||
|
||||
/* assign size of smallest request for everyone if possible; in the end roll dice to assign
|
||||
/* assign size of smallest production for everyone if possible; in the end roll dice to assign
|
||||
* small rest */
|
||||
for (rec = recruits; rec != NULL; rec = rec->next) {
|
||||
int want = rec->total - rec->assigned;
|
||||
|
@ -330,7 +324,7 @@ static int do_recruiting(recruitment * recruits, int available)
|
|||
|
||||
/* do actual recruiting */
|
||||
for (rec = recruits; rec != NULL; rec = rec->next) {
|
||||
request *req;
|
||||
econ_request *req;
|
||||
int get = rec->assigned;
|
||||
|
||||
for (req = rec->requests; req; req = req->next) {
|
||||
|
@ -379,7 +373,7 @@ void free_recruitments(recruitment * recruits)
|
|||
recruitment *rec = recruits;
|
||||
recruits = rec->next;
|
||||
while (rec->requests) {
|
||||
request *req = rec->requests;
|
||||
econ_request *req = rec->requests;
|
||||
rec->requests = req->next;
|
||||
free_order(req->ord);
|
||||
free(req);
|
||||
|
@ -389,7 +383,7 @@ void free_recruitments(recruitment * recruits)
|
|||
}
|
||||
|
||||
/* Rekrutierung */
|
||||
static void expandrecruit(region * r, request * recruitorders)
|
||||
static void expandrecruit(region * r, econ_request * recruitorders)
|
||||
{
|
||||
recruitment *recruits = NULL;
|
||||
|
||||
|
@ -430,11 +424,11 @@ static int recruit_cost(const faction * f, const race * rc)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void recruit(unit * u, struct order *ord, request ** recruitorders)
|
||||
static void recruit(unit * u, struct order *ord, econ_request ** recruitorders)
|
||||
{
|
||||
region *r = u->region;
|
||||
plane *pl;
|
||||
request *o;
|
||||
econ_request *o;
|
||||
int recruitcost = -1;
|
||||
const faction *f = u->faction;
|
||||
const struct race *rc = u_race(u);
|
||||
|
@ -555,7 +549,7 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
|
|||
return;
|
||||
}
|
||||
|
||||
o = (request *)calloc(1, sizeof(request));
|
||||
o = (econ_request *)calloc(1, sizeof(econ_request));
|
||||
o->qty = n;
|
||||
o->unit = u;
|
||||
o->ord = copy_order(ord);
|
||||
|
@ -751,7 +745,7 @@ void maintain_buildings(region * r)
|
|||
void economics(region * r)
|
||||
{
|
||||
unit *u;
|
||||
request *recruitorders = NULL;
|
||||
econ_request *recruitorders = NULL;
|
||||
|
||||
/* Geben vor Selbstmord (doquit)! Hier alle unmittelbaren Befehle.
|
||||
* Rekrutieren vor allen Einnahmequellen. Bewachen JA vor Steuern
|
||||
|
@ -1441,7 +1435,7 @@ const attrib_type at_luxuries = {
|
|||
"luxuries", NULL, free_luxuries, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
static void expandbuying(region * r, request * buyorders)
|
||||
static void expandbuying(region * r, econ_request * buyorders)
|
||||
{
|
||||
const resource_type *rsilver = get_resourcetype(R_SILVER);
|
||||
int max_products;
|
||||
|
@ -1554,12 +1548,12 @@ attrib_type at_trades = {
|
|||
NO_READ
|
||||
};
|
||||
|
||||
static void buy(unit * u, request ** buyorders, struct order *ord)
|
||||
static void buy(unit * u, econ_request ** buyorders, struct order *ord)
|
||||
{
|
||||
char token[128];
|
||||
region *r = u->region;
|
||||
int n, k;
|
||||
request *o;
|
||||
econ_request *o;
|
||||
attrib *a;
|
||||
const item_type *itype = NULL;
|
||||
const luxury_type *ltype = NULL;
|
||||
|
@ -1650,7 +1644,7 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
|
|||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "luxury_notsold", ""));
|
||||
return;
|
||||
}
|
||||
o = (request *)calloc(1, sizeof(request));
|
||||
o = (econ_request *)calloc(1, sizeof(econ_request));
|
||||
o->type.ltype = ltype; /* sollte immer gleich sein */
|
||||
|
||||
o->unit = u;
|
||||
|
@ -1659,18 +1653,18 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
static void add_income(unit * u, int type, int want, int qty)
|
||||
void add_income(unit * u, income_t type, int want, int qty)
|
||||
{
|
||||
if (want == INT_MAX)
|
||||
want = qty;
|
||||
ADDMSG(&u->faction->msgs, msg_message("income",
|
||||
"unit region mode wanted amount", u, u->region, type, want, qty));
|
||||
"unit region mode wanted amount", u, u->region, (int)type, want, qty));
|
||||
}
|
||||
|
||||
/* Steuers<72>tze in % bei Burggr<67><72>e */
|
||||
static int tax_per_size[7] = { 0, 6, 12, 18, 24, 30, 36 };
|
||||
|
||||
static void expandselling(region * r, request * sellorders, int limit)
|
||||
static void expandselling(region * r, econ_request * sellorders, int limit)
|
||||
{
|
||||
int money, price, max_products;
|
||||
unsigned int j;
|
||||
|
@ -1769,8 +1763,6 @@ static void expandselling(region * r, request * sellorders, int limit)
|
|||
price = ltype->price * multi;
|
||||
|
||||
if (money >= price) {
|
||||
int abgezogenhafen = 0;
|
||||
int abgezogensteuer = 0;
|
||||
unit *u = g_requests[j].unit;
|
||||
item *itm;
|
||||
attrib *a = a_find(u->attribs, &at_luxuries);
|
||||
|
@ -1785,7 +1777,7 @@ static void expandselling(region * r, request * sellorders, int limit)
|
|||
|
||||
if (hafenowner != NULL) {
|
||||
if (hafenowner->faction != u->faction) {
|
||||
abgezogenhafen = price / 10;
|
||||
int abgezogenhafen = price / 10;
|
||||
hafencollected += abgezogenhafen;
|
||||
price -= abgezogenhafen;
|
||||
money -= abgezogenhafen;
|
||||
|
@ -1793,7 +1785,7 @@ static void expandselling(region * r, request * sellorders, int limit)
|
|||
}
|
||||
if (maxb != NULL) {
|
||||
if (maxowner->faction != u->faction) {
|
||||
abgezogensteuer = price * tax_per_size[maxeffsize] / 100;
|
||||
int abgezogensteuer = price * tax_per_size[maxeffsize] / 100;
|
||||
taxcollected += abgezogensteuer;
|
||||
price -= abgezogensteuer;
|
||||
money -= abgezogensteuer;
|
||||
|
@ -1859,7 +1851,7 @@ static void expandselling(region * r, request * sellorders, int limit)
|
|||
}
|
||||
}
|
||||
|
||||
static bool sell(unit * u, request ** sellorders, struct order *ord)
|
||||
static bool sell(unit * u, econ_request ** sellorders, struct order *ord)
|
||||
{
|
||||
char token[128];
|
||||
bool unlimited = true;
|
||||
|
@ -1952,7 +1944,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|||
}
|
||||
else {
|
||||
attrib *a;
|
||||
request *o;
|
||||
econ_request *o;
|
||||
int k, available;
|
||||
|
||||
if (!r_demand(r, ltype)) {
|
||||
|
@ -1977,7 +1969,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|||
cmistake(u, ord, 264, MSG_COMMERCE);
|
||||
return false;
|
||||
}
|
||||
/* Hier wird request->type verwendet, weil die obere limit durch
|
||||
/* Hier wird production->type verwendet, weil die obere limit durch
|
||||
* das silber gegeben wird (region->money), welches f<EFBFBD>r alle
|
||||
* (!) produkte als summe gilt, als nicht wie bei der
|
||||
* produktion, wo f<EFBFBD>r jedes produkt einzeln eine obere limite
|
||||
|
@ -2000,7 +1992,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|||
assert(n >= 0);
|
||||
/* die Menge der verkauften G<>ter merken */
|
||||
a->data.i += n;
|
||||
o = (request *)calloc(1, sizeof(request));
|
||||
o = (econ_request *)calloc(1, sizeof(econ_request));
|
||||
o->unit = u;
|
||||
o->qty = n;
|
||||
o->type.ltype = ltype;
|
||||
|
@ -2010,48 +2002,6 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
static void expandstealing(region * r, request * stealorders)
|
||||
{
|
||||
const resource_type *rsilver = get_resourcetype(R_SILVER);
|
||||
unsigned int j;
|
||||
|
||||
assert(rsilver);
|
||||
|
||||
expandorders(r, stealorders);
|
||||
if (!norders) return;
|
||||
|
||||
/* F<>r jede unit in der Region wird Geld geklaut, wenn sie Opfer eines
|
||||
* Beklauen-Orders ist. Jedes Opfer mu<EFBFBD> einzeln behandelt werden.
|
||||
*
|
||||
* u ist die beklaute unit. oa.unit ist die klauende unit.
|
||||
*/
|
||||
|
||||
for (j = 0; j != norders && g_requests[j].unit->n <= g_requests[j].unit->wants; j++) {
|
||||
unit *u = findunitg(g_requests[j].no, r);
|
||||
int n = 0;
|
||||
if (u && u->region == r) {
|
||||
n = get_pooled(u, rsilver, GET_ALL, INT_MAX);
|
||||
}
|
||||
if (n > 10 && rplane(r) && (rplane(r)->flags & PFL_NOALLIANCES)) {
|
||||
/* In Questen nur reduziertes Klauen */
|
||||
n = 10;
|
||||
}
|
||||
if (n > 0) {
|
||||
n = MIN(n, g_requests[j].unit->wants);
|
||||
use_pooled(u, rsilver, GET_ALL, n);
|
||||
g_requests[j].unit->n = n;
|
||||
change_money(g_requests[j].unit, n);
|
||||
ADDMSG(&u->faction->msgs, msg_message("stealeffect", "unit region amount",
|
||||
u, u->region, n));
|
||||
}
|
||||
add_income(g_requests[j].unit, IC_STEAL, g_requests[j].unit->wants, g_requests[j].unit->n);
|
||||
fset(g_requests[j].unit, UFL_LONGACTION | UFL_NOTMOVING);
|
||||
}
|
||||
free(g_requests);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
static void plant(unit * u, int raw)
|
||||
{
|
||||
|
@ -2371,162 +2321,11 @@ static void research_cmd(unit * u, struct order *ord)
|
|||
}
|
||||
}
|
||||
|
||||
static int max_skill(region * r, faction * f, skill_t sk)
|
||||
{
|
||||
unit *u;
|
||||
int w = 0;
|
||||
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->faction == f) {
|
||||
int effsk = effskill(u, sk, 0);
|
||||
if (effsk > w) {
|
||||
w = effsk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
message * check_steal(const unit * u, struct order *ord) {
|
||||
plane *pl;
|
||||
|
||||
if (fval(u_race(u), RCF_NOSTEAL)) {
|
||||
return msg_feedback(u, ord, "race_nosteal", "race", u_race(u));
|
||||
}
|
||||
|
||||
if (fval(u->region->terrain, SEA_REGION) && u_race(u) != get_race(RC_AQUARIAN)) {
|
||||
return msg_feedback(u, ord, "error_onlandonly", "");
|
||||
}
|
||||
|
||||
pl = rplane(u->region);
|
||||
if (pl && fval(pl, PFL_NOATTACK)) {
|
||||
return msg_feedback(u, ord, "error270", "");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void steal_cmd(unit * u, struct order *ord, request ** stealorders)
|
||||
{
|
||||
const resource_type *rring = get_resourcetype(R_RING_OF_NIMBLEFINGER);
|
||||
int n, i, id, effsk;
|
||||
bool goblin = false;
|
||||
request *o;
|
||||
unit *u2 = NULL;
|
||||
region *r = u->region;
|
||||
faction *f = NULL;
|
||||
message * msg;
|
||||
keyword_t kwd;
|
||||
|
||||
kwd = init_order_depr(ord);
|
||||
assert(kwd == K_STEAL);
|
||||
|
||||
assert(skill_enabled(SK_PERCEPTION) && skill_enabled(SK_STEALTH));
|
||||
|
||||
msg = check_steal(u, ord);
|
||||
if (msg) {
|
||||
ADDMSG(&u->faction->msgs, msg);
|
||||
return;
|
||||
}
|
||||
id = read_unitid(u->faction, r);
|
||||
if (id > 0) {
|
||||
u2 = findunitr(r, id);
|
||||
}
|
||||
if (u2 && u2->region == u->region) {
|
||||
f = u2->faction;
|
||||
}
|
||||
else {
|
||||
/* TODO: is this really necessary? it's the only time we use faction.c/deadhash
|
||||
* it allows stealing from a unit in a dead faction, but why? */
|
||||
f = dfindhash(id);
|
||||
}
|
||||
|
||||
for (u2 = r->units; u2; u2 = u2->next) {
|
||||
if (u2->faction == f && cansee(u->faction, r, u2, 0))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!u2) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found",
|
||||
""));
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsImmune(u2->faction)) {
|
||||
ADDMSG(&u->faction->msgs,
|
||||
msg_feedback(u, ord, "newbie_immunity_error", "turns", NewbieImmunity()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->faction->alliance && u->faction->alliance == u2->faction->alliance) {
|
||||
cmistake(u, ord, 47, MSG_INCOME);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(u->region == u2->region);
|
||||
if (!can_contact(r, u, u2)) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error60", ""));
|
||||
return;
|
||||
}
|
||||
|
||||
effsk = effskill(u, SK_STEALTH, 0);
|
||||
n = effsk - max_skill(r, f, SK_PERCEPTION);
|
||||
|
||||
if (n <= 0) {
|
||||
/* Wahrnehmung == Tarnung */
|
||||
if (u_race(u) != get_race(RC_GOBLIN) || effsk <= 3) {
|
||||
ADDMSG(&u->faction->msgs, msg_message("stealfail", "unit target", u, u2));
|
||||
if (n == 0) {
|
||||
ADDMSG(&u2->faction->msgs, msg_message("stealdetect", "unit", u2));
|
||||
}
|
||||
else {
|
||||
ADDMSG(&u2->faction->msgs, msg_message("thiefdiscover", "unit target",
|
||||
u, u2));
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
ADDMSG(&u->faction->msgs, msg_message("stealfatal", "unit target", u,
|
||||
u2));
|
||||
ADDMSG(&u2->faction->msgs, msg_message("thiefdiscover", "unit target", u,
|
||||
u2));
|
||||
n = 1;
|
||||
goblin = true;
|
||||
}
|
||||
}
|
||||
|
||||
i = MIN(u->number, i_get(u->items, rring->itype));
|
||||
if (i > 0) {
|
||||
n *= STEALINCOME * (u->number + i * (roqf_factor() - 1));
|
||||
}
|
||||
else {
|
||||
n *= u->number * STEALINCOME;
|
||||
}
|
||||
|
||||
u->wants = n;
|
||||
|
||||
/* wer dank unsichtbarkeitsringen klauen kann, muss nicht unbedingt ein
|
||||
* guter dieb sein, schliesslich macht man immer noch sehr viel laerm */
|
||||
|
||||
o = (request *)calloc(1, sizeof(request));
|
||||
o->unit = u;
|
||||
o->qty = 1; /* Betrag steht in u->wants */
|
||||
o->no = u2->no;
|
||||
o->type.goblin = goblin; /* Merken, wenn Goblin-Spezialklau */
|
||||
addlist(stealorders, o);
|
||||
|
||||
/* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */
|
||||
|
||||
produceexp(u, SK_STEALTH, MIN(n, u->number));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
static void expandentertainment(region * r)
|
||||
{
|
||||
unit *u;
|
||||
int m = entertainmoney(r);
|
||||
request *o;
|
||||
econ_request *o;
|
||||
|
||||
for (o = &entertainers[0]; o != nextentertainer; ++o) {
|
||||
double part = m / (double)entertaining;
|
||||
|
@ -2551,7 +2350,7 @@ void entertain_cmd(unit * u, struct order *ord)
|
|||
{
|
||||
region *r = u->region;
|
||||
int max_e;
|
||||
request *o;
|
||||
econ_request *o;
|
||||
static int entertainbase = 0;
|
||||
static int entertainperlevel = 0;
|
||||
keyword_t kwd;
|
||||
|
@ -2604,7 +2403,7 @@ void entertain_cmd(unit * u, struct order *ord)
|
|||
* \return number of working spaces taken by players
|
||||
*/
|
||||
static void
|
||||
expandwork(region * r, request * work_begin, request * work_end, int maxwork)
|
||||
expandwork(region * r, econ_request * work_begin, econ_request * work_end, int maxwork)
|
||||
{
|
||||
int earnings;
|
||||
/* n: verbleibende Einnahmen */
|
||||
|
@ -2612,7 +2411,7 @@ expandwork(region * r, request * work_begin, request * work_end, int maxwork)
|
|||
int jobs = maxwork;
|
||||
int p_wage = wage(r, NULL, NULL, turn);
|
||||
int money = rmoney(r);
|
||||
request *o;
|
||||
econ_request *o;
|
||||
|
||||
for (o = work_begin; o != work_end; ++o) {
|
||||
unit *u = o->unit;
|
||||
|
@ -2655,7 +2454,7 @@ expandwork(region * r, request * work_begin, request * work_end, int maxwork)
|
|||
rsetmoney(r, money + earnings);
|
||||
}
|
||||
|
||||
static int do_work(unit * u, order * ord, request * o)
|
||||
static int do_work(unit * u, order * ord, econ_request * o)
|
||||
{
|
||||
if (playerrace(u_race(u))) {
|
||||
region *r = u->region;
|
||||
|
@ -2690,7 +2489,7 @@ static int do_work(unit * u, order * ord, request * o)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void expandloot(region * r, request * lootorders)
|
||||
static void expandloot(region * r, econ_request * lootorders)
|
||||
{
|
||||
unit *u;
|
||||
unsigned int i;
|
||||
|
@ -2727,7 +2526,7 @@ static void expandloot(region * r, request * lootorders)
|
|||
}
|
||||
}
|
||||
|
||||
void expandtax(region * r, request * taxorders)
|
||||
void expandtax(region * r, econ_request * taxorders)
|
||||
{
|
||||
unit *u;
|
||||
unsigned int i;
|
||||
|
@ -2751,13 +2550,13 @@ void expandtax(region * r, request * taxorders)
|
|||
}
|
||||
}
|
||||
|
||||
void tax_cmd(unit * u, struct order *ord, request ** taxorders)
|
||||
void tax_cmd(unit * u, struct order *ord, econ_request ** taxorders)
|
||||
{
|
||||
/* Steuern werden noch vor der Forschung eingetrieben */
|
||||
region *r = u->region;
|
||||
unit *u2;
|
||||
int n;
|
||||
request *o;
|
||||
econ_request *o;
|
||||
int max;
|
||||
keyword_t kwd;
|
||||
static int taxperlevel = 0;
|
||||
|
@ -2819,20 +2618,20 @@ void tax_cmd(unit * u, struct order *ord, request ** taxorders)
|
|||
* fraktionen werden dann bei eintreiben unter allen eintreibenden
|
||||
* einheiten aufgeteilt. */
|
||||
|
||||
o = (request *)calloc(1, sizeof(request));
|
||||
o = (econ_request *)calloc(1, sizeof(econ_request));
|
||||
o->qty = u->wants / TAXFRACTION;
|
||||
o->unit = u;
|
||||
addlist(taxorders, o);
|
||||
return;
|
||||
}
|
||||
|
||||
void loot_cmd(unit * u, struct order *ord, request ** lootorders)
|
||||
void loot_cmd(unit * u, struct order *ord, econ_request ** lootorders)
|
||||
{
|
||||
region *r = u->region;
|
||||
unit *u2;
|
||||
int n;
|
||||
int max;
|
||||
request *o;
|
||||
econ_request *o;
|
||||
keyword_t kwd;
|
||||
|
||||
kwd = init_order_depr(ord);
|
||||
|
@ -2884,7 +2683,7 @@ void loot_cmd(unit * u, struct order *ord, request ** lootorders)
|
|||
u->wants = MIN(n * skbonus * 10, max);
|
||||
}
|
||||
|
||||
o = (request *)calloc(1, sizeof(request));
|
||||
o = (econ_request *)calloc(1, sizeof(econ_request));
|
||||
o->qty = u->wants / TAXFRACTION;
|
||||
o->unit = u;
|
||||
addlist(lootorders, o);
|
||||
|
@ -2895,8 +2694,8 @@ void loot_cmd(unit * u, struct order *ord, request ** lootorders)
|
|||
#define MAX_WORKERS 2048
|
||||
void auto_work(region * r)
|
||||
{
|
||||
request workers[MAX_WORKERS];
|
||||
request *nextworker = workers;
|
||||
econ_request workers[MAX_WORKERS];
|
||||
econ_request *nextworker = workers;
|
||||
unit *u;
|
||||
|
||||
for (u = r->units; u; u = u->next) {
|
||||
|
@ -2964,11 +2763,11 @@ static bool rule_autowork(void) {
|
|||
|
||||
void produce(struct region *r)
|
||||
{
|
||||
request workers[MAX_WORKERS];
|
||||
request *taxorders, *lootorders, *sellorders, *stealorders, *buyorders;
|
||||
econ_request workers[MAX_WORKERS];
|
||||
econ_request *taxorders, *lootorders, *sellorders, *stealorders, *buyorders;
|
||||
unit *u;
|
||||
bool limited = true;
|
||||
request *nextworker = workers;
|
||||
econ_request *nextworker = workers;
|
||||
static int bt_cache;
|
||||
static const struct building_type *caravan_bt;
|
||||
static int rc_cache;
|
||||
|
|
|
@ -45,7 +45,18 @@ extern "C" {
|
|||
struct faction;
|
||||
struct order;
|
||||
struct message;
|
||||
struct request;
|
||||
|
||||
typedef struct econ_request {
|
||||
struct econ_request *next;
|
||||
struct unit *unit;
|
||||
struct order *ord;
|
||||
int qty;
|
||||
int no;
|
||||
union {
|
||||
bool goblin; /* stealing */
|
||||
const struct luxury_type *ltype; /* trading */
|
||||
} type;
|
||||
} econ_request;
|
||||
|
||||
int income(const struct unit *u);
|
||||
int entertainmoney(const struct region *r);
|
||||
|
@ -54,17 +65,26 @@ extern "C" {
|
|||
void produce(struct region *r);
|
||||
void auto_work(struct region *r);
|
||||
|
||||
enum { IC_WORK, IC_ENTERTAIN, IC_TAX, IC_TRADE, IC_TRADETAX, IC_STEAL, IC_MAGIC, IC_LOOT };
|
||||
unsigned int expand_production(struct region * r, struct econ_request * requests, struct econ_request **results);
|
||||
|
||||
typedef enum income_t { IC_WORK, IC_ENTERTAIN, IC_TAX, IC_TRADE, IC_TRADETAX, IC_STEAL, IC_MAGIC, IC_LOOT } income_t;
|
||||
void add_income(struct unit * u, income_t type, int want, int qty);
|
||||
|
||||
void maintain_buildings(struct region *r);
|
||||
void make_item(struct unit * u, const struct item_type * itype, int want);
|
||||
int make_cmd(struct unit *u, struct order *ord);
|
||||
void split_allocations(struct region *r);
|
||||
int give_control_cmd(struct unit *u, struct order *ord);
|
||||
void give_control(struct unit * u, struct unit * u2);
|
||||
void tax_cmd(struct unit * u, struct order *ord, struct request ** taxorders);
|
||||
void expandtax(struct region * r, struct request * taxorders);
|
||||
|
||||
void tax_cmd(struct unit * u, struct order *ord, struct econ_request ** taxorders);
|
||||
void expandtax(struct region * r, struct econ_request * taxorders);
|
||||
|
||||
struct message * steal_message(const struct unit * u, struct order *ord);
|
||||
void steal_cmd(struct unit * u, struct order *ord, struct econ_request ** stealorders);
|
||||
void expandstealing(struct region * r, struct econ_request * stealorders);
|
||||
|
||||
void add_recruits(struct unit * u, int number, int wanted);
|
||||
struct message * check_steal(const struct unit * u, struct order *ord);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ static void test_steal_okay(CuTest * tc) {
|
|||
rc = test_create_race("human");
|
||||
rc->flags = 0;
|
||||
setup_steal(&env, ter, rc);
|
||||
CuAssertPtrEquals(tc, 0, check_steal(env.u, 0));
|
||||
CuAssertPtrEquals(tc, 0, steal_message(env.u, 0));
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ static void test_steal_nosteal(CuTest * tc) {
|
|||
rc = test_create_race("human");
|
||||
rc->flags = RCF_NOSTEAL;
|
||||
setup_steal(&env, ter, rc);
|
||||
CuAssertPtrNotNull(tc, msg = check_steal(env.u, 0));
|
||||
CuAssertPtrNotNull(tc, msg = steal_message(env.u, 0));
|
||||
msg_release(msg);
|
||||
test_cleanup();
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ static void test_steal_ocean(CuTest * tc) {
|
|||
ter = test_create_terrain("ocean", SEA_REGION);
|
||||
rc = test_create_race("human");
|
||||
setup_steal(&env, ter, rc);
|
||||
CuAssertPtrNotNull(tc, msg = check_steal(env.u, 0));
|
||||
CuAssertPtrNotNull(tc, msg = steal_message(env.u, 0));
|
||||
msg_release(msg);
|
||||
test_cleanup();
|
||||
}
|
||||
|
@ -300,26 +300,13 @@ static void test_buy_cmd(CuTest *tc) {
|
|||
test_cleanup();
|
||||
}
|
||||
|
||||
typedef struct request {
|
||||
struct request *next;
|
||||
struct unit *unit;
|
||||
struct order *ord;
|
||||
int qty;
|
||||
int no;
|
||||
union {
|
||||
bool goblin; /* stealing */
|
||||
const struct luxury_type *ltype; /* trading */
|
||||
} type;
|
||||
} request;
|
||||
|
||||
static void test_tax_cmd(CuTest *tc) {
|
||||
order *ord;
|
||||
faction *f;
|
||||
region *r;
|
||||
unit *u;
|
||||
item_type *sword, *silver;
|
||||
request *taxorders = 0;
|
||||
|
||||
econ_request *taxorders = 0;
|
||||
|
||||
test_setup();
|
||||
init_resources();
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
#include <kernel/config.h>
|
||||
#include <util/log.h>
|
||||
|
||||
#if MUSEUM_MODULE
|
||||
#include <modules/museum.h>
|
||||
#endif
|
||||
#include <triggers/triggers.h>
|
||||
#include <util/language.h>
|
||||
#include <util/functions.h>
|
||||
|
@ -41,6 +39,7 @@
|
|||
|
||||
void game_done(void)
|
||||
{
|
||||
#undef CLEANUP_CODE
|
||||
#ifdef CLEANUP_CODE
|
||||
/* Diese Routine enfernt allen allokierten Speicher wieder. Das ist nur
|
||||
* zum Debugging interessant, wenn man Leak Detection hat, und nach
|
||||
|
@ -78,16 +77,12 @@ void game_init(void)
|
|||
register_names();
|
||||
register_resources();
|
||||
register_itemfunctions();
|
||||
#if MUSEUM_MODULE
|
||||
register_museum();
|
||||
#endif
|
||||
wormholes_register();
|
||||
|
||||
register_weapons();
|
||||
register_xerewards();
|
||||
#ifdef USE_LIBXML2
|
||||
register_xmlreader();
|
||||
#endif
|
||||
register_attributes();
|
||||
register_gmcmd();
|
||||
|
||||
|
|
|
@ -239,12 +239,6 @@ struct order *ord)
|
|||
change_reservation(dest, item2resource(itype), r);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#if MUSEUM_MODULE && defined(TODO)
|
||||
/* TODO: use a trigger for the museum warden! */
|
||||
if (a_find(dest->attribs, &at_warden)) {
|
||||
warden_add_give(src, dest, itype, delta);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -24,9 +24,7 @@
|
|||
|
||||
#include <modules/xmas.h>
|
||||
#include <modules/gmcmd.h>
|
||||
#if MUSEUM_MODULE
|
||||
#include <modules/museum.h>
|
||||
#endif
|
||||
#include <modules/autoseed.h>
|
||||
|
||||
#include <kernel/building.h>
|
||||
|
|
|
@ -304,11 +304,24 @@ struct trigger_type tt_caldera = {
|
|||
caldera_read
|
||||
};
|
||||
|
||||
|
||||
static int building_action_read(struct attrib *a, void *owner, gamedata *data)
|
||||
{
|
||||
struct storage *store = data->store;
|
||||
|
||||
if (data->version < ATTRIBOWNER_VERSION) {
|
||||
READ_INT(data->store, NULL);
|
||||
}
|
||||
READ_TOK(store, NULL, 0);
|
||||
READ_TOK(store, NULL, 0);
|
||||
return AT_READ_DEPR;
|
||||
}
|
||||
|
||||
void register_tolua_helpers(void)
|
||||
{
|
||||
tt_register(&tt_caldera);
|
||||
at_register(&at_direction);
|
||||
at_register(&at_building_action);
|
||||
at_deprecate("lcbuilding", building_action_read);
|
||||
|
||||
callbacks.cast_spell = lua_callspell;
|
||||
callbacks.use_item = use_item_lua;
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
#include <platform.h>
|
||||
#include <CuTest.h>
|
||||
#include <stream.h>
|
||||
#include <memstream.h>
|
||||
|
||||
#include <kernel/region.h>
|
||||
#include <kernel/terrain.h>
|
||||
|
||||
#include "json.h"
|
||||
#include "tests.h"
|
||||
|
||||
#include <kernel/region.h>
|
||||
#include <kernel/terrain.h>
|
||||
|
||||
#include <stream.h>
|
||||
#include <memstream.h>
|
||||
|
||||
#include <cJSON.h>
|
||||
#include <CuTest.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
static char *strip(char *str) {
|
||||
char *s = str, *b = str, *e = str;
|
||||
/* b is where text begins, e where it ends, s where we insert it. */
|
||||
|
|
|
@ -422,7 +422,7 @@ const char *alliancename(const alliance * al)
|
|||
char *ibuf = idbuf[(++nextbuf) % 8];
|
||||
|
||||
if (al && al->name) {
|
||||
slprintf(ibuf, sizeof(name), "%s (%s)", al->name, itoa36(al->id));
|
||||
slprintf(ibuf, sizeof(idbuf[0]), "%s (%s)", al->name, itoa36(al->id));
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
|
@ -430,46 +430,6 @@ const char *alliancename(const alliance * al)
|
|||
return ibuf;
|
||||
}
|
||||
|
||||
void alliancevictory(void)
|
||||
{
|
||||
const struct building_type *btype = bt_find("stronghold");
|
||||
region *r = regions;
|
||||
alliance *al = alliances;
|
||||
if (btype == NULL)
|
||||
return;
|
||||
while (r != NULL) {
|
||||
building *b = r->buildings;
|
||||
while (b != NULL) {
|
||||
if (b->type == btype) {
|
||||
unit *u = building_owner(b);
|
||||
if (u) {
|
||||
fset(u->faction->alliance, FFL_MARK);
|
||||
}
|
||||
}
|
||||
b = b->next;
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
while (al != NULL) {
|
||||
if (!fval(al, FFL_MARK)) {
|
||||
faction **fp;
|
||||
for (fp = &factions; *fp; ) {
|
||||
faction *f = *fp;
|
||||
if (f->alliance == al) {
|
||||
ADDMSG(&f->msgs, msg_message("alliance::lost", "alliance", al));
|
||||
destroyfaction(fp);
|
||||
} else {
|
||||
fp = &f->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
freset(al, FFL_MARK);
|
||||
}
|
||||
al = al->next;
|
||||
}
|
||||
}
|
||||
|
||||
void alliance_setname(alliance * self, const char *name)
|
||||
{
|
||||
free(self->name);
|
||||
|
|
|
@ -499,7 +499,7 @@ const char *buildingname(const building * b)
|
|||
static name idbuf[8];
|
||||
static int nextbuf = 0;
|
||||
char *ibuf = idbuf[(++nextbuf) % 8];
|
||||
return write_buildingname(b, ibuf, sizeof(name));
|
||||
return write_buildingname(b, ibuf, sizeof(idbuf[0]));
|
||||
}
|
||||
|
||||
void building_set_owner(struct unit * owner)
|
||||
|
@ -774,22 +774,11 @@ int cmp_wage(const struct building *b, const building * a)
|
|||
return -1;
|
||||
}
|
||||
|
||||
bool is_owner_building(const struct building * b)
|
||||
{
|
||||
region *r = b->region;
|
||||
if (b->type->taxes && r->land && r->land->ownership) {
|
||||
unit *u = building_owner(b);
|
||||
return u && u->faction == r->land->ownership->owner;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int building_taxes(const building *b) {
|
||||
assert(b);
|
||||
return b->type->taxes;
|
||||
}
|
||||
|
||||
|
||||
int cmp_taxes(const building * b, const building * a)
|
||||
{
|
||||
faction *f = region_get_owner(b->region);
|
||||
|
|
|
@ -71,7 +71,6 @@ extern "C" {
|
|||
} building_type;
|
||||
|
||||
extern struct selist *buildingtypes;
|
||||
extern struct attrib_type at_building_action;
|
||||
extern struct attrib_type at_building_generic_type;
|
||||
|
||||
int cmp_castle_size(const struct building *b, const struct building *a);
|
||||
|
|
|
@ -73,11 +73,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "guard.h"
|
||||
#include "prefix.h"
|
||||
|
||||
#ifdef USE_LIBXML2
|
||||
/* libxml includes */
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/xpath.h>
|
||||
#endif
|
||||
|
||||
/* external libraries */
|
||||
#include <iniparser.h>
|
||||
|
@ -260,15 +258,6 @@ param_t getparam(const struct locale * lang)
|
|||
return s ? findparam(s, lang) : NOPARAM;
|
||||
}
|
||||
|
||||
unit *getnewunit(const region * r, const faction * f)
|
||||
{
|
||||
int n;
|
||||
n = getid();
|
||||
|
||||
return findnewunit(r, f, n);
|
||||
}
|
||||
|
||||
|
||||
/* -- Erschaffung neuer Einheiten ------------------------------ */
|
||||
|
||||
static const char *forbidden[] = { "t", "te", "tem", "temp", NULL };
|
||||
|
@ -611,9 +600,7 @@ void kernel_done(void)
|
|||
/* calling this function releases memory assigned to static variables, etc.
|
||||
* calling it is optional, e.g. a release server will most likely not do it.
|
||||
*/
|
||||
#ifdef USE_LIBXML2
|
||||
xml_done();
|
||||
#endif
|
||||
attrib_done();
|
||||
item_done();
|
||||
message_done();
|
||||
|
|
|
@ -41,10 +41,10 @@ int db_driver_order_save(struct order_data *od)
|
|||
|
||||
assert(od && od->_str);
|
||||
key.data = &recno;
|
||||
key.size = sizeof(recno);
|
||||
key.size = key.ulen = sizeof(recno);
|
||||
key.flags = DB_DBT_USERMEM;
|
||||
data.data = (void *)od->_str;
|
||||
data.size = strlen(od->_str) + 1;
|
||||
data.size = data.ulen = strlen(od->_str) + 1;
|
||||
data.flags = DB_DBT_USERMEM;
|
||||
ret = g_dbp->put(g_dbp, NULL, &key, &data, DB_APPEND);
|
||||
assert(ret == 0);
|
||||
|
@ -63,7 +63,7 @@ struct order_data *db_driver_order_load(int id)
|
|||
memset(&data, 0, sizeof(DBT));
|
||||
recno = (db_recno_t)id;
|
||||
key.data = &recno;
|
||||
key.size = sizeof(recno);
|
||||
key.size = key.ulen = sizeof(recno);
|
||||
key.flags = DB_DBT_USERMEM;
|
||||
ret = g_dbp->get(g_dbp, NULL, &key, &data, 0);
|
||||
if (ret == 0) {
|
||||
|
|
|
@ -195,7 +195,7 @@ const char *factionname(const faction * f)
|
|||
char *ibuf = idbuf[(++nextbuf) % 8];
|
||||
|
||||
if (f && f->name) {
|
||||
slprintf(ibuf, sizeof(name), "%s (%s)", f->name, itoa36(f->no));
|
||||
slprintf(ibuf, sizeof(idbuf[0]), "%s (%s)", f->name, itoa36(f->no));
|
||||
}
|
||||
else {
|
||||
strcpy(ibuf, "Unbekannte Partei (?)");
|
||||
|
|
|
@ -84,9 +84,6 @@ extern "C" {
|
|||
score_t score;
|
||||
struct alliance *alliance;
|
||||
int alliance_joindate; /* the turn on which the faction joined its current alliance (or left the last one) */
|
||||
#ifdef VICTORY_DELAY
|
||||
unsigned char victory_delay;
|
||||
#endif
|
||||
struct unit *units;
|
||||
struct attrib *attribs;
|
||||
struct message_list *msgs;
|
||||
|
|
|
@ -596,7 +596,7 @@ const resource_type *get_resourcetype(resource_t type) {
|
|||
static struct resource_type * rtypes[MAX_RESOURCES];
|
||||
const resource_type *rtype = NULL;
|
||||
if (update != num_resources) {
|
||||
memset(rtypes, 0, sizeof(rtypes));
|
||||
memset(rtypes, 0, sizeof(resource_type *) * MAX_RESOURCES);
|
||||
update = num_resources;
|
||||
}
|
||||
else {
|
||||
|
@ -631,27 +631,6 @@ int set_item(unit * u, const item_type *itype, int value)
|
|||
return value;
|
||||
}
|
||||
|
||||
/* t_item::flags */
|
||||
#define FL_ITEM_CURSED (1<<0)
|
||||
#define FL_ITEM_NOTLOST (1<<1)
|
||||
#define FL_ITEM_NOTINBAG (1<<2) /* nicht im Bag Of Holding */
|
||||
#define FL_ITEM_ANIMAL (1<<3) /* ist ein Tier */
|
||||
#define FL_ITEM_MOUNT ((1<<4) | FL_ITEM_ANIMAL) /* ist ein Reittier */
|
||||
|
||||
typedef struct t_item {
|
||||
const char *name;
|
||||
/* [0]: Einzahl fuer eigene; [1]: Mehrzahl fuer eigene;
|
||||
* [2]: Einzahl fuer Fremde; [3]: Mehrzahl fuer Fremde */
|
||||
bool is_resource;
|
||||
skill_t skill;
|
||||
int minskill;
|
||||
int gewicht;
|
||||
int preis;
|
||||
unsigned int flags;
|
||||
void(*benutze_funktion) (struct region *, struct unit *, int amount,
|
||||
struct order *);
|
||||
} t_item;
|
||||
|
||||
#include "move.h"
|
||||
|
||||
static int
|
||||
|
@ -746,11 +725,13 @@ void init_resources(void)
|
|||
int get_money(const unit * u)
|
||||
{
|
||||
const struct resource_type *rtype = get_resourcetype(R_SILVER);
|
||||
const item *i = u->items;
|
||||
while (i && i->type->rtype != rtype) {
|
||||
i = i->next;
|
||||
const item *i;
|
||||
for (i = u->items; i; i = i->next) {
|
||||
if (i->type->rtype == rtype) {
|
||||
return i->number;
|
||||
}
|
||||
return i ? i->number : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_money(unit * u, int v)
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include <util/language.h>
|
||||
#include <util/log.h>
|
||||
#include <util/parser.h>
|
||||
#include <util/strings.h>
|
||||
|
||||
#include <stream.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <assert.h>
|
||||
|
@ -135,6 +138,49 @@ char* get_command(const order *ord, const struct locale *lang, char *sbuffer, si
|
|||
return sbuffer;
|
||||
}
|
||||
|
||||
int stream_order(struct stream *out, const struct order *ord, const struct locale *lang, bool escape)
|
||||
{
|
||||
const char *str, *text;
|
||||
order_data *od = NULL;
|
||||
keyword_t kwd = ORD_KEYWORD(ord);
|
||||
|
||||
if (ord->command & CMD_QUIET) {
|
||||
swrite("!", 1, 1, out);
|
||||
}
|
||||
if (ord->command & CMD_PERSIST) {
|
||||
swrite("@", 1, 1, out);
|
||||
}
|
||||
|
||||
if (ord->id < 0) {
|
||||
skill_t sk = (skill_t)(100 + ord->id);
|
||||
assert(kwd == K_STUDY && sk != SK_MAGIC && sk < MAXSKILLS);
|
||||
text = skillname(sk, lang);
|
||||
}
|
||||
else {
|
||||
od = odata_load(ord->id);
|
||||
text = OD_STRING(od);
|
||||
}
|
||||
if (kwd != NOKEYWORD) {
|
||||
str = (const char *)LOC(lang, keyword(kwd));
|
||||
assert(str);
|
||||
swrite(str, 1, strlen(str), out);
|
||||
}
|
||||
|
||||
if (text) {
|
||||
char obuf[1024];
|
||||
swrite(" ", 1, 1, out);
|
||||
if (escape) {
|
||||
text = escape_string(text, obuf, sizeof(obuf));
|
||||
}
|
||||
swrite(text, 1, strlen(text), out);
|
||||
}
|
||||
if (od) {
|
||||
odata_release(od);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free_order(order * ord)
|
||||
{
|
||||
if (ord != NULL) {
|
||||
|
|
|
@ -22,6 +22,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct locale;
|
||||
struct stream;
|
||||
|
||||
/* Encapsulation of an order
|
||||
*
|
||||
|
@ -69,6 +70,7 @@ extern "C" {
|
|||
|
||||
char *write_order(const order * ord, const struct locale *lang,
|
||||
char *buffer, size_t size);
|
||||
int stream_order(struct stream *out, const struct order *ord, const struct locale *lang, bool escape);
|
||||
keyword_t init_order_depr(const struct order *ord);
|
||||
keyword_t init_order(const struct order *ord, const struct locale *lang);
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ int change_reservation(unit * u, const item_type * itype, int value)
|
|||
res->type = itype;
|
||||
res->value = value;
|
||||
}
|
||||
else if (res && res->value + value <= 0) {
|
||||
else if (res->value + value <= 0) {
|
||||
*rp = res->next;
|
||||
free(res);
|
||||
return 0;
|
||||
|
@ -139,7 +139,7 @@ int set_resvalue(unit * u, const item_type * itype, int value)
|
|||
res->type = itype;
|
||||
res->value = value;
|
||||
}
|
||||
else if (res && value <= 0) {
|
||||
else if (value <= 0) {
|
||||
*rp = res->next;
|
||||
free(res);
|
||||
return 0;
|
||||
|
|
|
@ -139,7 +139,7 @@ const char *regionname(const region * r, const faction * f)
|
|||
|
||||
int region_maxworkers(const region *r)
|
||||
{
|
||||
int size = production(r);
|
||||
int size = max_production(r);
|
||||
int treespace = (rtrees(r, 2) + rtrees(r, 1) / 2) * TREESIZE;
|
||||
return MAX(size - treespace, MIN(size / 10, 200));
|
||||
}
|
||||
|
@ -1244,7 +1244,7 @@ void terraform_region(region * r, const terrain_type * terrain)
|
|||
* egal ob durch den spell oder anderes angelegt.
|
||||
**/
|
||||
#include "curse.h"
|
||||
int production(const region * r)
|
||||
int max_production(const region * r)
|
||||
{
|
||||
/* muß rterrain(r) sein, nicht rterrain() wegen rekursion */
|
||||
int p = r->terrain->size;
|
||||
|
|
|
@ -240,7 +240,7 @@ extern "C" {
|
|||
extern const int delta_x[MAXDIRECTIONS];
|
||||
extern const int delta_y[MAXDIRECTIONS];
|
||||
direction_t dir_invert(direction_t dir);
|
||||
int production(const struct region *r);
|
||||
int max_production(const struct region *r);
|
||||
|
||||
void region_set_owner(struct region *r, struct faction *owner, int turn);
|
||||
struct faction *region_get_owner(const struct region *r);
|
||||
|
|
|
@ -124,30 +124,6 @@ static void terraform_default(struct rawmaterial *res, const region * r)
|
|||
UNUSED_ARG(r);
|
||||
}
|
||||
|
||||
#ifdef RANDOM_CHANGE
|
||||
static void resource_random_change(int *pvalue, bool used)
|
||||
{
|
||||
int split = 5;
|
||||
int rnd = rng_int() % 100;
|
||||
|
||||
if (pvalue == 0 || rnd % 10 >= 10)
|
||||
return;
|
||||
if (used)
|
||||
split = 4;
|
||||
/* if a resource was mined this round, there is a 6% probability
|
||||
* of a decline and a 4% probability of a raise. */
|
||||
/* if it wasn't mined this round, there is an equal probability
|
||||
* of 5% for a decline or a raise. */
|
||||
if (rnd < split) {
|
||||
(*pvalue)++;
|
||||
} else {
|
||||
(*pvalue)--;
|
||||
}
|
||||
if ((*pvalue) < 0)
|
||||
(*pvalue) = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int visible_default(const rawmaterial * res, int skilllevel)
|
||||
/* resources are visible, if skill equals minimum skill to mine them
|
||||
* plus current level of difficulty */
|
||||
|
|
|
@ -102,71 +102,6 @@ int firstx = 0, firsty = 0;
|
|||
/* TODO: is this still important? */
|
||||
int enc_gamedata = ENCODING_UTF8;
|
||||
|
||||
/* local symbols */
|
||||
static region *current_region;
|
||||
|
||||
char *rns(FILE * f, char *c, size_t size)
|
||||
{
|
||||
char *s = c;
|
||||
do {
|
||||
*s = (char)getc(f);
|
||||
} while (*s != '"');
|
||||
|
||||
for (;;) {
|
||||
*s = (char)getc(f);
|
||||
if (*s == '"')
|
||||
break;
|
||||
if (s < c + size)
|
||||
++s;
|
||||
}
|
||||
*s = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
/* #define INNER_WORLD */
|
||||
/* fürs debuggen nur den inneren Teil der Welt laden */
|
||||
/* -9;-27;-1;-19;Sumpfloch */
|
||||
int inner_world(region * r)
|
||||
{
|
||||
static int xy[2] = { 18, -45 };
|
||||
static int size[2] = { 27, 27 };
|
||||
|
||||
if (r->x >= xy[0] && r->x < xy[0] + size[0] && r->y >= xy[1]
|
||||
&& r->y < xy[1] + size[1])
|
||||
return 2;
|
||||
if (r->x >= xy[0] - 9 && r->x < xy[0] + size[0] + 9 && r->y >= xy[1] - 9
|
||||
&& r->y < xy[1] + size[1] + 9)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int maxregions = -1;
|
||||
int loadplane = 0;
|
||||
|
||||
enum {
|
||||
U_MAN,
|
||||
U_UNDEAD,
|
||||
U_ILLUSION,
|
||||
U_FIREDRAGON,
|
||||
U_DRAGON,
|
||||
U_WYRM,
|
||||
U_SPELL,
|
||||
U_TAVERNE,
|
||||
U_MONSTER,
|
||||
U_BIRTHDAYDRAGON,
|
||||
U_TREEMAN,
|
||||
MAXTYPES
|
||||
};
|
||||
|
||||
race_t typus2race(unsigned char typus)
|
||||
{
|
||||
if (typus > 0 && typus <= 11)
|
||||
return (race_t)(typus - 1);
|
||||
return NORACE;
|
||||
}
|
||||
|
||||
static void read_alliances(gamedata *data)
|
||||
{
|
||||
storage *store = data->store;
|
||||
|
@ -366,7 +301,7 @@ int current_turn(void)
|
|||
perror(zText);
|
||||
}
|
||||
else {
|
||||
int c = fscanf(F, "%d\n", &cturn);
|
||||
int c = fscanf(F, "%4d\n", &cturn);
|
||||
fclose(F);
|
||||
if (c != 1) {
|
||||
return -1;
|
||||
|
@ -676,7 +611,6 @@ static region *readregion(gamedata *data, int x, int y)
|
|||
}
|
||||
else {
|
||||
assert(uid == 0 || r->uid == uid);
|
||||
current_region = r;
|
||||
while (r->attribs)
|
||||
a_remove(&r->attribs, r->attribs);
|
||||
if (r->land) {
|
||||
|
@ -1440,7 +1374,6 @@ int read_game(gamedata *data)
|
|||
building **bp;
|
||||
ship **shp;
|
||||
unit *u;
|
||||
int rmax = maxregions;
|
||||
storage * store = data->store;
|
||||
const struct building_type *bt_lighthouse = bt_find("lighthouse");
|
||||
const struct race *rc_spell = rc_find("spell");
|
||||
|
@ -1485,10 +1418,8 @@ int read_game(gamedata *data)
|
|||
|
||||
READ_INT(store, &nread);
|
||||
assert(nread < MAXREGIONS && nread >=0);
|
||||
if (rmax < 0) {
|
||||
rmax = nread;
|
||||
}
|
||||
log_debug(" - Einzulesende Regionen: %d/%d", rmax, nread);
|
||||
|
||||
log_debug(" - Einzulesende Regionen: %d", nread);
|
||||
|
||||
while (--nread >= 0) {
|
||||
unit **up;
|
||||
|
@ -1551,7 +1482,6 @@ int read_game(gamedata *data)
|
|||
update_interval(u->faction, r);
|
||||
}
|
||||
}
|
||||
--rmax;
|
||||
}
|
||||
read_borders(data);
|
||||
|
||||
|
@ -1613,9 +1543,6 @@ int read_game(gamedata *data)
|
|||
fix_familiars();
|
||||
}
|
||||
|
||||
if (loadplane || maxregions >= 0) {
|
||||
remove_empty_factions();
|
||||
}
|
||||
log_debug("Done loading turn %d.", turn);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -386,7 +386,7 @@ const char *shipname(const ship * sh)
|
|||
static name idbuf[8];
|
||||
static int nextbuf = 0;
|
||||
char *ibuf = idbuf[(++nextbuf) % 8];
|
||||
return write_shipname(sh, ibuf, sizeof(name));
|
||||
return write_shipname(sh, ibuf, sizeof(idbuf[0]));
|
||||
}
|
||||
|
||||
int shipcapacity(const ship * sh)
|
||||
|
|
|
@ -394,11 +394,14 @@ faction *dfindhash(int no)
|
|||
}
|
||||
#else
|
||||
struct faction *dfindhash(int no) {
|
||||
unit *u = deleted_units;
|
||||
while (u && u->no != no) {
|
||||
u = u->next;
|
||||
unit *u;
|
||||
|
||||
for (u = deleted_units; u; u = u->next) {
|
||||
if (u->no == no) {
|
||||
return u->faction;
|
||||
}
|
||||
return u ? u->faction : NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1597,12 +1600,6 @@ int countheroes(const struct faction *f)
|
|||
n += u->number;
|
||||
u = u->nextF;
|
||||
}
|
||||
#ifdef DEBUG_MAXHEROES
|
||||
int m = maxheroes(f);
|
||||
if (n > m) {
|
||||
log_warning("%s has %d of %d heroes\n", factionname(f), n, m);
|
||||
}
|
||||
#endif
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -1708,7 +1705,6 @@ void unit_addorder(unit * u, order * ord)
|
|||
int unit_max_hp(const unit * u)
|
||||
{
|
||||
int h;
|
||||
double p;
|
||||
static int config;
|
||||
static bool rule_stamina;
|
||||
h = u_race(u)->hitpoints;
|
||||
|
@ -1717,7 +1713,7 @@ int unit_max_hp(const unit * u)
|
|||
rule_stamina = config_get_int("rules.stamina", 1)!=0;
|
||||
}
|
||||
if (rule_stamina) {
|
||||
p = pow(effskill(u, SK_STAMINA, u->region) / 2.0, 1.5) * 0.2;
|
||||
double p = pow(effskill(u, SK_STAMINA, u->region) / 2.0, 1.5) * 0.2;
|
||||
h += (int)(h * p + 0.5);
|
||||
}
|
||||
|
||||
|
@ -1887,7 +1883,7 @@ char *write_unitname(const unit * u, char *buffer, size_t size)
|
|||
const char *unitname(const unit * u)
|
||||
{
|
||||
char *ubuf = idbuf[(++nextbuf) % 8];
|
||||
return write_unitname(u, ubuf, sizeof(name));
|
||||
return write_unitname(u, ubuf, sizeof(idbuf[0]));
|
||||
}
|
||||
|
||||
bool unit_name_equals_race(const unit *u) {
|
||||
|
@ -1929,10 +1925,6 @@ int read_unitid(const faction * f, const region * r)
|
|||
char token[16];
|
||||
const char *s = gettoken(token, sizeof(token));
|
||||
|
||||
/* Da s nun nur einen string enthaelt, suchen wir ihn direkt in der
|
||||
* paramliste. machen wir das nicht, dann wird getnewunit in s nach der
|
||||
* nummer suchen, doch dort steht bei temp-units nur "temp" drinnen! */
|
||||
|
||||
if (!s || *s == 0 || !isalnum(*s)) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,6 @@ const char *eressea_version(void) {
|
|||
|
||||
int version_no(const char *str) {
|
||||
int maj = 0, min = 0, pat = 0;
|
||||
sscanf(str, "%d.%d.%d", &maj, &min, &pat);
|
||||
sscanf(str, "%4d.%4d.%4d", &maj, &min, &pat);
|
||||
return (maj << 16) | (min << 8) | pat;
|
||||
}
|
||||
|
|
|
@ -48,12 +48,10 @@ without prior permission by the authors of Eressea.
|
|||
#include <util/nrmessage.h>
|
||||
#include <util/xml.h>
|
||||
|
||||
#ifdef USE_LIBXML2
|
||||
/* libxml includes */
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/xpath.h>
|
||||
#include <libxml/encoding.h>
|
||||
#endif
|
||||
|
||||
/* libc includes */
|
||||
#include <assert.h>
|
||||
|
@ -61,7 +59,6 @@ without prior permission by the authors of Eressea.
|
|||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_LIBXML2
|
||||
|
||||
static variant xml_fraction(xmlNodePtr node, const char *name) {
|
||||
xmlChar *propValue = xmlGetProp(node, BAD_CAST name);
|
||||
|
@ -284,13 +281,13 @@ static int parse_buildings(xmlDocPtr doc)
|
|||
{
|
||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
||||
xmlXPathObjectPtr buildings;
|
||||
int i;
|
||||
|
||||
/* reading eressea/buildings/building */
|
||||
buildings =
|
||||
xmlXPathEvalExpression(BAD_CAST "/eressea/buildings/building", xpath);
|
||||
if (buildings->nodesetval != NULL) {
|
||||
xmlNodeSetPtr nodes = buildings->nodesetval;
|
||||
int i;
|
||||
for (i = 0; i != nodes->nodeNr; ++i) {
|
||||
xmlNodePtr node = nodes->nodeTab[i];
|
||||
xmlChar *propValue;
|
||||
|
@ -396,12 +393,12 @@ static int parse_ships(xmlDocPtr doc)
|
|||
{
|
||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
||||
xmlXPathObjectPtr ships;
|
||||
int i;
|
||||
|
||||
/* reading eressea/ships/ship */
|
||||
ships = xmlXPathEvalExpression(BAD_CAST "/eressea/ships/ship", xpath);
|
||||
if (ships->nodesetval != NULL) {
|
||||
xmlNodeSetPtr nodes = ships->nodesetval;
|
||||
int i;
|
||||
for (i = 0; i != nodes->nodeNr; ++i) {
|
||||
xmlNodePtr child, node = nodes->nodeTab[i];
|
||||
xmlChar *propValue;
|
||||
|
@ -810,7 +807,6 @@ static int parse_resources(xmlDocPtr doc)
|
|||
resource_type *rtype;
|
||||
unsigned int flags = RTF_NONE;
|
||||
xmlXPathObjectPtr result;
|
||||
int k;
|
||||
|
||||
if (xml_bvalue(node, "pooled", true))
|
||||
flags |= RTF_POOLED;
|
||||
|
@ -828,7 +824,8 @@ static int parse_resources(xmlDocPtr doc)
|
|||
/* reading eressea/resources/resource/function */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "function", xpath);
|
||||
if (result->nodesetval != NULL)
|
||||
if (result->nodesetval != NULL) {
|
||||
int k;
|
||||
for (k = 0; k != result->nodesetval->nodeNr; ++k) {
|
||||
xmlNodePtr node = result->nodesetval->nodeTab[k];
|
||||
pf_generic fun;
|
||||
|
@ -852,6 +849,7 @@ static int parse_resources(xmlDocPtr doc)
|
|||
}
|
||||
xmlFree(propValue);
|
||||
}
|
||||
}
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
if (xml_bvalue(node, "material", false)) {
|
||||
|
@ -1760,4 +1758,3 @@ void register_xmlreader(void)
|
|||
xml_register_callback(parse_strings);
|
||||
xml_register_callback(parse_messages);
|
||||
}
|
||||
#endif
|
||||
|
|
27
src/laws.c
27
src/laws.c
|
@ -314,7 +314,7 @@ static void peasants(region * r, int rule)
|
|||
{
|
||||
int peasants = rpeasants(r);
|
||||
int money = rmoney(r);
|
||||
int maxp = production(r);
|
||||
int maxp = max_production(r);
|
||||
int n, satiated;
|
||||
int dead = 0;
|
||||
|
||||
|
@ -433,14 +433,15 @@ static void horses(region * r)
|
|||
rsethorses(r, (int)(horses * 0.9));
|
||||
}
|
||||
else if (maxhorses) {
|
||||
int i;
|
||||
double growth =
|
||||
(RESOURCE_QUANTITY * HORSEGROWTH * 200 * (maxhorses -
|
||||
horses)) / maxhorses;
|
||||
|
||||
if (growth > 0) {
|
||||
if (a_find(r->attribs, &at_horseluck))
|
||||
int i;
|
||||
if (a_find(r->attribs, &at_horseluck)) {
|
||||
growth *= 2;
|
||||
}
|
||||
/* printf("Horses: <%d> %d -> ", growth, horses); */
|
||||
i = (int)(0.5 + (horses * 0.0001) * growth);
|
||||
/* printf("%d\n", horses); */
|
||||
|
@ -562,13 +563,13 @@ growing_trees_e3(region * r, const int current_season,
|
|||
static void
|
||||
growing_trees(region * r, const int current_season, const int last_weeks_season)
|
||||
{
|
||||
int growth, grownup_trees, i, seeds, sprout;
|
||||
direction_t d;
|
||||
int grownup_trees, i, seeds, sprout;
|
||||
attrib *a;
|
||||
|
||||
if (current_season == SEASON_SUMMER || current_season == SEASON_AUTUMN) {
|
||||
double seedchance = 0.01F * RESOURCE_QUANTITY;
|
||||
int elves = count_race(r, get_race(RC_ELF));
|
||||
direction_t d;
|
||||
|
||||
a = a_find(r->attribs, &at_germs);
|
||||
if (a && last_weeks_season == SEASON_SPRING) {
|
||||
|
@ -588,12 +589,12 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
|
|||
return;
|
||||
}
|
||||
|
||||
if (production(r) <= 0)
|
||||
if (max_production(r) <= 0)
|
||||
return;
|
||||
|
||||
/* Grundchance 1.0% */
|
||||
/* Jeder Elf in der Region erhöht die Chance marginal */
|
||||
elves = MIN(elves, production(r) / 8);
|
||||
elves = MIN(elves, max_production(r) / 8);
|
||||
if (elves) {
|
||||
seedchance += 1.0 - pow(0.99999, elves * RESOURCE_QUANTITY);
|
||||
}
|
||||
|
@ -638,6 +639,7 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
|
|||
|
||||
}
|
||||
else if (current_season == SEASON_SPRING) {
|
||||
int growth;
|
||||
|
||||
if (is_cursed(r->attribs, &ct_godcursezone))
|
||||
return;
|
||||
|
@ -2153,7 +2155,6 @@ int email_cmd(unit * u, struct order *ord)
|
|||
int password_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
char pwbuf[32];
|
||||
int i;
|
||||
const char *s;
|
||||
bool pwok = true;
|
||||
|
||||
|
@ -2161,6 +2162,7 @@ int password_cmd(unit * u, struct order *ord)
|
|||
s = gettoken(pwbuf, sizeof(pwbuf));
|
||||
|
||||
if (!s || !*s) {
|
||||
int i;
|
||||
for (i = 0; i < 6; i++)
|
||||
pwbuf[i] = (char)(97 + rng_int() % 26);
|
||||
pwbuf[6] = 0;
|
||||
|
@ -4272,7 +4274,7 @@ void update_subscriptions(void)
|
|||
int subscription, fno;
|
||||
faction *f;
|
||||
|
||||
if (fscanf(F, "%d %4s", &subscription, zFaction) <= 0)
|
||||
if (fscanf(F, "%4d %4s", &subscription, zFaction) <= 0)
|
||||
break;
|
||||
fno = atoi36(zFaction);
|
||||
f = findfaction(fno);
|
||||
|
@ -4358,7 +4360,7 @@ bool cansee_unit(const unit * u, const unit * target, int modifier)
|
|||
else if (target->faction == u->faction)
|
||||
return true;
|
||||
else {
|
||||
int n, rings, o;
|
||||
int n, rings;
|
||||
|
||||
if (is_guard(target) || usiege(target) || target->building
|
||||
|| target->ship) {
|
||||
|
@ -4375,7 +4377,7 @@ bool cansee_unit(const unit * u, const unit * target, int modifier)
|
|||
return false;
|
||||
}
|
||||
if (skill_enabled(SK_PERCEPTION)) {
|
||||
o = effskill(u, SK_PERCEPTION, target->region);
|
||||
int o = effskill(u, SK_PERCEPTION, target->region);
|
||||
if (o >= n) {
|
||||
return true;
|
||||
}
|
||||
|
@ -4394,7 +4396,6 @@ cansee_durchgezogen(const faction * f, const region * r, const unit * u,
|
|||
/* und es muss niemand aus f in der region sein, wenn sie vom Turm
|
||||
* erblickt wird */
|
||||
{
|
||||
int n;
|
||||
unit *u2;
|
||||
|
||||
if (fval(u_race(u), RCF_INVISIBLE) || u->number == 0)
|
||||
|
@ -4402,7 +4403,7 @@ cansee_durchgezogen(const faction * f, const region * r, const unit * u,
|
|||
else if (u->faction == f)
|
||||
return true;
|
||||
else {
|
||||
int rings;
|
||||
int rings, n;
|
||||
|
||||
if (is_guard(u) || usiege(u) || u->building || u->ship) {
|
||||
return true;
|
||||
|
|
|
@ -4,7 +4,6 @@ autoseed.c
|
|||
gmcmd.c
|
||||
museum.c
|
||||
score.c
|
||||
weather.c
|
||||
xmas.c
|
||||
)
|
||||
FOREACH(_FILE ${_FILES})
|
||||
|
|
|
@ -155,7 +155,7 @@ newfaction *read_newfactions(const char *filename)
|
|||
email[0] = '\0';
|
||||
password[0] = '\0';
|
||||
|
||||
if (sscanf(buf, "%54s %19s %7s %15s %d %d", email, race, lang,
|
||||
if (sscanf(buf, "%54s %19s %7s %15s %4d %4d", email, race, lang,
|
||||
password, &subscription, &alliance) < 3) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
#include <kernel/config.h>
|
||||
|
||||
#if MUSEUM_MODULE
|
||||
#include "museum.h"
|
||||
|
||||
/* kernel includes */
|
||||
|
@ -502,5 +501,3 @@ void register_museum(void)
|
|||
register_item_use(use_museumkey, "use_questkey1");
|
||||
register_item_use(use_museumkey, "use_questkey2");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,10 +20,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#define HEADER_MUSEUM_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if MUSEUM_MODULE == 0
|
||||
#error "must define MUSEUM_MODULE to use this module"
|
||||
#endif
|
||||
|
||||
extern struct attrib_type at_warden;
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
**/
|
||||
|
||||
#ifdef WEATHER
|
||||
|
||||
#include <platform.h>
|
||||
#include <config.h>
|
||||
#include "weather.h"
|
||||
|
||||
/* libc includes */
|
||||
#include <math.h>
|
||||
|
||||
weather *create_weather(region * r, weather_t type)
|
||||
{
|
||||
weather *w;
|
||||
|
||||
w = calloc(1, sizeof(weather));
|
||||
w->center[0] = r->x;
|
||||
w->center[1] = r->y;
|
||||
w->type = type;
|
||||
w->move[0] = (rng_int() % 3) - 1;
|
||||
w->move[1] = (rng_int() % 3) - 1;
|
||||
|
||||
switch (type) {
|
||||
case WEATHER_STORM:
|
||||
w->radius = rng_int() % 2 + 1;
|
||||
break;
|
||||
case WEATHER_HURRICANE:
|
||||
w->radius = 1;
|
||||
break;
|
||||
default:
|
||||
w->radius = 0;
|
||||
}
|
||||
|
||||
addlist(&weathers, w);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
double distance(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
|
||||
}
|
||||
|
||||
/* Diese Funktion ermittelt für jede Region, welches Wetter in ihr
|
||||
herrscht. Die Wettertypen sind dabei nach ihrer Reihenfolge in der
|
||||
enumeration priorisiert.
|
||||
|
||||
- Einladen
|
||||
set_weather();
|
||||
- Eigentliche Auswertung
|
||||
- Veränderungen des Wetters
|
||||
set_weather();
|
||||
- Report generieren
|
||||
- Abspeichern
|
||||
|
||||
Diese Routine ist sehr rechenaufwendig!
|
||||
*/
|
||||
|
||||
void set_weather(void)
|
||||
{
|
||||
weather_t i;
|
||||
weather *w;
|
||||
short x, y;
|
||||
int d;
|
||||
region *r;
|
||||
|
||||
for (r = regions; r; r = r->next) {
|
||||
r->weathertype = WEATHER_NONE;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXWEATHERS; i++) {
|
||||
for (w = weathers; w; w = w->next) {
|
||||
if (w->type == i) {
|
||||
for (x = w->center[0] - w->radius; x <= w->center[0] + w->radius; x++) {
|
||||
for (y = w->center[1] - w->radius; y <= w->center[1] + w->radius; y++) {
|
||||
d = distance(w->center[0], w->center[1], x, y);
|
||||
if (floor(d + 0.5) <= w->radius) {
|
||||
r = findregion(x, y);
|
||||
if (r) {
|
||||
r->weathertype = w->type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void move_weather(void)
|
||||
{
|
||||
weather *w, *wnext;
|
||||
region *r;
|
||||
|
||||
for (w = weathers; w;) {
|
||||
wnext = w->next;
|
||||
w->center[0] = w->center[0] + w->move[0];
|
||||
w->center[1] = w->center[1] + w->move[1];
|
||||
r = findregion(w->center[0], w->center[1]);
|
||||
if (!r || rng_int() % 100 < 5) {
|
||||
removelist(&weathers, w);
|
||||
}
|
||||
w = wnext;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#include <stdio.h>
|
||||
static const char *copyright = "(c) Eressea PBEM 2000";
|
||||
|
||||
void init_weather(void)
|
||||
{
|
||||
fputs(copyright, stderr);
|
||||
/* TODO: Initialization */
|
||||
}
|
||||
#endif
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
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_MOD_WEATHER_H
|
||||
#define H_MOD_WEATHER_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef WEATHER
|
||||
# error "the weather system is disabled"
|
||||
#endif
|
||||
|
||||
enum {
|
||||
WEATHER_NONE,
|
||||
WEATHER_STORM,
|
||||
WEATHER_HURRICANE,
|
||||
MAXWEATHERS
|
||||
};
|
||||
|
||||
typedef unsigned char weather_t;
|
||||
|
||||
typedef struct weather {
|
||||
struct weather *next;
|
||||
weather_t type; /* Typ der Wetterzone */
|
||||
int center[2]; /* Koordinaten des Zentrums */
|
||||
int radius;
|
||||
int move[2];
|
||||
} weather;
|
||||
|
||||
weather *weathers;
|
||||
|
||||
void set_weather(void);
|
||||
void move_weather(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
18
src/move.c
18
src/move.c
|
@ -1764,9 +1764,9 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting)
|
|||
}
|
||||
|
||||
if (!flying_ship(sh)) {
|
||||
int stormchance = 0;
|
||||
int reason;
|
||||
if (storms_enabled) {
|
||||
int stormchance = 0;
|
||||
int stormyness;
|
||||
gamedate date;
|
||||
get_gamedate(turn, &date);
|
||||
|
@ -2323,22 +2323,6 @@ int follow_ship(unit * u, order * ord)
|
|||
return 1; /* true -> Einheitenliste von vorne durchgehen */
|
||||
}
|
||||
|
||||
void destroy_damaged_ships(void)
|
||||
{
|
||||
region *r;
|
||||
ship *sh, *shn;
|
||||
|
||||
for (r = regions; r; r = r->next) {
|
||||
for (sh = r->ships; sh;) {
|
||||
shn = sh->next;
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
sh = shn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Bewegung, Verfolgung, Piraterie */
|
||||
|
||||
/** ships that folow other ships
|
||||
|
|
|
@ -974,7 +974,7 @@ void report_region(struct stream *out, const region * r, faction * f)
|
|||
/* Trees */
|
||||
trees = rtrees(r, 2);
|
||||
saplings = rtrees(r, 1);
|
||||
if (production(r)) {
|
||||
if (max_production(r)) {
|
||||
if (trees > 0 || saplings > 0) {
|
||||
bytes = snprintf(bufp, size, ", %d/%d ", trees, saplings);
|
||||
if (wrptr(&bufp, &size, bytes) != 0)
|
||||
|
@ -1311,7 +1311,7 @@ static void statistics(struct stream *out, const region * r, const faction * f)
|
|||
paragraph(out, buf, 2, 2, 0);
|
||||
msg_release(m);
|
||||
}
|
||||
if (production(r) && (!fval(r->terrain, SEA_REGION)
|
||||
if (max_production(r) && (!fval(r->terrain, SEA_REGION)
|
||||
|| f->race == get_race(RC_AQUARIAN))) {
|
||||
if (markets_module()) { /* hack */
|
||||
m =
|
||||
|
|
|
@ -24,12 +24,6 @@
|
|||
|
||||
#define ROW_FACTOR 3 /* factor for combat row advancement rule */
|
||||
|
||||
/* optional game components. TODO: These should either be
|
||||
* configuration variables (XML), script extensions (lua),
|
||||
* or both. We don't want separate binaries for different games
|
||||
*/
|
||||
#define MUSEUM_MODULE 1
|
||||
|
||||
/* TODO: move these settings to settings.h or into configuration files */
|
||||
#define TREESIZE (8) /* space used by trees (in #peasants) */
|
||||
#define PEASANTFORCE 0.75 /* Chance einer Vermehrung trotz 90% Auslastung */
|
||||
|
|
126
src/spells.c
126
src/spells.c
|
@ -1280,10 +1280,8 @@ static int sp_rosthauch(castorder * co)
|
|||
add_ironweapon(it_find("axe"), it_find("rustyaxe"), 1.0);
|
||||
add_ironweapon(it_find("greatsword"), it_find("rustygreatsword"), 1.0);
|
||||
add_ironweapon(it_find("halberd"), it_find("rustyhalberd"), 0.5f);
|
||||
#ifndef NO_RUSTY_ARMOR
|
||||
add_ironweapon(it_find("shield"), it_find("rustyshield"), 0.5f);
|
||||
add_ironweapon(it_find("chainmail"), it_find("rustychainmail"), 0.2f);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (force > 0) {
|
||||
|
@ -2358,7 +2356,6 @@ static int sp_earthquake(castorder * co)
|
|||
/* ------------------------------------------------------------- */
|
||||
void patzer_peasantmob(const castorder * co)
|
||||
{
|
||||
int anteil = 6, n;
|
||||
unit *u;
|
||||
attrib *a;
|
||||
region *r;
|
||||
|
@ -2370,8 +2367,9 @@ void patzer_peasantmob(const castorder * co)
|
|||
faction *f = get_monsters();
|
||||
const struct locale *lang = f->locale;
|
||||
message *msg;
|
||||
int anteil, n;
|
||||
|
||||
anteil += rng_int() % 4;
|
||||
anteil = 6 + rng_int() % 4;
|
||||
n = rpeasants(r) * anteil / 10;
|
||||
rsetpeasants(r, rpeasants(r) - n);
|
||||
assert(rpeasants(r) >= 0);
|
||||
|
@ -2966,12 +2964,12 @@ static int sp_deathcloud(castorder * co)
|
|||
return co->level;
|
||||
}
|
||||
|
||||
void patzer_deathcloud(castorder * co)
|
||||
static void patzer_deathcloud(const castorder * co)
|
||||
{
|
||||
unit *mage = co->magician.u;
|
||||
int hp = (mage->hp - 2);
|
||||
|
||||
change_hitpoints(mage, -rng_int() % hp);
|
||||
change_hitpoints(mage, -(rng_int() % hp));
|
||||
|
||||
ADDMSG(&mage->faction->msgs, msg_message("magic_fumble",
|
||||
"unit region command", mage, mage->region, co->order));
|
||||
|
@ -4527,28 +4525,6 @@ int sp_illusionary_shapeshift(castorder * co)
|
|||
return cast_level;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/* Name: Regionstraum analysieren
|
||||
* Stufe: 9
|
||||
* Aura: 18
|
||||
* Kosten: SPC_FIX
|
||||
* Wirkung:
|
||||
* Zeigt die Verzauberungen eines Objekts an (curse->name,
|
||||
* curse::info). Aus der Differenz Spruchstaerke und Curse->vigour
|
||||
* ergibt sich die Chance den Spruch zu identifizieren ((force -
|
||||
* c->vigour)*10 + 100 %).
|
||||
*/
|
||||
int sp_analyseregionsdream(castorder * co)
|
||||
{
|
||||
region *r = co_get_region(co);
|
||||
unit *mage = co->magician.u;
|
||||
int cast_level = co->level;
|
||||
|
||||
magicanalyse_region(r, mage, cast_level);
|
||||
|
||||
return cast_level;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/* Name: Traumbilder erkennen
|
||||
* Stufe: 5
|
||||
|
@ -5476,7 +5452,8 @@ int sp_fetchastral(castorder * co)
|
|||
return cast_level;
|
||||
}
|
||||
|
||||
#ifdef SHOWASTRAL_NOT_BORKED
|
||||
#define SHOWASTRAL_IS_BORKED
|
||||
#ifndef SHOWASTRAL_IS_BORKED
|
||||
int sp_showastral(castorder * co)
|
||||
{
|
||||
unit *u;
|
||||
|
@ -5563,8 +5540,6 @@ int sp_showastral(castorder * co)
|
|||
|
||||
free_regionlist(rl);
|
||||
return cast_level;
|
||||
UNUSED_ARG(co);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -6144,89 +6119,6 @@ int sp_speed2(castorder * co)
|
|||
return MAX(1, used);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/* Name: Magiefresser
|
||||
* Stufe: 7
|
||||
* Kosten: SPC_LEVEL
|
||||
*
|
||||
* Wirkung:
|
||||
* Kann eine bestimmte Verzauberung angreifen und aufloesen. Die Staerke
|
||||
* des Zaubers muss staerker sein als die der Verzauberung.
|
||||
* Syntax:
|
||||
* ZAUBERE \"Magiefresser\" REGION
|
||||
* ZAUBERE \"Magiefresser\" EINHEIT <Einheit-Nr>
|
||||
* ZAUBERE \"Magiefresser\" GEBAEUDE <Gebaeude-Nr>
|
||||
* ZAUBERE \"Magiefresser\" SCHIFF <Schiff-Nr>
|
||||
*
|
||||
* "kc?c"
|
||||
* Flags:
|
||||
* (FARCASTING | SPELLLEVEL | ONSHIPCAST | TESTCANSEE)
|
||||
*/
|
||||
/* Jeder gebrochene Zauber verbraucht c->vigour an Zauberkraft
|
||||
* (force) */
|
||||
int sp_q_antimagie(castorder * co)
|
||||
{
|
||||
attrib **ap;
|
||||
int obj;
|
||||
curse *c = NULL;
|
||||
int succ;
|
||||
region *r = co_get_region(co);
|
||||
unit *mage = co->magician.u;
|
||||
int cast_level = co->level;
|
||||
double force = co->force;
|
||||
spellparameter *pa = co->par;
|
||||
const char *ts = NULL;
|
||||
|
||||
obj = pa->param[0]->typ;
|
||||
|
||||
switch (obj) {
|
||||
case SPP_REGION:
|
||||
ap = &r->attribs;
|
||||
ts = regionname(r, mage->faction);
|
||||
break;
|
||||
|
||||
case SPP_TEMP:
|
||||
case SPP_UNIT:
|
||||
{
|
||||
unit *u = pa->param[0]->data.u;
|
||||
ap = &u->attribs;
|
||||
ts = itoa36(u->no);
|
||||
break;
|
||||
}
|
||||
case SPP_BUILDING:
|
||||
{
|
||||
building *b = pa->param[0]->data.b;
|
||||
ap = &b->attribs;
|
||||
ts = itoa36(b->no);
|
||||
break;
|
||||
}
|
||||
case SPP_SHIP:
|
||||
{
|
||||
ship *sh = pa->param[0]->data.sh;
|
||||
ap = &sh->attribs;
|
||||
ts = itoa36(sh->no);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* Das Zielobjekt wurde vergessen */
|
||||
cmistake(mage, co->order, 203, MSG_MAGIC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
succ = break_curse(ap, cast_level, force, c);
|
||||
|
||||
if (succ) {
|
||||
ADDMSG(&mage->faction->msgs, msg_message("destroy_magic_effect",
|
||||
"unit region command succ target", mage, mage->region, co->order, succ,
|
||||
ts));
|
||||
}
|
||||
else {
|
||||
ADDMSG(&mage->faction->msgs, msg_message("destroy_magic_noeffect",
|
||||
"unit region command", mage, mage->region, co->order));
|
||||
}
|
||||
return MAX(succ, 1);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/* Name: Fluch brechen
|
||||
* Stufe: 7
|
||||
|
@ -6541,7 +6433,7 @@ static spelldata spell_functions[] = {
|
|||
{ "forestfire", sp_forest_fire, patzer_peasantmob },
|
||||
{ "draigdestroymagic", sp_destroy_magic, 0 },
|
||||
{ "unholypower", sp_unholypower, 0 },
|
||||
{ "deathcloud", sp_deathcloud, patzer_peasantmob },
|
||||
{ "deathcloud", sp_deathcloud, patzer_deathcloud },
|
||||
{ "summondragon", sp_summondragon, patzer_peasantmob },
|
||||
{ "summonshadowlords", sp_summonshadowlords, patzer_peasantmob },
|
||||
{ "chaossuction", sp_chaossuction, patzer_peasantmob },
|
||||
|
@ -6567,7 +6459,7 @@ static spelldata spell_functions[] = {
|
|||
{ "mindblast", sp_mindblast_temp, 0 },
|
||||
{ "orkdream", sp_sweetdreams, 0 },
|
||||
/* M_CERDDOR */
|
||||
{ "appeasement", sp_denyattack, 0 },
|
||||
{ "appeasement", sp_appeasement, 0 },
|
||||
{ "song_of_healing", sp_healing, 0 },
|
||||
{ "generous", sp_generous, 0 },
|
||||
{ "song_of_fear", sp_song_of_fear, 0 },
|
||||
|
@ -6600,7 +6492,7 @@ static spelldata spell_functions[] = {
|
|||
{ "analyze_magic", sp_analysemagic, 0 },
|
||||
{ "concealing_aura", sp_itemcloak, 0 },
|
||||
{ "tybiedfumbleshield", sp_fumbleshield, 0 },
|
||||
#ifdef SHOWASTRAL_NOT_BORKED
|
||||
#ifndef SHOWASTRAL_IS_BORKED
|
||||
{ "show_astral", sp_showastral, 0 },
|
||||
#endif
|
||||
{ "resist_magic", sp_resist_magic_bonus, 0 },
|
||||
|
|
|
@ -622,7 +622,6 @@ int sp_dragonodem(struct castorder * co)
|
|||
troop dt;
|
||||
troop at;
|
||||
int force, enemies;
|
||||
int killed = 0;
|
||||
const char *damage;
|
||||
|
||||
/* 11-26 HP */
|
||||
|
@ -641,6 +640,7 @@ int sp_dragonodem(struct castorder * co)
|
|||
}
|
||||
else {
|
||||
struct message *m;
|
||||
int killed = 0;
|
||||
|
||||
at.fighter = fi;
|
||||
at.index = 0;
|
||||
|
@ -717,53 +717,6 @@ int sp_immolation(struct castorder * co)
|
|||
return level;
|
||||
}
|
||||
|
||||
int sp_drainodem(fighter * fi, int level, double power, spell * sp)
|
||||
{
|
||||
battle *b = fi->side->battle;
|
||||
troop dt;
|
||||
troop at;
|
||||
int force, enemies;
|
||||
int drained = 0;
|
||||
int killed = 0;
|
||||
const char *damage;
|
||||
message *m;
|
||||
|
||||
/* 11-26 HP */
|
||||
damage = spell_damage(4);
|
||||
/* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */
|
||||
force = lovar(get_force(power, 6));
|
||||
|
||||
enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE);
|
||||
|
||||
if (!enemies) {
|
||||
m = msg_message("spell_out_of_range", "mage spell", fi->unit, sp);
|
||||
message_all(b, m);
|
||||
msg_release(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
at.fighter = fi;
|
||||
at.index = 0;
|
||||
|
||||
while (force && drained < enemies) {
|
||||
dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE);
|
||||
assert(dt.fighter);
|
||||
if (hits(at, dt, NULL)) {
|
||||
drain_exp(dt.fighter->unit, 90);
|
||||
++drained;
|
||||
killed += terminate(dt, at, AT_COMBATSPELL, damage, false);
|
||||
}
|
||||
--force;
|
||||
}
|
||||
|
||||
m =
|
||||
msg_message("cast_drainlife_effect", "mage spell amount", fi->unit, sp,
|
||||
drained);
|
||||
message_all(b, m);
|
||||
msg_release(m);
|
||||
return level;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/* PRECOMBAT */
|
||||
|
||||
|
@ -1309,7 +1262,7 @@ int sp_reeling_arrows(struct castorder * co)
|
|||
/* Magier weicht dem Kampf aus. Wenn er sich bewegen kann, zieht er in
|
||||
* eine Nachbarregion, wobei ein NACH ber<EFBFBD>cksichtigt wird. Ansonsten
|
||||
* bleibt er stehen und nimmt nicht weiter am Kampf teil. */
|
||||
int sp_denyattack(struct castorder * co)
|
||||
int sp_appeasement(struct castorder * co)
|
||||
{
|
||||
fighter * fi = co->magician.fig;
|
||||
int level = co->level;
|
||||
|
|
|
@ -30,7 +30,7 @@ extern "C" {
|
|||
int sp_berserk(struct castorder * co);
|
||||
int sp_tiredsoldiers(struct castorder * co);
|
||||
int sp_reeling_arrows(struct castorder * co);
|
||||
int sp_denyattack(struct castorder * co);
|
||||
int sp_appeasement(struct castorder * co);
|
||||
int sp_sleep(struct castorder * co);
|
||||
int sp_windshield(struct castorder * co);
|
||||
int sp_strong_wall(struct castorder * co);
|
||||
|
|
11
src/sqlite.c
11
src/sqlite.c
|
@ -12,17 +12,6 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
faction *get_faction_by_id(int uid)
|
||||
{
|
||||
faction *f;
|
||||
for (f = factions; f; f = f->next) {
|
||||
if (f->subscription == uid) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct db_faction {
|
||||
int uid;
|
||||
int no;
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
Copyright (c) 1998-2014,
|
||||
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 "economy.h"
|
||||
|
||||
#include "laws.h"
|
||||
#include "skill.h"
|
||||
#include "study.h"
|
||||
|
||||
#include <util/message.h>
|
||||
|
||||
#include <kernel/build.h>
|
||||
#include <kernel/faction.h>
|
||||
#include <kernel/item.h>
|
||||
#include <kernel/messages.h>
|
||||
#include <kernel/order.h>
|
||||
#include <kernel/plane.h>
|
||||
#include <kernel/pool.h>
|
||||
#include <kernel/race.h>
|
||||
#include <kernel/region.h>
|
||||
#include <kernel/terrain.h>
|
||||
#include <kernel/unit.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
void expandstealing(region * r, econ_request * stealorders)
|
||||
{
|
||||
const resource_type *rsilver = get_resourcetype(R_SILVER);
|
||||
unsigned int j;
|
||||
unsigned int norders;
|
||||
econ_request *requests;
|
||||
|
||||
assert(rsilver);
|
||||
|
||||
norders = expand_production(r, stealorders, &requests);
|
||||
if (!norders) return;
|
||||
|
||||
/* F<>r jede unit in der Region wird Geld geklaut, wenn sie Opfer eines
|
||||
* Beklauen-Orders ist. Jedes Opfer muss einzeln behandelt werden.
|
||||
*
|
||||
* u ist die beklaute unit. oa.unit ist die klauende unit.
|
||||
*/
|
||||
|
||||
for (j = 0; j != norders; j++) {
|
||||
unit *u;
|
||||
int n = 0;
|
||||
|
||||
if (requests[j].unit->n > requests[j].unit->wants) {
|
||||
break;
|
||||
}
|
||||
|
||||
u = findunitg(requests[j].no, r);
|
||||
|
||||
if (u && u->region == r) {
|
||||
n = get_pooled(u, rsilver, GET_ALL, INT_MAX);
|
||||
}
|
||||
if (n > 10 && rplane(r) && (rplane(r)->flags & PFL_NOALLIANCES)) {
|
||||
/* In Questen nur reduziertes Klauen */
|
||||
n = 10;
|
||||
}
|
||||
if (n > 0) {
|
||||
n = MIN(n, requests[j].unit->wants);
|
||||
use_pooled(u, rsilver, GET_ALL, n);
|
||||
requests[j].unit->n = n;
|
||||
change_money(requests[j].unit, n);
|
||||
ADDMSG(&u->faction->msgs, msg_message("stealeffect", "unit region amount",
|
||||
u, u->region, n));
|
||||
}
|
||||
add_income(requests[j].unit, IC_STEAL, requests[j].unit->wants, requests[j].unit->n);
|
||||
fset(requests[j].unit, UFL_LONGACTION | UFL_NOTMOVING);
|
||||
}
|
||||
free(requests);
|
||||
}
|
||||
|
||||
static int max_skill(region * r, struct faction * f, skill_t sk)
|
||||
{
|
||||
unit *u;
|
||||
int w = 0;
|
||||
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->faction == f) {
|
||||
int effsk = effskill(u, sk, 0);
|
||||
if (effsk > w) {
|
||||
w = effsk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
message * steal_message(const unit * u, struct order *ord) {
|
||||
plane *pl;
|
||||
|
||||
if (fval(u_race(u), RCF_NOSTEAL)) {
|
||||
return msg_feedback(u, ord, "race_nosteal", "race", u_race(u));
|
||||
}
|
||||
|
||||
if (fval(u->region->terrain, SEA_REGION) && u_race(u) != get_race(RC_AQUARIAN)) {
|
||||
return msg_feedback(u, ord, "error_onlandonly", "");
|
||||
}
|
||||
|
||||
pl = rplane(u->region);
|
||||
if (pl && fval(pl, PFL_NOATTACK)) {
|
||||
return msg_feedback(u, ord, "error270", "");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void steal_cmd(unit * u, struct order *ord, econ_request ** stealorders)
|
||||
{
|
||||
const resource_type *rring = get_resourcetype(R_RING_OF_NIMBLEFINGER);
|
||||
int n, i, id, effsk;
|
||||
bool goblin = false;
|
||||
econ_request *o;
|
||||
unit *u2 = NULL;
|
||||
region *r = u->region;
|
||||
faction *f = NULL;
|
||||
message * msg;
|
||||
keyword_t kwd;
|
||||
|
||||
kwd = init_order_depr(ord);
|
||||
assert(kwd == K_STEAL);
|
||||
|
||||
assert(skill_enabled(SK_PERCEPTION) && skill_enabled(SK_STEALTH));
|
||||
|
||||
msg = steal_message(u, ord);
|
||||
if (msg) {
|
||||
ADDMSG(&u->faction->msgs, msg);
|
||||
return;
|
||||
}
|
||||
id = read_unitid(u->faction, r);
|
||||
if (id > 0) {
|
||||
u2 = findunitr(r, id);
|
||||
}
|
||||
if (u2 && u2->region == u->region) {
|
||||
f = u2->faction;
|
||||
}
|
||||
else {
|
||||
/* TODO: is this really necessary? it's the only time we use faction.c/deadhash
|
||||
* it allows stealing from a unit in a dead faction, but why? */
|
||||
f = dfindhash(id);
|
||||
}
|
||||
|
||||
for (u2 = r->units; u2; u2 = u2->next) {
|
||||
if (u2->faction == f && cansee(u->faction, r, u2, 0))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!u2) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found",
|
||||
""));
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsImmune(u2->faction)) {
|
||||
ADDMSG(&u->faction->msgs,
|
||||
msg_feedback(u, ord, "newbie_immunity_error", "turns", NewbieImmunity()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->faction->alliance && u->faction->alliance == u2->faction->alliance) {
|
||||
cmistake(u, ord, 47, MSG_INCOME);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(u->region == u2->region);
|
||||
if (!can_contact(r, u, u2)) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error60", ""));
|
||||
return;
|
||||
}
|
||||
|
||||
effsk = effskill(u, SK_STEALTH, 0);
|
||||
n = effsk - max_skill(r, f, SK_PERCEPTION);
|
||||
|
||||
if (n <= 0) {
|
||||
/* Wahrnehmung == Tarnung */
|
||||
if (u_race(u) != get_race(RC_GOBLIN) || effsk <= 3) {
|
||||
ADDMSG(&u->faction->msgs, msg_message("stealfail", "unit target", u, u2));
|
||||
if (n == 0) {
|
||||
ADDMSG(&u2->faction->msgs, msg_message("stealdetect", "unit", u2));
|
||||
}
|
||||
else {
|
||||
ADDMSG(&u2->faction->msgs, msg_message("thiefdiscover", "unit target",
|
||||
u, u2));
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
ADDMSG(&u->faction->msgs, msg_message("stealfatal", "unit target", u,
|
||||
u2));
|
||||
ADDMSG(&u2->faction->msgs, msg_message("thiefdiscover", "unit target", u,
|
||||
u2));
|
||||
n = 1;
|
||||
goblin = true;
|
||||
}
|
||||
}
|
||||
|
||||
i = MIN(u->number, i_get(u->items, rring->itype));
|
||||
if (i > 0) {
|
||||
n *= STEALINCOME * (u->number + i * (roqf_factor() - 1));
|
||||
}
|
||||
else {
|
||||
n *= u->number * STEALINCOME;
|
||||
}
|
||||
|
||||
u->wants = n;
|
||||
|
||||
/* wer dank unsichtbarkeitsringen klauen kann, muss nicht unbedingt ein
|
||||
* guter dieb sein, schliesslich macht man immer noch sehr viel laerm */
|
||||
|
||||
o = (econ_request *)calloc(1, sizeof(econ_request));
|
||||
o->unit = u;
|
||||
o->qty = 1; /* Betrag steht in u->wants */
|
||||
o->no = u2->no;
|
||||
o->type.goblin = goblin; /* Merken, wenn Goblin-Spezialklau */
|
||||
o->next = *stealorders;
|
||||
*stealorders = o;
|
||||
|
||||
/* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */
|
||||
|
||||
produceexp(u, SK_STEALTH, MIN(n, u->number));
|
||||
}
|
|
@ -811,23 +811,21 @@ void produceexp(struct unit *u, skill_t sk, int n)
|
|||
produceexp_ex(u, sk, n, learn_skill);
|
||||
}
|
||||
|
||||
#ifndef NO_TESTS
|
||||
static learn_fun inject_learn_fun = 0;
|
||||
|
||||
void inject_learn(learn_fun fun) {
|
||||
inject_learn_fun = fun;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** days should be scaled by u->number; STUDYDAYS * u->number is one week worth of learning */
|
||||
void learn_skill(unit *u, skill_t sk, int days) {
|
||||
int leveldays = STUDYDAYS * u->number;
|
||||
int weeks = 0;
|
||||
#ifndef NO_TESTS
|
||||
|
||||
if (inject_learn_fun) {
|
||||
inject_learn_fun(u, sk, days);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
while (days >= leveldays) {
|
||||
++weeks;
|
||||
days -= leveldays;
|
||||
|
|
|
@ -56,9 +56,7 @@ extern "C" {
|
|||
|
||||
extern const struct attrib_type at_learning;
|
||||
|
||||
#ifndef NO_TESTS
|
||||
void inject_learn(learn_fun fun);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <platform.h>
|
||||
#include "shock.h"
|
||||
|
||||
#include "magic.h"
|
||||
#include <magic.h>
|
||||
|
||||
/* kernel includes */
|
||||
#include <kernel/curse.h>
|
||||
|
|
|
@ -537,5 +537,5 @@ void a_write_orig(struct storage *store, const attrib * attribs, const void *own
|
|||
|
||||
void attrib_done(void) {
|
||||
cb_clear(&cb_deprecated);
|
||||
memset(at_hash, 0, sizeof at_hash);
|
||||
memset(at_hash, 0, sizeof(at_hash[0]) * MAXATHASH);
|
||||
}
|
||||
|
|
|
@ -57,13 +57,14 @@ const char *itoab(int i, int base)
|
|||
static char sstr[80];
|
||||
char *s, *dst;
|
||||
static int index = 0; /* STATIC_XCALL: used across calls */
|
||||
int neg = 0;
|
||||
|
||||
s = sstr + (index * 20);
|
||||
index = (index + 1) & 3; /* quick for % 4 */
|
||||
dst = s + 19;
|
||||
(*dst--) = 0;
|
||||
if (i != 0) {
|
||||
int neg = 0;
|
||||
|
||||
if (i < 0) {
|
||||
i = -i;
|
||||
neg = 1;
|
||||
|
|
|
@ -78,8 +78,6 @@ char * strlcpy_w(char *dst, const char *src, size_t *siz, const char *err, const
|
|||
return buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
#define HAVE_STRLCAT
|
||||
size_t strlcat(char *dst, const char *src, size_t siz)
|
||||
|
|
|
@ -76,16 +76,6 @@ void translist(void *l1, void *l2, void *p)
|
|||
addlist(l2, p);
|
||||
}
|
||||
|
||||
void insertlist(void_list ** l, void_list * p)
|
||||
{
|
||||
|
||||
/* insert entry p at the beginning of list l */
|
||||
|
||||
p->next = *l;
|
||||
*l = p;
|
||||
|
||||
}
|
||||
|
||||
void removelist(void *l, void *p)
|
||||
{
|
||||
|
||||
|
|
|
@ -33,14 +33,8 @@ extern "C" {
|
|||
void freestrlist(strlist * s);
|
||||
void addlist(void *l1, void *p1);
|
||||
void translist(void *l1, void *l2, void *p);
|
||||
#ifndef MALLOCDBG
|
||||
void freelist(void *p1);
|
||||
void removelist(void *l, void *p);
|
||||
#else
|
||||
#define freelist(p) { while (p) { void * p2 = p->next; free(p); p = p2; } }
|
||||
#define removelist(l,p) { choplist(l, p); free(p); }
|
||||
#endif
|
||||
|
||||
unsigned int listlen(void *l);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -60,7 +60,7 @@ arg_type *find_argtype(const char *name)
|
|||
|
||||
message_type *mt_new(const char *name, const char *args[])
|
||||
{
|
||||
int i, nparameters = 0;
|
||||
int nparameters = 0;
|
||||
message_type *mtype;
|
||||
|
||||
assert(name != NULL);
|
||||
|
@ -85,6 +85,8 @@ message_type *mt_new(const char *name, const char *args[])
|
|||
mtype->types = NULL;
|
||||
}
|
||||
if (args != NULL) {
|
||||
int i;
|
||||
|
||||
for (i = 0; args[i]; ++i) {
|
||||
const char *x = args[i];
|
||||
const char *spos = strchr(x, ':');
|
||||
|
|
|
@ -16,10 +16,8 @@
|
|||
#include "log.h"
|
||||
#include "assert.h"
|
||||
|
||||
#ifdef USE_LIBXML2
|
||||
#include <libxml/catalog.h>
|
||||
#include <libxml/xmlstring.h>
|
||||
#endif
|
||||
|
||||
/* libc includes */
|
||||
#include <stdio.h>
|
||||
|
@ -27,7 +25,6 @@
|
|||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef USE_LIBXML2
|
||||
int xml_ivalue(xmlNodePtr node, const char *name, int dflt)
|
||||
{
|
||||
int i = dflt;
|
||||
|
@ -110,11 +107,9 @@ void xml_register_callback(xml_callback callback)
|
|||
insert = &(*insert)->next;
|
||||
*insert = reader;
|
||||
}
|
||||
#endif
|
||||
|
||||
int read_xml(const char *filename, const char *catalog)
|
||||
{
|
||||
#ifdef USE_LIBXML2
|
||||
xml_reader *reader = xmlReaders;
|
||||
xmlDocPtr doc;
|
||||
int result;
|
||||
|
@ -141,8 +136,4 @@ int read_xml(const char *filename, const char *catalog)
|
|||
}
|
||||
xmlFreeDoc(doc);
|
||||
return result;
|
||||
#else
|
||||
log_error("LIBXML2 disabled, cannot read %s.\n", filename);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBXML2
|
||||
/* new xml functions: */
|
||||
#include <libxml/tree.h>
|
||||
|
||||
|
@ -30,7 +29,6 @@ extern "C" {
|
|||
double xml_fvalue(xmlNodePtr node, const char *name, double dflt);
|
||||
int xml_ivalue(xmlNodePtr node, const char *name, int dflt);
|
||||
bool xml_bvalue(xmlNodePtr node, const char *name, bool dflt);
|
||||
#endif
|
||||
|
||||
void xml_done(void);
|
||||
int read_xml(const char *filename, const char *catalog);
|
||||
|
|
Loading…
Reference in New Issue