Cube  Check-in [89fbd7a152]

Overview
Comment:Make more use of convenience methods
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 89fbd7a1520ecb65809b4c1bd10006ce9bb3a662cb7e7804abaf85d1ee1da63a
User & Date: js on 2025-03-20 13:21:56
Other Links: manifest | tags
Context
2025-03-20
16:04
Convert entity to a class check-in: 4b002822f9 user: js tags: trunk
13:21
Make more use of convenience methods check-in: 89fbd7a152 user: js tags: trunk
11:03
Use enumerateObjectsUsingBlock: where appropriate check-in: fd4460c7b6 user: js tags: trunk
Changes

Modified src/Alias.h from [6c97091132] to [12efdce9a2].

1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
#import "Identifier.h"

OF_ASSUME_NONNULL_BEGIN

@interface Alias: Identifier
@property (copy, nonatomic) OFString *action;
@property (readonly, nonatomic) bool persisted;




- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name
                      action:(OFString *)action
                   persisted:(bool)persisted;
@end

OF_ASSUME_NONNULL_END








>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#import "Identifier.h"

OF_ASSUME_NONNULL_BEGIN

@interface Alias: Identifier
@property (copy, nonatomic) OFString *action;
@property (readonly, nonatomic) bool persisted;

+ (instancetype)aliasWithName:(OFString *)name
                       action:(OFString *)action
                    persisted:(bool)persisted;
- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name
                      action:(OFString *)action
                   persisted:(bool)persisted;
@end

OF_ASSUME_NONNULL_END

Modified src/Alias.m from [2901519ebd] to [dce3b067a2].

1
2
3









4
5
6
7
8
9
10
#import "Alias.h"

@implementation Alias









- (instancetype)initWithName:(OFString *)name
                      action:(OFString *)action
                   persisted:(bool)persisted
{
	self = [super initWithName:name];

	_action = [action copy];



>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#import "Alias.h"

@implementation Alias
+ (instancetype)aliasWithName:(OFString *)name
                       action:(OFString *)action
                    persisted:(bool)persisted;
{
	return [[self alloc] initWithName:name
	                           action:action
	                        persisted:persisted];
}

- (instancetype)initWithName:(OFString *)name
                      action:(OFString *)action
                   persisted:(bool)persisted
{
	self = [super initWithName:name];

	_action = [action copy];

Added src/Client.h version [3002aefde8].

Added src/Client.mm version [432ce6fc62].

Modified src/Command.h from [e066e0d794] to [e984d89122].

1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
#import "Identifier.h"

OF_ASSUME_NONNULL_BEGIN

@interface Command: Identifier
@property (readonly, nonatomic) void (*function)();
@property (readonly, nonatomic) int argumentsTypes;




- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name
                    function:(void (*)())function
              argumentsTypes:(int)argumentsTypes;
- (int)callWithArguments:(OFArray<OFString *> *)arguments isDown:(bool)isDown;
@end









>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#import "Identifier.h"

OF_ASSUME_NONNULL_BEGIN

@interface Command: Identifier
@property (readonly, nonatomic) void (*function)();
@property (readonly, nonatomic) int argumentsTypes;

+ (instancetype)commandWithName:(OFString *)name
                       function:(void (*)())function
                 argumentsTypes:(int)argumentsTypes;
- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name
                    function:(void (*)())function
              argumentsTypes:(int)argumentsTypes;
- (int)callWithArguments:(OFArray<OFString *> *)arguments isDown:(bool)isDown;
@end

Modified src/Command.mm from [16592a90b0] to [ca8bd2ebde].

16
17
18
19
20
21
22









23
24
25
26
27
28
29
		[copy addObject:@""];

	[copy makeImmutable];
	return copy;
}

@implementation Command









- (instancetype)initWithName:(OFString *)name
                    function:(void (*)())function
              argumentsTypes:(int)argumentsTypes
{
	self = [super initWithName:name];

	_function = function;







>
>
>
>
>
>
>
>
>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
		[copy addObject:@""];

	[copy makeImmutable];
	return copy;
}

@implementation Command
+ (instancetype)commandWithName:(OFString *)name
                       function:(void (*)())function
                 argumentsTypes:(int)argumentsTypes
{
	return [[self alloc] initWithName:name
	                         function:function
	                   argumentsTypes:argumentsTypes];
}

- (instancetype)initWithName:(OFString *)name
                    function:(void (*)())function
              argumentsTypes:(int)argumentsTypes
{
	self = [super initWithName:name];

	_function = function;

Added src/ConsoleLine.h version [a5636ed577].

Added src/ConsoleLine.m version [8c83ebcd46].

Modified src/KeyMapping.h from [995386e6ec] to [4403af7dfe].

1
2
3
4
5
6
7
8
9


10
11
12
13
#import <ObjFW/ObjFW.h>

OF_ASSUME_NONNULL_BEGIN

@interface KeyMapping: OFObject
@property (readonly) int code;
@property (readonly, nonatomic) OFString *name;
@property (copy, nonatomic) OFString *action;



- (instancetype)initWithCode:(int)code name:(OFString *)name;
@end

OF_ASSUME_NONNULL_END









>
>




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#import <ObjFW/ObjFW.h>

OF_ASSUME_NONNULL_BEGIN

@interface KeyMapping: OFObject
@property (readonly) int code;
@property (readonly, nonatomic) OFString *name;
@property (copy, nonatomic) OFString *action;

+ (instancetype)mappingWithCode:(int)code name:(OFString *)name;
- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithCode:(int)code name:(OFString *)name;
@end

OF_ASSUME_NONNULL_END

Modified src/KeyMapping.m from [c90f999690] to [49eed66821].

1
2
3





4
5
6
7
8
9
10
#import "KeyMapping.h"

@implementation KeyMapping





- (instancetype)initWithCode:(int)code name:(OFString *)name
{
	self = [super init];

	_code = code;
	_name = [name copy];




>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#import "KeyMapping.h"

@implementation KeyMapping
+ (instancetype)mappingWithCode:(int)code name:(OFString *)name
{
	return [[self alloc] initWithCode:code name:name];
}

- (instancetype)initWithCode:(int)code name:(OFString *)name
{
	self = [super init];

	_code = code;
	_name = [name copy];

Modified src/MD2.h from [3eecbab1e8] to [abc59220a9].

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22
23
24
25
26
#import <ObjFW/ObjFW.h>

OF_ASSUME_NONNULL_BEGIN

@class MapModelInfo;

@interface MD2: OFObject
@property (nonatomic) MapModelInfo *mmi;
@property (copy, nonatomic) OFString *loadname;
@property (nonatomic) int mdlnum;
@property (nonatomic) bool loaded;


- (bool)loadWithIRI:(OFIRI *)IRI;
- (void)renderWithLight:(OFVector3D)light
                  frame:(int)frame
                  range:(int)range
                      x:(float)x
                      y:(float)y
                      z:(float)z
                    yaw:(float)yaw
                  pitch:(float)pitch
                  scale:(float)scale
                  speed:(float)speed
                   snap:(int)snap
               basetime:(int)basetime;
- (void)scaleWithFrame:(int)frame scale:(float)scale snap:(int)snap;












>




|
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


19
20
21
22
23
24
25
#import <ObjFW/ObjFW.h>

OF_ASSUME_NONNULL_BEGIN

@class MapModelInfo;

@interface MD2: OFObject
@property (nonatomic) MapModelInfo *mmi;
@property (copy, nonatomic) OFString *loadname;
@property (nonatomic) int mdlnum;
@property (nonatomic) bool loaded;

+ (instancetype)md2;
- (bool)loadWithIRI:(OFIRI *)IRI;
- (void)renderWithLight:(OFVector3D)light
                  frame:(int)frame
                  range:(int)range
               position:(OFVector3D)position


                    yaw:(float)yaw
                  pitch:(float)pitch
                  scale:(float)scale
                  speed:(float)speed
                   snap:(int)snap
               basetime:(int)basetime;
- (void)scaleWithFrame:(int)frame scale:(float)scale snap:(int)snap;

Modified src/MD2.mm from [4b55922953] to [3c502ddbf2].

39
40
41
42
43
44
45





46
47
48
49
50
51
52
	int _numFrames;
	int _numVerts;
	char *_frames;
	OFVector3D **_mverts;
	int _displaylist;
	int _displaylistverts;
}






- (void)dealloc
{
	if (_glCommands)
		delete[] _glCommands;
	if (_frames)
		delete[] _frames;







>
>
>
>
>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
	int _numFrames;
	int _numVerts;
	char *_frames;
	OFVector3D **_mverts;
	int _displaylist;
	int _displaylistverts;
}

+ (instancetype)md2
{
	return [[self alloc] init];
}

- (void)dealloc
{
	if (_glCommands)
		delete[] _glCommands;
	if (_frames)
		delete[] _frames;
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
		v->z = (snap(sn, cv[2] * cf->scale[2]) + cf->translate[2]) / sc;
	}
}

- (void)renderWithLight:(OFVector3D)light
                  frame:(int)frame
                  range:(int)range
                      x:(float)x
                      y:(float)y
                      z:(float)z
                    yaw:(float)yaw
                  pitch:(float)pitch
                  scale:(float)sc
                  speed:(float)speed
                   snap:(int)sn
               basetime:(int)basetime
{
	loopi(range) if (!_mverts[frame + i])[self scaleWithFrame:frame + i
	                                                    scale:sc
	                                                     snap:sn];

	glPushMatrix();
	glTranslatef(x, y, z);
	glRotatef(yaw + 180, 0, -1, 0);
	glRotatef(pitch, 0, 0, 1);

	glColor3fv((float *)&light);

	if (_displaylist && frame == 0 && range == 1) {
		glCallList(_displaylist);







|
<
<












|







127
128
129
130
131
132
133
134


135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
		v->z = (snap(sn, cv[2] * cf->scale[2]) + cf->translate[2]) / sc;
	}
}

- (void)renderWithLight:(OFVector3D)light
                  frame:(int)frame
                  range:(int)range
               position:(OFVector3D)position


                    yaw:(float)yaw
                  pitch:(float)pitch
                  scale:(float)sc
                  speed:(float)speed
                   snap:(int)sn
               basetime:(int)basetime
{
	loopi(range) if (!_mverts[frame + i])[self scaleWithFrame:frame + i
	                                                    scale:sc
	                                                     snap:sn];

	glPushMatrix();
	glTranslatef(position.x, position.y, position.z);
	glRotatef(yaw + 180, 0, -1, 0);
	glRotatef(pitch, 0, 0, 1);

	glColor3fv((float *)&light);

	if (_displaylist && frame == 0 && range == 1) {
		glCallList(_displaylist);

Modified src/MapModelInfo.h from [5ed60ec67c] to [2be3bcf086].

1
2
3
4
5
6
7
8






9
10
11
12
13
14
15
#import <ObjFW/ObjFW.h>

OF_ASSUME_NONNULL_BEGIN

@interface MapModelInfo: OFObject
@property (nonatomic) int rad, h, zoff, snap;
@property (copy, nonatomic) OFString *name;







- (instancetype)initWithRad:(int)rad
                          h:(int)h
                       zoff:(int)zoff
                       snap:(int)snap
                       name:(OFString *)name;
@end









>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#import <ObjFW/ObjFW.h>

OF_ASSUME_NONNULL_BEGIN

@interface MapModelInfo: OFObject
@property (nonatomic) int rad, h, zoff, snap;
@property (copy, nonatomic) OFString *name;

+ (instancetype)infoWithRad:(int)rad
                          h:(int)h
                       zoff:(int)zoff
                       snap:(int)snap
                       name:(OFString *)name;
- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithRad:(int)rad
                          h:(int)h
                       zoff:(int)zoff
                       snap:(int)snap
                       name:(OFString *)name;
@end

Modified src/MapModelInfo.m from [a1a57242f0] to [d506409929].

1
2
3









4
5
6
7
8
9
10
#import "MapModelInfo.h"

@implementation MapModelInfo









- (instancetype)initWithRad:(int)rad
                          h:(int)h
                       zoff:(int)zoff
                       snap:(int)snap
                       name:(OFString *)name
{
	self = [super init];



>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#import "MapModelInfo.h"

@implementation MapModelInfo
+ (instancetype)infoWithRad:(int)rad
                          h:(int)h
                       zoff:(int)zoff
                       snap:(int)snap
                       name:(OFString *)name
{
	return [[self alloc] initWithRad:rad h:h zoff:zoff snap:snap name:name];
}

- (instancetype)initWithRad:(int)rad
                          h:(int)h
                       zoff:(int)zoff
                       snap:(int)snap
                       name:(OFString *)name
{
	self = [super init];

Modified src/Menu.h from [5fa014f8d6] to [d8e35c6745].

1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
#import <ObjFW/ObjFW.h>

OF_ASSUME_NONNULL_BEGIN

@class MenuItem;

@interface Menu: OFObject
@property (readonly, nonatomic) OFString *name;
@property (readonly) OFMutableArray<MenuItem *> *items;
@property (nonatomic) int mwidth;
@property (nonatomic) int menusel;



- (instancetype)initWithName:(OFString *)name;
@end

OF_ASSUME_NONNULL_END












>
>




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#import <ObjFW/ObjFW.h>

OF_ASSUME_NONNULL_BEGIN

@class MenuItem;

@interface Menu: OFObject
@property (readonly, nonatomic) OFString *name;
@property (readonly) OFMutableArray<MenuItem *> *items;
@property (nonatomic) int mwidth;
@property (nonatomic) int menusel;

+ (instancetype)menuWithName:(OFString *)name;
- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name;
@end

OF_ASSUME_NONNULL_END

Modified src/Menu.m from [bdc2f1f706] to [e5fbce3936].

1
2
3





4
5
6
7
8
9
10
#import "Menu.h"

@implementation Menu





- (instancetype)initWithName:(OFString *)name
{
	self = [super init];

	_name = [name copy];
	_items = [[OFMutableArray alloc] init];




>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#import "Menu.h"

@implementation Menu
+ (instancetype)menuWithName:(OFString *)name
{
	return [[self alloc] initWithName:name];
}

- (instancetype)initWithName:(OFString *)name
{
	self = [super init];

	_name = [name copy];
	_items = [[OFMutableArray alloc] init];

Modified src/MenuItem.h from [3f56310839] to [237d14ade3].

1
2
3
4
5


6
7
#import <ObjFW/ObjFW.h>

@interface MenuItem: OFObject
@property (readonly, nonatomic) OFString *text, *action;



- (instancetype)initWithText:(OFString *)text action:(OFString *)action;
@end





>
>


1
2
3
4
5
6
7
8
9
#import <ObjFW/ObjFW.h>

@interface MenuItem: OFObject
@property (readonly, nonatomic) OFString *text, *action;

+ (instancetype)itemWithText:(OFString *)text action:(OFString *)action;
- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithText:(OFString *)text action:(OFString *)action;
@end

Modified src/MenuItem.m from [2a6ad46c6d] to [5ee318d452].

1
2
3





4
5
6
7
8
9
10
#import "MenuItem.h"

@implementation MenuItem





- (instancetype)initWithText:(OFString *)text action:(OFString *)action
{
	self = [super init];

	_text = [text copy];
	_action = [action copy];




>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#import "MenuItem.h"

@implementation MenuItem
+ (instancetype)itemWithText:(OFString *)text action:(OFString *)action
{
	return [[self alloc] initWithText:text action:action];
}

- (instancetype)initWithText:(OFString *)text action:(OFString *)action
{
	self = [super init];

	_text = [text copy];
	_action = [action copy];

Modified src/Projectile.h from [f3375dc858] to [03669c69fe].

1
2
3
4
5
6
7
8
9
10


11
#import <ObjFW/ObjFW.h>

@class DynamicEntity;

@interface Projectile: OFObject
@property (nonatomic) OFVector3D o, to;
@property (nonatomic) float speed;
@property (nonatomic) DynamicEntity *owner;
@property (nonatomic) int gun;
@property (nonatomic) bool inuse, local;


@end










>
>

1
2
3
4
5
6
7
8
9
10
11
12
13
#import <ObjFW/ObjFW.h>

@class DynamicEntity;

@interface Projectile: OFObject
@property (nonatomic) OFVector3D o, to;
@property (nonatomic) float speed;
@property (nonatomic) DynamicEntity *owner;
@property (nonatomic) int gun;
@property (nonatomic) bool inuse, local;

+ (instancetype)projectile;
@end

Modified src/Projectile.m from [902fed7b64] to [f2a969a0fa].

1
2
3




4
#import "Projectile.h"

@implementation Projectile




@end



>
>
>
>

1
2
3
4
5
6
7
8
#import "Projectile.h"

@implementation Projectile
+ (instancetype)projectile
{
	return [[self alloc] init];
}
@end

Added src/ResolverResult.h version [7ec5a5a420].

Added src/ResolverResult.mm version [36dcd5aa96].

Added src/ResolverThread.h version [648d3b8e86].

Added src/ResolverThread.mm version [5a480794ce].

Modified src/ServerInfo.h from [fa8f02f977] to [3ffaecefa4].

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
#import <ObjFW/ObjFW.h>

#include <enet/enet.h>

@interface ServerInfo: OFObject <OFComparing>
@property (readonly, nonatomic) OFString *name;
@property (copy, nonatomic) OFString *full;
@property (copy, nonatomic) OFString *map;
@property (copy, nonatomic) OFString *sdesc;
@property (nonatomic) int mode, numplayers, ping, protocol, minremain;
@property (nonatomic) ENetAddress address;


- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name;
@end












>



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#import <ObjFW/ObjFW.h>

#include <enet/enet.h>

@interface ServerInfo: OFObject <OFComparing>
@property (readonly, nonatomic) OFString *name;
@property (copy, nonatomic) OFString *full;
@property (copy, nonatomic) OFString *map;
@property (copy, nonatomic) OFString *sdesc;
@property (nonatomic) int mode, numplayers, ping, protocol, minremain;
@property (nonatomic) ENetAddress address;

+ (instancetype)infoWithName:(OFString *)name;
- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name;
@end

Modified src/ServerInfo.mm from [4b142ee758] to [d173cecbd6].

1
2
3
4
5





6
7
8
9
10
11
12
#import "ServerInfo.h"

#include "cube.h"

@implementation ServerInfo





- (instancetype)initWithName:(OFString *)name
{
	self = [super init];

	_name = [name copy];
	_full = @"";
	_mode = 0;





>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#import "ServerInfo.h"

#include "cube.h"

@implementation ServerInfo
+ (instancetype)infoWithName:(OFString *)name;
{
	return [[self alloc] initWithName:name];
}

- (instancetype)initWithName:(OFString *)name
{
	self = [super init];

	_name = [name copy];
	_full = @"";
	_mode = 0;

Modified src/Variable.h from [82779ddfda] to [1fe61b3c20].

1
2
3
4
5
6
7
8
9
10






11
12
13
14
15
16
17
#import "Identifier.h"

OF_ASSUME_NONNULL_BEGIN

@interface Variable: Identifier
@property (readonly, nonatomic) int min, max;
@property (readonly, nonatomic) int *storage;
@property (readonly, nonatomic) void (*__cdecl function)();
@property (readonly, nonatomic) bool persisted;







- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name
                         min:(int)min
                         max:(int)max
                     storage:(int *)storage
                    function:(void (*__cdecl)())function
                   persisted:(bool)persisted;










>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#import "Identifier.h"

OF_ASSUME_NONNULL_BEGIN

@interface Variable: Identifier
@property (readonly, nonatomic) int min, max;
@property (readonly, nonatomic) int *storage;
@property (readonly, nonatomic) void (*__cdecl function)();
@property (readonly, nonatomic) bool persisted;

+ (instancetype)variableWithName:(OFString *)name
                             min:(int)min
                             max:(int)max
                         storage:(int *)storage
                        function:(void (*__cdecl)())function
                       persisted:(bool)persisted;
- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name
                         min:(int)min
                         max:(int)max
                     storage:(int *)storage
                    function:(void (*__cdecl)())function
                   persisted:(bool)persisted;

Modified src/Variable.mm from [a7099f1853] to [eb5893de54].

1
2
3
4
5















6
7
8
9
10
11
12
#import "Variable.h"

#include "cube.h"

@implementation Variable















- (instancetype)initWithName:(OFString *)name
                         min:(int)min
                         max:(int)max
                     storage:(int *)storage
                    function:(void (*__cdecl)())function
                   persisted:(bool)persisted
{





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#import "Variable.h"

#include "cube.h"

@implementation Variable
+ (instancetype)variableWithName:(OFString *)name
                             min:(int)min
                             max:(int)max
                         storage:(int *)storage
                        function:(void (*__cdecl)())function
                       persisted:(bool)persisted
{
	return [[self alloc] initWithName:name
	                              min:min
	                              max:max
	                          storage:storage
	                         function:function
	                        persisted:persisted];
}

- (instancetype)initWithName:(OFString *)name
                         min:(int)min
                         max:(int)max
                     storage:(int *)storage
                    function:(void (*__cdecl)())function
                   persisted:(bool)persisted
{

Modified src/clientextras.mm from [d40925e827] to [6b3acabfcd].

67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
			speed = 300 / d.maxspeed;
	}
	if (hellpig) {
		n++;
		scale *= 32;
		mz -= 1.9f;
	}
	rendermodel(mdlname, frame[n], range[n], 0, 1.5f, d.o.x, mz, d.o.y,

	    d.yaw + 90, d.pitch / 2, team, scale, speed, 0, basetime);
}

extern int democlientnum;

void
renderclients()
{







|
>
|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
			speed = 300 / d.maxspeed;
	}
	if (hellpig) {
		n++;
		scale *= 32;
		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);
}

extern int democlientnum;

void
renderclients()
{
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
	if (m_teammode) {
		teamsUsed = 0;
		for (id player in players)
			if (player != [OFNull null])
				addteamscore(player);
		if (!demoplayback)
			addteamscore(player1);
		OFMutableString *teamScores = [[OFMutableString alloc] init];
		for (size_t j = 0; j < teamsUsed; j++)
			[teamScores appendFormat:@"[ %@: %d ]", teamName[j],
			            teamScore[j]];
		menumanual(0, scoreLines.count, @"");
		menumanual(0, scoreLines.count + 1, teamScores);
	}
}







|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
	if (m_teammode) {
		teamsUsed = 0;
		for (id player in players)
			if (player != [OFNull null])
				addteamscore(player);
		if (!demoplayback)
			addteamscore(player1);
		OFMutableString *teamScores = [OFMutableString string];
		for (size_t j = 0; j < teamsUsed; j++)
			[teamScores appendFormat:@"[ %@: %d ]", teamName[j],
			            teamScore[j]];
		menumanual(0, scoreLines.count, @"");
		menumanual(0, scoreLines.count + 1, teamScores);
	}
}

Modified src/clientgame.mm from [75ba298a0a] to [bec4825c49].

467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
DynamicEntity *
getclient(int cn) // ensure valid entity
{
	if (cn < 0 || cn >= MAXCLIENTS) {
		neterr(@"clientnum");
		return nil;
	}
	if (players == nil)
		players = [[OFMutableArray alloc] init];
	while (cn >= players.count)
		[players addObject:[OFNull null]];
	return (players[cn] != [OFNull null] ? players[cn]
	                                     : (players[cn] = newdynent()));
}

void
setclient(int cn, id client)
{
	if (cn < 0 || cn >= MAXCLIENTS)
		neterr(@"clientnum");
	if (players == nil)
		players = [[OFMutableArray alloc] init];
	while (cn >= players.count)
		[players addObject:[OFNull null]];
	players[cn] = client;
}

void
initclient()







<
<











<
<







467
468
469
470
471
472
473


474
475
476
477
478
479
480
481
482
483
484


485
486
487
488
489
490
491
DynamicEntity *
getclient(int cn) // ensure valid entity
{
	if (cn < 0 || cn >= MAXCLIENTS) {
		neterr(@"clientnum");
		return nil;
	}


	while (cn >= players.count)
		[players addObject:[OFNull null]];
	return (players[cn] != [OFNull null] ? players[cn]
	                                     : (players[cn] = newdynent()));
}

void
setclient(int cn, id client)
{
	if (cn < 0 || cn >= MAXCLIENTS)
		neterr(@"clientnum");


	while (cn >= players.count)
		[players addObject:[OFNull null]];
	players[cn] = client;
}

void
initclient()

Name change from src/client.mm to src/clients.mm.

Modified src/commands.mm from [8783bcd63b] to [586613b4e5].

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

void
alias(OFString *name, OFString *action)
{
	Alias *alias = identifiers[name];

	if (alias == nil) {
		alias = [[Alias alloc] initWithName:name
		                             action:action
		                          persisted:true];

		if (identifiers == nil)
			identifiers = [[OFMutableDictionary alloc] init];

		identifiers[name] = alias;
	} else {
		if ([alias isKindOfClass:Alias.class])
			alias.action = action;
		else
			conoutf(
			    @"cannot redefine builtin %@ with an alias", name);
	}
}
COMMAND(alias, ARG_2STR)

int
variable(OFString *name, int min, int cur, int max, int *storage,
    void (*function)(), bool persisted)
{
	Variable *variable = [[Variable alloc] initWithName:name
	                                                min:min
	                                                max:max
	                                            storage:storage
	                                           function:function
	                                          persisted:persisted];

	if (identifiers == nil)
		identifiers = [[OFMutableDictionary alloc] init];

	identifiers[name] = variable;

	return cur;







<
<
|



















|
|
|
|
|
|







16
17
18
19
20
21
22


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

void
alias(OFString *name, OFString *action)
{
	Alias *alias = identifiers[name];

	if (alias == nil) {


		alias = [Alias aliasWithName:name action:action persisted:true];

		if (identifiers == nil)
			identifiers = [[OFMutableDictionary alloc] init];

		identifiers[name] = alias;
	} else {
		if ([alias isKindOfClass:Alias.class])
			alias.action = action;
		else
			conoutf(
			    @"cannot redefine builtin %@ with an alias", name);
	}
}
COMMAND(alias, ARG_2STR)

int
variable(OFString *name, int min, int cur, int max, int *storage,
    void (*function)(), bool persisted)
{
	Variable *variable = [Variable variableWithName:name
	                                            min:min
	                                            max:max
	                                        storage:storage
	                                       function:function
	                                      persisted:persisted];

	if (identifiers == nil)
		identifiers = [[OFMutableDictionary alloc] init];

	identifiers[name] = variable;

	return cur;
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

	return nil;
}

bool
addcommand(OFString *name, void (*function)(), int argumentsTypes)
{
	Command *command = [[Command alloc] initWithName:name
	                                        function:function
	                                  argumentsTypes:argumentsTypes];

	if (identifiers == nil)
		identifiers = [[OFMutableDictionary alloc] init];

	identifiers[name] = command;

	return false;







|
|
|







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

	return nil;
}

bool
addcommand(OFString *name, void (*function)(), int argumentsTypes)
{
	Command *command = [Command commandWithName:name
	                                   function:function
	                             argumentsTypes:argumentsTypes];

	if (identifiers == nil)
		identifiers = [[OFMutableDictionary alloc] init];

	identifiers[name] = command;

	return false;

Modified src/console.mm from [c4ec2131b8] to [555c5a6eb3].

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// console.cpp: the console buffer, its display, and command line control

#include "cube.h"

#include <ctype.h>


#import "KeyMapping.h"
#import "OFString+Cube.h"

@interface ConsoleLine: OFObject
@property (readonly, copy) OFString *text;
@property (readonly) int outtime;

- (instancetype)initWithText:(OFString *)text outtime:(int)outtime;
@end

static OFMutableArray<ConsoleLine *> *conlines;

@implementation ConsoleLine
- (instancetype)initWithText:(OFString *)text outtime:(int)outtime
{
	self = [super init];

	_text = [text copy];
	_outtime = outtime;

	return self;
}

- (OFString *)description
{
	return _text;
}
@end

const int ndraw = 5;
const int WORDWRAP = 80;
int conskip = 0;

bool saycommandon = false;
static OFMutableString *commandbuf;







>



<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10







11
12

















13
14
15
16
17
18
19
// console.cpp: the console buffer, its display, and command line control

#include "cube.h"

#include <ctype.h>

#import "ConsoleLine.h"
#import "KeyMapping.h"
#import "OFString+Cube.h"








static OFMutableArray<ConsoleLine *> *conlines;


















const int ndraw = 5;
const int WORDWRAP = 80;
int conskip = 0;

bool saycommandon = false;
static OFMutableString *commandbuf;

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
	OFMutableString *text;

	// constrain the buffer size
	if (conlines.count > 100) {
		text = [conlines.lastObject.text mutableCopy];
		[conlines removeLastObject];
	} else
		text = [[OFMutableString alloc] init];

	if (highlight)
		// show line in a different colour, for chat etc.
		[text appendString:@"\f"];

	[text appendString:sf];

	if (conlines == nil)
		conlines = [[OFMutableArray alloc] init];

	[conlines insertObject:[[ConsoleLine alloc] initWithText:text
	                                                 outtime:lastmillis]
	               atIndex:0];

	puts(text.UTF8String);
#ifndef OF_WINDOWS
	fflush(stdout);
#endif
}







|










|
|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
	OFMutableString *text;

	// constrain the buffer size
	if (conlines.count > 100) {
		text = [conlines.lastObject.text mutableCopy];
		[conlines removeLastObject];
	} else
		text = [OFMutableString string];

	if (highlight)
		// show line in a different colour, for chat etc.
		[text appendString:@"\f"];

	[text appendString:sf];

	if (conlines == nil)
		conlines = [[OFMutableArray alloc] init];

	[conlines insertObject:[ConsoleLine lineWithText:text
	                                         outtime:lastmillis]
	               atIndex:0];

	puts(text.UTF8String);
#ifndef OF_WINDOWS
	fflush(stdout);
#endif
}
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

void
keymap(OFString *code, OFString *key, OFString *action)
{
	if (keyMappings == nil)
		keyMappings = [[OFMutableArray alloc] init];

	KeyMapping *mapping =
	    [[KeyMapping alloc] initWithCode:code.cube_intValue name:key];
	mapping.action = action;
	[keyMappings addObject:mapping];
}
COMMAND(keymap, ARG_3STR)

void
bindkey(OFString *key, OFString *action)







|
|







108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

void
keymap(OFString *code, OFString *key, OFString *action)
{
	if (keyMappings == nil)
		keyMappings = [[OFMutableArray alloc] init];

	KeyMapping *mapping = [KeyMapping mappingWithCode:code.cube_intValue
	                                             name:key];
	mapping.action = action;
	[keyMappings addObject:mapping];
}
COMMAND(keymap, ARG_3STR)

void
bindkey(OFString *key, OFString *action)

Modified src/entities.mm from [58180dec4d] to [c332d89e7c].

22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

46

47
48
49
50
51
52
53
54

int triggertime = 0;

void
renderent(entity &e, OFString *mdlname, float z, float yaw, int frame = 0,
    int numf = 1, int basetime = 0, float speed = 10.0f)
{
	rendermodel(mdlname, frame, numf, 0, 1.1f, e.x, z + S(e.x, e.y)->floor,

	    e.y, yaw, 0, false, 1.0f, speed, 0, basetime);
}

void
renderentities()
{
	if (lastmillis > triggertime + 1000)
		triggertime = 0;
	loopv(ents)
	{
		entity &e = ents[i];
		if (e.type == MAPMODEL) {
			MapModelInfo *mmi = getmminfo(e.attr2);
			if (mmi == nil)
				continue;
			rendermodel(mmi.name, 0, 1, e.attr4, (float)mmi.rad,

			    e.x, (float)S(e.x, e.y)->floor + mmi.zoff + e.attr3,

			    e.y, (float)((e.attr1 + 7) - (e.attr1 + 7) % 15), 0,
			    false, 1.0f, 10.0f, mmi.snap);
		} else {
			if (OUTBORD(e.x, e.y))
				continue;
			if (e.type != CARROT) {
				if (!e.spawned && e.type != TELEPORT)
					continue;







|
>
|















>
|
>
|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

int triggertime = 0;

void
renderent(entity &e, OFString *mdlname, float z, float yaw, int frame = 0,
    int numf = 1, int basetime = 0, float speed = 10.0f)
{
	rendermodel(mdlname, frame, numf, 0, 1.1f,
	    OFMakeVector3D(e.x, z + S(e.x, e.y)->floor, e.y), yaw, 0, false,
	    1.0f, speed, 0, basetime);
}

void
renderentities()
{
	if (lastmillis > triggertime + 1000)
		triggertime = 0;
	loopv(ents)
	{
		entity &e = ents[i];
		if (e.type == MAPMODEL) {
			MapModelInfo *mmi = getmminfo(e.attr2);
			if (mmi == nil)
				continue;
			rendermodel(mmi.name, 0, 1, e.attr4, (float)mmi.rad,
			    OFMakeVector3D(e.x,
			        (float)S(e.x, e.y)->floor + mmi.zoff + e.attr3,
			        e.y),
			    (float)((e.attr1 + 7) - (e.attr1 + 7) % 15), 0,
			    false, 1.0f, 10.0f, mmi.snap);
		} else {
			if (OUTBORD(e.x, e.y))
				continue;
			if (e.type != CARROT) {
				if (!e.spawned && e.type != TELEPORT)
					continue;

Modified src/menus.mm from [e754271834] to [bd623c6a87].

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

void
newmenu(OFString *name)
{
	if (menus == nil)
		menus = [[OFMutableArray alloc] init];

	[menus addObject:[[Menu alloc] initWithName:name]];
}
COMMAND(newmenu, ARG_1STR)

void
menumanual(int m, int n, OFString *text)
{
	if (n == 0)
		[menus[m].items removeAllObjects];

	MenuItem *item = [[MenuItem alloc] initWithText:text action:@""];
	[menus[m].items addObject:item];
}

void
menuitem(OFString *text, OFString *action)
{
	Menu *menu = menus.lastObject;

	MenuItem *item =
	    [[MenuItem alloc] initWithText:text
	                            action:(action.length > 0 ? action : text)];
	[menu.items addObject:item];
}
COMMAND(menuitem, ARG_2STR)

bool
menukey(int code, bool isdown)
{







|









|









|
|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

void
newmenu(OFString *name)
{
	if (menus == nil)
		menus = [[OFMutableArray alloc] init];

	[menus addObject:[Menu menuWithName:name]];
}
COMMAND(newmenu, ARG_1STR)

void
menumanual(int m, int n, OFString *text)
{
	if (n == 0)
		[menus[m].items removeAllObjects];

	MenuItem *item = [MenuItem itemWithText:text action:@""];
	[menus[m].items addObject:item];
}

void
menuitem(OFString *text, OFString *action)
{
	Menu *menu = menus.lastObject;

	MenuItem *item =
	    [MenuItem itemWithText:text
	                    action:(action.length > 0 ? action : text)];
	[menu.items addObject:item];
}
COMMAND(menuitem, ARG_2STR)

bool
menukey(int code, bool isdown)
{

Modified src/meson.build from [db6c55f2bb] to [7a5be72f65].

1
2
3

4

5
6
7
8
9
10
11
12
13
14


15
16
17
18
19
20
21
22
23
24
executable('client',
  [
    'Alias.m',

    'Command.mm',

    'Cube.mm',
    'DynamicEntity.mm',
    'Identifier.m',
    'KeyMapping.m',
    'MD2.mm',
    'MapModelInfo.m',
    'Menu.m',
    'MenuItem.m',
    'OFString+Cube.mm',
    'Projectile.m',


    'ServerInfo.mm',
    'Variable.mm',
    'client.mm',
    'clientextras.mm',
    'clientgame.mm',
    'clients2c.mm',
    'commands.mm',
    'console.mm',
    'editing.mm',
    'entities.mm',



>

>










>
>


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
executable('client',
  [
    'Alias.m',
    'Client.mm',
    'Command.mm',
    'ConsoleLine.m',
    'Cube.mm',
    'DynamicEntity.mm',
    'Identifier.m',
    'KeyMapping.m',
    'MD2.mm',
    'MapModelInfo.m',
    'Menu.m',
    'MenuItem.m',
    'OFString+Cube.mm',
    'Projectile.m',
    'ResolverResult.mm',
    'ResolverThread.mm',
    'ServerInfo.mm',
    'Variable.mm',
    'clients.mm',
    'clientextras.mm',
    'clientgame.mm',
    'clients2c.mm',
    'commands.mm',
    'console.mm',
    'editing.mm',
    'entities.mm',
58
59
60
61
62
63
64

65
66
67
68
69
70
71
  include_directories: [enet_includes],
  link_args: client_link_args,
  link_with: [enet],
  win_subsystem: 'windows')

executable('server',
  [

    'server.mm',
    'serverms.mm',
    'serverutil.mm',
    'tools.mm',
  ],
  objcpp_args: ['-DSTANDALONE'],
  dependencies: [







>







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
  include_directories: [enet_includes],
  link_args: client_link_args,
  link_with: [enet],
  win_subsystem: 'windows')

executable('server',
  [
    'Client.mm',
    'server.mm',
    'serverms.mm',
    'serverutil.mm',
    'tools.mm',
  ],
  objcpp_args: ['-DSTANDALONE'],
  dependencies: [

Modified src/protos.h from [2b4f29b604] to [ca691ec5c9].

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
extern void playsound(int n, const OFVector3D *loc = NULL);
extern void playsoundc(int n);
extern void initsound();
extern void cleansound();

// rendermd2
extern void rendermodel(OFString *mdl, int frame, int range, int tex, float rad,
    float x, float y, float z, float yaw, float pitch, bool teammate,
    float scale, float speed, int snap = 0, int basetime = 0);
@class MapModelInfo;
extern MapModelInfo *getmminfo(int i);

// server
extern void initserver(bool dedicated, int uprate, OFString *sdesc,
    OFString *ip, OFString *master, OFString *passwd, int maxcl);
extern void cleanupserver();







|
|







206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
extern void playsound(int n, const OFVector3D *loc = NULL);
extern void playsoundc(int n);
extern void initsound();
extern void cleansound();

// rendermd2
extern void rendermodel(OFString *mdl, int frame, int range, int tex, float rad,
    OFVector3D position, float yaw, float pitch, bool teammate, float scale,
    float speed, int snap = 0, int basetime = 0);
@class MapModelInfo;
extern MapModelInfo *getmminfo(int i);

// server
extern void initserver(bool dedicated, int uprate, OFString *sdesc,
    OFString *ip, OFString *master, OFString *passwd, int maxcl);
extern void cleanupserver();

Modified src/renderextras.mm from [87f5ac882b] to [0275a674d6].

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
			continue;
		OFVector3D v = OFMakeVector3D(e.x, e.y, e.z);
		particle_splash(2, 2, 40, v);
	}
	int e = closestent();
	if (e >= 0) {
		entity &c = ents[e];
		closeent = [[OFString alloc]
		    initWithFormat:@"closest entity = %@ (%d, %d, %d, %d), "
		                   @"selection = (%d, %d)",
		    entnames[c.type], c.attr1, c.attr2, c.attr3, c.attr4,
		    getvar(@"selxs"), getvar(@"selys")];
	}
}

void
loadsky(OFString *basename)
{
	static OFString *lastsky = @"";







|
|
|
|
|







188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
			continue;
		OFVector3D v = OFMakeVector3D(e.x, e.y, e.z);
		particle_splash(2, 2, 40, v);
	}
	int e = closestent();
	if (e >= 0) {
		entity &c = ents[e];
		closeent =
		    [OFString stringWithFormat:@"closest entity = %@ (%d, %d, "
		                               @"%d, %d), selection = (%d, %d)",
		              entnames[c.type], c.attr1, c.attr2, c.attr3,
		              c.attr4, getvar(@"selxs"), getvar(@"selys")];
	}
}

void
loadsky(OFString *basename)
{
	static OFString *lastsky = @"";

Modified src/rendergl.mm from [6d1422bea1] to [81f69c07bf].

355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
OFString *hudgunnames[] = { @"hudguns/fist", @"hudguns/shotg",
	@"hudguns/chaing", @"hudguns/rocket", @"hudguns/rifle" };

void
drawhudmodel(int start, int end, float speed, int base)
{
	rendermodel(hudgunnames[player1.gunselect], start, end, 0, 1.0f,
	    player1.o.x, player1.o.z, player1.o.y, player1.yaw + 90,
	    player1.pitch, false, 1.0f, speed, 0, base);
}

void
drawhudgun(float fovy, float aspect, int farplane)
{
	if (!hudgun /*|| !player1.gunselect*/)
		return;







|
|







355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
OFString *hudgunnames[] = { @"hudguns/fist", @"hudguns/shotg",
	@"hudguns/chaing", @"hudguns/rocket", @"hudguns/rifle" };

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),
	    player1.yaw + 90, player1.pitch, false, 1.0f, speed, 0, base);
}

void
drawhudgun(float fovy, float aspect, int farplane)
{
	if (!hudgun /*|| !player1.gunselect*/)
		return;

Modified src/rendermd2.mm from [9b0441a720] to [72886c2cec].

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
{
	static int modelnum = 0;

	MD2 *m = mdllookup[name];
	if (m != nil)
		return m;

	m = [[MD2 alloc] init];
	m.mdlnum = modelnum++;
	m.mmi = [[MapModelInfo alloc] initWithRad:2 h:2 zoff:0 snap:0 name:@""];
	m.loadname = name;

	if (mdllookup == nil)
		mdllookup = [[OFMutableDictionary alloc] init];

	mdllookup[name] = m;

	return m;
}

void
mapmodel(
    OFString *rad, OFString *h, OFString *zoff, OFString *snap, OFString *name)
{
	MD2 *m = loadmodel([name stringByReplacingOccurrencesOfString:@"\\"
	                                                   withString:@"/"]);
	m.mmi = [[MapModelInfo alloc] initWithRad:rad.cube_intValue
	                                        h:h.cube_intValue
	                                     zoff:zoff.cube_intValue
	                                     snap:snap.cube_intValue
	                                     name:m.loadname];

	if (mapmodels == nil)
		mapmodels = [[OFMutableArray alloc] init];

	[mapmodels addObject:m];
}
COMMAND(mapmodel, ARG_5STR)







|

|
















|
|
|
|
|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
{
	static int modelnum = 0;

	MD2 *m = mdllookup[name];
	if (m != nil)
		return m;

	m = [MD2 md2];
	m.mdlnum = modelnum++;
	m.mmi = [MapModelInfo infoWithRad:2 h:2 zoff:0 snap:0 name:@""];
	m.loadname = name;

	if (mdllookup == nil)
		mdllookup = [[OFMutableDictionary alloc] init];

	mdllookup[name] = m;

	return m;
}

void
mapmodel(
    OFString *rad, OFString *h, OFString *zoff, OFString *snap, OFString *name)
{
	MD2 *m = loadmodel([name stringByReplacingOccurrencesOfString:@"\\"
	                                                   withString:@"/"]);
	m.mmi = [MapModelInfo infoWithRad:rad.cube_intValue
	                                h:h.cube_intValue
	                             zoff:zoff.cube_intValue
	                             snap:snap.cube_intValue
	                             name:m.loadname];

	if (mapmodels == nil)
		mapmodels = [[OFMutableArray alloc] init];

	[mapmodels addObject:m];
}
COMMAND(mapmodel, ARG_5STR)
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
MapModelInfo *
getmminfo(int i)
{
	return i < mapmodels.count ? mapmodels[i].mmi : nil;
}

void
rendermodel(OFString *mdl, int frame, int range, int tex, float rad, float x,
    float y, float z, float yaw, float pitch, bool teammate, float scale,
    float speed, int snap, int basetime)
{
	MD2 *m = loadmodel(mdl);

	if (isoccluded(player1.o.x, player1.o.y, x - rad, z - rad, rad * 2))

		return;

	delayedload(m);

	int xs, ys;
	glBindTexture(GL_TEXTURE_2D,
	    tex ? lookuptexture(tex, &xs, &ys) : FIRSTMDL + m.mdlnum);

	int ix = (int)x;
	int iy = (int)z;
	OFVector3D light = OFMakeVector3D(1, 1, 1);

	if (!OUTBORD(ix, iy)) {
		sqr *s = S(ix, iy);
		float ll = 256.0f; // 0.96f;
		float of = 0.0f;   // 0.1f;
		light.x = s->r / ll + of;
		light.y = s->g / ll + of;
		light.z = s->b / ll + of;
	}

	if (teammate) {
		light.x *= 0.6f;
		light.y *= 0.7f;
		light.z *= 1.2f;
	}

	[m renderWithLight:light
	             frame:frame
	             range:range
	                 x:x
	                 y:y
	                 z:z
	               yaw:yaw
	             pitch:pitch
	             scale:scale
	             speed:speed
	              snap:snap
	          basetime:basetime];
}







|
|




|
>








|
|




















|
<
<







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128


129
130
131
132
133
134
135
MapModelInfo *
getmminfo(int i)
{
	return i < mapmodels.count ? mapmodels[i].mmi : nil;
}

void
rendermodel(OFString *mdl, int frame, int range, int tex, float rad,
    OFVector3D position, float yaw, float pitch, bool teammate, float scale,
    float speed, int snap, int basetime)
{
	MD2 *m = loadmodel(mdl);

	if (isoccluded(player1.o.x, player1.o.y, position.x - rad,
	        position.z - rad, rad * 2))
		return;

	delayedload(m);

	int xs, ys;
	glBindTexture(GL_TEXTURE_2D,
	    tex ? lookuptexture(tex, &xs, &ys) : FIRSTMDL + m.mdlnum);

	int ix = (int)position.x;
	int iy = (int)position.z;
	OFVector3D light = OFMakeVector3D(1, 1, 1);

	if (!OUTBORD(ix, iy)) {
		sqr *s = S(ix, iy);
		float ll = 256.0f; // 0.96f;
		float of = 0.0f;   // 0.1f;
		light.x = s->r / ll + of;
		light.y = s->g / ll + of;
		light.z = s->b / ll + of;
	}

	if (teammate) {
		light.x *= 0.6f;
		light.y *= 0.7f;
		light.z *= 1.2f;
	}

	[m renderWithLight:light
	             frame:frame
	             range:range
	          position:position


	               yaw:yaw
	             pitch:pitch
	             scale:scale
	             speed:speed
	              snap:snap
	          basetime:basetime];
}

Modified src/server.mm from [f99720b385] to [1804a617a4].

1
2
3
4


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// server.cpp: little more than enhanced multicaster
// runs dedicated or as client coroutine

#include "cube.h"



enum { ST_EMPTY, ST_LOCAL, ST_TCPIP };

// server side version of "dynent" type
@interface Client: OFObject
@property (nonatomic) int type;
@property (nonatomic) ENetPeer *peer;
@property (copy, nonatomic) OFString *hostname;
@property (copy, nonatomic) OFString *mapvote;
@property (copy, nonatomic) OFString *name;
@property (nonatomic) int modevote;
@end

@implementation Client
@end

static OFMutableArray<Client *> *clients;

int maxclients = 8;
static OFString *smapname;

// server side version of "entity" type
struct server_entity {




>
>



<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9













10
11
12
13
14
15
16
// server.cpp: little more than enhanced multicaster
// runs dedicated or as client coroutine

#include "cube.h"

#import "Client.h"

enum { ST_EMPTY, ST_LOCAL, ST_TCPIP };














static OFMutableArray<Client *> *clients;

int maxclients = 8;
static OFString *smapname;

// server side version of "entity" type
struct server_entity {
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
Client *
addclient()
{
	for (Client *client in clients)
		if (client.type == ST_EMPTY)
			return client;

	Client *client = [[Client alloc] init];

	if (clients == nil)
		clients = [[OFMutableArray alloc] init];

	[clients addObject:client];

	return client;







|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
Client *
addclient()
{
	for (Client *client in clients)
		if (client.type == ST_EMPTY)
			return client;

	Client *client = [Client client];

	if (clients == nil)
		clients = [[OFMutableArray alloc] init];

	[clients addObject:client];

	return client;

Modified src/serverbrowser.mm from [7409dbfc1c] to [40331e8345].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// serverbrowser.cpp: eihrul's concurrent resolver, and server browser window
// management

#include "SDL_thread.h"
#include "cube.h"

#import "ServerInfo.h"

@interface ResolverThread: OFThread
{
	volatile bool _stop;
}

@property (copy, nonatomic) OFString *query;
@property (nonatomic) int starttime;
@end

@interface ResolverResult: OFObject
@property (readonly, nonatomic) OFString *query;
@property (readonly, nonatomic) ENetAddress address;

- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithQuery:(OFString *)query address:(ENetAddress)address;
@end

static OFMutableArray<ResolverThread *> *resolverthreads;
static OFMutableArray<OFString *> *resolverqueries;
static OFMutableArray<ResolverResult *> *resolverresults;
static SDL_sem *resolversem;
static int resolverlimit = 1000;

@implementation ResolverThread
- (id)main
{
	while (!_stop) {
		SDL_SemWait(resolversem);

		@synchronized(ResolverThread.class) {
			if (resolverqueries.count == 0)
				continue;

			_query = resolverqueries.lastObject;
			[resolverqueries removeLastObject];
			_starttime = lastmillis;
		}

		ENetAddress address = { ENET_HOST_ANY, CUBE_SERVINFO_PORT };
		enet_address_set_host(&address, _query.UTF8String);

		@synchronized(ResolverThread.class) {
			[resolverresults addObject:[[ResolverResult alloc]
			                               initWithQuery:_query
			                                     address:address]];

			_query = NULL;
			_starttime = 0;
		}
	}

	return nil;
}

- (void)stop
{
	_stop = true;
}
@end

@implementation ResolverResult
- (instancetype)initWithQuery:(OFString *)query address:(ENetAddress)address
{
	self = [super init];

	_query = query;
	_address = address;

	return self;
}
@end

void
resolverinit(int threads, int limit)
{
	resolverthreads = [[OFMutableArray alloc] init];
	resolverqueries = [[OFMutableArray alloc] init];
	resolverresults = [[OFMutableArray alloc] init];
	resolverlimit = limit;
	resolversem = SDL_CreateSemaphore(0);

	while (threads > 0) {
		ResolverThread *rt = [[ResolverThread alloc] init];
		rt.name = @"resolverthread";
		[resolverthreads addObject:rt];
		[rt start];
		--threads;
	}
}

void
resolverstop(size_t i, bool restart)
{
	@synchronized(ResolverThread.class) {
		ResolverThread *rt = resolverthreads[i];
		[rt stop];

		if (restart) {
			rt = [[ResolverThread alloc] init];
			rt.name = @"resolverthread";

			resolverthreads[i] = rt;

			[rt start];
		} else
			[resolverthreads removeObjectAtIndex:i];






|
<
|
<
<
<
|
<
<
<

<
<
<
<
<
<
<
<

|
|
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










|















|







1
2
3
4
5
6
7

8



9



10








11
12
13
14
15
16

















































17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// serverbrowser.cpp: eihrul's concurrent resolver, and server browser window
// management

#include "SDL_thread.h"
#include "cube.h"

#import "ResolverResult.h"

#import "ResolverThread.h"



#import "ServerInfo.h"












static OFMutableArray<ResolverThread *> *resolverthreads;
OFMutableArray<OFString *> *resolverqueries;
OFMutableArray<ResolverResult *> *resolverresults;
SDL_sem *resolversem;
static int resolverlimit = 1000;


















































void
resolverinit(int threads, int limit)
{
	resolverthreads = [[OFMutableArray alloc] init];
	resolverqueries = [[OFMutableArray alloc] init];
	resolverresults = [[OFMutableArray alloc] init];
	resolverlimit = limit;
	resolversem = SDL_CreateSemaphore(0);

	while (threads > 0) {
		ResolverThread *rt = [ResolverThread thread];
		rt.name = @"resolverthread";
		[resolverthreads addObject:rt];
		[rt start];
		--threads;
	}
}

void
resolverstop(size_t i, bool restart)
{
	@synchronized(ResolverThread.class) {
		ResolverThread *rt = resolverthreads[i];
		[rt stop];

		if (restart) {
			rt = [ResolverThread thread];
			rt.name = @"resolverthread";

			resolverthreads[i] = rt;

			[rt start];
		} else
			[resolverthreads removeObjectAtIndex:i];
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	for (ServerInfo *si in servers)
		if ([si.name isEqual:servername])
			return;

	if (servers == nil)
		servers = [[OFMutableArray alloc] init];

	[servers addObject:[[ServerInfo alloc] initWithName:servername]];
}

void
pingservers()
{
	ENetBuffer buf;
	uchar ping[MAXTRANS];







|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
	for (ServerInfo *si in servers)
		if ([si.name isEqual:servername])
			return;

	if (servers == nil)
		servers = [[OFMutableArray alloc] init];

	[servers addObject:[ServerInfo infoWithName:servername]];
}

void
pingservers()
{
	ENetBuffer buf;
	uchar ping[MAXTRANS];
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
	[servers sort];

	__block int maxmenu = 16;
	[servers enumerateObjectsUsingBlock:^(
	    ServerInfo *si, size_t i, bool *stop) {
		if (si.address.host != ENET_HOST_ANY && si.ping != 9999) {
			if (si.protocol != PROTOCOL_VERSION)
				si.full = [[OFString alloc]
				    initWithFormat:
				        @"%@ [different cube protocol]",
				    si.name];
			else
				si.full = [[OFString alloc]
				    initWithFormat:@"%d\t%d\t%@, %@: %@ %@",
				    si.ping, si.numplayers,
				    si.map.length > 0 ? si.map : @"[unknown]",
				    modestr(si.mode), si.name, si.sdesc];
		} else
			si.full = [[OFString alloc]
			    initWithFormat:
			        (si.address.host != ENET_HOST_ANY
			                ? @"%@ [waiting for server response]"
			                : @"%@ [unknown host]\t"),
			    si.name];

		// cut off too long server descriptions
		if (si.full.length > 50)







|
|



|
|




|
|







212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
	[servers sort];

	__block int maxmenu = 16;
	[servers enumerateObjectsUsingBlock:^(
	    ServerInfo *si, size_t i, bool *stop) {
		if (si.address.host != ENET_HOST_ANY && si.ping != 9999) {
			if (si.protocol != PROTOCOL_VERSION)
				si.full = [OFString
				    stringWithFormat:
				        @"%@ [different cube protocol]",
				    si.name];
			else
				si.full = [OFString
				    stringWithFormat:@"%d\t%d\t%@, %@: %@ %@",
				    si.ping, si.numplayers,
				    si.map.length > 0 ? si.map : @"[unknown]",
				    modestr(si.mode), si.name, si.sdesc];
		} else
			si.full = [OFString
			    stringWithFormat:
			        (si.address.host != ENET_HOST_ANY
			                ? @"%@ [waiting for server response]"
			                : @"%@ [unknown host]\t"),
			    si.name];

		// cut off too long server descriptions
		if (si.full.length > 50)

Modified src/serverms.mm from [4bb1ac1ee8] to [0e5451e8b8].

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
servermsinit(OFString *master_, OFString *sdesc, bool listen)
{
	const char *master = master_.UTF8String;
	const char *mid = strstr(master, "/");
	if (!mid)
		mid = master;
	masterpath = @(mid);
	masterbase = [[OFString alloc] initWithUTF8String:master
	                                           length:mid - master];
	serverdesc = sdesc;

	if (listen) {
		ENetAddress address = { ENET_HOST_ANY, CUBE_SERVINFO_PORT };
		pongsock =
		    enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM, &address);
		if (pongsock == ENET_SOCKET_NULL)







<
|







154
155
156
157
158
159
160

161
162
163
164
165
166
167
168
servermsinit(OFString *master_, OFString *sdesc, bool listen)
{
	const char *master = master_.UTF8String;
	const char *mid = strstr(master, "/");
	if (!mid)
		mid = master;
	masterpath = @(mid);

	masterbase = [OFString stringWithUTF8String:master length:mid - master];
	serverdesc = sdesc;

	if (listen) {
		ENetAddress address = { ENET_HOST_ANY, CUBE_SERVINFO_PORT };
		pongsock =
		    enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM, &address);
		if (pongsock == ENET_SOCKET_NULL)

Modified src/weapon.mm from [5796e07781] to [ec6a711714].

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
void
newprojectile(OFVector3D &from, OFVector3D &to, float speed, bool local,
    DynamicEntity *owner, int gun)
{
	for (size_t i = 0; i < MAXPROJ; i++) {
		Projectile *p = projs[i];

		if (p == nil) {
			p = [[Projectile alloc] init];
			projs[i] = p;
		}

		if (p.inuse)
			continue;

		p.inuse = true;
		p.o = from;
		p.to = to;







|
<
|
<







144
145
146
147
148
149
150
151

152

153
154
155
156
157
158
159
void
newprojectile(OFVector3D &from, OFVector3D &to, float speed, bool local,
    DynamicEntity *owner, int gun)
{
	for (size_t i = 0; i < MAXPROJ; i++) {
		Projectile *p = projs[i];

		if (p == nil)

			projs[i] = p = [Projectile projectile];


		if (p.inuse)
			continue;

		p.inuse = true;
		p.o = from;
		p.to = to;
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
	hit(target, damage, d, at);
	vdist(dist, v, from, to);
	vmul(v, damage / dist / 50);
	vadd(d.vel, v);
}

void
raydamage(
    DynamicEntity *o, const OFVector3D &from, const OFVector3D &to, DynamicEntity *d, int i)
{
	if (o.state != CS_ALIVE)
		return;
	int qdam = guns[d.gunselect].damage;
	if (d.quadmillis)
		qdam *= 4;
	if (d.monsterstate)







|
|







348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
	hit(target, damage, d, at);
	vdist(dist, v, from, to);
	vmul(v, damage / dist / 50);
	vadd(d.vel, v);
}

void
raydamage(DynamicEntity *o, const OFVector3D &from, const OFVector3D &to,
    DynamicEntity *d, int i)
{
	if (o.state != CS_ALIVE)
		return;
	int qdam = guns[d.gunselect].damage;
	if (d.quadmillis)
		qdam *= 4;
	if (d.monsterstate)