forked from github/server
Das Thilo Gross System
This commit is contained in:
parent
a7acaff1c4
commit
9067a238cc
|
@ -247,11 +247,8 @@ change_level(unit * u, skill_t sk, int bylevel)
|
||||||
{
|
{
|
||||||
skill * sv = get_skill(u, sk);
|
skill * sv = get_skill(u, sk);
|
||||||
assert(bylevel>0);
|
assert(bylevel>0);
|
||||||
if (sv==0) set_skill(u, sk, bylevel, 0, false);
|
if (sv==0) sv = add_skill(u, sk);
|
||||||
else {
|
sk_set(sv, sv->level+bylevel);
|
||||||
sv->level = (unsigned char)(sv->level+bylevel);
|
|
||||||
sv->learning = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1468,18 +1468,25 @@ readgame(boolean backup)
|
||||||
if (global.data_version<NEWSKILL_VERSION) {
|
if (global.data_version<NEWSKILL_VERSION) {
|
||||||
/* convert old data */
|
/* convert old data */
|
||||||
while ((sk = (skill_t) ri(F)) != NOSKILL) {
|
while ((sk = (skill_t) ri(F)) != NOSKILL) {
|
||||||
int skill = ri(F) / u->number;
|
int days = ri(F) / u->number;
|
||||||
int lvl = level(skill);
|
int lvl = level(days);
|
||||||
int weeks = (skill - level_days(lvl))/30;
|
int weeks = lvl + 1 - (days - level_days(lvl))/30;
|
||||||
if (weeks || lvl) {
|
assert(weeks>0 && weeks<=lvl+1);
|
||||||
set_skill(u, sk, lvl, 2*weeks, true);
|
if (lvl) {
|
||||||
|
skill * sv = add_skill(u, sk);
|
||||||
|
sv->level = (unsigned char)lvl;
|
||||||
|
sv->weeks = (unsigned char)weeks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while ((sk = (skill_t) ri(F)) != NOSKILL) {
|
while ((sk = (skill_t) ri(F)) != NOSKILL) {
|
||||||
int level = ri(F);
|
int level = ri(F);
|
||||||
int weeks = ri(F);
|
int weeks = ri(F);
|
||||||
set_skill(u, sk, level, weeks, true);
|
if (level) {
|
||||||
|
skill * sv = add_skill(u, sk);
|
||||||
|
sv->level = (unsigned char)level;
|
||||||
|
sv->weeks = (unsigned char)weeks;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2069,11 +2076,11 @@ writegame(char *path, char quiet)
|
||||||
#else
|
#else
|
||||||
for (i=0;i!=u->skill_size;++i) {
|
for (i=0;i!=u->skill_size;++i) {
|
||||||
skill * sv = u->skills+i;
|
skill * sv = u->skills+i;
|
||||||
assert(sv->level>=0 && sv->learning>=0 && sv->learning<=sv->level*2);
|
assert(sv->level>=0 && sv->weeks>=0 && sv->weeks<=sv->level*2);
|
||||||
if (sv->learning || sv->level) {
|
if (sv->level>0) {
|
||||||
wi(F, sv->id);
|
wi(F, sv->id);
|
||||||
wi(F, sv->level);
|
wi(F, sv->level);
|
||||||
wi(F, sv->learning);
|
wi(F, sv->weeks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
/* libc includes */
|
/* libc includes */
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -257,46 +258,86 @@ level(int days)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !SKILLPOINTS
|
#if !SKILLPOINTS
|
||||||
void
|
|
||||||
reduce_skill(unit *u, skill * sv, int change)
|
/*
|
||||||
|
#define MAXLEVEL 32
|
||||||
|
static struct {
|
||||||
|
int permutations;
|
||||||
|
int * chances;
|
||||||
|
} upgrade[MAXLEVEL];
|
||||||
|
|
||||||
|
static double
|
||||||
|
fak(int n)
|
||||||
{
|
{
|
||||||
if (sv->learning>=change) {
|
int i;
|
||||||
/* just forget a few weeks */
|
double f=1;
|
||||||
sv->learning = (unsigned char)(sv->learning-change);
|
for (i=2;i<n;++i) f=f*i;
|
||||||
} else {
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sk_set(skill * sv, int level)
|
||||||
|
{
|
||||||
|
double i;
|
||||||
int weeks;
|
int weeks;
|
||||||
unsigned char oldlevel = sv->level;
|
int multi=1+(level/16);
|
||||||
attrib *a;
|
if (upgrade[level].permutations==0) {
|
||||||
|
int m;
|
||||||
change -= sv->learning;
|
int ctr = 1;
|
||||||
while (change>=sv->level && sv->level > 0) {
|
int n = level * 2 / multi;
|
||||||
change -= sv->level;
|
upgrade[level].permutations = 1 << n;
|
||||||
--sv->level;
|
if (n>0) upgrade[level].chances = malloc(sizeof(double)*n);
|
||||||
|
for (m=0;m!=n;++m) {
|
||||||
|
upgrade[level].chances[m] = (int)(fak(n)/(fak(m)*fak(n-m)));
|
||||||
|
ctr += upgrade[level].chances[m];
|
||||||
|
}
|
||||||
|
assert(ctr==upgrade[level].permutations);
|
||||||
|
}
|
||||||
|
i = rand() % upgrade[level].permutations;
|
||||||
|
for (weeks=0;weeks!=level*2/multi;++weeks) {
|
||||||
|
if (i<=upgrade[level].chances[weeks]) break;
|
||||||
|
else i-=upgrade[level].chances[weeks];
|
||||||
|
}
|
||||||
|
weeks*=multi;
|
||||||
|
sv->weeks = (unsigned char)(weeks+1);
|
||||||
|
sv->level = (unsigned char)level;
|
||||||
}
|
}
|
||||||
if (change && sv->level > 0 && change<sv->level) {
|
|
||||||
/* this is not an exact science... it would be better to set
|
|
||||||
* sv->learning so that the average time to rise was = change.
|
|
||||||
*/
|
*/
|
||||||
--sv->level;
|
|
||||||
weeks = (sv->level-change)*2;
|
|
||||||
} else {
|
|
||||||
weeks = 0;
|
|
||||||
}
|
|
||||||
sv->learning = (unsigned char)weeks;
|
|
||||||
|
|
||||||
for(a = a_find(u->attribs, &at_showskchange);a;a = a->nexttype) {
|
void
|
||||||
if(a->data.sa[0] == sv->id) {
|
sk_set(skill * sv, int level)
|
||||||
a->data.sa[1] = (short)(a->data.sa[1] + (sv->level-oldlevel));
|
{
|
||||||
break;
|
sv->weeks = (unsigned char)skill_weeks(level);
|
||||||
|
sv->level = (unsigned char)level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
skill_weeks(int level)
|
||||||
|
/* how many weeks must i study to get from level to level+1 */
|
||||||
|
{
|
||||||
|
/* derzeit gleichverteilt. MUSS geändert werden! */
|
||||||
|
return (1+rand()%(level*2+1));
|
||||||
}
|
}
|
||||||
if(a == NULL) {
|
|
||||||
a = a_add(&u->attribs, a_new(&at_showskchange));
|
void
|
||||||
a->data.sa[0] = sv->id;
|
reduce_skill(unit *u, skill * sv, int weeks)
|
||||||
a->data.sa[1] = (short)(sv->level-oldlevel);
|
{
|
||||||
|
boolean reroll = false;
|
||||||
|
while (sv->level>0 && weeks>sv->level) {
|
||||||
|
weeks -= sv->level;
|
||||||
|
--sv->level;
|
||||||
}
|
}
|
||||||
|
if (sv->level*2+1<sv->weeks) reroll = true;
|
||||||
|
if (sv->level>0) {
|
||||||
|
if (rand()%sv->level < weeks) {
|
||||||
|
--sv->level;
|
||||||
|
reroll = true;
|
||||||
}
|
}
|
||||||
assert(sv->level>=0 && sv->learning>=0 && sv->learning<=sv->level*2);
|
} else {
|
||||||
|
reroll = true;
|
||||||
|
}
|
||||||
|
if (reroll) sv->weeks = (unsigned char)skill_weeks(sv->level);
|
||||||
|
assert(sv->level>=0 && sv->weeks>=0 && sv->weeks<=sv->level*2);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -304,8 +345,8 @@ skill_compare(const skill * sk, const skill * sc)
|
||||||
{
|
{
|
||||||
if (sk->level > sc->level) return 1;
|
if (sk->level > sc->level) return 1;
|
||||||
if (sk->level < sc->level) return -1;
|
if (sk->level < sc->level) return -1;
|
||||||
if (sk->learning > sc->learning) return 1;
|
if (sk->weeks < sc->weeks) return 1;
|
||||||
if (sk->learning < sc->learning) return -1;
|
if (sk->weeks > sc->weeks) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,7 +29,7 @@ typedef struct skill {
|
||||||
#else
|
#else
|
||||||
unsigned char id;
|
unsigned char id;
|
||||||
unsigned char level;
|
unsigned char level;
|
||||||
unsigned char learning;
|
unsigned char weeks;
|
||||||
#endif
|
#endif
|
||||||
} skill;
|
} skill;
|
||||||
|
|
||||||
|
@ -58,7 +58,10 @@ extern int level(int days);
|
||||||
#else
|
#else
|
||||||
# define skill_level(level) (level)
|
# define skill_level(level) (level)
|
||||||
extern void reduce_skill(struct unit *u, skill * sv, int change);
|
extern void reduce_skill(struct unit *u, skill * sv, int change);
|
||||||
|
extern int skill_weeks(int level);
|
||||||
extern int skill_compare(const skill * sk, const skill * sc);
|
extern int skill_compare(const skill * sk, const skill * sc);
|
||||||
|
|
||||||
|
extern void sk_set(skill * sv, int level);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@ do_shock(unit *u, char *reason)
|
||||||
#else
|
#else
|
||||||
for (i=0;i!=u->skill_size;++i) if (rand()%5==0) {
|
for (i=0;i!=u->skill_size;++i) if (rand()%5==0) {
|
||||||
skill * sv = u->skills+i;
|
skill * sv = u->skills+i;
|
||||||
int weeks = (sv->level * sv->level - sv->level) / 2 + sv->learning;
|
int weeks = (sv->level * sv->level - sv->level) / 2;
|
||||||
int change = (weeks+9) / 10;
|
int change = (weeks+9) / 10;
|
||||||
reduce_skill(u, sv, change);
|
reduce_skill(u, sv, change);
|
||||||
}
|
}
|
||||||
|
|
|
@ -523,12 +523,14 @@ change_skill(unit * u, skill_t id, int byvalue)
|
||||||
static int
|
static int
|
||||||
change_skill_transfermen(unit * u, skill_t id, int byvalue)
|
change_skill_transfermen(unit * u, skill_t id, int byvalue)
|
||||||
{
|
{
|
||||||
skill *i = u->skills;
|
skill * sv = u->skills;
|
||||||
|
|
||||||
for (; i != u->skills + u->skill_size; ++i)
|
while (sv != u->skills + u->skill_size) {
|
||||||
if (i->id == id) {
|
if (sv->id == id) {
|
||||||
i->value = max(0, i->value + byvalue);
|
sv->value = max(0, sv->value + byvalue);
|
||||||
return i->value;
|
return sv->value;
|
||||||
|
}
|
||||||
|
++sv;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_skill(u, id, byvalue);
|
set_skill(u, id, byvalue);
|
||||||
|
@ -603,8 +605,7 @@ set_level(unit * u, skill_t id, int value)
|
||||||
skill * sv = u->skills;
|
skill * sv = u->skills;
|
||||||
while (sv != u->skills + u->skill_size) {
|
while (sv != u->skills + u->skill_size) {
|
||||||
if (sv->id == id) {
|
if (sv->id == id) {
|
||||||
sv->level = (unsigned char)value;
|
sk_set(sv, value);
|
||||||
sv->learning = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++sv;
|
++sv;
|
||||||
|
@ -775,20 +776,13 @@ transfermen(unit * u, unit * u2, int n)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
skill * sv;
|
skill * sv;
|
||||||
|
assert(u2->number+n>0);
|
||||||
for (sv=u->skills;sv!=u->skills+u->skill_size;++sv) {
|
for (sv=u->skills;sv!=u->skills+u->skill_size;++sv) {
|
||||||
if (u2->number == 0) {
|
|
||||||
set_skill(u2, sv->id, sv->level, sv->learning, false);
|
|
||||||
} else {
|
|
||||||
skill * sn = get_skill(u2, sv->id);
|
skill * sn = get_skill(u2, sv->id);
|
||||||
if (sn) {
|
if (sn==NULL) sn = add_skill(u2, sv->id);
|
||||||
int level = ((sv->level*n+sn->level*u2->number)/(u2->number+n));
|
/* level abrunden, wochen aufrunden. */
|
||||||
sn->level = (unsigned char)level;
|
sn->level = (unsigned char)((sv->level*n+sn->level*u2->number)/(u2->number+n));
|
||||||
if (sn->learning>sv->learning) sn->learning=sv->learning;
|
sn->weeks = (unsigned char)((sv->weeks*n+sn->weeks*u2->number+u2->number+n-1)/(u2->number+n));
|
||||||
} else {
|
|
||||||
int level = (sv->level*n/(u2->number+n));
|
|
||||||
set_level(u2, sv->id, level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
a = a_find(u->attribs, &at_effect);
|
a = a_find(u->attribs, &at_effect);
|
||||||
|
@ -921,18 +915,38 @@ set_number(unit * u, int count)
|
||||||
#if !SKILLPOINTS
|
#if !SKILLPOINTS
|
||||||
|
|
||||||
attrib_type at_showskchange = {
|
attrib_type at_showskchange = {
|
||||||
"showskchange", NULL, NULL, NULL, NULL, NULL
|
"showskchange", NULL, NULL, NULL, NULL, NULL, ATF_UNIQUE
|
||||||
};
|
};
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
learn_skill(unit * u, skill_t sk, double chance)
|
learn_skill(unit * u, skill_t sk, double chance)
|
||||||
{
|
{
|
||||||
|
skill * sv = u->skills;
|
||||||
|
if (chance < 1.0 && rand()%10000>=chance*10000) return false;
|
||||||
|
while (sv != u->skills + u->skill_size) {
|
||||||
|
assert (sv->weeks>0);
|
||||||
|
if (sv->id == sk) {
|
||||||
|
if (sv->weeks<=1) {
|
||||||
|
sk_set(sv, sv->level+1);
|
||||||
|
} else {
|
||||||
|
sv->weeks--;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
++sv;
|
||||||
|
}
|
||||||
|
++u->skill_size;
|
||||||
|
u->skills = realloc(u->skills, u->skill_size * sizeof(skill));
|
||||||
|
sv = (u->skills + u->skill_size - 1);
|
||||||
|
sk_set(sv, 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/*
|
||||||
int coins, heads = 0;
|
int coins, heads = 0;
|
||||||
int level = 0;
|
int level = 0;
|
||||||
int weeks = 0;
|
int weeks = 0;
|
||||||
skill * sv;
|
skill * sv;
|
||||||
assert (chance <= 1.0);
|
assert (chance <= 1.0);
|
||||||
if (chance < 1.0 && rand()%10000>=chance*10000) return false;
|
|
||||||
sv = get_skill(u, sk);
|
sv = get_skill(u, sk);
|
||||||
if (sv) {
|
if (sv) {
|
||||||
level = sv->level;
|
level = sv->level;
|
||||||
|
@ -953,29 +967,9 @@ learn_skill(unit * u, skill_t sk, double chance)
|
||||||
set_skill(u, sk, level, weeks, false);
|
set_skill(u, sk, level, weeks, false);
|
||||||
return heads==0;
|
return heads==0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
/*
|
||||||
set_skill(unit * u, skill_t id, int level, int weeks, boolean load)
|
|
||||||
{
|
|
||||||
attrib *a;
|
|
||||||
skill *i = u->skills;
|
|
||||||
unsigned char oldlevel = 0;
|
|
||||||
|
|
||||||
assert(level>=0 && weeks>=0 && weeks<=level*2);
|
|
||||||
for (; i != u->skills + u->skill_size; ++i) {
|
|
||||||
if (i->id == id) {
|
|
||||||
oldlevel = i->level;
|
|
||||||
if (level || weeks) {
|
|
||||||
i->level = (unsigned char)level;
|
|
||||||
i->learning = (unsigned char)weeks;
|
|
||||||
} else {
|
|
||||||
*i = *(u->skills + u->skill_size - 1);
|
|
||||||
--u->skill_size;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(load == false) {
|
if(load == false) {
|
||||||
for(a = a_find(u->attribs, &at_showskchange);a;a = a->nexttype) {
|
for(a = a_find(u->attribs, &at_showskchange);a;a = a->nexttype) {
|
||||||
if(a->data.sa[0] == id) {
|
if(a->data.sa[0] == id) {
|
||||||
|
@ -989,16 +983,24 @@ set_skill(unit * u, skill_t id, int level, int weeks, boolean load)
|
||||||
a->data.sa[1] = (short)(level-oldlevel);
|
a->data.sa[1] = (short)(level-oldlevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (!level && !weeks) {
|
skill *
|
||||||
return;
|
add_skill(unit * u, skill_t id)
|
||||||
|
{
|
||||||
|
skill * sv = u->skills;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
|
||||||
|
assert(sv->id != id);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
++u->skill_size;
|
++u->skill_size;
|
||||||
u->skills = realloc(u->skills, u->skill_size * sizeof(skill));
|
u->skills = realloc(u->skills, u->skill_size * sizeof(skill));
|
||||||
i = (u->skills + u->skill_size - 1);
|
sv = (u->skills + u->skill_size - 1);
|
||||||
i->level = (unsigned char)level;
|
sv->level = (unsigned char)0;
|
||||||
i->learning = (unsigned char)weeks;
|
sv->weeks = (unsigned char)1;
|
||||||
i->id = (unsigned char)id;
|
sv->id = (unsigned char)id;
|
||||||
|
return sv;
|
||||||
}
|
}
|
||||||
|
|
||||||
skill *
|
skill *
|
||||||
|
@ -1006,7 +1008,7 @@ get_skill(const unit * u, skill_t sk)
|
||||||
{
|
{
|
||||||
skill * sv = u->skills;
|
skill * sv = u->skills;
|
||||||
while (sv!=u->skills+u->skill_size) {
|
while (sv!=u->skills+u->skill_size) {
|
||||||
assert(sv->level>=0 && sv->learning>=0);
|
assert(sv->level>=0 && sv->weeks>=0);
|
||||||
if (sv->id==sk) return sv;
|
if (sv->id==sk) return sv;
|
||||||
++sv;
|
++sv;
|
||||||
}
|
}
|
||||||
|
@ -1018,9 +1020,9 @@ has_skill(const unit * u, skill_t sk)
|
||||||
{
|
{
|
||||||
skill * sv = u->skills;
|
skill * sv = u->skills;
|
||||||
while (sv!=u->skills+u->skill_size) {
|
while (sv!=u->skills+u->skill_size) {
|
||||||
assert(sv->level>=0 && sv->learning>=0);
|
assert(sv->level>=0 && sv->weeks>=0);
|
||||||
if (sv->id==sk) {
|
if (sv->id==sk) {
|
||||||
return (sv->level>0 || sv->learning>0);
|
return (sv->level>0);
|
||||||
}
|
}
|
||||||
++sv;
|
++sv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ extern int get_skill(const struct unit * u, skill_t id);
|
||||||
#define has_skill(u, id) (get_skill(u, id)>0)
|
#define has_skill(u, id) (get_skill(u, id)>0)
|
||||||
#define change_level(u, sk, bylevel) set_level(u, sk, max(0,get_level(u,sk)+bylevel));
|
#define change_level(u, sk, bylevel) set_level(u, sk, max(0,get_level(u,sk)+bylevel));
|
||||||
#else
|
#else
|
||||||
extern void set_skill(struct unit * u, skill_t id, int level, int weeks, boolean load);
|
extern struct skill * add_skill(struct unit * u, skill_t id);
|
||||||
extern struct skill * get_skill(const struct unit * u, skill_t id);
|
extern struct skill * get_skill(const struct unit * u, skill_t id);
|
||||||
extern boolean has_skill(const unit* u, skill_t sk);
|
extern boolean has_skill(const unit* u, skill_t sk);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue