Clean up DynamicEntity

FossilOrigin-Name: b787ad5a04fc238a69b9e48b3bdfccde416f636a021eef0d955445b5ab92252b
This commit is contained in:
Jonathan Schleifer 2025-03-22 23:10:13 +00:00
parent fd2b1dddf0
commit a7db00c740
24 changed files with 561 additions and 540 deletions

View file

@ -232,7 +232,7 @@ VARP(minmillis, 0, 5, 1000);
static float fps = 30.0f;
fps = (1000.0f / curtime + fps * 50) / 51;
computeraytable(player1.o.x, player1.o.y);
computeraytable(player1.origin.x, player1.origin.y);
readdepth(_width, _height);
SDL_GL_SwapWindow(_window);
extern void updatevol();

View file

@ -4,52 +4,55 @@
@interface DynamicEntity: OFObject <OFCopying>
@property (class, readonly, nonatomic) size_t serializedSize;
// origin, velocity
@property (nonatomic) OFVector3D o, vel;
@property (nonatomic) OFVector3D origin, velocity;
// used as OFVector3D in one place
@property (nonatomic) float yaw, pitch, roll;
// cubes per second, 24 for player
@property (nonatomic) float maxspeed;
@property (nonatomic) float maxSpeed;
// from his eyes
@property (nonatomic) bool outsidemap;
@property (nonatomic) bool inwater;
@property (nonatomic) bool onfloor, jumpnext;
@property (nonatomic) bool outsideMap;
@property (nonatomic) bool inWater;
@property (nonatomic) bool onFloor, jumpNext;
@property (nonatomic) int move, strafe;
// see input code
@property (nonatomic) bool k_left, k_right, k_up, k_down;
// used for fake gravity
@property (nonatomic) int timeinair;
@property (nonatomic) int timeInAir;
// bounding box size
@property (nonatomic) float radius, eyeheight, aboveeye;
@property (nonatomic) int lastupdate, plag, ping;
@property (nonatomic) float radius, eyeHeight, aboveEye;
@property (nonatomic) int lastUpdate, lag, ping;
// sequence id for each respawn, used in damage test
@property (nonatomic) int lifesequence;
@property (nonatomic) int lifeSequence;
// one of CS_* below
@property (nonatomic) int state;
@property (nonatomic) int frags;
@property (nonatomic) int health, armour, armourtype, quadmillis;
@property (nonatomic) int gunselect, gunwait;
@property (nonatomic) int lastaction, lastattackgun, lastmove;
@property (nonatomic) int health, armour, armourType, quadMillis;
@property (nonatomic) int gunSelect, gunWait;
@property (nonatomic) int lastAction, lastAttackGun, lastMove;
@property (nonatomic) bool attacking;
@property (readonly, nonatomic) int *ammo;
// one of M_* below, M_NONE means human
@property (nonatomic) int monsterstate;
// see monster.cpp
@property (nonatomic) int mtype;
@property (nonatomic) int monsterState;
// see monster.m
@property (nonatomic) int monsterType;
// monster wants to kill this entity
@property (nonatomic) DynamicEntity *enemy;
// monster wants to look in this direction
@property (nonatomic) float targetyaw;
@property (nonatomic) float targetYaw;
// used by physics to signal ai
@property (nonatomic) bool blocked, moving;
// millis at which transition to another monsterstate takes place
@property (nonatomic) int trigger;
// delayed attacks
@property (nonatomic) OFVector3D attacktarget;
@property (nonatomic) OFVector3D attackTarget;
// how many times already hit by fellow monster
@property (nonatomic) int anger;
@property (copy, nonatomic) OFString *name, *team;
+ (instancetype)entity;
- (OFData *)dataBySerializing;
- (void)setFromSerializedData:(OFData *)data;
- (void)resetMovement;
// reset player state not persistent accross spawns
- (void)resetToSpawnState;
@end

View file

@ -3,37 +3,42 @@
#include "cube.h"
struct dynent {
OFVector3D o, vel;
OFVector3D origin, velocity;
float yaw, pitch, roll;
float maxspeed;
bool outsidemap;
bool inwater;
bool onfloor, jumpnext;
float maxSpeed;
bool outsideMap;
bool inWater;
bool onFloor, jumpNext;
int move, strafe;
bool k_left, k_right, k_up, k_down;
int timeinair;
float radius, eyeheight, aboveeye;
int lastupdate, plag, ping;
int lifesequence;
int timeInAir;
float radius, eyeHeight, aboveEye;
int lastUpdate, lag, ping;
int lifeSequence;
int state;
int frags;
int health, armour, armourtype, quadmillis;
int gunselect, gunwait;
int lastaction, lastattackgun, lastmove;
int health, armour, armourType, quadMillis;
int gunSelect, gunWait;
int lastAction, lastAttackGun, lastMove;
bool attacking;
int ammo[NUMGUNS];
int monsterstate;
int mtype;
int monsterState;
int monsterType;
void *enemy;
float targetyaw;
float targetYaw;
bool blocked, moving;
int trigger;
OFVector3D attacktarget;
OFVector3D attackTarget;
int anger;
char name[260], team[260];
};
@implementation DynamicEntity
+ (instancetype)entity
{
return [[self alloc] init];
}
+ (size_t)serializedSize
{
return sizeof(struct dynent);
@ -45,6 +50,17 @@ struct dynent {
_ammo = (int *)OFAllocZeroedMemory(NUMGUNS, sizeof(int));
_yaw = 270;
_maxSpeed = 22;
_radius = 1.1f;
_eyeHeight = 3.2f;
_aboveEye = 0.7f;
_lastUpdate = lastmillis;
_name = _team = @"";
_state = CS_ALIVE;
[self resetToSpawnState];
return self;
}
@ -57,54 +73,54 @@ struct dynent {
{
DynamicEntity *copy = [[self.class alloc] init];
copy->_o = _o;
copy->_vel = _vel;
copy->_origin = _origin;
copy->_velocity = _velocity;
copy->_yaw = _yaw;
copy->_pitch = _pitch;
copy->_roll = _roll;
copy->_maxspeed = _maxspeed;
copy->_outsidemap = _outsidemap;
copy->_inwater = _inwater;
copy->_onfloor = _onfloor;
copy->_jumpnext = _jumpnext;
copy->_maxSpeed = _maxSpeed;
copy->_outsideMap = _outsideMap;
copy->_inWater = _inWater;
copy->_onFloor = _onFloor;
copy->_jumpNext = _jumpNext;
copy->_move = _move;
copy->_strafe = _strafe;
copy->_k_left = _k_left;
copy->_k_right = _k_right;
copy->_k_up = _k_up;
copy->_k_down = _k_down;
copy->_timeinair = _timeinair;
copy->_timeInAir = _timeInAir;
copy->_radius = _radius;
copy->_eyeheight = _eyeheight;
copy->_aboveeye = _aboveeye;
copy->_lastupdate = _lastupdate;
copy->_plag = _plag;
copy->_eyeHeight = _eyeHeight;
copy->_aboveEye = _aboveEye;
copy->_lastUpdate = _lastUpdate;
copy->_lag = _lag;
copy->_ping = _ping;
copy->_lifesequence = _lifesequence;
copy->_lifeSequence = _lifeSequence;
copy->_state = _state;
copy->_frags = _frags;
copy->_health = _health;
copy->_armour = _armour;
copy->_armourtype = _armourtype;
copy->_quadmillis = _quadmillis;
copy->_gunselect = _gunselect;
copy->_gunwait = _gunwait;
copy->_lastaction = _lastaction;
copy->_lastattackgun = _lastattackgun;
copy->_lastmove = _lastmove;
copy->_armourType = _armourType;
copy->_quadMillis = _quadMillis;
copy->_gunSelect = _gunSelect;
copy->_gunWait = _gunWait;
copy->_lastAction = _lastAction;
copy->_lastAttackGun = _lastAttackGun;
copy->_lastMove = _lastMove;
copy->_attacking = _attacking;
for (size_t i = 0; i < NUMGUNS; i++)
copy->_ammo[i] = _ammo[i];
copy->_monsterstate = _monsterstate;
copy->_mtype = _mtype;
copy->_monsterState = _monsterState;
copy->_monsterType = _monsterType;
copy->_enemy = _enemy;
copy->_targetyaw = _targetyaw;
copy->_targetYaw = _targetYaw;
copy->_blocked = _blocked;
copy->_moving = _moving;
copy->_trigger = _trigger;
copy->_attacktarget = _attacktarget;
copy->_attackTarget = _attackTarget;
copy->_anger = _anger;
copy->_name = [_name copy];
@ -117,49 +133,49 @@ struct dynent {
{
// This is frighteningly *TERRIBLE*, but the format used by existing
// savegames.
struct dynent data = { .o = _o,
.vel = _vel,
struct dynent data = { .origin = _origin,
.velocity = _velocity,
.yaw = _yaw,
.pitch = _pitch,
.roll = _roll,
.maxspeed = _maxspeed,
.outsidemap = _outsidemap,
.inwater = _inwater,
.onfloor = _onfloor,
.jumpnext = _jumpnext,
.maxSpeed = _maxSpeed,
.outsideMap = _outsideMap,
.inWater = _inWater,
.onFloor = _onFloor,
.jumpNext = _jumpNext,
.move = _move,
.strafe = _strafe,
.k_left = _k_left,
.k_right = _k_right,
.k_up = _k_up,
.k_down = _k_down,
.timeinair = _timeinair,
.timeInAir = _timeInAir,
.radius = _radius,
.eyeheight = _eyeheight,
.aboveeye = _aboveeye,
.lastupdate = _lastupdate,
.plag = _plag,
.eyeHeight = _eyeHeight,
.aboveEye = _aboveEye,
.lastUpdate = _lastUpdate,
.lag = _lag,
.ping = _ping,
.lifesequence = _lifesequence,
.lifeSequence = _lifeSequence,
.state = _state,
.frags = _frags,
.health = _health,
.armour = _armour,
.armourtype = _armourtype,
.quadmillis = _quadmillis,
.gunselect = _gunselect,
.gunwait = _gunwait,
.lastaction = _lastaction,
.lastattackgun = _lastattackgun,
.lastmove = _lastmove,
.armourType = _armourType,
.quadMillis = _quadMillis,
.gunSelect = _gunSelect,
.gunWait = _gunWait,
.lastAction = _lastAction,
.lastAttackGun = _lastAttackGun,
.lastMove = _lastMove,
.attacking = _attacking,
.monsterstate = _monsterstate,
.mtype = _mtype,
.targetyaw = _targetyaw,
.monsterState = _monsterState,
.monsterType = _monsterType,
.targetYaw = _targetYaw,
.blocked = _blocked,
.moving = _moving,
.trigger = _trigger,
.attacktarget = _attacktarget,
.attackTarget = _attackTarget,
.anger = _anger };
for (int i = 0; i < NUMGUNS; i++)
@ -180,56 +196,130 @@ struct dynent {
memcpy(&d, data.items, data.count);
_o = d.o;
_vel = d.vel;
_origin = d.origin;
_velocity = d.velocity;
_yaw = d.yaw;
_pitch = d.pitch;
_roll = d.roll;
_maxspeed = d.maxspeed;
_outsidemap = d.outsidemap;
_inwater = d.inwater;
_onfloor = d.onfloor;
_jumpnext = d.jumpnext;
_maxSpeed = d.maxSpeed;
_outsideMap = d.outsideMap;
_inWater = d.inWater;
_onFloor = d.onFloor;
_jumpNext = d.jumpNext;
_move = d.move;
_strafe = d.strafe;
_k_left = d.k_left;
_k_right = d.k_right;
_k_up = d.k_up;
_k_down = d.k_down;
_timeinair = d.timeinair;
_timeInAir = d.timeInAir;
_radius = d.radius;
_eyeheight = d.eyeheight;
_aboveeye = d.aboveeye;
_lastupdate = d.lastupdate;
_plag = d.plag;
_eyeHeight = d.eyeHeight;
_aboveEye = d.aboveEye;
_lastUpdate = d.lastUpdate;
_lag = d.lag;
_ping = d.ping;
_lifesequence = d.lifesequence;
_lifeSequence = d.lifeSequence;
_state = d.state;
_frags = d.frags;
_health = d.health;
_armour = d.armour;
_armourtype = d.armourtype;
_quadmillis = d.quadmillis;
_gunselect = d.gunselect;
_gunwait = d.gunwait;
_lastaction = d.lastaction;
_lastattackgun = d.lastattackgun;
_lastmove = d.lastmove;
_armourType = d.armourType;
_quadMillis = d.quadMillis;
_gunSelect = d.gunSelect;
_gunWait = d.gunWait;
_lastAction = d.lastAction;
_lastAttackGun = d.lastAttackGun;
_lastMove = d.lastMove;
_attacking = d.attacking;
for (int i = 0; i < NUMGUNS; i++)
_ammo[i] = d.ammo[i];
_monsterstate = d.monsterstate;
_mtype = d.mtype;
_targetyaw = d.targetyaw;
_monsterState = d.monsterState;
_monsterType = d.monsterType;
_targetYaw = d.targetYaw;
_blocked = d.blocked;
_moving = d.moving;
_trigger = d.trigger;
_attacktarget = d.attacktarget;
_attackTarget = d.attackTarget;
_anger = d.anger;
_name = [[OFString alloc] initWithUTF8String:d.name];
_team = [[OFString alloc] initWithUTF8String:d.team];
}
- (void)resetMovement
{
_k_left = false;
_k_right = false;
_k_up = false;
_k_down = false;
_jumpNext = false;
_strafe = 0;
_move = 0;
}
- (void)resetToSpawnState
{
[self resetMovement];
_velocity = OFMakeVector3D(0, 0, 0);
_onFloor = false;
_timeInAir = 0;
_health = 100;
_armour = 50;
_armourType = A_BLUE;
_quadMillis = 0;
_lastAttackGun = _gunSelect = GUN_SG;
_gunWait = 0;
_attacking = false;
_lastAction = 0;
for (size_t i = 0; i < NUMGUNS; i++)
_ammo[i] = 0;
_ammo[GUN_FIST] = 1;
if (m_noitems) {
_gunSelect = GUN_RIFLE;
_armour = 0;
if (m_noitemsrail) {
_health = 1;
_ammo[GUN_RIFLE] = 100;
} else {
if (gamemode == 12) {
// eihrul's secret "instafist" mode
_gunSelect = GUN_FIST;
return;
}
_health = 256;
if (m_tarena) {
_gunSelect = rnd(4) + 1;
baseammo(_gunSelect);
int gun2;
do {
gun2 = rnd(4) + 1;
} while (gun2 != _gunSelect);
baseammo(gun2);
} else if (m_arena) {
// insta arena
_ammo[GUN_RIFLE] = 100;
} else {
// efficiency
for (size_t i = 0; i < 4; i++)
baseammo(i + 1);
_gunSelect = GUN_CG;
}
_ammo[GUN_CG] /= 2;
}
} else
_ammo[GUN_SG] = 5;
}
@end

View file

@ -21,7 +21,7 @@ renderclient(
{
int n = 3;
float speed = 100.0f;
float mz = d.o.z - d.eyeheight + 1.55f * scale;
float mz = d.origin.z - d.eyeHeight + 1.55f * scale;
intptr_t tmp = (intptr_t)d;
int basetime = -(tmp & 0xFFF);
if (d.state == CS_DEAD) {
@ -33,8 +33,8 @@ renderclient(
n = (intptr_t)d % 3;
r = range[n];
}
basetime = d.lastaction;
int t = lastmillis - d.lastaction;
basetime = d.lastAction;
int t = lastmillis - d.lastAction;
if (t < 0 || t > 20000)
return;
if (t > (r - 1) * 100) {
@ -47,25 +47,25 @@ renderclient(
if (mz < -1000)
return;
// mdl = (((int)d>>6)&1)+1;
// mz = d.o.z-d.eyeheight+0.2f;
// mz = d.o.z-d.eyeHeight+0.2f;
// scale = 1.2f;
} else if (d.state == CS_EDITING) {
n = 16;
} else if (d.state == CS_LAGGED) {
n = 17;
} else if (d.monsterstate == M_ATTACKING) {
} else if (d.monsterState == M_ATTACKING) {
n = 8;
} else if (d.monsterstate == M_PAIN) {
} else if (d.monsterState == M_PAIN) {
n = 10;
} else if ((!d.move && !d.strafe) || !d.moving) {
n = 12;
} else if (!d.onfloor && d.timeinair > 100) {
} else if (!d.onFloor && d.timeInAir > 100) {
n = 18;
} else {
n = 14;
speed = 1200 / d.maxspeed * scale;
speed = 1200 / d.maxSpeed * scale;
if (hellpig)
speed = 300 / d.maxspeed;
speed = 300 / d.maxSpeed;
}
if (hellpig) {
n++;
@ -73,8 +73,8 @@ renderclient(
mz -= 1.9f;
}
rendermodel(mdlname, frame[n], range[n], 0, 1.5f,
OFMakeVector3D(d.o.x, mz, d.o.y), d.yaw + 90, d.pitch / 2, team,
scale, speed, 0, basetime);
OFMakeVector3D(d.origin.x, mz, d.origin.y), d.yaw + 90, d.pitch / 2,
team, scale, speed, 0, basetime);
}
extern int democlientnum;
@ -107,7 +107,7 @@ static OFMutableArray<OFString *> *scoreLines;
void
renderscore(DynamicEntity *d)
{
OFString *lag = [OFString stringWithFormat:@"%d", d.plag];
OFString *lag = [OFString stringWithFormat:@"%d", d.lag];
OFString *name = [OFString stringWithFormat:@"(%@)", d.name];
OFString *line =
[OFString stringWithFormat:@"%d\t%@\t%d\t%@\t%@", d.frags,

View file

@ -24,7 +24,7 @@ OFMutableArray *players; // other clients
void
initPlayers()
{
player1 = newdynent();
player1 = [[DynamicEntity alloc] init];
players = [[OFMutableArray alloc] init];
}
@ -42,101 +42,6 @@ getclientmap()
return clientmap;
}
void
resetmovement(DynamicEntity *d)
{
d.k_left = false;
d.k_right = false;
d.k_up = false;
d.k_down = false;
d.jumpnext = false;
d.strafe = 0;
d.move = 0;
}
// reset player state not persistent accross spawns
void
spawnstate(DynamicEntity *d)
{
resetmovement(d);
d.vel = OFMakeVector3D(0, 0, 0);
d.onfloor = false;
d.timeinair = 0;
d.health = 100;
d.armour = 50;
d.armourtype = A_BLUE;
d.quadmillis = 0;
d.lastattackgun = d.gunselect = GUN_SG;
d.gunwait = 0;
d.attacking = false;
d.lastaction = 0;
loopi(NUMGUNS) d.ammo[i] = 0;
d.ammo[GUN_FIST] = 1;
if (m_noitems) {
d.gunselect = GUN_RIFLE;
d.armour = 0;
if (m_noitemsrail) {
d.health = 1;
d.ammo[GUN_RIFLE] = 100;
} else {
if (gamemode == 12) {
// eihrul's secret "instafist" mode
d.gunselect = GUN_FIST;
return;
}
d.health = 256;
if (m_tarena) {
int gun1 = rnd(4) + 1;
baseammo(d.gunselect = gun1);
for (;;) {
int gun2 = rnd(4) + 1;
if (gun1 != gun2) {
baseammo(gun2);
break;
}
}
} else if (m_arena) {
// insta arena
d.ammo[GUN_RIFLE] = 100;
} else {
// efficiency
loopi(4) baseammo(i + 1);
d.gunselect = GUN_CG;
}
d.ammo[GUN_CG] /= 2;
}
} else
d.ammo[GUN_SG] = 5;
}
DynamicEntity *
newdynent() // create a new blank player or monster
{
DynamicEntity *d = [[DynamicEntity alloc] init];
d.o = OFMakeVector3D(0, 0, 0);
d.yaw = 270;
d.pitch = 0;
d.roll = 0;
d.maxspeed = 22;
d.outsidemap = false;
d.inwater = false;
d.radius = 1.1f;
d.eyeheight = 3.2f;
d.aboveeye = 0.7f;
d.frags = 0;
d.plag = 0;
d.ping = 0;
d.lastupdate = lastmillis;
d.enemy = NULL;
d.monsterstate = 0;
d.name = d.team = @"";
d.blocked = false;
d.lifesequence = 0;
d.state = CS_ALIVE;
spawnstate(d);
return d;
}
void
respawnself()
{
@ -203,7 +108,7 @@ otherplayers()
if (player == [OFNull null])
return;
const int lagtime = lastmillis - [player lastupdate];
const int lagtime = lastmillis - [player lastUpdate];
if (lagtime > 1000 && [player state] == CS_ALIVE) {
[player setState:CS_LAGGED];
return;
@ -271,11 +176,11 @@ updateworld(int millis) // main game update loop
if (!demoplayback) {
monsterthink();
if (player1.state == CS_DEAD) {
if (lastmillis - player1.lastaction < 2000) {
if (lastmillis - player1.lastAction < 2000) {
player1.move = player1.strafe = 0;
moveplayer(player1, 10, false);
} else if (!m_arena && !m_sp &&
lastmillis - player1.lastaction > 10000)
lastmillis - player1.lastAction > 10000)
respawn();
} else if (!intermission) {
moveplayer(player1, 20, true);
@ -296,14 +201,14 @@ entinmap(DynamicEntity *d)
{
float dx = (rnd(21) - 10) / 10.0f * i; // increasing distance
float dy = (rnd(21) - 10) / 10.0f * i;
OFVector3D old = d.o;
d.o = OFMakeVector3D(d.o.x + dx, d.o.y + dy, d.o.z);
OFVector3D old = d.origin;
d.origin = OFAddVector3D(d.origin, OFMakeVector3D(dx, dy, 0));
if (collide(d, true, 0, 0))
return;
d.o = old;
d.origin = old;
}
conoutf(
@"can't find entity spawn spot! (%d, %d)", (int)d.o.x, (int)d.o.y);
conoutf(@"can't find entity spawn spot! (%d, %d)", (int)d.origin.x,
(int)d.origin.y);
// leave ent at original pos, possibly stuck
}
@ -317,15 +222,16 @@ spawnplayer(DynamicEntity *d)
int r = fixspawn-- > 0 ? 4 : rnd(10) + 1;
loopi(r) spawncycle = findentity(PLAYERSTART, spawncycle + 1);
if (spawncycle != -1) {
d.o = OFMakeVector3D(
d.origin = OFMakeVector3D(
ents[spawncycle].x, ents[spawncycle].y, ents[spawncycle].z);
d.yaw = ents[spawncycle].attr1;
d.pitch = 0;
d.roll = 0;
} else
d.o = OFMakeVector3D((float)ssize / 2, (float)ssize / 2, 4);
d.origin =
OFMakeVector3D((float)ssize / 2, (float)ssize / 2, 4);
entinmap(d);
spawnstate(d);
[d resetToSpawnState];
d.state = CS_ALIVE;
}
@ -336,7 +242,7 @@ spawnplayer(DynamicEntity *d)
{ \
player1.s = isdown; \
player1.v = isdown ? d : (player1.os ? -(d) : 0); \
player1.lastmove = lastmillis; \
player1.lastMove = lastmillis; \
}
dir(backward, move, -1, k_down, k_up);
@ -358,7 +264,7 @@ attack(bool on)
void
jumpn(bool on)
{
if (!intermission && (player1.jumpnext = on))
if (!intermission && (player1.jumpNext = on))
respawn();
}
@ -406,7 +312,7 @@ selfdamage(int damage, int actor, DynamicEntity *act)
damageblend(damage);
demoblend(damage);
// let armour absorb when possible
int ad = damage * (player1.armourtype + 1) * 20 / 100;
int ad = damage * (player1.armourType + 1) * 20 / 100;
if (ad > player1.armour)
ad = player1.armour;
player1.armour -= ad;
@ -440,14 +346,14 @@ selfdamage(int damage, int actor, DynamicEntity *act)
}
showscores(true);
addmsg(1, 2, SV_DIED, actor);
player1.lifesequence++;
player1.lifeSequence++;
player1.attacking = false;
player1.state = CS_DEAD;
player1.pitch = 0;
player1.roll = 60;
playsound(S_DIE1 + rnd(2), NULL);
spawnstate(player1);
player1.lastaction = lastmillis;
[player1 resetToSpawnState];
player1.lastAction = lastmillis;
} else
playsound(S_PAIN6, NULL);
}
@ -473,10 +379,17 @@ getclient(int cn) // ensure valid entity
neterr(@"clientnum");
return nil;
}
while (cn >= players.count)
[players addObject:[OFNull null]];
return (players[cn] != [OFNull null] ? players[cn]
: (players[cn] = newdynent()));
id player = players[cn];
if (player == [OFNull null]) {
player = [DynamicEntity entity];
players[cn] = player;
}
return player;
}
void

View file

@ -142,7 +142,7 @@ disconnect(bool onlyclean, bool async)
disconnecting = 0;
clientnum = -1;
c2sinit = false;
player1.lifesequence = 0;
player1.lifeSequence = 0;
[players removeAllObjects];
localdisconnect();
@ -300,20 +300,20 @@ c2sinfo(DynamicEntity *d)
putint(&p, clientnum);
// quantize coordinates to 1/16th of a cube, between 1 and 3
// bytes
putint(&p, (int)(d.o.x * DMF));
putint(&p, (int)(d.o.y * DMF));
putint(&p, (int)(d.o.z * DMF));
putint(&p, (int)(d.origin.x * DMF));
putint(&p, (int)(d.origin.y * DMF));
putint(&p, (int)(d.origin.z * DMF));
putint(&p, (int)(d.yaw * DAF));
putint(&p, (int)(d.pitch * DAF));
putint(&p, (int)(d.roll * DAF));
// quantize to 1/100, almost always 1 byte
putint(&p, (int)(d.vel.x * DVF));
putint(&p, (int)(d.vel.y * DVF));
putint(&p, (int)(d.vel.z * DVF));
// pack rest in 1 byte: strafe:2, move:2, onfloor:1, state:3
putint(&p, (int)(d.velocity.x * DVF));
putint(&p, (int)(d.velocity.y * DVF));
putint(&p, (int)(d.velocity.z * DVF));
// pack rest in 1 byte: strafe:2, move:2, onFloor:1, state:3
putint(&p,
(d.strafe & 3) | ((d.move & 3) << 2) |
(((int)d.onfloor) << 4) |
(((int)d.onFloor) << 4) |
((editmode ? CS_EDITING : d.state) << 5));
if (senditemstoserver) {
@ -339,7 +339,7 @@ c2sinfo(DynamicEntity *d)
putint(&p, SV_INITC2S);
sendstring(player1.name, &p);
sendstring(player1.team, &p);
putint(&p, player1.lifesequence);
putint(&p, player1.lifeSequence);
}
for (OFData *msg in messages) {
// send messages collected during the previous frames

View file

@ -38,26 +38,27 @@ void
updatepos(DynamicEntity *d)
{
const float r = player1.radius + d.radius;
const float dx = player1.o.x - d.o.x;
const float dy = player1.o.y - d.o.y;
const float dz = player1.o.z - d.o.z;
const float rz = player1.aboveeye + d.eyeheight;
const float dx = player1.origin.x - d.origin.x;
const float dy = player1.origin.y - d.origin.y;
const float dz = player1.origin.z - d.origin.z;
const float rz = player1.aboveEye + d.eyeHeight;
const float fx = (float)fabs(dx), fy = (float)fabs(dy),
fz = (float)fabs(dz);
if (fx < r && fy < r && fz < rz && d.state != CS_DEAD) {
if (fx < fy)
// push aside
d.o = OFMakeVector3D(d.o.x,
d.o.y + (dy < 0 ? r - fy : -(r - fy)), d.o.z);
d.origin = OFAddVector3D(d.origin,
OFMakeVector3D(
0, (dy < 0 ? r - fy : -(r - fy)), 0));
else
d.o = OFMakeVector3D(
d.o.x + (dx < 0 ? r - fx : -(r - fx)), d.o.y,
d.o.z);
d.origin = OFAddVector3D(d.origin,
OFMakeVector3D(
(dx < 0 ? r - fx : -(r - fx)), 0, 0));
}
int lagtime = lastmillis - d.lastupdate;
int lagtime = lastmillis - d.lastUpdate;
if (lagtime) {
d.plag = (d.plag * 5 + lagtime) / 6;
d.lastupdate = lastmillis;
d.lag = (d.lag * 5 + lagtime) / 6;
d.lastUpdate = lastmillis;
}
}
@ -118,22 +119,22 @@ localservertoclient(uchar *buf, int len)
tmp.x = getint(&p) / DMF;
tmp.y = getint(&p) / DMF;
tmp.z = getint(&p) / DMF;
d.o = tmp;
d.origin = tmp;
d.yaw = getint(&p) / DAF;
d.pitch = getint(&p) / DAF;
d.roll = getint(&p) / DAF;
tmp.x = getint(&p) / DVF;
tmp.y = getint(&p) / DVF;
tmp.z = getint(&p) / DVF;
d.vel = tmp;
d.velocity = tmp;
int f = getint(&p);
d.strafe = (f & 3) == 3 ? -1 : f & 3;
f >>= 2;
d.move = (f & 3) == 3 ? -1 : f & 3;
d.onfloor = (f >> 2) & 1;
d.onFloor = (f >> 2) & 1;
int state = f >> 3;
if (state == CS_DEAD && d.state != CS_DEAD)
d.lastaction = lastmillis;
d.lastAction = lastmillis;
d.state = state;
if (!demoplayback)
updatepos(d);
@ -141,7 +142,7 @@ localservertoclient(uchar *buf, int len)
}
case SV_SOUND: {
OFVector3D loc = d.o;
OFVector3D loc = d.origin;
playsound(getint(&p), &loc);
break;
}
@ -197,7 +198,7 @@ localservertoclient(uchar *buf, int len)
d.name = @(text);
sgetstr();
d.team = @(text);
d.lifesequence = getint(&p);
d.lifeSequence = getint(&p);
break;
}
@ -230,10 +231,10 @@ localservertoclient(uchar *buf, int len)
int damage = getint(&p);
int ls = getint(&p);
if (target == clientnum) {
if (ls == player1.lifesequence)
if (ls == player1.lifeSequence)
selfdamage(damage, cn, d);
} else {
OFVector3D loc = getclient(target).o;
OFVector3D loc = getclient(target).origin;
playsound(S_PAIN1 + rnd(5), &loc);
}
break;
@ -267,9 +268,9 @@ localservertoclient(uchar *buf, int len)
a.name, d.name);
}
}
OFVector3D loc = d.o;
OFVector3D loc = d.origin;
playsound(S_DIE1 + rnd(2), &loc);
d.lifesequence++;
d.lifeSequence++;
break;
}

View file

@ -281,32 +281,10 @@ extern bool demoplayback;
// simplistic vector ops
#define dotprod(u, v) ((u).x * (v).x + (u).y * (v).y + (u).z * (v).z)
#define vmul(u, f) \
{ \
OFVector3D tmp_ = u; \
float tmp2_ = f; \
u = OFMakeVector3D( \
tmp_.x * tmp2_, tmp_.y * tmp2_, tmp_.z * tmp2_); \
}
#define vdiv(u, f) \
{ \
OFVector3D tmp_ = u; \
float tmp2_ = f; \
u = OFMakeVector3D( \
tmp_.x / tmp2_, tmp_.y / tmp2_, tmp_.z / tmp2_); \
}
#define vadd(u, v) \
{ \
OFVector3D tmp_ = u; \
u = OFMakeVector3D( \
tmp_.x + (v).x, tmp_.y + (v).y, tmp_.z + (v).z); \
}
#define vsub(u, v) \
{ \
OFVector3D tmp_ = u; \
u = OFMakeVector3D( \
tmp_.x - (v).x, tmp_.y - (v).y, tmp_.z - (v).z); \
}
#define vmul(u, f) u = OFMultiplyVector3D(u, OFMakeVector3D(f, f, f))
#define vdiv(u, f) u = OFDivideVector3D(u, OFMakeVector3D(f, f, f))
#define vadd(u, v) u = OFAddVector3D(u, v)
#define vsub(u, v) u = OFSubtractVector3D(u, v)
#define vdist(d, v, e, s) \
OFVector3D v = s; \
vsub(v, e); \

View file

@ -169,8 +169,9 @@ cursorupdate() // called every frame from hud
// selected wall
if (fabs(sheight(s, s, z) - z) > 1) {
x += x > player1.o.x ? 0.5f : -0.5f; // find right wall cube
y += y > player1.o.y ? 0.5f : -0.5f;
// find right wall cube
x += (x > player1.origin.x ? 0.5f : -0.5f);
y += (y > player1.origin.y ? 0.5f : -0.5f);
cx = (int)x;
cy = (int)y;
@ -622,7 +623,7 @@ void
newent(OFString *what, OFString *a1, OFString *a2, OFString *a3, OFString *a4)
{
EDITSEL;
newentity(sel.x, sel.y, (int)player1.o.z, what,
newentity(sel.x, sel.y, (int)player1.origin.z, what,
[a1 cube_intValueWithBase:0], [a2 cube_intValueWithBase:0],
[a3 cube_intValueWithBase:0], [a4 cube_intValueWithBase:0]);
}

View file

@ -171,16 +171,16 @@ realpickup(int n, DynamicEntity *d)
case I_GREENARMOUR:
d.armour = radditem(n, d.armour);
d.armourtype = A_GREEN;
d.armourType = A_GREEN;
break;
case I_YELLOWARMOUR:
d.armour = radditem(n, d.armour);
d.armourtype = A_YELLOW;
d.armourType = A_YELLOW;
break;
case I_QUAD:
d.quadmillis = radditem(n, d.quadmillis);
d.quadMillis = radditem(n, d.quadMillis);
conoutf(@"you got the quad!");
break;
}
@ -214,10 +214,11 @@ teleport(int n, DynamicEntity *d)
if (beenhere < 0)
beenhere = e;
if (ents[e].attr2 == tag) {
d.o = OFMakeVector3D(ents[e].x, ents[e].y, ents[e].z);
d.origin =
OFMakeVector3D(ents[e].x, ents[e].y, ents[e].z);
d.yaw = ents[e].attr1;
d.pitch = 0;
d.vel = OFMakeVector3D(0, 0, 0);
d.velocity = OFMakeVector3D(0, 0, 0);
entinmap(d);
playsoundc(S_TELEPORT);
break;
@ -257,7 +258,7 @@ pickup(int n, DynamicEntity *d)
case I_GREENARMOUR:
// (100h/100g only absorbs 166 damage)
if (d.armourtype == A_YELLOW && d.armour > 66)
if (d.armourType == A_YELLOW && d.armour > 66)
break;
additem(n, d.armour, 20);
break;
@ -267,7 +268,7 @@ pickup(int n, DynamicEntity *d)
break;
case I_QUAD:
additem(n, d.quadmillis, 60);
additem(n, d.quadMillis, 60);
break;
case CARROT:
@ -293,8 +294,9 @@ pickup(int n, DynamicEntity *d)
lastjumppad = lastmillis;
OFVector3D v = OFMakeVector3D((int)(char)ents[n].attr3 / 10.0f,
(int)(char)ents[n].attr2 / 10.0f, ents[n].attr1 / 10.0f);
player1.vel = OFMakeVector3D(player1.vel.x, player1.vel.y, 0);
vadd(player1.vel, v);
player1.velocity =
OFMakeVector3D(player1.velocity.x, player1.velocity.y, 0);
vadd(player1.velocity, v);
playsoundc(S_JUMPPAD);
break;
}
@ -318,8 +320,8 @@ checkitems()
return;
OFVector3D v = OFMakeVector3D(
e.x, e.y, (float)S(e.x, e.y)->floor + player1.eyeheight);
vdist(dist, t, player1.o, v);
e.x, e.y, (float)S(e.x, e.y)->floor + player1.eyeHeight);
vdist(dist, t, player1.origin, v);
if (dist < (e.type == TELEPORT ? 4 : 2.5))
pickup(i, player1);
@ -329,8 +331,8 @@ checkitems()
void
checkquad(int time)
{
if (player1.quadmillis && (player1.quadmillis -= time) < 0) {
player1.quadmillis = 0;
if (player1.quadMillis && (player1.quadMillis -= time) < 0) {
player1.quadMillis = 0;
playsoundc(S_PUPOUT);
conoutf(@"quad damage is over");
}

View file

@ -3,6 +3,8 @@
#include "cube.h"
#import "Menu.h"
#import "DynamicEntity.h"
#import "MenuItem.h"
static OFMutableArray<OFNumber *> *menuStack;
@ -13,7 +15,7 @@ void
menuset(int menu)
{
if ((vmenu = menu) >= 1)
resetmovement(player1);
[player1 resetMovement];
if (vmenu == 1)
menus[1].menusel = 0;
}

View file

@ -62,22 +62,22 @@ basicmonster(int type, int yaw, int state, int trigger, int move)
conoutf(@"warning: unknown monster in spawn: %d", type);
type = 0;
}
DynamicEntity *m = newdynent();
struct monstertype *t = &monstertypes[(m.mtype = type)];
m.eyeheight = 2.0f;
m.aboveeye = 1.9f;
DynamicEntity *m = [DynamicEntity entity];
struct monstertype *t = &monstertypes[(m.monsterType = type)];
m.eyeHeight = 2.0f;
m.aboveEye = 1.9f;
m.radius *= t->bscale / 10.0f;
m.eyeheight *= t->bscale / 10.0f;
m.aboveeye *= t->bscale / 10.0f;
m.monsterstate = state;
m.eyeHeight *= t->bscale / 10.0f;
m.aboveEye *= t->bscale / 10.0f;
m.monsterState = state;
if (state != M_SLEEP)
spawnplayer(m);
m.trigger = lastmillis + trigger;
m.targetyaw = m.yaw = (float)yaw;
m.targetYaw = m.yaw = (float)yaw;
m.move = move;
m.enemy = player1;
m.gunselect = t->gun;
m.maxspeed = (float)t->speed;
m.gunSelect = t->gun;
m.maxSpeed = (float)t->speed;
m.health = t->health;
m.armour = 0;
loopi(NUMGUNS) m.ammo[i] = 10000;
@ -129,7 +129,7 @@ monsterclear()
DynamicEntity *m =
basicmonster(e.attr2, e.attr1, M_SLEEP, 100, 0);
m.o = OFMakeVector3D(e.x, e.y, e.z);
m.origin = OFMakeVector3D(e.x, e.y, e.z);
entinmap(m);
monstertotal++;
}
@ -176,9 +176,9 @@ los(float lx, float ly, float lz, float bx, float by, float bz, OFVector3D *v)
bool
enemylos(DynamicEntity *m, OFVector3D *v)
{
*v = m.o;
return los(
m.o.x, m.o.y, m.o.z, m.enemy.o.x, m.enemy.o.y, m.enemy.o.z, v);
*v = m.origin;
return los(m.origin.x, m.origin.y, m.origin.z, m.enemy.origin.x,
m.enemy.origin.y, m.enemy.origin.z, v);
}
// monster AI is sequenced using transitions: they are in a particular state
@ -192,7 +192,7 @@ enemylos(DynamicEntity *m, OFVector3D *v)
void
transition(DynamicEntity *m, int state, int moving, int n, int r)
{
m.monsterstate = state;
m.monsterState = state;
m.move = moving;
n = n * 130 / 100;
m.trigger = lastmillis + n - skill * (n / 16) + rnd(r + 1);
@ -215,41 +215,42 @@ monsteraction(DynamicEntity *m)
m.enemy = player1;
m.anger = 0;
}
normalise(m, m.targetyaw);
normalise(m, m.targetYaw);
// slowly turn monster towards his target
if (m.targetyaw > m.yaw) {
if (m.targetYaw > m.yaw) {
m.yaw += curtime * 0.5f;
if (m.targetyaw < m.yaw)
m.yaw = m.targetyaw;
if (m.targetYaw < m.yaw)
m.yaw = m.targetYaw;
} else {
m.yaw -= curtime * 0.5f;
if (m.targetyaw > m.yaw)
m.yaw = m.targetyaw;
if (m.targetYaw > m.yaw)
m.yaw = m.targetYaw;
}
vdist(disttoenemy, vectoenemy, m.o, m.enemy.o);
m.pitch = atan2(m.enemy.o.z - m.o.z, disttoenemy) * 180 / PI;
vdist(disttoenemy, vectoenemy, m.origin, m.enemy.origin);
m.pitch = atan2(m.enemy.origin.z - m.origin.z, disttoenemy) * 180 / PI;
// special case: if we run into scenery
if (m.blocked) {
m.blocked = false;
// try to jump over obstackle (rare)
if (!rnd(20000 / monstertypes[m.mtype].speed))
m.jumpnext = true;
if (!rnd(20000 / monstertypes[m.monsterType].speed))
m.jumpNext = true;
// search for a way around (common)
else if (m.trigger < lastmillis &&
(m.monsterstate != M_HOME || !rnd(5))) {
(m.monsterState != M_HOME || !rnd(5))) {
// patented "random walk" AI pathfinding (tm) ;)
m.targetyaw += 180 + rnd(180);
m.targetYaw += 180 + rnd(180);
transition(m, M_SEARCH, 1, 400, 1000);
}
}
float enemyyaw =
-(float)atan2(m.enemy.o.x - m.o.x, m.enemy.o.y - m.o.y) / PI * 180 +
float enemyYaw = -(float)atan2(m.enemy.origin.x - m.origin.x,
m.enemy.origin.y - m.origin.y) /
PI * 180 +
180;
switch (m.monsterstate) {
switch (m.monsterState) {
case M_PAIN:
case M_ATTACKING:
case M_SEARCH:
@ -263,15 +264,15 @@ monsteraction(DynamicEntity *m)
OFVector3D target;
if (editmode || !enemylos(m, &target))
return; // skip running physics
normalise(m, enemyyaw);
float angle = (float)fabs(enemyyaw - m.yaw);
normalise(m, enemyYaw);
float angle = (float)fabs(enemyYaw - m.yaw);
if (disttoenemy < 8 // the better the angle to the player, the
// further the monster can see/hear
|| (disttoenemy < 16 && angle < 135) ||
(disttoenemy < 32 && angle < 90) ||
(disttoenemy < 64 && angle < 45) || angle < 10) {
transition(m, M_HOME, 1, 500, 200);
OFVector3D loc = m.o;
OFVector3D loc = m.origin;
playsound(S_GRUNT1 + rnd(2), &loc);
}
break;
@ -281,10 +282,10 @@ monsteraction(DynamicEntity *m)
// this state is the delay between wanting to shoot and actually
// firing
if (m.trigger < lastmillis) {
m.lastaction = 0;
m.lastAction = 0;
m.attacking = true;
OFVector3D attacktarget = m.attacktarget;
shoot(m, &attacktarget);
OFVector3D attackTarget = m.attackTarget;
shoot(m, &attackTarget);
transition(m, M_ATTACKING, 0, 600, 0);
}
break;
@ -292,7 +293,7 @@ monsteraction(DynamicEntity *m)
case M_HOME:
// monster has visual contact, heads straight for player and
// may want to shoot at any time
m.targetyaw = enemyyaw;
m.targetYaw = enemyYaw;
if (m.trigger < lastmillis) {
OFVector3D target;
if (!enemylos(m, &target)) {
@ -305,13 +306,15 @@ monsteraction(DynamicEntity *m)
if (!rnd((int)disttoenemy / 3 + 1) &&
m.enemy.state == CS_ALIVE) {
// get ready to fire
m.attacktarget = target;
m.attackTarget = target;
transition(m, M_AIMING, 0,
monstertypes[m.mtype].lag, 10);
monstertypes[m.monsterType].lag,
10);
} else
// track player some more
transition(m, M_HOME, 1,
monstertypes[m.mtype].rate, 0);
monstertypes[m.monsterType].rate,
0);
}
}
break;
@ -324,13 +327,14 @@ void
monsterpain(DynamicEntity *m, int damage, DynamicEntity *d)
{
// a monster hit us
if (d.monsterstate) {
if (d.monsterState) {
// guard for RL guys shooting themselves :)
if (m != d) {
// don't attack straight away, first get angry
m.anger++;
int anger = m.mtype == d.mtype ? m.anger / 2 : m.anger;
if (anger >= monstertypes[m.mtype].loyalty)
int anger = m.monsterType == d.monsterType ? m.anger / 2
: m.anger;
if (anger >= monstertypes[m.monsterType].loyalty)
// monster infight if very angry
m.enemy = d;
}
@ -340,20 +344,20 @@ monsterpain(DynamicEntity *m, int damage, DynamicEntity *d)
m.enemy = d;
}
// in this state monster won't attack
transition(m, M_PAIN, 0, monstertypes[m.mtype].pain, 200);
transition(m, M_PAIN, 0, monstertypes[m.monsterType].pain, 200);
if ((m.health -= damage) <= 0) {
m.state = CS_DEAD;
m.lastaction = lastmillis;
m.lastAction = lastmillis;
numkilled++;
player1.frags = numkilled;
OFVector3D loc = m.o;
playsound(monstertypes[m.mtype].diesound, &loc);
OFVector3D loc = m.origin;
playsound(monstertypes[m.monsterType].diesound, &loc);
int remain = monstertotal - numkilled;
if (remain > 0 && remain <= 5)
conoutf(@"only %d monster(s) remaining", remain);
} else {
OFVector3D loc = m.o;
playsound(monstertypes[m.mtype].painsound, &loc);
OFVector3D loc = m.origin;
playsound(monstertypes[m.monsterType].painsound, &loc);
}
}
@ -393,14 +397,14 @@ monsterthink()
OFMakeVector3D(e.x, e.y, (float)S(e.x, e.y)->floor);
for (DynamicEntity *monster in monsters) {
if (monster.state == CS_DEAD) {
if (lastmillis - monster.lastaction < 2000) {
if (lastmillis - monster.lastAction < 2000) {
monster.move = 0;
moveplayer(monster, 1, false);
}
} else {
v.z += monster.eyeheight;
vdist(dist, t, monster.o, v);
v.z -= monster.eyeheight;
v.z += monster.eyeHeight;
vdist(dist, t, monster.origin, v);
v.z -= monster.eyeHeight;
if (dist < 4)
teleport(i, monster);
@ -418,6 +422,7 @@ monsterrender()
{
for (DynamicEntity *monster in monsters)
renderclient(monster, false,
monstertypes[monster.mtype].mdlname, monster.mtype == 5,
monstertypes[monster.mtype].mscale / 10.0f);
monstertypes[monster.monsterType].mdlname,
monster.monsterType == 5,
monstertypes[monster.monsterType].mscale / 10.0f);
}

View file

@ -17,22 +17,26 @@ plcollide(
{
if (o.state != CS_ALIVE)
return true;
const float r = o.radius + d.radius;
if (fabs(o.o.x - d.o.x) < r && fabs(o.o.y - d.o.y) < r) {
if (d.o.z - d.eyeheight < o.o.z - o.eyeheight) {
if (o.o.z - o.eyeheight < *hi)
*hi = o.o.z - o.eyeheight - 1;
} else if (o.o.z + o.aboveeye > *lo)
*lo = o.o.z + o.aboveeye + 1;
if (fabs(o.o.z - d.o.z) < o.aboveeye + d.eyeheight)
const float r = o.radius + d.radius;
if (fabs(o.origin.x - d.origin.x) < r &&
fabs(o.origin.y - d.origin.y) < r) {
if (d.origin.z - d.eyeHeight < o.origin.z - o.eyeHeight) {
if (o.origin.z - o.eyeHeight < *hi)
*hi = o.origin.z - o.eyeHeight - 1;
} else if (o.origin.z + o.aboveEye > *lo)
*lo = o.origin.z + o.aboveEye + 1;
if (fabs(o.origin.z - d.origin.z) < o.aboveEye + d.eyeHeight)
return false;
if (d.monsterstate)
if (d.monsterState)
return false; // hack
*headspace = d.o.z - o.o.z - o.aboveeye - d.eyeheight;
//
*headspace = d.origin.z - o.origin.z - o.aboveEye - d.eyeHeight;
if (*headspace < 0)
*headspace = 10;
}
return true;
}
@ -69,11 +73,11 @@ mmcollide(DynamicEntity *d, float *hi, float *lo)
continue;
const float r = mmi.rad + d.radius;
if (fabs(e.x - d.o.x) < r && fabs(e.y - d.o.y) < r) {
if (fabs(e.x - d.origin.x) < r && fabs(e.y - d.origin.y) < r) {
float mmz =
(float)(S(e.x, e.y)->floor + mmi.zoff + e.attr3);
if (d.o.z - d.eyeheight < mmz) {
if (d.origin.z - d.eyeHeight < mmz) {
if (mmz < *hi)
*hi = mmz;
} else if (mmz + mmi.h > *lo)
@ -91,21 +95,21 @@ bool
collide(DynamicEntity *d, bool spawn, float drop, float rise)
{
// figure out integer cube rectangle this entity covers in map
const float fx1 = d.o.x - d.radius;
const float fy1 = d.o.y - d.radius;
const float fx2 = d.o.x + d.radius;
const float fy2 = d.o.y + d.radius;
const float fx1 = d.origin.x - d.radius;
const float fy1 = d.origin.y - d.radius;
const float fx2 = d.origin.x + d.radius;
const float fy2 = d.origin.y + d.radius;
const int x1 = fast_f2nat(fx1);
const int y1 = fast_f2nat(fy1);
const int x2 = fast_f2nat(fx2);
const int y2 = fast_f2nat(fy2);
float hi = 127, lo = -128;
// big monsters are afraid of heights, unless angry :)
float minfloor = (d.monsterstate && !spawn && d.health > 100)
? d.o.z - d.eyeheight - 4.5f
float minfloor = (d.monsterState && !spawn && d.health > 100)
? d.origin.z - d.eyeHeight - 4.5f
: -1000.0f;
for (int x = x1; x <= x2; x++)
for (int x = x1; x <= x2; x++) {
for (int y = y1; y <= y2; y++) {
// collide with map
if (OUTBORD(x, y))
@ -160,8 +164,9 @@ collide(DynamicEntity *d, bool spawn, float drop, float rise)
if (floor < minfloor)
return false;
}
}
if (hi - lo < d.eyeheight + d.aboveeye)
if (hi - lo < d.eyeHeight + d.aboveEye)
return false;
float headspace = 10;
@ -171,53 +176,61 @@ collide(DynamicEntity *d, bool spawn, float drop, float rise)
if (!plcollide(d, player, &headspace, &hi, &lo))
return false;
}
if (d != player1)
if (!plcollide(d, player1, &headspace, &hi, &lo))
return false;
// this loop can be a performance bottleneck with many monster on a slow
// cpu, should replace with a blockmap but seems mostly fast enough
for (DynamicEntity *monster in getmonsters())
if (!vreject(d.o, monster.o, 7.0f) && d != monster &&
if (!vreject(d.origin, monster.origin, 7.0f) && d != monster &&
!plcollide(d, monster, &headspace, &hi, &lo))
return false;
headspace -= 0.01f;
mmcollide(d, &hi, &lo); // collide with map models
if (spawn) {
// just drop to floor (sideeffect)
d.o = OFMakeVector3D(d.o.x, d.o.y, lo + d.eyeheight);
d.onfloor = true;
d.origin =
OFMakeVector3D(d.origin.x, d.origin.y, lo + d.eyeHeight);
d.onFloor = true;
} else {
const float space = d.o.z - d.eyeheight - lo;
const float space = d.origin.z - d.eyeHeight - lo;
if (space < 0) {
if (space > -0.01)
// stick on step
d.o = OFMakeVector3D(
d.o.x, d.o.y, lo + d.eyeheight);
d.origin = OFMakeVector3D(
d.origin.x, d.origin.y, lo + d.eyeHeight);
else if (space > -1.26f)
// rise thru stair
d.o =
OFMakeVector3D(d.o.x, d.o.y, d.o.z + rise);
d.origin = OFAddVector3D(
d.origin, OFMakeVector3D(0, 0, rise));
else
return false;
} else
// gravity
d.o = OFMakeVector3D(d.o.x, d.o.y,
d.o.z - min(min(drop, space), headspace));
d.origin = OFSubtractVector3D(d.origin,
OFMakeVector3D(
0, 0, min(min(drop, space), headspace)));
const float space2 = hi - (d.o.z + d.aboveeye);
const float space2 = hi - (d.origin.z + d.aboveEye);
if (space2 < 0) {
if (space2 < -0.1)
return false; // hack alert!
// glue to ceiling
d.o = OFMakeVector3D(d.o.x, d.o.y, hi - d.aboveeye);
d.origin = OFMakeVector3D(
d.origin.x, d.origin.y, hi - d.aboveEye);
// cancel out jumping velocity
d.vel = OFMakeVector3D(d.vel.x, d.vel.y, 0);
d.velocity =
OFMakeVector3D(d.velocity.x, d.velocity.y, 0);
}
d.onfloor = d.o.z - d.eyeheight - lo < 0.001f;
d.onFloor = (d.origin.z - d.eyeHeight - lo < 0.001f);
}
return true;
}
@ -251,7 +264,7 @@ physicsframe() // optimally schedule physics frames inside the graphics frames
static void
moveplayer4(DynamicEntity *pl, int moveres, bool local, int curtime)
{
const bool water = hdr.waterlevel > pl.o.z - 0.5f;
const bool water = (hdr.waterlevel > pl.origin.z - 0.5f);
const bool floating = (editmode && local) || pl.state == CS_EDITING;
OFVector3D d; // vector of direction we ideally want to move in
@ -269,18 +282,18 @@ moveplayer4(DynamicEntity *pl, int moveres, bool local, int curtime)
d.x += (float)(pl.strafe * cos(rad(pl.yaw - 180)));
d.y += (float)(pl.strafe * sin(rad(pl.yaw - 180)));
const float speed = curtime / (water ? 2000.0f : 1000.0f) * pl.maxspeed;
const float speed = curtime / (water ? 2000.0f : 1000.0f) * pl.maxSpeed;
const float friction =
water ? 20.0f : (pl.onfloor || floating ? 6.0f : 30.0f);
water ? 20.0f : (pl.onFloor || floating ? 6.0f : 30.0f);
const float fpsfric = friction / curtime * 20.0f;
// slowly apply friction and direction to
// velocity, gives a smooth movement
vmul(pl.vel, fpsfric - 1);
vadd(pl.vel, d);
vdiv(pl.vel, fpsfric);
d = pl.vel;
vmul(pl.velocity, fpsfric - 1);
vadd(pl.velocity, d);
vdiv(pl.velocity, fpsfric);
d = pl.velocity;
vmul(d, speed); // d is now frametime based velocity vector
pl.blocked = false;
@ -288,52 +301,55 @@ moveplayer4(DynamicEntity *pl, int moveres, bool local, int curtime)
if (floating) {
// just apply velocity
vadd(pl.o, d);
if (pl.jumpnext) {
pl.jumpnext = false;
pl.vel = OFMakeVector3D(pl.vel.x, pl.vel.y, 2);
vadd(pl.origin, d);
if (pl.jumpNext) {
pl.jumpNext = false;
pl.velocity =
OFMakeVector3D(pl.velocity.x, pl.velocity.y, 2);
}
} else {
// apply velocity with collision
if (pl.onfloor || water) {
if (pl.jumpnext) {
pl.jumpnext = false;
if (pl.onFloor || water) {
if (pl.jumpNext) {
pl.jumpNext = false;
// physics impulse upwards
pl.vel =
OFMakeVector3D(pl.vel.x, pl.vel.y, 1.7);
pl.velocity = OFMakeVector3D(
pl.velocity.x, pl.velocity.y, 1.7);
// dampen velocity change even harder, gives
// correct water feel
if (water)
pl.vel = OFMakeVector3D(pl.vel.x / 8,
pl.vel.y / 8, pl.vel.z);
pl.velocity = OFMakeVector3D(
pl.velocity.x / 8,
pl.velocity.y / 8, pl.velocity.z);
if (local)
playsoundc(S_JUMP);
else if (pl.monsterstate) {
OFVector3D loc = pl.o;
else if (pl.monsterState) {
OFVector3D loc = pl.origin;
playsound(S_JUMP, &loc);
}
} else if (pl.timeinair > 800) {
} else if (pl.timeInAir > 800) {
// if we land after long time must have been a
// high jump, make thud sound
if (local)
playsoundc(S_LAND);
else if (pl.monsterstate) {
OFVector3D loc = pl.o;
else if (pl.monsterState) {
OFVector3D loc = pl.origin;
playsound(S_LAND, &loc);
}
}
pl.timeinair = 0;
pl.timeInAir = 0;
} else
pl.timeinair += curtime;
pl.timeInAir += curtime;
const float gravity = 20;
const float f = 1.0f / moveres;
// incorrect, but works fine
float dropf = ((gravity - 1) + pl.timeinair / 15.0f);
float dropf = ((gravity - 1) + pl.timeInAir / 15.0f);
// float slowly down in water
if (water) {
dropf = 5;
pl.timeinair = 0;
pl.timeInAir = 0;
}
// at high fps, gravity kicks in too fast
const float drop = dropf * curtime / gravity / 100 / moveres;
@ -343,32 +359,39 @@ moveplayer4(DynamicEntity *pl, int moveres, bool local, int curtime)
loopi(moveres) // discrete steps collision detection & sliding
{
// try move forward
pl.o = OFMakeVector3D(pl.o.x + f * d.x,
pl.o.y + f * d.y, pl.o.z + f * d.z);
pl.origin = OFAddVector3D(pl.origin,
OFMakeVector3D(f * d.x, f * d.y, f * d.z));
if (collide(pl, false, drop, rise))
continue;
// player stuck, try slide along y axis
pl.blocked = true;
pl.o = OFMakeVector3D(pl.o.x - f * d.x, pl.o.y, pl.o.z);
pl.origin = OFSubtractVector3D(
pl.origin, OFMakeVector3D(f * d.x, 0, 0));
if (collide(pl, false, drop, rise)) {
d.x = 0;
continue;
}
// still stuck, try x axis
pl.o = OFMakeVector3D(
pl.o.x + f * d.x, pl.o.y - f * d.y, pl.o.z);
pl.origin = OFAddVector3D(
pl.origin, OFMakeVector3D(f * d.x, -f * d.y, 0));
if (collide(pl, false, drop, rise)) {
d.y = 0;
continue;
}
// try just dropping down
pl.moving = false;
pl.o = OFMakeVector3D(pl.o.x - f * d.x, pl.o.y, pl.o.z);
pl.origin = OFSubtractVector3D(
pl.origin, OFMakeVector3D(f * d.x, 0, 0));
if (collide(pl, false, drop, rise)) {
d.y = d.x = 0;
continue;
}
pl.o = OFMakeVector3D(pl.o.x, pl.o.y, pl.o.z - f * d.z);
pl.origin = OFSubtractVector3D(
pl.origin, OFMakeVector3D(0, 0, f * d.z));
break;
}
}
@ -376,13 +399,16 @@ moveplayer4(DynamicEntity *pl, int moveres, bool local, int curtime)
// detect wether player is outside map, used for skipping zbuffer clear
// mostly
if (pl.o.x < 0 || pl.o.x >= ssize || pl.o.y < 0 || pl.o.y > ssize)
pl.outsidemap = true;
if (pl.origin.x < 0 || pl.origin.x >= ssize || pl.origin.y < 0 ||
pl.origin.y > ssize)
pl.outsideMap = true;
else {
struct sqr *s = S((int)pl.o.x, (int)pl.o.y);
pl.outsidemap = SOLID(s) ||
pl.o.z < s->floor - (s->type == FHF ? s->vdelta / 4 : 0) ||
pl.o.z > s->ceil + (s->type == CHF ? s->vdelta / 4 : 0);
struct sqr *s = S((int)pl.origin.x, (int)pl.origin.y);
pl.outsideMap = SOLID(s) ||
pl.origin.z <
s->floor - (s->type == FHF ? s->vdelta / 4 : 0) ||
pl.origin.z >
s->ceil + (s->type == CHF ? s->vdelta / 4 : 0);
}
// automatically apply smooth roll when strafing
@ -399,15 +425,15 @@ moveplayer4(DynamicEntity *pl, int moveres, bool local, int curtime)
// play sounds on water transitions
if (!pl.inwater && water) {
OFVector3D loc = pl.o;
if (!pl.inWater && water) {
OFVector3D loc = pl.origin;
playsound(S_SPLASH2, &loc);
pl.vel = OFMakeVector3D(pl.vel.x, pl.vel.y, 0);
} else if (pl.inwater && !water) {
OFVector3D loc = pl.o;
pl.velocity = OFMakeVector3D(pl.velocity.x, pl.velocity.y, 0);
} else if (pl.inWater && !water) {
OFVector3D loc = pl.origin;
playsound(S_SPLASH1, &loc);
}
pl.inwater = water;
pl.inWater = water;
}
void

View file

@ -100,13 +100,11 @@ extern void changemap(OFString *name);
extern void initclient();
extern void spawnplayer(DynamicEntity *d);
extern void selfdamage(int damage, int actor, DynamicEntity *act);
extern DynamicEntity *newdynent();
extern OFString *getclientmap();
extern OFString *modestr(int n);
extern DynamicEntity *getclient(int cn);
extern void setclient(int cn, id client);
extern void timeupdate(int timeremain);
extern void resetmovement(DynamicEntity *d);
extern void fixplayer1range();
// clientextras

View file

@ -335,7 +335,7 @@ gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwater)
readmatrices();
if (editmode) {
if (cursordepth == 1.0f)
worldpos = player1.o;
worldpos = player1.origin;
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
cursorupdate();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@ -385,7 +385,7 @@ gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwater)
glBegin(GL_QUADS);
glColor3ub(255, 255, 255);
if (crosshairfx) {
if (player1.gunwait)
if (player1.gunWait)
glColor3ub(128, 128, 128);
else if (player1.health <= 25)
glColor3ub(255, 0, 0);
@ -428,7 +428,7 @@ gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwater)
draw_textf(@"%d", 90, 827, 2, player1.health);
if (player1.armour)
draw_textf(@"%d", 390, 827, 2, player1.armour);
draw_textf(@"%d", 690, 827, 2, player1.ammo[player1.gunselect]);
draw_textf(@"%d", 690, 827, 2, player1.ammo[player1.gunSelect]);
glPopMatrix();
glPushMatrix();
glOrtho(0, VIRTW, VIRTH, 0, -1, 1);
@ -436,8 +436,8 @@ gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwater)
drawicon(128, 128, 20, 1650);
if (player1.armour)
drawicon(
(float)(player1.armourtype * 64), 0, 620, 1650);
int g = player1.gunselect;
(float)(player1.armourType * 64), 0, 620, 1650);
int g = player1.gunSelect;
int r = 64;
if (g > 2) {
g -= 3;

View file

@ -350,10 +350,10 @@ transplayer()
glRotated(player1.pitch, -1.0, 0.0, 0.0);
glRotated(player1.yaw, 0.0, 1.0, 0.0);
glTranslated(-player1.o.x,
(player1.state == CS_DEAD ? player1.eyeheight - 0.2f : 0) -
player1.o.z,
-player1.o.y);
glTranslated(-player1.origin.x,
(player1.state == CS_DEAD ? player1.eyeHeight - 0.2f : 0) -
player1.origin.z,
-player1.origin.y);
}
VARP(fov, 10, 105, 120);
@ -371,15 +371,16 @@ OFString *hudgunnames[] = { @"hudguns/fist", @"hudguns/shotg",
void
drawhudmodel(int start, int end, float speed, int base)
{
rendermodel(hudgunnames[player1.gunselect], start, end, 0, 1.0f,
OFMakeVector3D(player1.o.x, player1.o.z, player1.o.y),
rendermodel(hudgunnames[player1.gunSelect], start, end, 0, 1.0f,
OFMakeVector3D(
player1.origin.x, player1.origin.z, player1.origin.y),
player1.yaw + 90, player1.pitch, false, 1.0f, speed, 0, base);
}
void
drawhudgun(float fovy, float aspect, int farplane)
{
if (!hudgun /*|| !player1.gunselect*/)
if (!hudgun /*|| !player1.gunSelect*/)
return;
glEnable(GL_CULL_FACE);
@ -390,10 +391,10 @@ drawhudgun(float fovy, float aspect, int farplane)
glMatrixMode(GL_MODELVIEW);
// glClear(GL_DEPTH_BUFFER_BIT);
int rtime = reloadtime(player1.gunselect);
if (player1.lastaction && player1.lastattackgun == player1.gunselect &&
lastmillis - player1.lastaction < rtime) {
drawhudmodel(7, 18, rtime / 18.0f, player1.lastaction);
int rtime = reloadtime(player1.gunSelect);
if (player1.lastAction && player1.lastAttackGun == player1.gunSelect &&
lastmillis - player1.lastAction < rtime) {
drawhudmodel(7, 18, rtime / 18.0f, player1.lastAction);
} else
drawhudmodel(6, 1, 100, 0);
@ -411,7 +412,7 @@ gl_drawframe(int w, int h, float curfps)
float hf = hdr.waterlevel - 0.3f;
float fovy = (float)fov * h / w;
float aspect = w / (float)h;
bool underwater = player1.o.z < hf;
bool underwater = (player1.origin.z < hf);
glFogi(GL_FOG_START, (fog + 64) / 8);
glFogi(GL_FOG_END, fog);
@ -428,7 +429,7 @@ gl_drawframe(int w, int h, float curfps)
glFogi(GL_FOG_END, (fog + 96) / 8);
}
glClear((player1.outsidemap ? GL_COLOR_BUFFER_BIT : 0) |
glClear((player1.outsideMap ? GL_COLOR_BUFFER_BIT : 0) |
GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
@ -449,8 +450,8 @@ gl_drawframe(int w, int h, float curfps)
curvert = 0;
[strips removeAllItems];
render_world(player1.o.x, player1.o.y, player1.o.z, (int)player1.yaw,
(int)player1.pitch, (float)fov, w, h);
render_world(player1.origin.x, player1.origin.y, player1.origin.z,
(int)player1.yaw, (int)player1.pitch, (float)fov, w, h);
finishstrips();
gl_setupworld();

View file

@ -93,7 +93,7 @@ rendermodel(OFString *mdl, int frame, int range, int tex, float rad,
{
MD2 *m = loadmodel(mdl);
if (isoccluded(player1.o.x, player1.o.y, position.x - rad,
if (isoccluded(player1.origin.x, player1.origin.y, position.x - rad,
position.z - rad, rad * 2))
return;

View file

@ -57,7 +57,7 @@ void
render_particles(int time)
{
if (demoplayback && demotracking) {
OFVector3D o = player1.o;
OFVector3D o = player1.origin;
OFVector3D nom = OFMakeVector3D(0, 0, 0);
newparticle(&o, &nom, 100000000, 8);
}

View file

@ -224,7 +224,7 @@ loadgamerest()
[data increaseCountBy:DynamicEntity.serializedSize];
gzread(f, data.mutableItems, data.count);
[player1 setFromSerializedData:data];
player1.lastaction = lastmillis;
player1.lastAction = lastmillis;
int nmonsters = gzgeti();
OFArray<DynamicEntity *> *monsters = getmonsters();
@ -237,9 +237,9 @@ loadgamerest()
// lazy, could save id of enemy instead
monster.enemy = player1;
// also lazy, but no real noticable effect on game
monster.lastaction = monster.trigger = lastmillis + 500;
monster.lastAction = monster.trigger = lastmillis + 500;
if (monster.state == CS_DEAD)
monster.lastaction = 0;
monster.lastAction = 0;
}
restoremonsterstate();
@ -313,13 +313,13 @@ incomingdemodata(uchar *buf, int len, bool extras)
gzwrite(f, buf, len);
gzput(extras);
if (extras) {
gzput(player1.gunselect);
gzput(player1.lastattackgun);
gzputi(player1.lastaction - starttime);
gzputi(player1.gunwait);
gzput(player1.gunSelect);
gzput(player1.lastAttackGun);
gzputi(player1.lastAction - starttime);
gzputi(player1.gunWait);
gzputi(player1.health);
gzputi(player1.armour);
gzput(player1.armourtype);
gzput(player1.armourType);
loopi(NUMGUNS) gzput(player1.ammo[i]);
gzput(player1.state);
gzputi(bdamage);
@ -440,16 +440,16 @@ demoplaybackstep()
// read additional client side state not present in normal
// network stream
if ((extras = gzget())) {
target.gunselect = gzget();
target.lastattackgun = gzget();
target.lastaction = scaletime(gzgeti());
target.gunwait = gzgeti();
target.gunSelect = gzget();
target.lastAttackGun = gzget();
target.lastAction = scaletime(gzgeti());
target.gunWait = gzgeti();
target.health = gzgeti();
target.armour = gzgeti();
target.armourtype = gzget();
target.armourType = gzget();
loopi(NUMGUNS) target.ammo[i] = gzget();
target.state = gzget();
target.lastmove = playbacktime;
target.lastMove = playbacktime;
if ((bdamage = gzgeti()))
damageblend(bdamage);
if ((ddamage = gzgeti())) {
@ -462,9 +462,9 @@ demoplaybackstep()
// insert latest copy of player into history
if (extras &&
(playerhistory.count == 0 ||
playerhistory.lastObject.lastupdate != playbacktime)) {
playerhistory.lastObject.lastUpdate != playbacktime)) {
DynamicEntity *d = [target copy];
d.lastupdate = playbacktime;
d.lastUpdate = playbacktime;
if (playerhistory == nil)
playerhistory = [[OFMutableArray alloc] init];
@ -485,7 +485,7 @@ demoplaybackstep()
// find 2 positions in history that surround interpolation time point
size_t count = playerhistory.count;
for (ssize_t i = count - 1; i >= 0; i--) {
if (playerhistory[i].lastupdate < itime) {
if (playerhistory[i].lastUpdate < itime) {
DynamicEntity *a = playerhistory[i];
DynamicEntity *b = a;
@ -503,16 +503,16 @@ demoplaybackstep()
z = playerhistory[i - 1];
// if(a==z || b==c)
// printf("* %d\n", lastmillis);
float bf = (itime - a.lastupdate) /
(float)(b.lastupdate - a.lastupdate);
float bf = (itime - a.lastUpdate) /
(float)(b.lastUpdate - a.lastUpdate);
fixwrap(a, player1);
fixwrap(c, player1);
fixwrap(z, player1);
vdist(dist, v, z.o, c.o);
vdist(dist, v, z.origin, c.origin);
// if teleport or spawn, don't interpolate
if (dist < 16) {
catmulrom(
z.o, a.o, b.o, c.o, bf, player1.o);
catmulrom(z.origin, a.origin, b.origin,
c.origin, bf, player1.origin);
OFVector3D vz = OFMakeVector3D(
z.yaw, z.pitch, z.roll);
OFVector3D va = OFMakeVector3D(

View file

@ -117,7 +117,7 @@ updatechanvol(int chan, const OFVector3D *loc)
{
int vol = soundvol, pan = 255 / 2;
if (loc) {
vdist(dist, v, *loc, player1.o);
vdist(dist, v, *loc, player1.origin);
vol -= (int)(dist * 3 * soundvol /
255); // simple mono distance attenuation
if (stereo && (v.x != 0 || v.y != 0)) {

View file

@ -32,7 +32,7 @@ selectgun(int a, int b, int c)
if (a < -1 || b < -1 || c < -1 || a >= NUMGUNS || b >= NUMGUNS ||
c >= NUMGUNS)
return;
int s = player1.gunselect;
int s = player1.gunSelect;
if (a >= 0 && s != a && player1.ammo[a])
s = a;
else if (b >= 0 && s != b && player1.ammo[b])
@ -49,9 +49,9 @@ selectgun(int a, int b, int c)
s = GUN_RIFLE;
else
s = GUN_FIST;
if (s != player1.gunselect)
if (s != player1.gunSelect)
playsoundc(S_WEAPLOAD);
player1.gunselect = s;
player1.gunSelect = s;
// conoutf(@"%@ selected", (int)guns[s].name);
}
@ -89,7 +89,7 @@ createrays(const OFVector3D *from, const OFVector3D *to)
static bool
intersect(DynamicEntity *d, const OFVector3D *from, const OFVector3D *to)
{
OFVector3D v = *to, w = d.o;
OFVector3D v = *to, w = d.origin;
const OFVector3D *p;
vsub(v, *from);
vsub(w, *from);
@ -109,9 +109,10 @@ intersect(DynamicEntity *d, const OFVector3D *from, const OFVector3D *to)
}
}
return (p->x <= d.o.x + d.radius && p->x >= d.o.x - d.radius &&
p->y <= d.o.y + d.radius && p->y >= d.o.y - d.radius &&
p->z <= d.o.z + d.aboveeye && p->z >= d.o.z - d.eyeheight);
return (p->x <= d.origin.x + d.radius &&
p->x >= d.origin.x - d.radius && p->y <= d.origin.y + d.radius &&
p->y >= d.origin.y - d.radius && p->z <= d.origin.z + d.aboveEye &&
p->z >= d.origin.z - d.eyeHeight);
}
OFString *
@ -124,7 +125,7 @@ playerincrosshair()
if (player == [OFNull null])
continue;
OFVector3D o = player1.o;
OFVector3D o = player1.origin;
if (intersect(player, &o, &worldpos))
return [player name];
}
@ -169,13 +170,13 @@ newprojectile(const OFVector3D *from, const OFVector3D *to, float speed,
void
hit(int target, int damage, DynamicEntity *d, DynamicEntity *at)
{
OFVector3D o = d.o;
OFVector3D o = d.origin;
if (d == player1)
selfdamage(damage, at == player1 ? -1 : -2, at);
else if (d.monsterstate)
else if (d.monsterState)
monsterpain(d, damage, at);
else {
addmsg(1, 4, SV_DAMAGE, target, damage, d.lifesequence);
addmsg(1, 4, SV_DAMAGE, target, damage, d.lifeSequence);
playsound(S_PAIN1 + rnd(5), &o);
}
particle_splash(3, damage, 1000, &o);
@ -191,7 +192,7 @@ radialeffect(
{
if (o.state != CS_ALIVE)
return;
vdist(dist, temp, *v, o.o);
vdist(dist, temp, *v, o.origin);
dist -= 2; // account for eye distance imprecision
if (dist < RL_DAMRAD) {
if (dist < 0)
@ -199,7 +200,7 @@ radialeffect(
int damage = (int)(qdam * (1 - (dist / RL_DAMRAD)));
hit(cn, damage, o, at);
vmul(temp, (RL_DAMRAD - dist) * damage / 800);
vadd(o.vel, temp);
vadd(o.velocity, temp);
}
}
@ -265,8 +266,8 @@ moveprojectiles(float time)
if (!p.inuse)
continue;
int qdam = guns[p.gun].damage * (p.owner.quadmillis ? 4 : 1);
if (p.owner.monsterstate)
int qdam = guns[p.gun].damage * (p.owner.quadMillis ? 4 : 1);
if (p.owner.monsterState)
qdam /= MONSTERDAMAGEFACTOR;
vdist(dist, v, p.o, p.to);
float dtime = dist * 1000 / p.speed;
@ -283,7 +284,7 @@ moveprojectiles(float time)
projdamage(player1, p, &v, -1, -1, qdam);
for (DynamicEntity *monster in getmonsters())
if (!vreject(monster.o, v, 10.0f) &&
if (!vreject(monster.origin, v, 10.0f) &&
monster != p.owner)
projdamage(monster, p, &v, -1, i, qdam);
}
@ -312,7 +313,7 @@ void
shootv(int gun, const OFVector3D *from, const OFVector3D *to, DynamicEntity *d,
bool local)
{
OFVector3D loc = d.o;
OFVector3D loc = d.origin;
playsound(guns[gun].sound, d == player1 ? NULL : &loc);
int pspeed = 25;
switch (gun) {
@ -334,7 +335,7 @@ shootv(int gun, const OFVector3D *from, const OFVector3D *to, DynamicEntity *d,
case GUN_ICEBALL:
case GUN_SLIMEBALL:
pspeed = guns[gun].projspeed;
if (d.monsterstate)
if (d.monsterState)
pspeed /= 2;
newprojectile(from, to, (float)pspeed, local, d, gun);
break;
@ -353,7 +354,7 @@ hitpush(int target, int damage, DynamicEntity *d, DynamicEntity *at,
hit(target, damage, d, at);
vdist(dist, v, *from, *to);
vmul(v, damage / dist / 50);
vadd(d.vel, v);
vadd(d.velocity, v);
}
void
@ -362,12 +363,12 @@ raydamage(DynamicEntity *o, const OFVector3D *from, const OFVector3D *to,
{
if (o.state != CS_ALIVE)
return;
int qdam = guns[d.gunselect].damage;
if (d.quadmillis)
int qdam = guns[d.gunSelect].damage;
if (d.quadMillis)
qdam *= 4;
if (d.monsterstate)
if (d.monsterState)
qdam /= MONSTERDAMAGEFACTOR;
if (d.gunselect == GUN_SG) {
if (d.gunSelect == GUN_SG) {
int damage = 0;
loop(r, SGRAYS) if (intersect(o, from, &sg[r])) damage += qdam;
if (damage)
@ -379,52 +380,52 @@ raydamage(DynamicEntity *o, const OFVector3D *from, const OFVector3D *to,
void
shoot(DynamicEntity *d, const OFVector3D *targ)
{
int attacktime = lastmillis - d.lastaction;
if (attacktime < d.gunwait)
int attacktime = lastmillis - d.lastAction;
if (attacktime < d.gunWait)
return;
d.gunwait = 0;
d.gunWait = 0;
if (!d.attacking)
return;
d.lastaction = lastmillis;
d.lastattackgun = d.gunselect;
if (!d.ammo[d.gunselect]) {
d.lastAction = lastmillis;
d.lastAttackGun = d.gunSelect;
if (!d.ammo[d.gunSelect]) {
playsoundc(S_NOAMMO);
d.gunwait = 250;
d.lastattackgun = -1;
d.gunWait = 250;
d.lastAttackGun = -1;
return;
}
if (d.gunselect)
d.ammo[d.gunselect]--;
OFVector3D from = d.o;
if (d.gunSelect)
d.ammo[d.gunSelect]--;
OFVector3D from = d.origin;
OFVector3D to = *targ;
from.z -= 0.2f; // below eye
vdist(dist, unitv, from, to);
vdiv(unitv, dist);
OFVector3D kickback = unitv;
vmul(kickback, guns[d.gunselect].kickamount * -0.01f);
vadd(d.vel, kickback);
vmul(kickback, guns[d.gunSelect].kickamount * -0.01f);
vadd(d.velocity, kickback);
if (d.pitch < 80.0f)
d.pitch += guns[d.gunselect].kickamount * 0.05f;
d.pitch += guns[d.gunSelect].kickamount * 0.05f;
if (d.gunselect == GUN_FIST || d.gunselect == GUN_BITE) {
if (d.gunSelect == GUN_FIST || d.gunSelect == GUN_BITE) {
vmul(unitv, 3); // punch range
to = from;
vadd(to, unitv);
}
if (d.gunselect == GUN_SG)
if (d.gunSelect == GUN_SG)
createrays(&from, &to);
if (d.quadmillis && attacktime > 200)
if (d.quadMillis && attacktime > 200)
playsoundc(S_ITEMPUP);
shootv(d.gunselect, &from, &to, d, true);
if (!d.monsterstate)
addmsg(1, 8, SV_SHOT, d.gunselect, (int)(from.x * DMF),
shootv(d.gunSelect, &from, &to, d, true);
if (!d.monsterState)
addmsg(1, 8, SV_SHOT, d.gunSelect, (int)(from.x * DMF),
(int)(from.y * DMF), (int)(from.z * DMF), (int)(to.x * DMF),
(int)(to.y * DMF), (int)(to.z * DMF));
d.gunwait = guns[d.gunselect].attackdelay;
d.gunWait = guns[d.gunSelect].attackdelay;
if (guns[d.gunselect].projspeed)
if (guns[d.gunSelect].projspeed)
return;
[players enumerateObjectsUsingBlock:^(id player, size_t i, bool *stop) {
@ -436,6 +437,6 @@ shoot(DynamicEntity *d, const OFVector3D *targ)
if (monster != d)
raydamage(monster, &from, &to, d, -2);
if (d.monsterstate)
if (d.monsterState)
raydamage(player1, &from, &to, d, -1);
}

View file

@ -270,7 +270,7 @@ closestent() // used for delent and edit mode ent display
return;
OFVector3D v = OFMakeVector3D(e.x, e.y, e.z);
vdist(dist, t, player1.o, v);
vdist(dist, t, player1.origin, v);
if (dist < bdist) {
best = i;
bdist = dist;

View file

@ -205,7 +205,7 @@ dodynlight(const OFVector3D *vold, const OFVector3D *v, int reach, int strength,
{
if (!reach)
reach = dynlight;
if (owner.monsterstate)
if (owner.monsterState)
reach = reach / 2;
if (!reach)
return;

View file

@ -137,7 +137,7 @@ render_seg_new(
// first collect occlusion information for this block
for (int oy = y; oy < ys; oy++) {
SWS(w, ox, oy, sz)->occluded =
isoccluded(player1.o.x, player1.o.y,
isoccluded(player1.origin.x, player1.origin.y,
(float)(ox << mip), (float)(oy << mip), fsize);
}
}