forked from github/server
autostudy framework
This commit is contained in:
parent
0eb030194c
commit
ee8a02c425
|
@ -86,6 +86,7 @@ ENDIF()
|
|||
|
||||
set (ERESSEA_SRC
|
||||
vortex.c
|
||||
automate.c
|
||||
move.c
|
||||
piracy.c
|
||||
spells.c
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
#include <platform.h>
|
||||
|
||||
#include "kernel/faction.h"
|
||||
#include "kernel/order.h"
|
||||
#include "kernel/region.h"
|
||||
#include "kernel/unit.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
#include "automate.h"
|
||||
#include "keyword.h"
|
||||
#include "study.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct student {
|
||||
unit *u;
|
||||
skill_t sk;
|
||||
int level;
|
||||
} student;
|
||||
|
||||
#define MAXSTUDENTS 128
|
||||
|
||||
int cmp_students(const void *lhs, const void *rhs) {
|
||||
const student *a = (const student *)lhs;
|
||||
const student *b = (const student *)rhs;
|
||||
if (a->sk == b->sk) {
|
||||
/* sort by level, descending: */
|
||||
return b->level - a->level;
|
||||
}
|
||||
/* order by skill */
|
||||
return (int)a->sk - (int)b->sk;
|
||||
}
|
||||
|
||||
void do_autostudy(region *r) {
|
||||
unit *u;
|
||||
int nstudents = 0;
|
||||
student students[MAXSTUDENTS];
|
||||
|
||||
for (u = r->units; u; u = u->next) {
|
||||
keyword_t kwd = getkeyword(u->thisorder);
|
||||
if (kwd == K_AUTOSTUDY) {
|
||||
student * st = students + nstudents;
|
||||
if (++nstudents == MAXSTUDENTS) {
|
||||
log_fatal("you must increase MAXSTUDENTS");
|
||||
}
|
||||
st->u = u;
|
||||
init_order(u->thisorder, u->faction->locale);
|
||||
st->sk = getskill(u->faction->locale);
|
||||
st->level = effskill_study(u, st->sk);
|
||||
}
|
||||
}
|
||||
if (nstudents > 0) {
|
||||
int i, taught = 0;
|
||||
skill_t sk = NOSKILL;
|
||||
student *teacher = NULL, *student = NULL;
|
||||
|
||||
qsort(students, nstudents, sizeof(student), cmp_students);
|
||||
for (i = 0; i != nstudents; ++i) {
|
||||
if (students[i].u) {
|
||||
if (sk == NOSKILL) {
|
||||
sk = students[i].sk;
|
||||
}
|
||||
else if (sk != students[i].sk) {
|
||||
continue;
|
||||
}
|
||||
students[i].u = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
Copyright (c) 1998-2018, 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.
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef H_GC_AUTOMATE
|
||||
#define H_GC_AUTOMATE
|
||||
|
||||
struct region;
|
||||
|
||||
void do_autostudy(struct region *r);
|
||||
|
||||
#endif
|
|
@ -135,7 +135,8 @@ const char *parameters[MAXPARAMS] = {
|
|||
"GRUPPE",
|
||||
"PARTEITARNUNG",
|
||||
"BAEUME",
|
||||
"ALLIANZ"
|
||||
"ALLIANZ",
|
||||
"AUTO"
|
||||
};
|
||||
|
||||
int findoption(const char *s, const struct locale *lang)
|
||||
|
|
|
@ -214,12 +214,12 @@ static int create_data(keyword_t kwd, const char *s,
|
|||
order_data *data;
|
||||
int id;
|
||||
|
||||
assert(kwd!=NOKEYWORD);
|
||||
assert(kwd != NOKEYWORD);
|
||||
|
||||
if (!s || *s == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (kwd==K_STUDY) {
|
||||
if (kwd == K_STUDY || kwd == K_AUTOSTUDY) {
|
||||
const char * sptr = s;
|
||||
skill_t sk = get_skill(parse_token_depr(&sptr), lang);
|
||||
if (sk != SK_MAGIC && sk != NOSKILL) {
|
||||
|
@ -332,6 +332,14 @@ order *parse_order(const char *s, const struct locale * lang)
|
|||
sptr = sp;
|
||||
}
|
||||
}
|
||||
else if (kwd == K_STUDY) {
|
||||
const char *sp = sptr;
|
||||
p = parse_token_depr(&sp);
|
||||
if (p && isparam(p, lang, P_AUTO)) {
|
||||
kwd = K_AUTOSTUDY;
|
||||
sptr = sp;
|
||||
}
|
||||
}
|
||||
if (kwd != NOKEYWORD) {
|
||||
order *ord = (order *)malloc(sizeof(order));
|
||||
create_order_i(ord, kwd, sptr, persistent, noerror, lang);
|
||||
|
@ -366,6 +374,7 @@ bool is_repeated(keyword_t kwd)
|
|||
case K_STEAL:
|
||||
case K_SABOTAGE:
|
||||
case K_STUDY:
|
||||
case K_AUTOSTUDY:
|
||||
case K_TEACH:
|
||||
case K_GROW:
|
||||
case K_PLANT:
|
||||
|
@ -406,6 +415,7 @@ bool is_exclusive(const order * ord)
|
|||
case K_STEAL:
|
||||
case K_SABOTAGE:
|
||||
case K_STUDY:
|
||||
case K_AUTOSTUDY:
|
||||
case K_TEACH:
|
||||
case K_GROW:
|
||||
case K_PLANT:
|
||||
|
@ -447,6 +457,7 @@ bool is_long(keyword_t kwd)
|
|||
case K_STEAL:
|
||||
case K_SABOTAGE:
|
||||
case K_STUDY:
|
||||
case K_AUTOSTUDY:
|
||||
case K_TEACH:
|
||||
case K_GROW:
|
||||
case K_PLANT:
|
||||
|
@ -541,7 +552,7 @@ keyword_t init_order(const struct order *ord, const struct locale *lang)
|
|||
|
||||
assert(sk < MAXSKILLS);
|
||||
assert(lang);
|
||||
assert(kwd == K_STUDY);
|
||||
assert(kwd == K_STUDY || kwd == K_AUTOSTUDY);
|
||||
str = skillname(sk, lang);
|
||||
if (strchr(str, ' ') == NULL) {
|
||||
init_tokens_str(str);
|
||||
|
@ -575,7 +586,7 @@ keyword_t init_order_depr(const struct order *ord)
|
|||
{
|
||||
if (ord) {
|
||||
keyword_t kwd = ORD_KEYWORD(ord);
|
||||
assert(kwd != K_STUDY);
|
||||
assert(kwd != K_STUDY && kwd != K_AUTOSTUDY);
|
||||
}
|
||||
return init_order(ord, NULL);
|
||||
}
|
||||
|
|
|
@ -130,6 +130,7 @@ typedef enum {
|
|||
P_FACTIONSTEALTH,
|
||||
P_TREES,
|
||||
P_ALLIANCE,
|
||||
P_AUTO,
|
||||
MAXPARAMS,
|
||||
NOPARAM
|
||||
} param_t;
|
||||
|
|
|
@ -1310,13 +1310,12 @@ int eff_skill(const unit * u, const skill *sv, const region *r)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int effskill_study(const unit * u, skill_t sk, const region * r)
|
||||
int effskill_study(const unit * u, skill_t sk)
|
||||
{
|
||||
skill *sv = unit_skill(u, sk);
|
||||
if (sv && sv->level > 0) {
|
||||
int mlevel = sv->level;
|
||||
if (!r) r = u->region;
|
||||
mlevel += get_modifier(u, sv->id, sv->level, r, true);
|
||||
mlevel += get_modifier(u, sv->id, sv->level, u->region, true);
|
||||
if (mlevel > 0)
|
||||
return mlevel;
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ extern "C" {
|
|||
void clone_men(const struct unit *src, struct unit *dst, int n); /* like transfer, but do not subtract from src */
|
||||
|
||||
int eff_skill(const struct unit *u, const struct skill *sv, const struct region *r);
|
||||
int effskill_study(const struct unit *u, skill_t sk, const struct region *r);
|
||||
int effskill_study(const struct unit *u, skill_t sk);
|
||||
|
||||
int get_modifier(const struct unit *u, skill_t sk, int level,
|
||||
const struct region *r, bool noitem);
|
||||
|
|
|
@ -149,5 +149,6 @@ const char *keywords[MAXKEYWORDS] = {
|
|||
"promote",
|
||||
"pay",
|
||||
"loot",
|
||||
"autostudy",
|
||||
};
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ extern "C"
|
|||
K_PROMOTION,
|
||||
K_PAY,
|
||||
K_LOOT,
|
||||
K_AUTOSTUDY,
|
||||
MAXKEYWORDS,
|
||||
NOKEYWORD
|
||||
} keyword_t;
|
||||
|
|
|
@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <modules/gmcmd.h>
|
||||
|
||||
#include "alchemy.h"
|
||||
#include "automate.h"
|
||||
#include "battle.h"
|
||||
#include "economy.h"
|
||||
#include "keyword.h"
|
||||
|
@ -4001,6 +4002,7 @@ void init_processor(void)
|
|||
}
|
||||
|
||||
p += 10;
|
||||
add_proc_region(p, do_autostudy, "study automation");
|
||||
add_proc_order(p, K_TEACH, teach_cmd, PROC_THISORDER | PROC_LONGORDER,
|
||||
"Lehren");
|
||||
p += 10;
|
||||
|
|
|
@ -69,7 +69,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#define TEACH_ALL 1
|
||||
#define TEACH_FRIENDS
|
||||
|
||||
static skill_t getskill(const struct locale *lang)
|
||||
skill_t getskill(const struct locale *lang)
|
||||
{
|
||||
char token[128];
|
||||
const char * s = gettoken(token, sizeof(token));
|
||||
|
@ -331,7 +331,7 @@ int teach_cmd(unit * teacher, struct order *ord)
|
|||
sk = teachskill[t];
|
||||
}
|
||||
if (sk != NOSKILL
|
||||
&& effskill_study(teacher, sk, 0) - TEACHDIFFERENCE > effskill_study(student, sk, 0)) {
|
||||
&& effskill_study(teacher, sk) - TEACHDIFFERENCE > effskill_study(student, sk)) {
|
||||
teaching -= teach_unit(teacher, student, teaching, sk, true, &academy_students);
|
||||
}
|
||||
}
|
||||
|
@ -343,7 +343,7 @@ int teach_cmd(unit * teacher, struct order *ord)
|
|||
init_order(student->thisorder, student->faction->locale);
|
||||
sk = getskill(student->faction->locale);
|
||||
if (sk != NOSKILL
|
||||
&& effskill_study(teacher, sk, 0) - TEACHDIFFERENCE >= effskill(student, sk, 0)) {
|
||||
&& effskill_study(teacher, sk) - TEACHDIFFERENCE >= effskill(student, sk)) {
|
||||
teaching -= teach_unit(teacher, student, teaching, sk, true, &academy_students);
|
||||
}
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ int teach_cmd(unit * teacher, struct order *ord)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (effskill_study(student, sk, 0) > effskill_study(teacher, sk, 0)
|
||||
if (effskill_study(student, sk, NULL) > effskill_study(teacher, sk)
|
||||
- TEACHDIFFERENCE) {
|
||||
if (feedback) {
|
||||
ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "teach_asgood",
|
||||
|
|
|
@ -33,6 +33,7 @@ extern "C" {
|
|||
int study_cmd(struct unit *u, struct order *ord);
|
||||
|
||||
magic_t getmagicskill(const struct locale *lang);
|
||||
skill_t getskill(const struct locale *lang);
|
||||
bool is_migrant(struct unit *u);
|
||||
int study_cost(struct unit *u, skill_t talent);
|
||||
|
||||
|
|
Loading…
Reference in New Issue