Artifact ba58eb8bdf46167d9726018312dca7135fb9ad7982d3aa5b376da996f6ee0a76:
- File
src/DynamicEntity.m
— part of check-in
[75e920ae30]
at
2025-03-29 14:25:43
on branch trunk
— Switch from clang-format to manual formatting
clang-format does too many weird things. (user: js, size: 6984) [annotate] [blame] [check-ins using]
#import "DynamicEntity.h" #include "cube.h" #import "Monster.h" #import "Player.h" struct dynent { OFVector3D origin, velocity; float yaw, pitch, roll; 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, lag, ping; int lifeSequence; int state; int frags; int health, armour, armourType, quadMillis; int gunSelect, gunWait; int lastAction, lastAttackGun, lastMove; bool attacking; int ammo[NUMGUNS]; int monsterState; int monsterType; void *enemy; float targetYaw; bool blocked, moving; int trigger; OFVector3D attackTarget; int anger; char name[260], team[260]; }; @implementation DynamicEntity + (instancetype)entity { return [[self alloc] init]; } + (size_t)serializedSize { return sizeof(struct dynent); } - (instancetype)init { self = [super init]; _ammo = (int *)OFAllocZeroedMemory(NUMGUNS, sizeof(int)); _yaw = 270; _maxSpeed = 22; _radius = 1.1f; _eyeHeight = 3.2f; _aboveEye = 0.7f; _lastUpdate = lastmillis; _name = @""; _state = CS_ALIVE; [self resetToSpawnState]; return self; } - (void)dealloc { OFFreeMemory(_ammo); } - (id)copy { DynamicEntity *copy = [[self.class alloc] init]; 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->_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->_radius = _radius; copy->_eyeHeight = _eyeHeight; copy->_aboveEye = _aboveEye; copy->_lastUpdate = _lastUpdate; copy->_lag = _lag; copy->_ping = _ping; copy->_state = _state; 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->_attacking = _attacking; for (size_t i = 0; i < NUMGUNS; i++) copy->_ammo[i] = _ammo[i]; copy->_blocked = _blocked; copy->_moving = _moving; copy->_name = [_name copy]; return copy; } - (OFData *)dataBySerializing { // This is frighteningly *TERRIBLE*, but the format used by existing // savegames. struct dynent data = { .origin = _origin, .velocity = _velocity, .yaw = _yaw, .pitch = _pitch, .roll = _roll, .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, .radius = _radius, .eyeHeight = _eyeHeight, .aboveEye = _aboveEye, .lastUpdate = _lastUpdate, .lag = _lag, .ping = _ping, .state = _state, .health = _health, .armour = _armour, .armourType = _armourType, .quadMillis = _quadMillis, .gunSelect = _gunSelect, .gunWait = _gunWait, .lastAction = _lastAction, .lastAttackGun = _lastAttackGun, .lastMove = _lastMove, .attacking = _attacking, .blocked = _blocked, .moving = _moving }; for (int i = 0; i < NUMGUNS; i++) data.ammo[i] = _ammo[i]; memcpy(data.name, _name.UTF8String, min(_name.UTF8StringLength, 259)); if ([self isKindOfClass: Player.class]) { Player *player = (Player *)self; data.lifeSequence = player.lifeSequence, data.frags = player.frags; memcpy(data.team, player.team.UTF8String, min(player.team.UTF8StringLength, 259)); } if ([self isKindOfClass: Monster.class]) { Monster *monster = (Monster *)self; data.monsterState = monster.monsterState; data.monsterType = monster.monsterType; data.targetYaw = monster.targetYaw; data.trigger = monster.trigger; data.attackTarget = monster.attackTarget; data.anger = monster.anger; } return [OFData dataWithItems: &data count: sizeof(data)]; } - (void)setFromSerializedData: (OFData *)data { struct dynent d; if (data.count != sizeof(struct dynent)) @throw [OFOutOfRangeException exception]; memcpy(&d, data.items, data.count); _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; _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; _radius = d.radius; _eyeHeight = d.eyeHeight; _aboveEye = d.aboveEye; _lastUpdate = d.lastUpdate; _lag = d.lag; _ping = d.ping; _state = d.state; _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; _attacking = d.attacking; for (int i = 0; i < NUMGUNS; i++) _ammo[i] = d.ammo[i]; _blocked = d.blocked; _moving = d.moving; _name = [[OFString alloc] initWithUTF8String: d.name]; if ([self isKindOfClass: Player.class]) { Player *player = (Player *)self; player.lifeSequence = d.lifeSequence; player.frags = d.frags; player.team = @(d.team); } if ([self isKindOfClass: Monster.class]) { Monster *monster = (Monster *)self; monster.monsterState = d.monsterState; monster.monsterType = d.monsterType; monster.targetYaw = d.targetYaw; monster.trigger = d.trigger; monster.attackTarget = d.attackTarget; monster.anger = d.anger; } } - (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