void rpgent::tryattack(vec &lookatpos, rpgobj &weapon) { if(lastmillis-lastaction<weapon.s_attackrate) return; lastaction = lastmillis; switch(weapon.s_usetype) { case 1: if(!weapon.s_damage) return; weapon.usesound(this); loopallrpgobjsexcept(ro) tryattackobj(*eo, weapon); break; case 2: { if(!weapon.s_damage) return; weapon.usesound(this); particle_splash(PART_SPARK, 200, 250, lookatpos, 0xB49B4B, 0.24f); vec flarestart = o; flarestart.z -= 2; particle_flare(flarestart, lookatpos, 600, PART_STREAK, 0xFFC864, 0.28f); // FIXME hudgunorigin(), and shorten to maxrange float bestdist = 1e16f; rpgobj *best = NULL; loopallrpgobjsexcept(ro) { if(eo->ent->state!=CS_ALIVE) continue; if(!intersect(eo->ent, o, lookatpos)) continue; float dist = o.dist(eo->ent->o); if(dist<weapon.s_maxrange && dist<bestdist) { best = eo; bestdist = dist; } } if(best) weapon.useaction(*best, *this, true); break; } case 3: if(weapon.s_maxrange) // projectile, cast on target { if(magicprojectile) return; // only one in the air at once if(!ro->usemana(weapon)) return; magicprojectile = true; mpweapon = &weapon; mppos = o; //mpdir = vec(yaw*RAD, pitch*RAD); float worlddist = lookatpos.dist(o, mpdir); mpdir.normalize(); mpdist = min(float(weapon.s_maxrange), worlddist); } else { weapon.useaction(*ro, *this, true); // cast on self } break; } }
void finalize() { center = vec(bbmin).add(bbmax).mul(0.5f); radius = bbmin.dist(bbmax)/2; bborigin = ivec(int(floor(bbmin.x)), int(floor(bbmin.y)), int(floor(bbmin.z))); bbsize = ivec(int(ceil(bbmax.x)), int(ceil(bbmax.y)), int(ceil(bbmax.z))).sub(bborigin); if(dbgpseed) conoutf(CON_DEBUG, "radius: %f, maxfade: %d", radius, maxfade); }
void finalize() { center = vec(bbmin).add(bbmax).mul(0.5f); radius = bbmin.dist(bbmax)/2; cullmin = ivec(int(floor(bbmin.x)), int(floor(bbmin.y)), int(floor(bbmin.z))); cullmax = ivec(int(ceil(bbmax.x)), int(ceil(bbmax.y)), int(ceil(bbmax.z))); if(dbgpseed) spdlog::get("global")->debug("radius: {0}, maxfade: {1}", radius, maxfade); }
void finalize() { center = vec(bbmin).add(bbmax).mul(0.5f); radius = bbmin.dist(bbmax)/2; cullmin = ivec::floor(bbmin); cullmax = ivec::ceil(bbmax); if(dbgpseed) conoutf(CON_DEBUG, "radius: %f, maxfade: %d", radius, maxfade); }
bool effect::drawline(vec &from, vec &to, float size, int type, int elapse) { if(size <= 0) return false; size *= this->size; int fade, gravity, num; setvars(this, type, fade, gravity, num); num *= from.dist(to) / (10 * size) * partmul * (elapse ? logf(elapse) / 3 : 1); if(particle == PART_STREAK || particle == PART_LIGHTNING) num /= 2; num = min<int>(min(num, linemaxsteps), from.dist(to) / linemininterval); if(!num) return false; vec delta = vec(to).sub(from).div(num); loopi(num) { switch(particle) { case PART_EXPLOSION: case PART_EXPLOSION_BLUE: particle_fireball(from, size * 2, particle, fade, colour, size * 2); break; case PART_STREAK: case PART_LIGHTNING: { if(!curtime) return false; vec start = vec(rnd(360) * RAD, rnd(360) * RAD).mul(4 * size).add(from); vec end = vec(delta).mul(1.5).add(start); particle_flare(start, end, fade, particle, colour, size); break; } default: particle_splash(particle, 2, fade, from, colour, size, max<int>(1, size * 5), gravity); break; } from.add(delta); } return true; }
bool getsight(vec &o, float yaw, float pitch, vec &q, vec &v, float mdist, float fovx, float fovy) { float dist = o.dist(q); if(dist <= mdist) { float x = fmod(fabs(asin((q.z-o.z)/dist)/RAD-pitch), 360); float y = fmod(fabs(-atan2(q.x-o.x, q.y-o.y)/RAD-yaw), 360); if(min(x, 360-x) <= fovx && min(y, 360-y) <= fovy) return raycubelos(o, q, v); } return false; }
bool getsight(vec &o, float yaw, float pitch, vec &q, vec &v, float mdist, float fovx, float fovy) { float dist = o.dist(q); if(dist <= mdist) { float x = fabs((asin((q.z-o.z)/dist)/RAD)-pitch); float y = fabs((-(float)atan2(q.x-o.x, q.y-o.y)/PI*180+180)-yaw); if(x <= fovx && y <= fovy) return raycubelos(o, q, v); } return false; }
void TargetingControl::intersectClosestMapmodel(vec &from, vec &to, float& dist, extentity*& target) { vec unitv; float maxdist = to.dist(from, unitv); unitv.div(maxdist); vec hitpos; int orient, ent; extern float rayent(const vec &o, const vec &ray, float radius, int mode, int size, int &orient, int &ent); dist = rayent(from, unitv, 1000.0f, RAY_CLIPMAT|RAY_ALPHAPOLY/*was: RAY_ENTS*/, 0, orient, ent); // TODO: maxdist, or 1000.0f...? if (ent != -1) target = entities::storage[ent]; else { target = NULL; dist = -1; }; }
void TargetingControl::intersectClosestDynamicEntity(vec &from, vec &to, physent *targeter, float& dist, dynent*& target) { dynent *best = NULL; float bestdist = 1e16f; loopi(game::numdynents()) { dynent *o = game::iterdynents(i); if(!o || o==targeter) continue; if(!game::intersect(o, from, to)) continue; float dist = from.dist(o->o); if(dist<bestdist) { best = o; bestdist = dist; } } dist = bestdist; target = best; }
void adddynlight(const vec &o, float radius, const vec &color, int fade, int peak, int flags, float initradius, const vec &initcolor, physent *owner) { if(renderpath==R_FIXEDFUNCTION ? !ffdynlights || maxtmus<3 : !maxdynlights) return; if(o.dist(camera1->o) > dynlightdist) return; int insert = 0, expire = fade + peak + lastmillis; loopvrev(dynlights) if(expire>=dynlights[i].expire && (!(flags&DL_KEEP) || (dynlights[i].flags&DL_KEEP))) { insert = i+1; break; } dynlight d; d.o = o; d.radius = radius; d.initradius = initradius; d.color = color; d.initcolor = initcolor; d.fade = fade; d.peak = peak; d.expire = expire; d.flags = flags; d.owner = owner; dynlights.insert(insert, d); }
void adddynlight(const vec &o, float radius, const vec &color, int fade, int peak, int flags, float initradius, const vec &initcolor, physent *owner) { if(!maxdynlights) return; if(o.dist(camera1->o) > dynlightdist || radius <= 0) return; int insert = 0, expire = fade + peak + lastmillis; loopvrev(dynlights) if(expire>=dynlights[i].expire) { insert = i+1; break; } dynlight d; d.o = d.hud = o; d.radius = radius; d.initradius = initradius; d.color = color; d.initcolor = initcolor; d.fade = fade; d.peak = peak; d.expire = expire; d.flags = flags; d.owner = owner; dynlights.insert(insert, d); }