#include #include #include #include #include #include "bullet_s.h" #include "exception.h" #include "explosion_s.h" #include "item_s.h" #include "parse.h" #include "person_s.h" #include "weapon_s.h" using namespace JFK::server; using std::string; using std::min; person::person(const string& iname) : JFK::person(iname), drunk(0), firing(0), reload_time(0) { } void person::assign(const object* o) { *this = *dynamic_cast(o); } string person::diffstring(const object* oldobj) const { std::ostringstream oss; const person* o = dynamic_cast(oldobj); int weapons = 0; int oldweapons = 0; for (size_t i = 0; i < MAX_WEAPON; i++) { if (hasweapon[i]) weapons |= 1 << i; if (o->hasweapon[i]) oldweapons |= 1 << i; } if (v != o->v) oss << "v=" << v << ' '; if (w != o->w) oss << "w=" << w << ' '; if (curweapon != o->curweapon) oss << "curweapon=" << curweapon << ' '; if (weapons != oldweapons) oss << "weapons=" << weapons << ' '; if (blocked != o->blocked) oss << "blocked=" << blocked << ' '; if (health != o->health) oss << "health=" << health << ' '; if (ammo[curweapon] != o->ammo[o->curweapon]) oss << "ammo=" << ammo[curweapon] << ' '; if (score != o->score) oss << "score=" << score << ' '; if (deaths != o->deaths) oss << "deaths=" << deaths << ' '; if (oss.str().length() > 0) { oss << "x=" << x << " y=" << y << " dx=" << dx << " dy=" << dy; } return oss.str(); } object* person::action(double t) { bullet* ret = NULL; if (reload_time > 0.0) reload_time -= t; if (reload_time <= 0.0 && firing && ammo[curweapon] > 0) { /* create the new bullet in an adequate distance, so that this * player isn't hurt by his own bullet */ // +2 to avoid suicide with watergun... ret = new bullet(curweapon, this); ret->x = x + (r + bulletdata[curweapon].r + 2) * dx; ret->y = y + (r + bulletdata[curweapon].r + 2) * dy; ret->dx = dx; ret->dy = dy; reload_time = bulletdata[curweapon].reload_time; ammo[curweapon]--; } /* random turns if drunk */ if (std::rand() / (RAND_MAX + 1.0) < t * drunk * 0.1) { w += 0.04 * std::rand() / (RAND_MAX + 1.0) - 0.02; } /* let's become sober again */ if (drunk > 0 && std::rand() / (RAND_MAX + 1.0) < t * 0.001) { drunk--; } if (health <= 0) { suicide = true; } return ret; } void person::delegate_collision(object* obj) const { obj->collide_with_person(this); } void person::collide_with_bullet(const bullet* b) { health -= b->damage; person *o = dynamic_cast(b->originator.operator->()); o->score += b->damage; } void person::collide_with_explosion(const explosion* e) { health -= 20; /* punish those who bomb themselves up */ person *o = dynamic_cast(e->originator.operator->()); o->score += this != o ? 20 : -40; } void person::collide_with_item(const item* i) { switch (i->type) { case MEDIKIT_20: health = min(health + 20, 100); break; case MEDIKIT_50: health = min(health + 50, 100); break; case MUNITION_50: ammo[curweapon] += 50 / bulletdata[curweapon].ammo_cost; break; case MUNITION_100: ammo[curweapon] += 100 / bulletdata[curweapon].ammo_cost; break; case ALK: drunk++; break; case GRAVE: break; default: assert(0); } } void person::collide_with_obstacle(const obstacle*) { blocked = true; } void person::collide_with_weapon(const weapon* w) { assert(w->type >= 0 && w->type < MAX_WEAPON); hasweapon[w->type] = true; ammo[w->type] += 200 / bulletdata[w->type].ammo_cost; } void person::collide_with_person(const person*) { blocked = true; }