Clean up identifiers, use blocks for commands
FossilOrigin-Name: d7661be1b1dc8fda8e4de50f9a9d75907f498e6e07530241fb04be015ca3d9ae
This commit is contained in:
parent
e995b95a84
commit
daa4c19312
25 changed files with 391 additions and 535 deletions
|
@ -2,17 +2,27 @@
|
||||||
|
|
||||||
OF_ASSUME_NONNULL_BEGIN
|
OF_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
#define COMMAND(name, nargs, block_) \
|
||||||
|
OF_CONSTRUCTOR() \
|
||||||
|
{ \
|
||||||
|
enqueueInit(^{ \
|
||||||
|
[Identifier \
|
||||||
|
addIdentifier:[Command commandWithName:@ #name \
|
||||||
|
argumentsTypes:nargs \
|
||||||
|
block:block_]]; \
|
||||||
|
}); \
|
||||||
|
}
|
||||||
|
|
||||||
@interface Command: Identifier
|
@interface Command: Identifier
|
||||||
@property (readonly, nonatomic) void (*function)();
|
|
||||||
@property (readonly, nonatomic) int argumentsTypes;
|
@property (readonly, nonatomic) int argumentsTypes;
|
||||||
|
|
||||||
+ (instancetype)commandWithName:(OFString *)name
|
+ (instancetype)commandWithName:(OFString *)name
|
||||||
function:(void (*)())function
|
argumentsTypes:(int)argumentsTypes
|
||||||
argumentsTypes:(int)argumentsTypes;
|
block:(id)block;
|
||||||
- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
|
- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
|
||||||
- (instancetype)initWithName:(OFString *)name
|
- (instancetype)initWithName:(OFString *)name
|
||||||
function:(void (*)())function
|
argumentsTypes:(int)argumentsTypes
|
||||||
argumentsTypes:(int)argumentsTypes;
|
block:(id)block;
|
||||||
- (int)callWithArguments:(OFArray<OFString *> *)arguments isDown:(bool)isDown;
|
- (int)callWithArguments:(OFArray<OFString *> *)arguments isDown:(bool)isDown;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -20,23 +20,27 @@ padArguments(OFArray<OFString *> *arguments, size_t count)
|
||||||
}
|
}
|
||||||
|
|
||||||
@implementation Command
|
@implementation Command
|
||||||
|
{
|
||||||
|
id _block;
|
||||||
|
}
|
||||||
|
|
||||||
+ (instancetype)commandWithName:(OFString *)name
|
+ (instancetype)commandWithName:(OFString *)name
|
||||||
function:(void (*)())function
|
|
||||||
argumentsTypes:(int)argumentsTypes
|
argumentsTypes:(int)argumentsTypes
|
||||||
|
block:(id)block
|
||||||
{
|
{
|
||||||
return [[self alloc] initWithName:name
|
return [[self alloc] initWithName:name
|
||||||
function:function
|
argumentsTypes:argumentsTypes
|
||||||
argumentsTypes:argumentsTypes];
|
block:block];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithName:(OFString *)name
|
- (instancetype)initWithName:(OFString *)name
|
||||||
function:(void (*)())function
|
|
||||||
argumentsTypes:(int)argumentsTypes
|
argumentsTypes:(int)argumentsTypes
|
||||||
|
block:(id)block
|
||||||
{
|
{
|
||||||
self = [super initWithName:name];
|
self = [super initWithName:name];
|
||||||
|
|
||||||
_function = function;
|
|
||||||
_argumentsTypes = argumentsTypes;
|
_argumentsTypes = argumentsTypes;
|
||||||
|
_block = block;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -47,14 +51,14 @@ padArguments(OFArray<OFString *> *arguments, size_t count)
|
||||||
case ARG_1INT:
|
case ARG_1INT:
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
arguments = padArguments(arguments, 2);
|
arguments = padArguments(arguments, 2);
|
||||||
((void(__cdecl *)(int))_function)(
|
((void (^)(int))_block)(
|
||||||
[arguments[1] cube_intValueWithBase:0]);
|
[arguments[1] cube_intValueWithBase:0]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARG_2INT:
|
case ARG_2INT:
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
arguments = padArguments(arguments, 3);
|
arguments = padArguments(arguments, 3);
|
||||||
((void(__cdecl *)(int, int))_function)(
|
((void (^)(int, int))_block)(
|
||||||
[arguments[1] cube_intValueWithBase:0],
|
[arguments[1] cube_intValueWithBase:0],
|
||||||
[arguments[2] cube_intValueWithBase:0]);
|
[arguments[2] cube_intValueWithBase:0]);
|
||||||
}
|
}
|
||||||
|
@ -62,7 +66,7 @@ padArguments(OFArray<OFString *> *arguments, size_t count)
|
||||||
case ARG_3INT:
|
case ARG_3INT:
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
arguments = padArguments(arguments, 4);
|
arguments = padArguments(arguments, 4);
|
||||||
((void(__cdecl *)(int, int, int))_function)(
|
((void (^)(int, int, int))_block)(
|
||||||
[arguments[1] cube_intValueWithBase:0],
|
[arguments[1] cube_intValueWithBase:0],
|
||||||
[arguments[2] cube_intValueWithBase:0],
|
[arguments[2] cube_intValueWithBase:0],
|
||||||
[arguments[3] cube_intValueWithBase:0]);
|
[arguments[3] cube_intValueWithBase:0]);
|
||||||
|
@ -71,7 +75,7 @@ padArguments(OFArray<OFString *> *arguments, size_t count)
|
||||||
case ARG_4INT:
|
case ARG_4INT:
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
arguments = padArguments(arguments, 5);
|
arguments = padArguments(arguments, 5);
|
||||||
((void(__cdecl *)(int, int, int, int))_function)(
|
((void (^)(int, int, int, int))_block)(
|
||||||
[arguments[1] cube_intValueWithBase:0],
|
[arguments[1] cube_intValueWithBase:0],
|
||||||
[arguments[2] cube_intValueWithBase:0],
|
[arguments[2] cube_intValueWithBase:0],
|
||||||
[arguments[3] cube_intValueWithBase:0],
|
[arguments[3] cube_intValueWithBase:0],
|
||||||
|
@ -80,57 +84,55 @@ padArguments(OFArray<OFString *> *arguments, size_t count)
|
||||||
break;
|
break;
|
||||||
case ARG_NONE:
|
case ARG_NONE:
|
||||||
if (isDown)
|
if (isDown)
|
||||||
((void(__cdecl *)())_function)();
|
((void (^)())_block)();
|
||||||
break;
|
break;
|
||||||
case ARG_1STR:
|
case ARG_1STR:
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
arguments = padArguments(arguments, 2);
|
arguments = padArguments(arguments, 2);
|
||||||
((void(__cdecl *)(OFString *))_function)(arguments[1]);
|
((void (^)(OFString *))_block)(arguments[1]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARG_2STR:
|
case ARG_2STR:
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
arguments = padArguments(arguments, 3);
|
arguments = padArguments(arguments, 3);
|
||||||
((void(__cdecl *)(OFString *, OFString *))_function)(
|
((void (^)(OFString *, OFString *))_block)(
|
||||||
arguments[1], arguments[2]);
|
arguments[1], arguments[2]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARG_3STR:
|
case ARG_3STR:
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
arguments = padArguments(arguments, 4);
|
arguments = padArguments(arguments, 4);
|
||||||
((void(__cdecl *)(
|
((void (^)(OFString *, OFString *, OFString *))_block)(
|
||||||
OFString *, OFString *, OFString *))_function)(
|
|
||||||
arguments[1], arguments[2], arguments[3]);
|
arguments[1], arguments[2], arguments[3]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARG_5STR:
|
case ARG_5STR:
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
arguments = padArguments(arguments, 6);
|
arguments = padArguments(arguments, 6);
|
||||||
((void(__cdecl *)(OFString *, OFString *, OFString *,
|
((void (^)(OFString *, OFString *, OFString *,
|
||||||
OFString *, OFString *))_function)(arguments[1],
|
OFString *, OFString *))_block)(arguments[1],
|
||||||
arguments[2], arguments[3], arguments[4],
|
arguments[2], arguments[3], arguments[4],
|
||||||
arguments[5]);
|
arguments[5]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARG_DOWN:
|
case ARG_DOWN:
|
||||||
((void(__cdecl *)(bool))_function)(isDown);
|
((void (^)(bool))_block)(isDown);
|
||||||
break;
|
break;
|
||||||
case ARG_DWN1:
|
case ARG_DWN1:
|
||||||
arguments = padArguments(arguments, 2);
|
arguments = padArguments(arguments, 2);
|
||||||
((void(__cdecl *)(bool, OFString *))_function)(
|
((void (^)(bool, OFString *))_block)(isDown, arguments[1]);
|
||||||
isDown, arguments[1]);
|
|
||||||
break;
|
break;
|
||||||
case ARG_1EXP:
|
case ARG_1EXP:
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
arguments = padArguments(arguments, 2);
|
arguments = padArguments(arguments, 2);
|
||||||
return ((int(__cdecl *)(int))_function)(
|
return ((int (^)(int))_block)(
|
||||||
execute(arguments[1], isDown));
|
execute(arguments[1], isDown));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARG_2EXP:
|
case ARG_2EXP:
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
arguments = padArguments(arguments, 3);
|
arguments = padArguments(arguments, 3);
|
||||||
return ((int(__cdecl *)(int, int))_function)(
|
return ((int (^)(int, int))_block)(
|
||||||
execute(arguments[1], isDown),
|
execute(arguments[1], isDown),
|
||||||
execute(arguments[2], isDown));
|
execute(arguments[2], isDown));
|
||||||
}
|
}
|
||||||
|
@ -138,21 +140,20 @@ padArguments(OFArray<OFString *> *arguments, size_t count)
|
||||||
case ARG_1EST:
|
case ARG_1EST:
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
arguments = padArguments(arguments, 2);
|
arguments = padArguments(arguments, 2);
|
||||||
return ((int(__cdecl *)(OFString *))_function)(
|
return ((int (^)(OFString *))_block)(arguments[1]);
|
||||||
arguments[1]);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARG_2EST:
|
case ARG_2EST:
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
arguments = padArguments(arguments, 3);
|
arguments = padArguments(arguments, 3);
|
||||||
return ((int(__cdecl *)(OFString *,
|
return ((int (^)(OFString *, OFString *))_block)(
|
||||||
OFString *))_function)(arguments[1], arguments[2]);
|
arguments[1], arguments[2]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARG_VARI:
|
case ARG_VARI:
|
||||||
if (isDown)
|
if (isDown)
|
||||||
// limit, remove
|
// limit, remove
|
||||||
((void(__cdecl *)(OFString *))_function)([[arguments
|
((void (^)(OFString *))_block)([[arguments
|
||||||
objectsInRange:OFMakeRange(1, arguments.count - 1)]
|
objectsInRange:OFMakeRange(1, arguments.count - 1)]
|
||||||
componentsJoinedByString:@" "]);
|
componentsJoinedByString:@" "]);
|
||||||
break;
|
break;
|
||||||
|
|
16
src/Cube.m
16
src/Cube.m
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
|
|
||||||
OF_APPLICATION_DELEGATE(Cube)
|
OF_APPLICATION_DELEGATE(Cube)
|
||||||
|
@ -373,16 +374,11 @@ fatal(OFConstantString *s, ...)
|
||||||
[OFApplication terminateWithStatus:1];
|
[OFApplication terminateWithStatus:1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
// normal exit
|
||||||
quit() // normal exit
|
COMMAND(quit, ARG_NONE, ^{
|
||||||
{
|
|
||||||
[Cube.sharedInstance quit];
|
[Cube.sharedInstance quit];
|
||||||
}
|
})
|
||||||
COMMAND(quit, ARG_NONE)
|
|
||||||
|
|
||||||
void
|
COMMAND(screenshot, ARG_NONE, ^{
|
||||||
screenshot()
|
|
||||||
{
|
|
||||||
[Cube.sharedInstance screenshot];
|
[Cube.sharedInstance screenshot];
|
||||||
}
|
})
|
||||||
COMMAND(screenshot, ARG_NONE)
|
|
||||||
|
|
|
@ -5,6 +5,9 @@ OF_ASSUME_NONNULL_BEGIN
|
||||||
@interface Identifier: OFObject
|
@interface Identifier: OFObject
|
||||||
@property (readonly, copy, nonatomic) OFString *name;
|
@property (readonly, copy, nonatomic) OFString *name;
|
||||||
|
|
||||||
|
+ (void)addIdentifier:(__kindof Identifier *)identifier;
|
||||||
|
+ (__kindof Identifier *)identifierForName:(OFString *)name;
|
||||||
|
+ (void)enumerateIdentifiersUsingBlock:(void (^)(__kindof Identifier *))block;
|
||||||
- (instancetype)init OF_UNAVAILABLE;
|
- (instancetype)init OF_UNAVAILABLE;
|
||||||
- (instancetype)initWithName:(OFString *)name;
|
- (instancetype)initWithName:(OFString *)name;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,6 +1,33 @@
|
||||||
#import "Identifier.h"
|
#import "Identifier.h"
|
||||||
|
|
||||||
|
// contains ALL vars/commands/aliases
|
||||||
|
static OFMutableDictionary<OFString *, __kindof Identifier *> *identifiers;
|
||||||
|
|
||||||
@implementation Identifier
|
@implementation Identifier
|
||||||
|
+ (void)initialize
|
||||||
|
{
|
||||||
|
if (self == Identifier.class)
|
||||||
|
identifiers = [[OFMutableDictionary alloc] init];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)addIdentifier:(__kindof Identifier *)identifier
|
||||||
|
{
|
||||||
|
identifiers[identifier.name] = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (__kindof Identifier *)identifierForName:(OFString *)name
|
||||||
|
{
|
||||||
|
return identifiers[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)enumerateIdentifiersUsingBlock:(void (^)(__kindof Identifier *))block
|
||||||
|
{
|
||||||
|
[identifiers enumerateKeysAndObjectsUsingBlock:^(
|
||||||
|
OFString *name, __kindof Identifier *identifier, bool *stop) {
|
||||||
|
block(identifier);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)initWithName:(OFString *)name
|
- (instancetype)initWithName:(OFString *)name
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
#import "Monster.h"
|
#import "Monster.h"
|
||||||
|
|
||||||
|
@ -177,9 +178,7 @@ renderscores()
|
||||||
|
|
||||||
// sendmap/getmap commands, should be replaced by more intuitive map downloading
|
// sendmap/getmap commands, should be replaced by more intuitive map downloading
|
||||||
|
|
||||||
void
|
COMMAND(sendmap, ARG_1STR, (^(OFString *mapname) {
|
||||||
sendmap(OFString *mapname)
|
|
||||||
{
|
|
||||||
if (mapname.length > 0)
|
if (mapname.length > 0)
|
||||||
save_world(mapname);
|
save_world(mapname);
|
||||||
changemap(mapname);
|
changemap(mapname);
|
||||||
|
@ -210,11 +209,9 @@ sendmap(OFString *mapname)
|
||||||
@"\"getmap\" to receive it]",
|
@"\"getmap\" to receive it]",
|
||||||
mapname];
|
mapname];
|
||||||
toserver(msg);
|
toserver(msg);
|
||||||
}
|
}))
|
||||||
|
|
||||||
void
|
COMMAND(getmap, ARG_NONE, ^{
|
||||||
getmap()
|
|
||||||
{
|
|
||||||
ENetPacket *packet =
|
ENetPacket *packet =
|
||||||
enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
|
enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
|
||||||
unsigned char *start = packet->data;
|
unsigned char *start = packet->data;
|
||||||
|
@ -224,7 +221,4 @@ getmap()
|
||||||
enet_packet_resize(packet, p - start);
|
enet_packet_resize(packet, p - start);
|
||||||
sendpackettoserv(packet);
|
sendpackettoserv(packet);
|
||||||
conoutf(@"requesting map from server...");
|
conoutf(@"requesting map from server...");
|
||||||
}
|
})
|
||||||
|
|
||||||
COMMAND(sendmap, ARG_1STR)
|
|
||||||
COMMAND(getmap, ARG_NONE)
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
#import "Entity.h"
|
#import "Entity.h"
|
||||||
#import "Monster.h"
|
#import "Monster.h"
|
||||||
|
@ -10,12 +11,9 @@
|
||||||
int nextmode = 0; // nextmode becomes gamemode after next map load
|
int nextmode = 0; // nextmode becomes gamemode after next map load
|
||||||
VAR(gamemode, 1, 0, 0);
|
VAR(gamemode, 1, 0, 0);
|
||||||
|
|
||||||
static void
|
COMMAND(mode, ARG_1INT, ^(int n) {
|
||||||
mode(int n)
|
|
||||||
{
|
|
||||||
addmsg(1, 2, SV_GAMEMODE, nextmode = n);
|
addmsg(1, 2, SV_GAMEMODE, nextmode = n);
|
||||||
}
|
})
|
||||||
COMMAND(mode, ARG_1INT)
|
|
||||||
|
|
||||||
bool intermission = false;
|
bool intermission = false;
|
||||||
|
|
||||||
|
@ -142,13 +140,10 @@ respawn()
|
||||||
|
|
||||||
int sleepwait = 0;
|
int sleepwait = 0;
|
||||||
static OFString *sleepcmd = nil;
|
static OFString *sleepcmd = nil;
|
||||||
void
|
COMMAND(sleep, ARG_2STR, ^(OFString *msec, OFString *cmd) {
|
||||||
sleepf(OFString *msec, OFString *cmd)
|
|
||||||
{
|
|
||||||
sleepwait = msec.cube_intValue + lastmillis;
|
sleepwait = msec.cube_intValue + lastmillis;
|
||||||
sleepcmd = cmd;
|
sleepcmd = cmd;
|
||||||
}
|
})
|
||||||
COMMANDN(sleep, sleepf, ARG_2STR)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
updateworld(int millis) // main game update loop
|
updateworld(int millis) // main game update loop
|
||||||
|
@ -240,43 +235,34 @@ spawnplayer(DynamicEntity *d)
|
||||||
// movement input code
|
// movement input code
|
||||||
|
|
||||||
#define dir(name, v, d, s, os) \
|
#define dir(name, v, d, s, os) \
|
||||||
static void name(bool isdown) \
|
COMMAND(name, ARG_DOWN, ^(bool isDown) { \
|
||||||
{ \
|
player1.s = isDown; \
|
||||||
player1.s = isdown; \
|
player1.v = isDown ? d : (player1.os ? -(d) : 0); \
|
||||||
player1.v = isdown ? d : (player1.os ? -(d) : 0); \
|
|
||||||
player1.lastMove = lastmillis; \
|
player1.lastMove = lastmillis; \
|
||||||
}
|
})
|
||||||
|
|
||||||
dir(backward, move, -1, k_down, k_up);
|
dir(backward, move, -1, k_down, k_up);
|
||||||
dir(forward, move, 1, k_up, k_down);
|
dir(forward, move, 1, k_up, k_down);
|
||||||
dir(left, strafe, 1, k_left, k_right);
|
dir(left, strafe, 1, k_left, k_right);
|
||||||
dir(right, strafe, -1, k_right, k_left);
|
dir(right, strafe, -1, k_right, k_left);
|
||||||
|
|
||||||
void
|
COMMAND(attack, ARG_DOWN, ^(bool on) {
|
||||||
attack(bool on)
|
|
||||||
{
|
|
||||||
if (intermission)
|
if (intermission)
|
||||||
return;
|
return;
|
||||||
if (editmode)
|
if (editmode)
|
||||||
editdrag(on);
|
editdrag(on);
|
||||||
else if ((player1.attacking = on))
|
else if ((player1.attacking = on))
|
||||||
respawn();
|
respawn();
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(jump, ARG_DOWN, ^(bool on) {
|
||||||
jumpn(bool on)
|
|
||||||
{
|
|
||||||
if (!intermission && (player1.jumpNext = on))
|
if (!intermission && (player1.jumpNext = on))
|
||||||
respawn();
|
respawn();
|
||||||
}
|
})
|
||||||
|
|
||||||
COMMAND(backward, ARG_DOWN)
|
COMMAND(showscores, ARG_DOWN, ^(bool isDown) {
|
||||||
COMMAND(forward, ARG_DOWN)
|
showscores(isDown);
|
||||||
COMMAND(left, ARG_DOWN)
|
})
|
||||||
COMMAND(right, ARG_DOWN)
|
|
||||||
COMMANDN(jump, jumpn, ARG_DOWN)
|
|
||||||
COMMAND(attack, ARG_DOWN)
|
|
||||||
COMMAND(showscores, ARG_DOWN)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
fixplayer1range()
|
fixplayer1range()
|
||||||
|
@ -440,4 +426,6 @@ startmap(OFString *name) // called just after a map load
|
||||||
conoutf(@"game mode is %@", modestr(gamemode));
|
conoutf(@"game mode is %@", modestr(gamemode));
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMANDN(map, changemap, ARG_1STR)
|
COMMAND(map, ARG_1STR, ^(OFString *name) {
|
||||||
|
changemap(name);
|
||||||
|
})
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
|
|
||||||
static ENetHost *clienthost = NULL;
|
static ENetHost *clienthost = NULL;
|
||||||
|
@ -60,7 +61,7 @@ throttle()
|
||||||
throttle_interval * 1000, throttle_accel, throttle_decel);
|
throttle_interval * 1000, throttle_accel, throttle_decel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
newname(OFString *name)
|
newname(OFString *name)
|
||||||
{
|
{
|
||||||
c2sinit = false;
|
c2sinit = false;
|
||||||
|
@ -70,9 +71,12 @@ newname(OFString *name)
|
||||||
|
|
||||||
player1.name = name;
|
player1.name = name;
|
||||||
}
|
}
|
||||||
COMMANDN(name, newname, ARG_1STR)
|
|
||||||
|
|
||||||
void
|
COMMAND(name, ARG_1STR, ^(OFString *name) {
|
||||||
|
newname(name);
|
||||||
|
})
|
||||||
|
|
||||||
|
static void
|
||||||
newteam(OFString *name)
|
newteam(OFString *name)
|
||||||
{
|
{
|
||||||
c2sinit = false;
|
c2sinit = false;
|
||||||
|
@ -82,7 +86,10 @@ newteam(OFString *name)
|
||||||
|
|
||||||
player1.team = name;
|
player1.team = name;
|
||||||
}
|
}
|
||||||
COMMANDN(team, newteam, ARG_1STR)
|
|
||||||
|
COMMAND(team, ARG_1STR, ^(OFString *name) {
|
||||||
|
newteam(name);
|
||||||
|
})
|
||||||
|
|
||||||
void
|
void
|
||||||
writeclientinfo(OFStream *stream)
|
writeclientinfo(OFStream *stream)
|
||||||
|
@ -177,16 +184,18 @@ toserver(OFString *text)
|
||||||
ctext = text;
|
ctext = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(echo, ARG_VARI, ^(OFString *text) {
|
||||||
echo(OFString *text)
|
|
||||||
{
|
|
||||||
conoutf(@"%@", text);
|
conoutf(@"%@", text);
|
||||||
}
|
})
|
||||||
|
COMMAND(say, ARG_VARI, ^(OFString *text) {
|
||||||
COMMAND(echo, ARG_VARI)
|
toserver(text);
|
||||||
COMMANDN(say, toserver, ARG_VARI)
|
})
|
||||||
COMMANDN(connect, connects, ARG_1STR)
|
COMMAND(connect, ARG_1STR, ^(OFString *servername) {
|
||||||
COMMANDN(disconnect, trydisconnect, ARG_NONE)
|
connects(servername);
|
||||||
|
})
|
||||||
|
COMMAND(disconnect, ARG_NONE, ^{
|
||||||
|
trydisconnect();
|
||||||
|
})
|
||||||
|
|
||||||
// collect c2s messages conveniently
|
// collect c2s messages conveniently
|
||||||
|
|
||||||
|
@ -239,12 +248,9 @@ bool senditemstoserver =
|
||||||
false; // after a map change, since server doesn't have map data
|
false; // after a map change, since server doesn't have map data
|
||||||
|
|
||||||
OFString *clientpassword;
|
OFString *clientpassword;
|
||||||
void
|
COMMAND(password, ARG_1STR, ^(OFString *p) {
|
||||||
password(OFString *p)
|
|
||||||
{
|
|
||||||
clientpassword = p;
|
clientpassword = p;
|
||||||
}
|
})
|
||||||
COMMAND(password, ARG_1STR)
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
netmapstart()
|
netmapstart()
|
||||||
|
|
226
src/commands.m
226
src/commands.m
|
@ -9,9 +9,6 @@
|
||||||
#import "OFString+Cube.h"
|
#import "OFString+Cube.h"
|
||||||
#import "Variable.h"
|
#import "Variable.h"
|
||||||
|
|
||||||
// contains ALL vars/commands/aliases
|
|
||||||
static OFMutableDictionary<OFString *, __kindof Identifier *> *identifiers;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cleanup(char **string)
|
cleanup(char **string)
|
||||||
{
|
{
|
||||||
|
@ -21,16 +18,13 @@ cleanup(char **string)
|
||||||
void
|
void
|
||||||
alias(OFString *name, OFString *action)
|
alias(OFString *name, OFString *action)
|
||||||
{
|
{
|
||||||
Alias *alias = identifiers[name];
|
Alias *alias = [Identifier identifierForName:name];
|
||||||
|
|
||||||
if (alias == nil) {
|
if (alias == nil)
|
||||||
alias = [Alias aliasWithName:name action:action persisted:true];
|
[Identifier addIdentifier:[Alias aliasWithName:name
|
||||||
|
action:action
|
||||||
if (identifiers == nil)
|
persisted:true]];
|
||||||
identifiers = [[OFMutableDictionary alloc] init];
|
else {
|
||||||
|
|
||||||
identifiers[name] = alias;
|
|
||||||
} else {
|
|
||||||
if ([alias isKindOfClass:Alias.class])
|
if ([alias isKindOfClass:Alias.class])
|
||||||
alias.action = action;
|
alias.action = action;
|
||||||
else
|
else
|
||||||
|
@ -38,49 +32,54 @@ alias(OFString *name, OFString *action)
|
||||||
@"cannot redefine builtin %@ with an alias", name);
|
@"cannot redefine builtin %@ with an alias", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
COMMAND(alias, ARG_2STR)
|
|
||||||
|
COMMAND(alias, ARG_2STR, ^(OFString *name, OFString *action) {
|
||||||
|
alias(name, action);
|
||||||
|
})
|
||||||
|
|
||||||
int
|
int
|
||||||
variable(OFString *name, int min, int cur, int max, int *storage,
|
variable(OFString *name, int min, int cur, int max, int *storage,
|
||||||
void (*function)(), bool persisted)
|
void (*function)(), bool persisted)
|
||||||
{
|
{
|
||||||
Variable *variable = [Variable variableWithName:name
|
[Identifier addIdentifier:[Variable variableWithName:name
|
||||||
min:min
|
min:min
|
||||||
max:max
|
max:max
|
||||||
storage:storage
|
storage:storage
|
||||||
function:function
|
function:function
|
||||||
persisted:persisted];
|
persisted:persisted]];
|
||||||
|
|
||||||
if (identifiers == nil)
|
|
||||||
identifiers = [[OFMutableDictionary alloc] init];
|
|
||||||
|
|
||||||
identifiers[name] = variable;
|
|
||||||
|
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setvar(OFString *name, int i)
|
setvar(OFString *name, int i)
|
||||||
{
|
{
|
||||||
*[identifiers[name] storage] = i;
|
Variable *variable = [Identifier identifierForName:name];
|
||||||
|
|
||||||
|
if ([variable isKindOfClass:Variable.class])
|
||||||
|
*variable.storage = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
getvar(OFString *name)
|
getvar(OFString *name)
|
||||||
{
|
{
|
||||||
return *[identifiers[name] storage];
|
Variable *variable = [Identifier identifierForName:name];
|
||||||
|
|
||||||
|
if ([variable isKindOfClass:Variable.class])
|
||||||
|
return *variable.storage;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
identexists(OFString *name)
|
identexists(OFString *name)
|
||||||
{
|
{
|
||||||
return (identifiers[name] != nil);
|
return ([Identifier identifierForName:name] != nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
OFString *
|
OFString *
|
||||||
getalias(OFString *name)
|
getalias(OFString *name)
|
||||||
{
|
{
|
||||||
Alias *alias = identifiers[name];
|
Alias *alias = [Identifier identifierForName:name];
|
||||||
|
|
||||||
if ([alias isKindOfClass:Alias.class])
|
if ([alias isKindOfClass:Alias.class])
|
||||||
return alias.action;
|
return alias.action;
|
||||||
|
@ -88,21 +87,6 @@ getalias(OFString *name)
|
||||||
return nil;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse any nested set of () or []
|
// parse any nested set of () or []
|
||||||
static char *
|
static char *
|
||||||
parseexp(char **p, int right)
|
parseexp(char **p, int right)
|
||||||
|
@ -168,7 +152,8 @@ parseword(char **p)
|
||||||
OFString *
|
OFString *
|
||||||
lookup(OFString *n)
|
lookup(OFString *n)
|
||||||
{
|
{
|
||||||
__kindof Identifier *identifier = identifiers[[n substringFromIndex:1]];
|
__kindof Identifier *identifier =
|
||||||
|
[Identifier identifierForName:[n substringFromIndex:1]];
|
||||||
|
|
||||||
if ([identifier isKindOfClass:Variable.class]) {
|
if ([identifier isKindOfClass:Variable.class]) {
|
||||||
return [OFString stringWithFormat:@"%d", *[identifier storage]];
|
return [OFString stringWithFormat:@"%d", *[identifier storage]];
|
||||||
|
@ -275,7 +260,7 @@ execute(OFString *string, bool isDown)
|
||||||
if (c.length == 0)
|
if (c.length == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
val = executeIdentifier(identifiers[c],
|
val = executeIdentifier([Identifier identifierForName:c],
|
||||||
[OFArray arrayWithObjects:w count:numargs], isDown);
|
[OFArray arrayWithObjects:w count:numargs], isDown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,8 +292,8 @@ complete(OFMutableString *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
__block int idx = 0;
|
__block int idx = 0;
|
||||||
[identifiers enumerateKeysAndObjectsUsingBlock:^(
|
[Identifier enumerateIdentifiersUsingBlock:^(
|
||||||
OFString *name, Identifier *identifier, bool *stop) {
|
__kindof Identifier *identifier) {
|
||||||
if (strncmp(identifier.name.UTF8String, s.UTF8String + 1,
|
if (strncmp(identifier.name.UTF8String, s.UTF8String + 1,
|
||||||
completesize) == 0 &&
|
completesize) == 0 &&
|
||||||
idx++ == completeidx)
|
idx++ == completeidx)
|
||||||
|
@ -348,6 +333,10 @@ exec(OFString *cfgfile)
|
||||||
conoutf(@"could not read \"%@\"", cfgfile);
|
conoutf(@"could not read \"%@\"", cfgfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COMMAND(exec, ARG_1STR, ^(OFString *cfgfile) {
|
||||||
|
exec(cfgfile);
|
||||||
|
})
|
||||||
|
|
||||||
void
|
void
|
||||||
writecfg()
|
writecfg()
|
||||||
{
|
{
|
||||||
|
@ -370,8 +359,8 @@ writecfg()
|
||||||
writeclientinfo(stream);
|
writeclientinfo(stream);
|
||||||
[stream writeString:@"\n"];
|
[stream writeString:@"\n"];
|
||||||
|
|
||||||
[identifiers enumerateKeysAndObjectsUsingBlock:^(
|
[Identifier
|
||||||
OFString *name, __kindof Identifier *identifier, bool *stop) {
|
enumerateIdentifiersUsingBlock:^(__kindof Identifier *identifier) {
|
||||||
if (![identifier isKindOfClass:Variable.class] ||
|
if (![identifier isKindOfClass:Variable.class] ||
|
||||||
![identifier persisted])
|
![identifier persisted])
|
||||||
return;
|
return;
|
||||||
|
@ -384,8 +373,8 @@ writecfg()
|
||||||
writebinds(stream);
|
writebinds(stream);
|
||||||
[stream writeString:@"\n"];
|
[stream writeString:@"\n"];
|
||||||
|
|
||||||
[identifiers enumerateKeysAndObjectsUsingBlock:^(
|
[Identifier
|
||||||
OFString *name, __kindof Identifier *identifier, bool *stop) {
|
enumerateIdentifiersUsingBlock:^(__kindof Identifier *identifier) {
|
||||||
if (![identifier isKindOfClass:Alias.class] ||
|
if (![identifier isKindOfClass:Alias.class] ||
|
||||||
[identifier.name hasPrefix:@"nextmap_"])
|
[identifier.name hasPrefix:@"nextmap_"])
|
||||||
return;
|
return;
|
||||||
|
@ -397,7 +386,9 @@ writecfg()
|
||||||
[stream close];
|
[stream close];
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMAND(writecfg, ARG_NONE)
|
COMMAND(writecfg, ARG_NONE, ^{
|
||||||
|
writecfg();
|
||||||
|
})
|
||||||
|
|
||||||
// below the commands that implement a small imperative language. thanks to the
|
// below the commands that implement a small imperative language. thanks to the
|
||||||
// semantics of () and [] expressions, any control construct can be defined
|
// semantics of () and [] expressions, any control construct can be defined
|
||||||
|
@ -409,36 +400,28 @@ intset(OFString *name, int v)
|
||||||
alias(name, [OFString stringWithFormat:@"%d", v]);
|
alias(name, [OFString stringWithFormat:@"%d", v]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(if, ARG_3STR, ^(OFString *cond, OFString *thenp, OFString *elsep) {
|
||||||
ifthen(OFString *cond, OFString *thenp, OFString *elsep)
|
|
||||||
{
|
|
||||||
execute((![cond hasPrefix:@"0"] ? thenp : elsep), true);
|
execute((![cond hasPrefix:@"0"] ? thenp : elsep), true);
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(loop, ARG_2STR, ^(OFString *times, OFString *body) {
|
||||||
loopa(OFString *times, OFString *body)
|
|
||||||
{
|
|
||||||
int t = times.cube_intValue;
|
int t = times.cube_intValue;
|
||||||
|
|
||||||
for (int i = 0; i < t; i++) {
|
for (int i = 0; i < t; i++) {
|
||||||
intset(@"i", i);
|
intset(@"i", i);
|
||||||
execute(body, true);
|
execute(body, true);
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(while, ARG_2STR, ^(OFString *cond, OFString *body) {
|
||||||
whilea(OFString *cond, OFString *body)
|
|
||||||
{
|
|
||||||
while (execute(cond, true))
|
while (execute(cond, true))
|
||||||
execute(body, true);
|
execute(body, true);
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(onrelease, ARG_DWN1, ^(bool on, OFString *body) {
|
||||||
onrelease(bool on, OFString *body)
|
|
||||||
{
|
|
||||||
if (!on)
|
if (!on)
|
||||||
execute(body, true);
|
execute(body, true);
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
void
|
||||||
concat(OFString *s)
|
concat(OFString *s)
|
||||||
|
@ -446,15 +429,15 @@ concat(OFString *s)
|
||||||
alias(@"s", s);
|
alias(@"s", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(concat, ARG_VARI, ^(OFString *s) {
|
||||||
concatword(OFString *s)
|
concat(s);
|
||||||
{
|
})
|
||||||
concat([s stringByReplacingOccurrencesOfString:@" " withString:@""]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
COMMAND(concatword, ARG_VARI, ^(OFString *s) {
|
||||||
listlen(OFString *a_)
|
concat([s stringByReplacingOccurrencesOfString:@" " withString:@""]);
|
||||||
{
|
})
|
||||||
|
|
||||||
|
COMMAND(listlen, ARG_1EST, ^(OFString *a_) {
|
||||||
const char *a = a_.UTF8String;
|
const char *a = a_.UTF8String;
|
||||||
|
|
||||||
if (!*a)
|
if (!*a)
|
||||||
|
@ -466,11 +449,9 @@ listlen(OFString *a_)
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
return n + 1;
|
return n + 1;
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(at, ARG_2STR, ^(OFString *s_, OFString *pos) {
|
||||||
at(OFString *s_, OFString *pos)
|
|
||||||
{
|
|
||||||
int n = pos.cube_intValue;
|
int n = pos.cube_intValue;
|
||||||
char *copy __attribute__((__cleanup__(cleanup))) =
|
char *copy __attribute__((__cleanup__(cleanup))) =
|
||||||
strdup(s_.UTF8String);
|
strdup(s_.UTF8String);
|
||||||
|
@ -481,91 +462,48 @@ at(OFString *s_, OFString *pos)
|
||||||
}
|
}
|
||||||
s[strcspn(s, " \0")] = 0;
|
s[strcspn(s, " \0")] = 0;
|
||||||
concat(@(s));
|
concat(@(s));
|
||||||
}
|
})
|
||||||
|
|
||||||
COMMANDN(loop, loopa, ARG_2STR)
|
COMMAND(+, ARG_2EXP, ^(int a, int b) {
|
||||||
COMMANDN(while, whilea, ARG_2STR)
|
|
||||||
COMMANDN(if, ifthen, ARG_3STR)
|
|
||||||
COMMAND(onrelease, ARG_DWN1)
|
|
||||||
COMMAND(exec, ARG_1STR)
|
|
||||||
COMMAND(concat, ARG_VARI)
|
|
||||||
COMMAND(concatword, ARG_VARI)
|
|
||||||
COMMAND(at, ARG_2STR)
|
|
||||||
COMMAND(listlen, ARG_1EST)
|
|
||||||
|
|
||||||
int
|
|
||||||
add(int a, int b)
|
|
||||||
{
|
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
})
|
||||||
COMMANDN(+, add, ARG_2EXP)
|
|
||||||
|
|
||||||
int
|
COMMAND(*, ARG_2EXP, ^(int a, int b) {
|
||||||
mul(int a, int b)
|
|
||||||
{
|
|
||||||
return a * b;
|
return a * b;
|
||||||
}
|
})
|
||||||
COMMANDN(*, mul, ARG_2EXP)
|
|
||||||
|
|
||||||
int
|
COMMAND(-, ARG_2EXP, ^(int a, int b) {
|
||||||
sub(int a, int b)
|
|
||||||
{
|
|
||||||
return a - b;
|
return a - b;
|
||||||
}
|
})
|
||||||
COMMANDN(-, sub, ARG_2EXP)
|
|
||||||
|
|
||||||
int
|
COMMAND(div, ARG_2EXP, ^(int a, int b) {
|
||||||
divi(int a, int b)
|
|
||||||
{
|
|
||||||
return b ? a / b : 0;
|
return b ? a / b : 0;
|
||||||
}
|
})
|
||||||
COMMANDN(div, divi, ARG_2EXP)
|
|
||||||
|
|
||||||
int
|
COMMAND(mod, ARG_2EXP, ^(int a, int b) {
|
||||||
mod(int a, int b)
|
|
||||||
{
|
|
||||||
return b ? a % b : 0;
|
return b ? a % b : 0;
|
||||||
}
|
})
|
||||||
COMMAND(mod, ARG_2EXP)
|
|
||||||
|
|
||||||
int
|
COMMAND(=, ARG_2EXP, ^(int a, int b) {
|
||||||
equal(int a, int b)
|
|
||||||
{
|
|
||||||
return (int)(a == b);
|
return (int)(a == b);
|
||||||
}
|
})
|
||||||
COMMANDN(=, equal, ARG_2EXP)
|
|
||||||
|
|
||||||
int
|
COMMAND(<, ARG_2EXP, ^(int a, int b) {
|
||||||
lt(int a, int b)
|
|
||||||
{
|
|
||||||
return (int)(a < b);
|
return (int)(a < b);
|
||||||
}
|
})
|
||||||
COMMANDN(<, lt, ARG_2EXP)
|
|
||||||
|
|
||||||
int
|
COMMAND(>, ARG_2EXP, ^(int a, int b) {
|
||||||
gt(int a, int b)
|
|
||||||
{
|
|
||||||
return (int)(a > b);
|
return (int)(a > b);
|
||||||
}
|
})
|
||||||
COMMANDN(>, gt, ARG_2EXP)
|
|
||||||
|
|
||||||
int
|
COMMAND(strcmp, ARG_2EST, ^(OFString *a, OFString *b) {
|
||||||
strcmpa(OFString *a, OFString *b)
|
|
||||||
{
|
|
||||||
return [a isEqual:b];
|
return [a isEqual:b];
|
||||||
}
|
})
|
||||||
COMMANDN(strcmp, strcmpa, ARG_2EST)
|
|
||||||
|
|
||||||
int
|
COMMAND(rnd, ARG_1EXP, ^(int a) {
|
||||||
rndn(int a)
|
return (a > 0 ? rnd(a) : 0);
|
||||||
{
|
})
|
||||||
return a > 0 ? rnd(a) : 0;
|
|
||||||
}
|
|
||||||
COMMANDN(rnd, rndn, ARG_1EXP)
|
|
||||||
|
|
||||||
int
|
COMMAND(millis, ARG_1EXP, ^(int unused) {
|
||||||
explastmillis()
|
|
||||||
{
|
|
||||||
return lastmillis;
|
return lastmillis;
|
||||||
}
|
})
|
||||||
COMMANDN(millis, explastmillis, ARG_1EXP)
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "ConsoleLine.h"
|
#import "ConsoleLine.h"
|
||||||
#import "KeyMapping.h"
|
#import "KeyMapping.h"
|
||||||
#import "OFString+Cube.h"
|
#import "OFString+Cube.h"
|
||||||
|
@ -17,14 +18,11 @@ int conskip = 0;
|
||||||
bool saycommandon = false;
|
bool saycommandon = false;
|
||||||
static OFMutableString *commandbuf;
|
static OFMutableString *commandbuf;
|
||||||
|
|
||||||
void
|
COMMAND(conskip, ARG_1INT, ^(int n) {
|
||||||
setconskip(int n)
|
|
||||||
{
|
|
||||||
conskip += n;
|
conskip += n;
|
||||||
if (conskip < 0)
|
if (conskip < 0)
|
||||||
conskip = 0;
|
conskip = 0;
|
||||||
}
|
})
|
||||||
COMMANDN(conskip, setconskip, ARG_1INT)
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
conline(OFString *sf, bool highlight) // add a line to the console buffer
|
conline(OFString *sf, bool highlight) // add a line to the console buffer
|
||||||
|
@ -104,9 +102,7 @@ renderconsole()
|
||||||
|
|
||||||
static OFMutableArray<KeyMapping *> *keyMappings = nil;
|
static OFMutableArray<KeyMapping *> *keyMappings = nil;
|
||||||
|
|
||||||
void
|
COMMAND(keymap, ARG_3STR, ^(OFString *code, OFString *key, OFString *action) {
|
||||||
keymap(OFString *code, OFString *key, OFString *action)
|
|
||||||
{
|
|
||||||
if (keyMappings == nil)
|
if (keyMappings == nil)
|
||||||
keyMappings = [[OFMutableArray alloc] init];
|
keyMappings = [[OFMutableArray alloc] init];
|
||||||
|
|
||||||
|
@ -114,12 +110,9 @@ keymap(OFString *code, OFString *key, OFString *action)
|
||||||
name:key];
|
name:key];
|
||||||
mapping.action = action;
|
mapping.action = action;
|
||||||
[keyMappings addObject:mapping];
|
[keyMappings addObject:mapping];
|
||||||
}
|
})
|
||||||
COMMAND(keymap, ARG_3STR)
|
|
||||||
|
|
||||||
void
|
COMMAND(bind, ARG_2STR, ^(OFString *key, OFString *action) {
|
||||||
bindkey(OFString *key, OFString *action)
|
|
||||||
{
|
|
||||||
for (KeyMapping *mapping in keyMappings) {
|
for (KeyMapping *mapping in keyMappings) {
|
||||||
if ([mapping.name caseInsensitiveCompare:key] ==
|
if ([mapping.name caseInsensitiveCompare:key] ==
|
||||||
OFOrderedSame) {
|
OFOrderedSame) {
|
||||||
|
@ -129,11 +122,11 @@ bindkey(OFString *key, OFString *action)
|
||||||
}
|
}
|
||||||
|
|
||||||
conoutf(@"unknown key \"%@\"", key);
|
conoutf(@"unknown key \"%@\"", key);
|
||||||
}
|
})
|
||||||
COMMANDN(bind, bindkey, ARG_2STR)
|
|
||||||
|
|
||||||
void
|
// turns input to the command line on or off
|
||||||
saycommand(OFString *init) // turns input to the command line on or off
|
static void
|
||||||
|
saycommand(OFString *init)
|
||||||
{
|
{
|
||||||
saycommandon = (init != nil);
|
saycommandon = (init != nil);
|
||||||
if (saycommandon)
|
if (saycommandon)
|
||||||
|
@ -149,15 +142,15 @@ saycommand(OFString *init) // turns input to the command line on or off
|
||||||
|
|
||||||
commandbuf = [init mutableCopy];
|
commandbuf = [init mutableCopy];
|
||||||
}
|
}
|
||||||
COMMAND(saycommand, ARG_VARI)
|
|
||||||
|
|
||||||
void
|
COMMAND(saycommand, ARG_VARI, ^(OFString *init) {
|
||||||
mapmsg(OFString *s)
|
saycommand(init);
|
||||||
{
|
})
|
||||||
|
|
||||||
|
COMMAND(mapmsg, ARG_1STR, ^(OFString *s) {
|
||||||
memset(hdr.maptitle, '\0', sizeof(hdr.maptitle));
|
memset(hdr.maptitle, '\0', sizeof(hdr.maptitle));
|
||||||
strncpy(hdr.maptitle, s.UTF8String, 127);
|
strncpy(hdr.maptitle, s.UTF8String, 127);
|
||||||
}
|
})
|
||||||
COMMAND(mapmsg, ARG_1STR)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pasteconsole()
|
pasteconsole()
|
||||||
|
@ -168,9 +161,7 @@ pasteconsole()
|
||||||
static OFMutableArray<OFString *> *vhistory;
|
static OFMutableArray<OFString *> *vhistory;
|
||||||
static int histpos = 0;
|
static int histpos = 0;
|
||||||
|
|
||||||
void
|
COMMAND(history, ARG_1INT, ^(int n) {
|
||||||
history(int n)
|
|
||||||
{
|
|
||||||
static bool rec = false;
|
static bool rec = false;
|
||||||
|
|
||||||
if (!rec && n >= 0 && n < vhistory.count) {
|
if (!rec && n >= 0 && n < vhistory.count) {
|
||||||
|
@ -178,8 +169,7 @@ history(int n)
|
||||||
execute(vhistory[vhistory.count - n - 1], true);
|
execute(vhistory[vhistory.count - n - 1], true);
|
||||||
rec = false;
|
rec = false;
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
COMMAND(history, ARG_1INT)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
keypress(int code, bool isDown)
|
keypress(int code, bool isDown)
|
||||||
|
|
|
@ -340,14 +340,6 @@ enum {
|
||||||
|
|
||||||
// nasty macros for registering script functions, abuses globals to avoid
|
// nasty macros for registering script functions, abuses globals to avoid
|
||||||
// excessive infrastructure
|
// excessive infrastructure
|
||||||
#define COMMANDN(name, fun, nargs) \
|
|
||||||
OF_CONSTRUCTOR() \
|
|
||||||
{ \
|
|
||||||
enqueueInit(^{ \
|
|
||||||
addcommand(@ #name, (void (*)())fun, nargs); \
|
|
||||||
}); \
|
|
||||||
}
|
|
||||||
#define COMMAND(name, nargs) COMMANDN(name, name, nargs)
|
|
||||||
#define VARP(name, min, cur, max) \
|
#define VARP(name, min, cur, max) \
|
||||||
int name; \
|
int name; \
|
||||||
OF_CONSTRUCTOR() \
|
OF_CONSTRUCTOR() \
|
||||||
|
|
134
src/editing.m
134
src/editing.m
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
#import "Monster.h"
|
#import "Monster.h"
|
||||||
#import "OFString+Cube.h"
|
#import "OFString+Cube.h"
|
||||||
|
@ -78,7 +79,10 @@ toggleedit()
|
||||||
selset = false;
|
selset = false;
|
||||||
editing = editmode;
|
editing = editmode;
|
||||||
}
|
}
|
||||||
COMMANDN(edittoggle, toggleedit, ARG_NONE)
|
|
||||||
|
COMMAND(edittoggle, ARG_NONE, ^{
|
||||||
|
toggleedit();
|
||||||
|
})
|
||||||
|
|
||||||
void
|
void
|
||||||
correctsel() // ensures above invariant
|
correctsel() // ensures above invariant
|
||||||
|
@ -120,14 +124,12 @@ noselection()
|
||||||
if (noteditmode() || multiplayer()) \
|
if (noteditmode() || multiplayer()) \
|
||||||
return;
|
return;
|
||||||
|
|
||||||
void
|
COMMAND(select, ARG_4INT, (^(int x, int y, int xs, int ys) {
|
||||||
selectpos(int x, int y, int xs, int ys)
|
|
||||||
{
|
|
||||||
struct block s = { x, y, xs, ys };
|
struct block s = { x, y, xs, ys };
|
||||||
sel = s;
|
sel = s;
|
||||||
selh = 0;
|
selh = 0;
|
||||||
correctsel();
|
correctsel();
|
||||||
}
|
}))
|
||||||
|
|
||||||
void
|
void
|
||||||
makesel()
|
makesel()
|
||||||
|
@ -272,9 +274,7 @@ makeundo()
|
||||||
pruneundos(undomegs << 20);
|
pruneundos(undomegs << 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(undo, ARG_NONE, ^{
|
||||||
editundo()
|
|
||||||
{
|
|
||||||
EDITMP;
|
EDITMP;
|
||||||
if (undos.count == 0) {
|
if (undos.count == 0) {
|
||||||
conoutf(@"nothing more to undo");
|
conoutf(@"nothing more to undo");
|
||||||
|
@ -284,24 +284,20 @@ editundo()
|
||||||
[undos removeLastItem];
|
[undos removeLastItem];
|
||||||
blockpaste(p);
|
blockpaste(p);
|
||||||
OFFreeMemory(p);
|
OFFreeMemory(p);
|
||||||
}
|
})
|
||||||
|
|
||||||
static struct block *copybuf = NULL;
|
static struct block *copybuf = NULL;
|
||||||
|
|
||||||
void
|
COMMAND(copy, ARG_NONE, ^{
|
||||||
copy()
|
|
||||||
{
|
|
||||||
EDITSELMP;
|
EDITSELMP;
|
||||||
|
|
||||||
if (copybuf)
|
if (copybuf)
|
||||||
OFFreeMemory(copybuf);
|
OFFreeMemory(copybuf);
|
||||||
|
|
||||||
copybuf = blockcopy(&sel);
|
copybuf = blockcopy(&sel);
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(paste, ARG_NONE, ^{
|
||||||
paste()
|
|
||||||
{
|
|
||||||
EDITMP;
|
EDITMP;
|
||||||
if (!copybuf) {
|
if (!copybuf) {
|
||||||
conoutf(@"nothing to paste");
|
conoutf(@"nothing to paste");
|
||||||
|
@ -318,7 +314,7 @@ paste()
|
||||||
copybuf->x = sel.x;
|
copybuf->x = sel.x;
|
||||||
copybuf->y = sel.y;
|
copybuf->y = sel.y;
|
||||||
blockpaste(copybuf);
|
blockpaste(copybuf);
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
void
|
||||||
tofronttex() // maintain most recently used of the texture lists when applying
|
tofronttex() // maintain most recently used of the texture lists when applying
|
||||||
|
@ -378,7 +374,10 @@ editheight(int flr, int amount)
|
||||||
editheightxy(isfloor, amount, &sel);
|
editheightxy(isfloor, amount, &sel);
|
||||||
addmsg(1, 7, SV_EDITH, sel.x, sel.y, sel.xs, sel.ys, isfloor, amount);
|
addmsg(1, 7, SV_EDITH, sel.x, sel.y, sel.xs, sel.ys, isfloor, amount);
|
||||||
}
|
}
|
||||||
COMMAND(editheight, ARG_2INT)
|
|
||||||
|
COMMAND(editheight, ARG_2INT, ^(int flr, int amount) {
|
||||||
|
editheight(flr, amount);
|
||||||
|
})
|
||||||
|
|
||||||
void
|
void
|
||||||
edittexxy(int type, int t, const struct block *sel)
|
edittexxy(int type, int t, const struct block *sel)
|
||||||
|
@ -399,9 +398,7 @@ edittexxy(int type, int t, const struct block *sel)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(edittex, ARG_2INT, ^(int type, int dir) {
|
||||||
edittex(int type, int dir)
|
|
||||||
{
|
|
||||||
EDITSEL;
|
EDITSEL;
|
||||||
|
|
||||||
if (type < 0 || type > 3)
|
if (type < 0 || type > 3)
|
||||||
|
@ -419,11 +416,9 @@ edittex(int type, int dir)
|
||||||
int t = lasttex = hdr.texlists[atype][i];
|
int t = lasttex = hdr.texlists[atype][i];
|
||||||
edittexxy(type, t, &sel);
|
edittexxy(type, t, &sel);
|
||||||
addmsg(1, 7, SV_EDITT, sel.x, sel.y, sel.xs, sel.ys, type, t);
|
addmsg(1, 7, SV_EDITT, sel.x, sel.y, sel.xs, sel.ys, type, t);
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(replace, ARG_NONE, (^{
|
||||||
replace()
|
|
||||||
{
|
|
||||||
EDITSELMP;
|
EDITSELMP;
|
||||||
|
|
||||||
for (int x = 0; x < ssize; x++) {
|
for (int x = 0; x < ssize; x++) {
|
||||||
|
@ -452,7 +447,7 @@ replace()
|
||||||
|
|
||||||
struct block b = { 0, 0, ssize, ssize };
|
struct block b = { 0, 0, ssize, ssize };
|
||||||
remip(&b, 0);
|
remip(&b, 0);
|
||||||
}
|
}))
|
||||||
|
|
||||||
void
|
void
|
||||||
edittypexy(int type, const struct block *sel)
|
edittypexy(int type, const struct block *sel)
|
||||||
|
@ -460,7 +455,7 @@ edittypexy(int type, const struct block *sel)
|
||||||
loopselxy(s->type = type);
|
loopselxy(s->type = type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
edittype(int type)
|
edittype(int type)
|
||||||
{
|
{
|
||||||
EDITSEL;
|
EDITSEL;
|
||||||
|
@ -476,26 +471,17 @@ edittype(int type)
|
||||||
addmsg(1, 6, SV_EDITS, sel.x, sel.y, sel.xs, sel.ys, type);
|
addmsg(1, 6, SV_EDITS, sel.x, sel.y, sel.xs, sel.ys, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(heightfield, ARG_1INT, ^(int t) {
|
||||||
heightfield(int t)
|
|
||||||
{
|
|
||||||
edittype(t == 0 ? FHF : CHF);
|
edittype(t == 0 ? FHF : CHF);
|
||||||
}
|
})
|
||||||
COMMAND(heightfield, ARG_1INT)
|
|
||||||
|
|
||||||
void
|
COMMAND(solid, ARG_1INT, ^(int t) {
|
||||||
solid(int t)
|
|
||||||
{
|
|
||||||
edittype(t == 0 ? SPACE : SOLID);
|
edittype(t == 0 ? SPACE : SOLID);
|
||||||
}
|
})
|
||||||
COMMAND(solid, ARG_1INT)
|
|
||||||
|
|
||||||
void
|
COMMAND(corner, ARG_NONE, ^{
|
||||||
corner()
|
|
||||||
{
|
|
||||||
edittype(CORNER);
|
edittype(CORNER);
|
||||||
}
|
})
|
||||||
COMMAND(corner, ARG_NONE)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
editequalisexy(bool isfloor, const struct block *sel)
|
editequalisexy(bool isfloor, const struct block *sel)
|
||||||
|
@ -517,17 +503,14 @@ editequalisexy(bool isfloor, const struct block *sel)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(equalize, ARG_1INT, ^(int flr) {
|
||||||
equalize(int flr)
|
|
||||||
{
|
|
||||||
bool isfloor = (flr == 0);
|
bool isfloor = (flr == 0);
|
||||||
|
|
||||||
EDITSEL;
|
EDITSEL;
|
||||||
|
|
||||||
editequalisexy(isfloor, &sel);
|
editequalisexy(isfloor, &sel);
|
||||||
addmsg(1, 6, SV_EDITE, sel.x, sel.y, sel.xs, sel.ys, isfloor);
|
addmsg(1, 6, SV_EDITE, sel.x, sel.y, sel.xs, sel.ys, isfloor);
|
||||||
}
|
})
|
||||||
COMMAND(equalize, ARG_1INT)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
setvdeltaxy(int delta, const struct block *sel)
|
setvdeltaxy(int delta, const struct block *sel)
|
||||||
|
@ -536,22 +519,18 @@ setvdeltaxy(int delta, const struct block *sel)
|
||||||
remipmore(sel, 0);
|
remipmore(sel, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(vdelta, ARG_1INT, ^(int delta) {
|
||||||
setvdelta(int delta)
|
|
||||||
{
|
|
||||||
EDITSEL;
|
EDITSEL;
|
||||||
|
|
||||||
setvdeltaxy(delta, &sel);
|
setvdeltaxy(delta, &sel);
|
||||||
addmsg(1, 6, SV_EDITD, sel.x, sel.y, sel.xs, sel.ys, delta);
|
addmsg(1, 6, SV_EDITD, sel.x, sel.y, sel.xs, sel.ys, delta);
|
||||||
}
|
})
|
||||||
|
|
||||||
#define MAXARCHVERT 50
|
#define MAXARCHVERT 50
|
||||||
int archverts[MAXARCHVERT][MAXARCHVERT];
|
int archverts[MAXARCHVERT][MAXARCHVERT];
|
||||||
bool archvinit = false;
|
bool archvinit = false;
|
||||||
|
|
||||||
void
|
COMMAND(archvertex, ARG_3INT, ^(int span, int vert, int delta) {
|
||||||
archvertex(int span, int vert, int delta)
|
|
||||||
{
|
|
||||||
if (!archvinit) {
|
if (!archvinit) {
|
||||||
archvinit = true;
|
archvinit = true;
|
||||||
for (int s = 0; s < MAXARCHVERT; s++)
|
for (int s = 0; s < MAXARCHVERT; s++)
|
||||||
|
@ -561,11 +540,9 @@ archvertex(int span, int vert, int delta)
|
||||||
if (span >= MAXARCHVERT || vert >= MAXARCHVERT || span < 0 || vert < 0)
|
if (span >= MAXARCHVERT || vert >= MAXARCHVERT || span < 0 || vert < 0)
|
||||||
return;
|
return;
|
||||||
archverts[span][vert] = delta;
|
archverts[span][vert] = delta;
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(arch, ARG_2INT, ^(int sidedelta, int _a) {
|
||||||
arch(int sidedelta, int _a)
|
|
||||||
{
|
|
||||||
EDITSELMP;
|
EDITSELMP;
|
||||||
|
|
||||||
sel.xs++;
|
sel.xs++;
|
||||||
|
@ -585,11 +562,9 @@ arch(int sidedelta, int _a)
|
||||||
: (archverts[sel->ys - 1][y] +
|
: (archverts[sel->ys - 1][y] +
|
||||||
(x == 0 || x == sel->xs - 1 ? sidedelta : 0)));
|
(x == 0 || x == sel->xs - 1 ? sidedelta : 0)));
|
||||||
remipmore(sel, 0);
|
remipmore(sel, 0);
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(slope, ARG_2INT, ^(int xd, int yd) {
|
||||||
slope(int xd, int yd)
|
|
||||||
{
|
|
||||||
EDITSELMP;
|
EDITSELMP;
|
||||||
|
|
||||||
int off = 0;
|
int off = 0;
|
||||||
|
@ -606,11 +581,9 @@ slope(int xd, int yd)
|
||||||
struct block *sel = sel_;
|
struct block *sel = sel_;
|
||||||
loopselxy(s->vdelta = xd * x + yd * y + off);
|
loopselxy(s->vdelta = xd * x + yd * y + off);
|
||||||
remipmore(sel, 0);
|
remipmore(sel, 0);
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(perlin, ARG_3INT, ^(int scale, int seed, int psize) {
|
||||||
perlin(int scale, int seed, int psize)
|
|
||||||
{
|
|
||||||
EDITSELMP;
|
EDITSELMP;
|
||||||
|
|
||||||
sel.xs++;
|
sel.xs++;
|
||||||
|
@ -630,7 +603,7 @@ perlin(int scale, int seed, int psize)
|
||||||
|
|
||||||
sel.xs--;
|
sel.xs--;
|
||||||
sel.ys--;
|
sel.ys--;
|
||||||
}
|
})
|
||||||
|
|
||||||
VARF(
|
VARF(
|
||||||
fullbright, 0, 0, 1, if (fullbright) {
|
fullbright, 0, 0, 1, if (fullbright) {
|
||||||
|
@ -640,37 +613,20 @@ VARF(
|
||||||
world[i].r = world[i].g = world[i].b = 176;
|
world[i].r = world[i].g = world[i].b = 176;
|
||||||
});
|
});
|
||||||
|
|
||||||
void
|
COMMAND(edittag, ARG_1INT, ^(int tag) {
|
||||||
edittag(int tag)
|
|
||||||
{
|
|
||||||
EDITSELMP;
|
EDITSELMP;
|
||||||
|
|
||||||
struct block *sel_ = &sel;
|
struct block *sel_ = &sel;
|
||||||
// Ugly hack to make the macro work.
|
// Ugly hack to make the macro work.
|
||||||
struct block *sel = sel_;
|
struct block *sel = sel_;
|
||||||
loopselxy(s->tag = tag);
|
loopselxy(s->tag = tag);
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(newent, ARG_5STR,
|
||||||
newent(OFString *what, OFString *a1, OFString *a2, OFString *a3, OFString *a4)
|
^(OFString *what, OFString *a1, OFString *a2, OFString *a3, OFString *a4) {
|
||||||
{
|
|
||||||
EDITSEL;
|
EDITSEL;
|
||||||
|
|
||||||
newentity(sel.x, sel.y, (int)player1.origin.z, what,
|
newentity(sel.x, sel.y, (int)player1.origin.z, what,
|
||||||
[a1 cube_intValueWithBase:0], [a2 cube_intValueWithBase:0],
|
[a1 cube_intValueWithBase:0], [a2 cube_intValueWithBase:0],
|
||||||
[a3 cube_intValueWithBase:0], [a4 cube_intValueWithBase:0]);
|
[a3 cube_intValueWithBase:0], [a4 cube_intValueWithBase:0]);
|
||||||
}
|
})
|
||||||
|
|
||||||
COMMANDN(select, selectpos, ARG_4INT)
|
|
||||||
COMMAND(edittag, ARG_1INT)
|
|
||||||
COMMAND(replace, ARG_NONE)
|
|
||||||
COMMAND(archvertex, ARG_3INT)
|
|
||||||
COMMAND(arch, ARG_2INT)
|
|
||||||
COMMAND(slope, ARG_2INT)
|
|
||||||
COMMANDN(vdelta, setvdelta, ARG_1INT)
|
|
||||||
COMMANDN(undo, editundo, ARG_NONE)
|
|
||||||
COMMAND(copy, ARG_NONE)
|
|
||||||
COMMAND(paste, ARG_NONE)
|
|
||||||
COMMAND(edittex, ARG_2INT)
|
|
||||||
COMMAND(newent, ARG_5STR)
|
|
||||||
COMMAND(perlin, ARG_3INT)
|
|
||||||
|
|
20
src/menus.m
20
src/menus.m
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#import "Menu.h"
|
#import "Menu.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
#import "MenuItem.h"
|
#import "MenuItem.h"
|
||||||
|
|
||||||
|
@ -20,9 +21,7 @@ menuset(int menu)
|
||||||
menus[1].menusel = 0;
|
menus[1].menusel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(showmenu, ARG_1STR, ^(OFString *name) {
|
||||||
showmenu(OFString *name)
|
|
||||||
{
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Menu *menu in menus) {
|
for (Menu *menu in menus) {
|
||||||
if (i > 1 && [menu.name isEqual:name]) {
|
if (i > 1 && [menu.name isEqual:name]) {
|
||||||
|
@ -31,8 +30,7 @@ showmenu(OFString *name)
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
COMMAND(showmenu, ARG_1STR)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sortmenu()
|
sortmenu()
|
||||||
|
@ -97,7 +95,10 @@ newmenu(OFString *name)
|
||||||
|
|
||||||
[menus addObject:[Menu menuWithName:name]];
|
[menus addObject:[Menu menuWithName:name]];
|
||||||
}
|
}
|
||||||
COMMAND(newmenu, ARG_1STR)
|
|
||||||
|
COMMAND(newmenu, ARG_1STR, ^(OFString *name) {
|
||||||
|
newmenu(name);
|
||||||
|
})
|
||||||
|
|
||||||
void
|
void
|
||||||
menumanual(int m, int n, OFString *text)
|
menumanual(int m, int n, OFString *text)
|
||||||
|
@ -109,17 +110,14 @@ menumanual(int m, int n, OFString *text)
|
||||||
[menus[m].items addObject:item];
|
[menus[m].items addObject:item];
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(menuitem, ARG_2STR, ^(OFString *text, OFString *action) {
|
||||||
menuitem(OFString *text, OFString *action)
|
|
||||||
{
|
|
||||||
Menu *menu = menus.lastObject;
|
Menu *menu = menus.lastObject;
|
||||||
|
|
||||||
MenuItem *item =
|
MenuItem *item =
|
||||||
[MenuItem itemWithText:text
|
[MenuItem itemWithText:text
|
||||||
action:(action.length > 0 ? action : text)];
|
action:(action.length > 0 ? action : text)];
|
||||||
[menu.items addObject:item];
|
[menu.items addObject:item];
|
||||||
}
|
})
|
||||||
COMMAND(menuitem, ARG_2STR)
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
menukey(int code, bool isdown)
|
menukey(int code, bool isdown)
|
||||||
|
|
|
@ -10,7 +10,6 @@ extern int variable(OFString *name, int min, int cur, int max, int *storage,
|
||||||
extern void setvar(OFString *name, int i);
|
extern void setvar(OFString *name, int i);
|
||||||
extern int getvar(OFString *name);
|
extern int getvar(OFString *name);
|
||||||
extern bool identexists(OFString *name);
|
extern bool identexists(OFString *name);
|
||||||
extern bool addcommand(OFString *name, void (*fun)(), int narg);
|
|
||||||
extern int execute(OFString *p, bool down);
|
extern int execute(OFString *p, bool down);
|
||||||
extern void exec(OFString *cfgfile);
|
extern void exec(OFString *cfgfile);
|
||||||
extern bool execfile(OFIRI *cfgfile);
|
extern bool execfile(OFIRI *cfgfile);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
|
|
||||||
static struct vertex *verts = NULL;
|
static struct vertex *verts = NULL;
|
||||||
int curvert;
|
int curvert;
|
||||||
static int curmaxverts = 10000;
|
static int curmaxverts = 10000;
|
||||||
|
@ -61,12 +63,9 @@ int ol3r, ol3g, ol3b, ol4r, ol4g, ol4b;
|
||||||
int firstindex;
|
int firstindex;
|
||||||
bool showm = false;
|
bool showm = false;
|
||||||
|
|
||||||
void
|
COMMAND(showmip, ARG_NONE, ^{
|
||||||
showmip()
|
|
||||||
{
|
|
||||||
showm = !showm;
|
showm = !showm;
|
||||||
}
|
})
|
||||||
COMMAND(showmip, ARG_NONE)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mipstats(int a, int b, int c)
|
mipstats(int a, int b, int c)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
#import "Entity.h"
|
#import "Entity.h"
|
||||||
|
|
||||||
|
@ -203,9 +204,7 @@ renderents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(loadsky, ARG_1STR, (^(OFString *basename) {
|
||||||
loadsky(OFString *basename)
|
|
||||||
{
|
|
||||||
static OFString *lastsky = @"";
|
static OFString *lastsky = @"";
|
||||||
|
|
||||||
basename = [basename stringByReplacingOccurrencesOfString:@"\\"
|
basename = [basename stringByReplacingOccurrencesOfString:@"\\"
|
||||||
|
@ -230,8 +229,7 @@ loadsky(OFString *basename)
|
||||||
}
|
}
|
||||||
|
|
||||||
lastsky = basename;
|
lastsky = basename;
|
||||||
}
|
}))
|
||||||
COMMAND(loadsky, ARG_1STR)
|
|
||||||
|
|
||||||
float cursordepth = 0.9f;
|
float cursordepth = 0.9f;
|
||||||
GLint viewport[4];
|
GLint viewport[4];
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
#import "Monster.h"
|
#import "Monster.h"
|
||||||
#import "OFString+Cube.h"
|
#import "OFString+Cube.h"
|
||||||
|
@ -185,16 +186,11 @@ purgetextures()
|
||||||
|
|
||||||
int curtexnum = 0;
|
int curtexnum = 0;
|
||||||
|
|
||||||
void
|
COMMAND(texturereset, ARG_NONE, ^{
|
||||||
texturereset()
|
|
||||||
{
|
|
||||||
curtexnum = 0;
|
curtexnum = 0;
|
||||||
}
|
})
|
||||||
COMMAND(texturereset, ARG_NONE)
|
|
||||||
|
|
||||||
void
|
COMMAND(texture, ARG_2STR, (^(OFString *aframe, OFString *name) {
|
||||||
texture(OFString *aframe, OFString *name)
|
|
||||||
{
|
|
||||||
int num = curtexnum++, frame = aframe.cube_intValue;
|
int num = curtexnum++, frame = aframe.cube_intValue;
|
||||||
|
|
||||||
if (num < 0 || num >= 256 || frame < 0 || frame >= MAXFRAMES)
|
if (num < 0 || num >= 256 || frame < 0 || frame >= MAXFRAMES)
|
||||||
|
@ -203,8 +199,7 @@ texture(OFString *aframe, OFString *name)
|
||||||
mapping[num][frame] = 1;
|
mapping[num][frame] = 1;
|
||||||
mapname[num][frame] = [name stringByReplacingOccurrencesOfString:@"\\"
|
mapname[num][frame] = [name stringByReplacingOccurrencesOfString:@"\\"
|
||||||
withString:@"/"];
|
withString:@"/"];
|
||||||
}
|
}))
|
||||||
COMMAND(texture, ARG_2STR)
|
|
||||||
|
|
||||||
int
|
int
|
||||||
lookuptexture(int tex, int *xs, int *ys)
|
lookuptexture(int tex, int *xs, int *ys)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
#import "MD2.h"
|
#import "MD2.h"
|
||||||
#import "MapModelInfo.h"
|
#import "MapModelInfo.h"
|
||||||
|
@ -54,11 +55,11 @@ loadmodel(OFString *name)
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(mapmodel, ARG_5STR,
|
||||||
mapmodel(
|
^(OFString *rad, OFString *h, OFString *zoff, OFString *snap,
|
||||||
OFString *rad, OFString *h, OFString *zoff, OFString *snap, OFString *name)
|
OFString *name) {
|
||||||
{
|
MD2 *m =
|
||||||
MD2 *m = loadmodel([name stringByReplacingOccurrencesOfString:@"\\"
|
loadmodel([name stringByReplacingOccurrencesOfString:@"\\"
|
||||||
withString:@"/"]);
|
withString:@"/"]);
|
||||||
m.mmi = [MapModelInfo infoWithRad:rad.cube_intValue
|
m.mmi = [MapModelInfo infoWithRad:rad.cube_intValue
|
||||||
h:h.cube_intValue
|
h:h.cube_intValue
|
||||||
|
@ -70,15 +71,11 @@ mapmodel(
|
||||||
mapmodels = [[OFMutableArray alloc] init];
|
mapmodels = [[OFMutableArray alloc] init];
|
||||||
|
|
||||||
[mapmodels addObject:m];
|
[mapmodels addObject:m];
|
||||||
}
|
})
|
||||||
COMMAND(mapmodel, ARG_5STR)
|
|
||||||
|
|
||||||
void
|
COMMAND(mapmodelreset, ARG_NONE, ^{
|
||||||
mapmodelreset()
|
|
||||||
{
|
|
||||||
[mapmodels removeAllObjects];
|
[mapmodels removeAllObjects];
|
||||||
}
|
})
|
||||||
COMMAND(mapmodelreset, ARG_NONE)
|
|
||||||
|
|
||||||
MapModelInfo *
|
MapModelInfo *
|
||||||
getmminfo(int i)
|
getmminfo(int i)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
#import "Entity.h"
|
#import "Entity.h"
|
||||||
#import "Monster.h"
|
#import "Monster.h"
|
||||||
|
@ -129,9 +130,7 @@ savestate(OFIRI *IRI)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(savegame, ARG_1STR, (^(OFString *name) {
|
||||||
savegame(OFString *name)
|
|
||||||
{
|
|
||||||
if (!m_classicsp) {
|
if (!m_classicsp) {
|
||||||
conoutf(@"can only save classic sp games");
|
conoutf(@"can only save classic sp games");
|
||||||
return;
|
return;
|
||||||
|
@ -143,8 +142,7 @@ savegame(OFString *name)
|
||||||
savestate(IRI);
|
savestate(IRI);
|
||||||
stop();
|
stop();
|
||||||
conoutf(@"wrote %@", IRI.string);
|
conoutf(@"wrote %@", IRI.string);
|
||||||
}
|
}))
|
||||||
COMMAND(savegame, ARG_1STR)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
loadstate(OFIRI *IRI)
|
loadstate(OFIRI *IRI)
|
||||||
|
@ -184,15 +182,12 @@ out:
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(loadgame, ARG_1STR, (^(OFString *name) {
|
||||||
loadgame(OFString *name)
|
|
||||||
{
|
|
||||||
OFString *path = [OFString stringWithFormat:@"savegames/%@.csgz", name];
|
OFString *path = [OFString stringWithFormat:@"savegames/%@.csgz", name];
|
||||||
OFIRI *IRI =
|
OFIRI *IRI =
|
||||||
[Cube.sharedInstance.userDataIRI IRIByAppendingPathComponent:path];
|
[Cube.sharedInstance.userDataIRI IRIByAppendingPathComponent:path];
|
||||||
loadstate(IRI);
|
loadstate(IRI);
|
||||||
}
|
}))
|
||||||
COMMAND(loadgame, ARG_1STR)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
loadgameout()
|
loadgameout()
|
||||||
|
@ -268,9 +263,7 @@ int playbacktime = 0;
|
||||||
int ddamage, bdamage;
|
int ddamage, bdamage;
|
||||||
OFVector3D dorig;
|
OFVector3D dorig;
|
||||||
|
|
||||||
void
|
COMMAND(record, ARG_1STR, (^(OFString *name) {
|
||||||
record(OFString *name)
|
|
||||||
{
|
|
||||||
if (m_sp) {
|
if (m_sp) {
|
||||||
conoutf(@"cannot record singleplayer games");
|
conoutf(@"cannot record singleplayer games");
|
||||||
return;
|
return;
|
||||||
|
@ -289,8 +282,7 @@ record(OFString *name)
|
||||||
demorecording = true;
|
demorecording = true;
|
||||||
starttime = lastmillis;
|
starttime = lastmillis;
|
||||||
ddamage = bdamage = 0;
|
ddamage = bdamage = 0;
|
||||||
}
|
}))
|
||||||
COMMAND(record, ARG_1STR)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
demodamage(int damage, const OFVector3D *o)
|
demodamage(int damage, const OFVector3D *o)
|
||||||
|
@ -337,16 +329,13 @@ incomingdemodata(unsigned char *buf, int len, bool extras)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(demo, ARG_1STR, (^(OFString *name) {
|
||||||
demo(OFString *name)
|
|
||||||
{
|
|
||||||
OFString *path = [OFString stringWithFormat:@"demos/%@.cdgz", name];
|
OFString *path = [OFString stringWithFormat:@"demos/%@.cdgz", name];
|
||||||
OFIRI *IRI =
|
OFIRI *IRI =
|
||||||
[Cube.sharedInstance.userDataIRI IRIByAppendingPathComponent:path];
|
[Cube.sharedInstance.userDataIRI IRIByAppendingPathComponent:path];
|
||||||
loadstate(IRI);
|
loadstate(IRI);
|
||||||
demoloading = true;
|
demoloading = true;
|
||||||
}
|
}))
|
||||||
COMMAND(demo, ARG_1STR)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
stopreset()
|
stopreset()
|
||||||
|
@ -549,13 +538,10 @@ demoplaybackstep()
|
||||||
// if(player1->state!=CS_DEAD) showscores(false);
|
// if(player1->state!=CS_DEAD) showscores(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(stop, ARG_NONE, ^{
|
||||||
stopn()
|
|
||||||
{
|
|
||||||
if (demoplayback)
|
if (demoplayback)
|
||||||
stopreset();
|
stopreset();
|
||||||
else
|
else
|
||||||
stop();
|
stop();
|
||||||
conoutf(@"demo stopped");
|
conoutf(@"demo stopped");
|
||||||
}
|
})
|
||||||
COMMANDN(stop, stopn, ARG_NONE)
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "SDL_thread.h"
|
#include "SDL_thread.h"
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "ResolverResult.h"
|
#import "ResolverResult.h"
|
||||||
#import "ResolverThread.h"
|
#import "ResolverThread.h"
|
||||||
#import "ServerInfo.h"
|
#import "ServerInfo.h"
|
||||||
|
@ -126,6 +127,10 @@ addserver(OFString *servername)
|
||||||
[servers addObject:[ServerInfo infoWithName:servername]];
|
[servers addObject:[ServerInfo infoWithName:servername]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COMMAND(addserver, ARG_1STR, ^(OFString *servername) {
|
||||||
|
addserver(servername);
|
||||||
|
})
|
||||||
|
|
||||||
void
|
void
|
||||||
pingservers()
|
pingservers()
|
||||||
{
|
{
|
||||||
|
@ -245,7 +250,7 @@ refreshservers()
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
servermenu()
|
servermenu()
|
||||||
{
|
{
|
||||||
if (pingsock == ENET_SOCKET_NULL) {
|
if (pingsock == ENET_SOCKET_NULL) {
|
||||||
|
@ -262,9 +267,11 @@ servermenu()
|
||||||
menuset(1);
|
menuset(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(servermenu, ARG_NONE, ^{
|
||||||
updatefrommaster()
|
servermenu();
|
||||||
{
|
})
|
||||||
|
|
||||||
|
COMMAND(updatefrommaster, ARG_NONE, ^{
|
||||||
const int MAXUPD = 32000;
|
const int MAXUPD = 32000;
|
||||||
unsigned char buf[MAXUPD];
|
unsigned char buf[MAXUPD];
|
||||||
unsigned char *reply = retrieveservers(buf, MAXUPD);
|
unsigned char *reply = retrieveservers(buf, MAXUPD);
|
||||||
|
@ -276,11 +283,7 @@ updatefrommaster()
|
||||||
execute(@((char *)reply), true);
|
execute(@((char *)reply), true);
|
||||||
}
|
}
|
||||||
servermenu();
|
servermenu();
|
||||||
}
|
})
|
||||||
|
|
||||||
COMMAND(addserver, ARG_1STR)
|
|
||||||
COMMAND(servermenu, ARG_NONE)
|
|
||||||
COMMAND(updatefrommaster, ARG_NONE)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
writeservercfg()
|
writeservercfg()
|
||||||
|
|
22
src/sound.m
22
src/sound.m
|
@ -1,5 +1,6 @@
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
|
|
||||||
#include <SDL_mixer.h>
|
#include <SDL_mixer.h>
|
||||||
|
@ -47,9 +48,7 @@ initsound()
|
||||||
Mix_AllocateChannels(MAXCHAN);
|
Mix_AllocateChannels(MAXCHAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(music, ARG_1STR, (^(OFString *name) {
|
||||||
music(OFString *name)
|
|
||||||
{
|
|
||||||
if (nosound)
|
if (nosound)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -69,15 +68,12 @@ music(OFString *name)
|
||||||
Mix_VolumeMusic((musicvol * MAXVOL) / 255);
|
Mix_VolumeMusic((musicvol * MAXVOL) / 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}))
|
||||||
COMMAND(music, ARG_1STR)
|
|
||||||
|
|
||||||
static OFMutableData *samples;
|
static OFMutableData *samples;
|
||||||
static OFMutableArray<OFString *> *snames;
|
static OFMutableArray<OFString *> *snames;
|
||||||
|
|
||||||
int
|
COMMAND(registersound, ARG_1EST, ^int(OFString *name) {
|
||||||
registersound(OFString *name)
|
|
||||||
{
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (OFString *iter in snames) {
|
for (OFString *iter in snames) {
|
||||||
if ([iter isEqual:name])
|
if ([iter isEqual:name])
|
||||||
|
@ -98,8 +94,7 @@ registersound(OFString *name)
|
||||||
[samples addItem:&sample];
|
[samples addItem:&sample];
|
||||||
|
|
||||||
return samples.count - 1;
|
return samples.count - 1;
|
||||||
}
|
})
|
||||||
COMMAND(registersound, ARG_1EST)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cleansound()
|
cleansound()
|
||||||
|
@ -216,9 +211,6 @@ playsound(int n, const OFVector3D *loc)
|
||||||
updatechanvol(chan, loc);
|
updatechanvol(chan, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(sound, ARG_1INT, ^(int n) {
|
||||||
sound(int n)
|
|
||||||
{
|
|
||||||
playsound(n, NULL);
|
playsound(n, NULL);
|
||||||
}
|
})
|
||||||
COMMAND(sound, ARG_1INT)
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
#import "Monster.h"
|
#import "Monster.h"
|
||||||
#import "OFString+Cube.h"
|
#import "OFString+Cube.h"
|
||||||
|
@ -62,14 +63,11 @@ reloadtime(int gun)
|
||||||
return guns[gun].attackdelay;
|
return guns[gun].attackdelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(weapon, ARG_3STR, ^(OFString *a1, OFString *a2, OFString *a3) {
|
||||||
weapon(OFString *a1, OFString *a2, OFString *a3)
|
|
||||||
{
|
|
||||||
selectgun((a1.length > 0 ? a1.cube_intValue : -1),
|
selectgun((a1.length > 0 ? a1.cube_intValue : -1),
|
||||||
(a2.length > 0 ? a2.cube_intValue : -1),
|
(a2.length > 0 ? a2.cube_intValue : -1),
|
||||||
(a3.length > 0 ? a3.cube_intValue : -1));
|
(a3.length > 0 ? a3.cube_intValue : -1));
|
||||||
}
|
})
|
||||||
COMMAND(weapon, ARG_3STR)
|
|
||||||
|
|
||||||
// create random spread of rays for the shotgun
|
// create random spread of rays for the shotgun
|
||||||
void
|
void
|
||||||
|
|
52
src/world.m
52
src/world.m
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
#import "Entity.h"
|
#import "Entity.h"
|
||||||
#import "Monster.h"
|
#import "Monster.h"
|
||||||
|
@ -91,7 +92,10 @@ trigger(int tag, int type, bool savegame)
|
||||||
if (type == 2)
|
if (type == 2)
|
||||||
[Monster endSinglePlayerWithAllKilled:false];
|
[Monster endSinglePlayerWithAllKilled:false];
|
||||||
}
|
}
|
||||||
COMMAND(trigger, ARG_2INT)
|
|
||||||
|
COMMAND(trigger, ARG_2INT, ^(int tag, int type, bool savegame) {
|
||||||
|
trigger(tag, type, savegame);
|
||||||
|
})
|
||||||
|
|
||||||
// main geometric mipmapping routine, recursively rebuild mipmaps within block
|
// main geometric mipmapping routine, recursively rebuild mipmaps within block
|
||||||
// b. tries to produce cube out of 4 lower level mips as well as possible, sets
|
// b. tries to produce cube out of 4 lower level mips as well as possible, sets
|
||||||
|
@ -304,9 +308,7 @@ closestent() // used for delent and edit mode ent display
|
||||||
return (bdist == 99999 ? -1 : best);
|
return (bdist == 99999 ? -1 : best);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(entproperty, ARG_2INT, ^(int prop, int amount) {
|
||||||
entproperty(int prop, int amount)
|
|
||||||
{
|
|
||||||
int e = closestent();
|
int e = closestent();
|
||||||
if (e < 0)
|
if (e < 0)
|
||||||
return;
|
return;
|
||||||
|
@ -324,11 +326,9 @@ entproperty(int prop, int amount)
|
||||||
ents[e].attr4 += amount;
|
ents[e].attr4 += amount;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(delent, ARG_NONE, ^{
|
||||||
delent()
|
|
||||||
{
|
|
||||||
int e = closestent();
|
int e = closestent();
|
||||||
if (e < 0) {
|
if (e < 0) {
|
||||||
conoutf(@"no more entities");
|
conoutf(@"no more entities");
|
||||||
|
@ -340,7 +340,7 @@ delent()
|
||||||
addmsg(1, 10, SV_EDITENT, e, NOTUSED, 0, 0, 0, 0, 0, 0, 0);
|
addmsg(1, 10, SV_EDITENT, e, NOTUSED, 0, 0, 0, 0, 0, 0, 0);
|
||||||
if (t == LIGHT)
|
if (t == LIGHT)
|
||||||
calclight();
|
calclight();
|
||||||
}
|
})
|
||||||
|
|
||||||
int
|
int
|
||||||
findtype(OFString *what)
|
findtype(OFString *what)
|
||||||
|
@ -397,9 +397,7 @@ newentity(int x, int y, int z, OFString *what, int v1, int v2, int v3, int v4)
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(clearents, ARG_1STR, ^(OFString *name) {
|
||||||
clearents(OFString *name)
|
|
||||||
{
|
|
||||||
int type = findtype(name);
|
int type = findtype(name);
|
||||||
|
|
||||||
if (noteditmode() || multiplayer())
|
if (noteditmode() || multiplayer())
|
||||||
|
@ -411,8 +409,7 @@ clearents(OFString *name)
|
||||||
|
|
||||||
if (type == LIGHT)
|
if (type == LIGHT)
|
||||||
calclight();
|
calclight();
|
||||||
}
|
})
|
||||||
COMMAND(clearents, ARG_1STR)
|
|
||||||
|
|
||||||
static unsigned char
|
static unsigned char
|
||||||
scalecomp(unsigned char c, int intens)
|
scalecomp(unsigned char c, int intens)
|
||||||
|
@ -423,9 +420,7 @@ scalecomp(unsigned char c, int intens)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(scalelights, ARG_2INT, ^(int f, int intens) {
|
||||||
scalelights(int f, int intens)
|
|
||||||
{
|
|
||||||
for (Entity *e in ents) {
|
for (Entity *e in ents) {
|
||||||
if (e.type != LIGHT)
|
if (e.type != LIGHT)
|
||||||
continue;
|
continue;
|
||||||
|
@ -444,8 +439,7 @@ scalelights(int f, int intens)
|
||||||
}
|
}
|
||||||
|
|
||||||
calclight();
|
calclight();
|
||||||
}
|
})
|
||||||
COMMAND(scalelights, ARG_2INT)
|
|
||||||
|
|
||||||
int
|
int
|
||||||
findentity(int type, int index)
|
findentity(int type, int index)
|
||||||
|
@ -551,20 +545,14 @@ empty_world(int factor, bool force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
COMMAND(mapenlarge, ARG_NONE, ^{
|
||||||
mapenlarge()
|
|
||||||
{
|
|
||||||
empty_world(-1, false);
|
empty_world(-1, false);
|
||||||
}
|
})
|
||||||
|
|
||||||
void
|
COMMAND(newmap, ARG_1INT, ^(int i) {
|
||||||
newmap(int i)
|
|
||||||
{
|
|
||||||
empty_world(i, false);
|
empty_world(i, false);
|
||||||
}
|
})
|
||||||
|
|
||||||
COMMAND(mapenlarge, ARG_NONE)
|
COMMAND(recalc, ARG_NONE, ^{
|
||||||
COMMAND(newmap, ARG_1INT)
|
calclight();
|
||||||
COMMANDN(recalc, calclight, ARG_NONE)
|
})
|
||||||
COMMAND(delent, ARG_NONE)
|
|
||||||
COMMAND(entproperty, ARG_2INT)
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "Entity.h"
|
#import "Entity.h"
|
||||||
|
|
||||||
struct persistent_entity {
|
struct persistent_entity {
|
||||||
|
@ -256,7 +257,10 @@ save_world(OFString *mname)
|
||||||
conoutf(@"wrote map file %@", cgzname);
|
conoutf(@"wrote map file %@", cgzname);
|
||||||
settagareas();
|
settagareas();
|
||||||
}
|
}
|
||||||
COMMANDN(savemap, save_world, ARG_1STR)
|
|
||||||
|
COMMAND(savemap, ARG_1STR, ^(OFString *mname) {
|
||||||
|
save_world(mname);
|
||||||
|
})
|
||||||
|
|
||||||
void
|
void
|
||||||
load_world(OFString *mname) // still supports all map formats that have existed
|
load_world(OFString *mname) // still supports all map formats that have existed
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
|
#import "Command.h"
|
||||||
#import "DynamicEntity.h"
|
#import "DynamicEntity.h"
|
||||||
|
|
||||||
#define NUMRAYS 512
|
#define NUMRAYS 512
|
||||||
|
@ -10,12 +11,9 @@ float rdist[NUMRAYS];
|
||||||
bool ocull = true;
|
bool ocull = true;
|
||||||
float odist = 256;
|
float odist = 256;
|
||||||
|
|
||||||
void
|
COMMAND(toggleocull, ARG_NONE, ^{
|
||||||
toggleocull()
|
|
||||||
{
|
|
||||||
ocull = !ocull;
|
ocull = !ocull;
|
||||||
}
|
})
|
||||||
COMMAND(toggleocull, ARG_NONE)
|
|
||||||
|
|
||||||
// constructs occlusion map: cast rays in all directions on the 2d plane and
|
// constructs occlusion map: cast rays in all directions on the 2d plane and
|
||||||
// record distance. done exactly once per frame.
|
// record distance. done exactly once per frame.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue