forked from github/server
totaler rewrite von sp_deathcloud
This commit is contained in:
parent
97eb1eb81d
commit
0139fb99e6
|
@ -80,9 +80,6 @@
|
||||||
#include <attributes/targetregion.h>
|
#include <attributes/targetregion.h>
|
||||||
#include <attributes/hate.h>
|
#include <attributes/hate.h>
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
attrib_type at_deathcloud = {
|
|
||||||
"zauber_todeswolke", NULL, NULL, NULL, NULL, NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
attrib_type at_unitdissolve = {
|
attrib_type at_unitdissolve = {
|
||||||
"unitdissolve", NULL, NULL, NULL, a_writedefault, a_readdefault
|
"unitdissolve", NULL, NULL, NULL, a_writedefault, a_readdefault
|
||||||
|
@ -3311,52 +3308,129 @@ sp_unholypower(castorder *co)
|
||||||
* (FARCASTING | REGIONSPELL | TESTRESISTANCE)
|
* (FARCASTING | REGIONSPELL | TESTRESISTANCE)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef struct dc_data {
|
||||||
|
region * r;
|
||||||
|
unit * mage;
|
||||||
|
double strength;
|
||||||
|
int countdown;
|
||||||
|
boolean active;
|
||||||
|
} dc_data;
|
||||||
|
|
||||||
|
static void
|
||||||
|
dc_initialize(struct attrib *a)
|
||||||
|
{
|
||||||
|
dc_data * data = (dc_data *)malloc(sizeof(dc_data));
|
||||||
|
a->data.v = data;
|
||||||
|
data->active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dc_finalize(struct attrib * a)
|
||||||
|
{
|
||||||
|
free(a->data.v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dc_age(struct attrib * a)
|
||||||
|
/* age returns 0 if the attribute needs to be removed, !=0 otherwise */
|
||||||
|
{
|
||||||
|
dc_data * data = (dc_data *)a->data.v;
|
||||||
|
region * r = data->r;
|
||||||
|
unit ** up = &r->units;
|
||||||
|
unit * mage = data->mage;
|
||||||
|
unit * u;
|
||||||
|
|
||||||
|
if (mage==NULL) {
|
||||||
|
/* if the mage disappears, so does the spell. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->active) while (*up!=NULL) {
|
||||||
|
unit * u = *up;
|
||||||
|
double damage = data->strength * u->number;
|
||||||
|
|
||||||
|
freset(u->faction, FL_DH);
|
||||||
|
if (target_resists_magic(mage, u, TYP_UNIT, 0)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reduziert durch Magieresistenz */
|
||||||
|
damage *= (1.0 - magic_resistance(u));
|
||||||
|
change_hitpoints(u, -(int)damage);
|
||||||
|
|
||||||
|
if (*up==u) up=&u->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* melden, 1x pro Partei */
|
||||||
|
for (u = r->units; u; u = u->next ) {
|
||||||
|
if (!fval(u->faction, FL_DH) ) {
|
||||||
|
fset(u->faction, FL_DH);
|
||||||
|
ADDMSG(&u->faction->msgs, msg_message("deathcloud_effect",
|
||||||
|
"mage region", cansee(u->faction, r, mage, 0) ? mage : NULL, r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fval(mage->faction, FL_DH)){
|
||||||
|
ADDMSG(&mage->faction->msgs, msg_message("deathcloud_effect",
|
||||||
|
"mage region", mage, r));
|
||||||
|
}
|
||||||
|
|
||||||
|
return --data->countdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dc_write(const struct attrib * a, FILE* F)
|
||||||
|
{
|
||||||
|
const dc_data * data = (const dc_data *)a->data.v;
|
||||||
|
fprintf(F, "%d %lf ", data->countdown, data->strength);
|
||||||
|
write_unit_reference(data->mage, F);
|
||||||
|
write_region_reference(data->r, F);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dc_read(struct attrib * a, FILE* F)
|
||||||
|
/* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */
|
||||||
|
{
|
||||||
|
dc_data * data = (dc_data *)a->data.v;
|
||||||
|
fscanf(F, "%d %lf ", &data->countdown, &data->strength);
|
||||||
|
read_unit_reference(&data->mage, F);
|
||||||
|
return read_region_reference(&data->r, F);
|
||||||
|
}
|
||||||
|
|
||||||
|
attrib_type at_deathcloud = {
|
||||||
|
"zauber_todeswolke", dc_initialize, dc_finalize, dc_age, dc_write, dc_read
|
||||||
|
};
|
||||||
|
|
||||||
|
static attrib *
|
||||||
|
mk_deathcloud(unit * mage, region * r, double strength, int duration)
|
||||||
|
{
|
||||||
|
attrib * a = a_new(&at_deathcloud);
|
||||||
|
dc_data * data = (dc_data *)a->data.v;
|
||||||
|
|
||||||
|
data->countdown = duration;
|
||||||
|
data->r = r;
|
||||||
|
data->mage = mage;
|
||||||
|
data->strength = strength;
|
||||||
|
data->active = false;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sp_deathcloud(castorder *co)
|
sp_deathcloud(castorder *co)
|
||||||
{
|
{
|
||||||
unit *u;
|
region *r = co->rt;
|
||||||
double damage;
|
unit *mage = (unit *)co->magician;
|
||||||
region *r = co->rt;
|
|
||||||
unit *mage = (unit *)co->magician;
|
|
||||||
int cast_level = co->level;
|
|
||||||
|
|
||||||
attrib *a = a_find(r->attribs, &at_deathcloud);
|
attrib *a = a_find(r->attribs, &at_deathcloud);
|
||||||
|
|
||||||
if(a){
|
if (a!=NULL) {
|
||||||
report_failure(mage, co->order);
|
report_failure(mage, co->order);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u = r->units; u; u = u->next){
|
a_add(&r->attribs, mk_deathcloud(mage, r, co->force/2, co->level));
|
||||||
if (target_resists_magic(mage, u, TYP_UNIT, 0)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Jede Person verliert 18 HP */
|
|
||||||
damage = 18 * u->number;
|
|
||||||
/* Reduziert durch Magieresistenz */
|
|
||||||
damage *= (1.0 - magic_resistance(u));
|
|
||||||
change_hitpoints(u, -(int)damage);
|
|
||||||
}
|
|
||||||
|
|
||||||
a = a_add(&r->attribs, a_new(&at_deathcloud));
|
return co->level;
|
||||||
|
|
||||||
/* melden, 1x pro Partei */
|
|
||||||
for (u = r->units; u; u = u->next) freset(u->faction, FL_DH);
|
|
||||||
|
|
||||||
for(u = r->units; u; u = u->next ) {
|
|
||||||
if(!fval(u->faction, FL_DH) ) {
|
|
||||||
fset(u->faction, FL_DH);
|
|
||||||
add_message(&u->faction->msgs, new_message(u->faction,
|
|
||||||
"deathcloud_effect%u:mage%r:region",
|
|
||||||
cansee(u->faction, r, mage, 0) ? mage:NULL, r));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!fval(mage->faction, FL_DH)){
|
|
||||||
add_message(&mage->faction->msgs, new_message(mage->faction,
|
|
||||||
"deathcloud_effect%u:mage%r:region", mage, r));
|
|
||||||
}
|
|
||||||
|
|
||||||
return cast_level;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -465,20 +465,17 @@ write_unit_reference(const unit * u, FILE * F)
|
||||||
int
|
int
|
||||||
read_unit_reference(unit ** up, FILE * F)
|
read_unit_reference(unit ** up, FILE * F)
|
||||||
{
|
{
|
||||||
char zId[10];
|
char zId[10];
|
||||||
int i;
|
int i;
|
||||||
fscanf(F, "%s", zId);
|
|
||||||
if (up==NULL) {
|
assert(up!=NULL);
|
||||||
return AT_READ_FAIL;
|
fscanf(F, "%s", zId);
|
||||||
}
|
i = atoi36(zId);
|
||||||
i = atoi36(zId);
|
assert(i!=0);
|
||||||
if (i==0) {
|
|
||||||
*up = NULL;
|
*up = findunit(i);
|
||||||
return AT_READ_FAIL;
|
if (*up==NULL) ur_add((void*)i, (void**)up, resolve_unit);
|
||||||
}
|
return AT_READ_OK;
|
||||||
*up = findunit(i);
|
|
||||||
if (*up==NULL) ur_add((void*)i, (void**)up, resolve_unit);
|
|
||||||
return AT_READ_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attrib_type at_stealth = {
|
attrib_type at_stealth = {
|
||||||
|
|
|
@ -40,19 +40,22 @@ __at_hashkey(const char* s)
|
||||||
void
|
void
|
||||||
at_register(attrib_type * at)
|
at_register(attrib_type * at)
|
||||||
{
|
{
|
||||||
attrib_type * find;
|
attrib_type * find;
|
||||||
|
|
||||||
at->hashkey = __at_hashkey(at->name);
|
if (at->read==NULL) {
|
||||||
find = at_hash[at->hashkey % MAXATHASH];
|
log_warning(("registering non-persistent attribute %s.\n", at->name));
|
||||||
while (find && at->hashkey!=find->hashkey) find = find->nexthash;
|
}
|
||||||
if (find && find==at) {
|
at->hashkey = __at_hashkey(at->name);
|
||||||
log_warning(("attribute '%s' was registered more than once\n", at->name));
|
find = at_hash[at->hashkey % MAXATHASH];
|
||||||
return;
|
while (find && at->hashkey!=find->hashkey) find = find->nexthash;
|
||||||
} else {
|
if (find && find==at) {
|
||||||
assert(!find || !"hashkey is already in use");
|
log_warning(("attribute '%s' was registered more than once\n", at->name));
|
||||||
}
|
return;
|
||||||
at->nexthash = at_hash[at->hashkey % MAXATHASH];
|
} else {
|
||||||
at_hash[at->hashkey % MAXATHASH] = at;
|
assert(!find || !"hashkey is already in use");
|
||||||
|
}
|
||||||
|
at->nexthash = at_hash[at->hashkey % MAXATHASH];
|
||||||
|
at_hash[at->hashkey % MAXATHASH] = at;
|
||||||
}
|
}
|
||||||
|
|
||||||
static attrib_type *
|
static attrib_type *
|
||||||
|
|
|
@ -178,6 +178,11 @@ unit_removespell(unit& u, const spell * sp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
unit_hpmax(const unit& u)
|
||||||
|
{
|
||||||
|
return unit_max_hp(&u);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bind_unit(lua_State * L)
|
bind_unit(lua_State * L)
|
||||||
|
@ -192,6 +197,8 @@ bind_unit(lua_State * L)
|
||||||
.def_readonly("region", &unit::region)
|
.def_readonly("region", &unit::region)
|
||||||
.def_readonly("faction", &unit::faction)
|
.def_readonly("faction", &unit::faction)
|
||||||
.def_readonly("id", &unit::no)
|
.def_readonly("id", &unit::no)
|
||||||
|
.def_readwrite("hp", &unit::hp)
|
||||||
|
.def("hp_max", &unit_hpmax)
|
||||||
.def("get_item", &unit_getitem)
|
.def("get_item", &unit_getitem)
|
||||||
.def("add_item", &unit_additem)
|
.def("add_item", &unit_additem)
|
||||||
.def("get_skill", &unit_getskill)
|
.def("get_skill", &unit_getskill)
|
||||||
|
|
Loading…
Reference in New Issue