64 string autocvar_sv_minigames_bulldozer_startlevel =
"level1";
72 if ( e.classname ==
"minigame_board_piece" && e.netname == tile && ((check_target) ? e.bd_tiletype == BD_TILE_TARGET : e.bd_tiletype != BD_TILE_TARGET) )
81 if ( e.classname ==
"bd_controller" && e.bd_tilelet == letter )
93 return 0 <= number && number < BD_NUM_CNT && 0 <= letter && letter <
BD_LET_CNT;
99 controller.bd_forceupdate =
number;
108 if ( e.classname ==
"minigame_board_piece" && e.bd_tiletype == BD_TILE_DOZER )
116 WriteHeader(MSG_ENTITY, ENT_CLIENT_BD_CONTROLLER);
126 int number = this.bd_forceupdate;
135 if(sf & BD_SF_UPDATE_ALL)
151 NET_HANDLE(ENT_CLIENT_BD_CONTROLLER,
bool isNew)
157 this.bd_tilelet = ReadByte();
180 int total = 0, valid = 0;
183 if ( e.classname ==
"minigame_board_piece" && e.bd_tiletype == BD_TILE_TARGET )
186 if(
bd_find_piece(minig, e.netname,
false).bd_tiletype == BD_TILE_BOULDER)
223 if(bdir ==
"up" || bdir ==
"u")
225 if(bdir ==
"down" || bdir ==
"dn" || bdir ==
"d")
227 if(bdir ==
"left" || bdir ==
"lt" || bdir ==
"l")
229 if(bdir ==
"right" || bdir ==
"rt" || bdir ==
"r")
272 switch(hit.bd_tiletype)
301 switch(controller.bd_tiletypes[tnum])
313 strcpy(hit.netname, testpos);
321 switch(controller.bd_tiletypes[number])
333 strcpy(dozer.netname, newpos);
354 string thedir = strtolower(dir);
360 if ( e.classname ==
"minigame_board_piece" && e.bd_tiletype == BD_TILE_DOZER )
385 if ( pos && thetile )
392 if(found_piece.bd_tiletype == BD_TILE_DOZER && thedir !=
"")
394 string newdir = strtolower(thedir);
397 found_piece.bd_dir = bdir;
409 if(controller.bd_tiletypes[tnum])
411 controller.bd_tiletypes[tnum] = 0;
412 controller.bd_dirs[tnum] = 0;
417 if(found_piece || (targ && thetile != BD_TILE_BOULDER))
435 controller.bd_tiletypes[
number] = thetile;
436 controller.bd_dirs[
number] = 0;
444 piece.bd_tiletype = thetile;
457 bd_move(minigame, player, dir);
488 if(targ && thetype == targ.bd_tiletype)
493 else if(piece && thetype == piece.bd_tiletype)
509 if(!player.minigame_players.bd_canedit)
511 sprint(player.minigame_players,
"You're not allowed to edit levels, sorry!\n");
518 int thetype =
stof(thetile);
527 if(targ) { killtype = targ.bd_tiletype; }
528 if(piece) { killtype = piece.bd_tiletype; }
551 for(e = minigame.minigame_players; e; e = e.list_next)
555 if ( e.classname ==
"minigame_player" )
568 if(e.classname ==
"minigame_board_piece")
575 if(e.classname ==
"bd_controller")
580 for(
int letter = 0; letter <
BD_LET_CNT; ++letter)
583 controller.owner = minigame;
584 controller.bd_tilelet = letter;
586 Net_LinkEntity(controller,
false, 0, bd_controller_send);
598 if(minigame.bd_nextlevel && minigame.bd_nextlevel !=
"")
600 strcpy(minigame.bd_levelname, minigame.bd_nextlevel);
610 strcpy(minigame.bd_nextlevel, next);
635 if(!player.minigame_players.bd_canedit)
637 sprint(player.minigame_players,
"You're not allowed to edit levels, sorry!\n");
652 string bd_string =
"";
656 bd_string =
strcat(bd_string,
"\"", tilename,
"\" ");
657 bd_string =
strcat(bd_string,
ftos(e.bd_tiletypes[number]),
" ");
658 bd_string =
strcat(bd_string,
ftos(e.bd_dirs[number]));
665 string bd_string =
"";
667 bd_string =
strcat(bd_string,
"\"", e.netname,
"\" ");
668 bd_string =
strcat(bd_string,
ftos(e.bd_tiletype),
" ");
669 bd_string =
strcat(bd_string,
ftos(e.bd_dir));
683 if(dir.x == 0 && dir.y == 1) {
return BD_DIR_UP; }
684 if(dir.x == 0 && dir.y == -1) {
return BD_DIR_DN; }
685 if(dir.x == -1 && dir.y == 0) {
return BD_DIR_LF; }
686 if(dir.x == 1 && dir.y == 0) {
return BD_DIR_RT; }
694 string bd_string = s;
699 string tilename =
strzone(
argv(argv_num)); ++argv_num;
700 int tiletype =
stoi(
argv(argv_num)); ++argv_num;
708 controller.bd_tiletypes[
number] = tiletype;
716 e.netname = tilename;
719 e.bd_tiletype = tiletype;
726 if(minigame.bd_levelname && minigame.bd_levelname !=
"")
728 int target_count = 0, boulder_count = 0;
731 if(piece.classname ==
"minigame_board_piece")
733 if(piece.bd_tiletype == BD_TILE_BOULDER)
735 else if(piece.bd_tiletype == BD_TILE_TARGET)
739 if(boulder_count != target_count)
741 LOG_INFO(
"Not enough targets or boulders, fix your level!");
749 file_name =
strcat(
"minigames/bulldozer/storage_", minigame.bd_levelname,
".txt");
751 fputs(file_get,
strcat(
"// bulldozer storage \"", minigame.bd_levelname,
"\" last updated ", strftime(
true,
"%d-%m-%Y %H:%M:%S"),
"\n"));
753 if(minigame.bd_nextlevel && minigame.bd_nextlevel !=
"" &&
fexists(
strcat(
"minigames/bulldozer/storage_", minigame.bd_nextlevel,
".txt")))
754 fputs(file_get,
strcat(
"nextlevel = \"", minigame.bd_nextlevel,
"\"\n"));
758 if ( e.classname ==
"bd_controller" )
769 if ( e.classname ==
"minigame_board_piece" )
785 string file_read, file_name;
788 file_name =
strcat(
"minigames/bulldozer/storage_", minigame.bd_levelname,
".txt");
792 LOG_INFO(
"^3BULLDOZER: ^7could not find storage file ^3", file_name,
"^7, no items were loaded");
798 file_read =
fgets(file_get);
805 if(
substring(file_read, 0, 9) ==
"nextlevel")
820 if(!player.minigame_players.bd_canedit)
822 sprint(player.minigame_players,
"You're not allowed to edit levels, sorry!\n");
830 LOG_INFO(
"You need to place a bulldozer on the level to save it!");
841 LOG_INFO(
"You need to set the level name!");
849 int bd_server_event(
entity minigame,
string event, ...)
855 strcpy(minigame.bd_levelname, autocvar_sv_minigames_bulldozer_startlevel);
865 if(e.classname ==
"minigame_board_piece")
872 if(e.classname ==
"bd_controller")
877 strfree(minigame.bd_nextlevel);
878 strfree(minigame.bd_levelname);
933 if ( sent.classname ==
"minigame_board_piece" && (sf &
MINIG_SF_UPDATE) )
966 string bd_get_tile_pic(
int tileid)
991 bd_boardsize = mySize;
1001 if(e.classname ==
"minigame_board_piece")
1003 if(e.bd_tiletype == BD_TILE_TARGET)
1008 else if(e.bd_tiletype == BD_TILE_BOULDER)
1017 if ( e.classname ==
"bd_controller" )
1021 if(!e.bd_tiletypes[j])
continue;
1023 int letter = e.bd_tilelet;
1029 string thepiece = bd_get_tile_pic(e.bd_tiletypes[j]);
1036 else if ( e.classname ==
"minigame_board_piece" )
1038 if(e.bd_tiletype != BD_TILE_DOZER && !e.bd_hide)
1043 string thepiece = bd_get_tile_pic(e.bd_tiletype);
1046 thepiece =
"bd/boulder_target";
1058 if ( e.classname ==
"minigame_board_piece" && e.bd_tiletype == BD_TILE_DOZER )
1063 int bdir = e.bd_dir;
1076 tile_size, tile_size/2,
'1 1 1',
1086 string thepiece = ((piece || (targ && bd_curr_tile !=
BD_TILE_BOULDER)) ?
"bd/delete" : bd_get_tile_pic(bd_curr_tile));
1090 if(bd_curr_tile == BD_TILE_DOZER)
1093 tile_size, tile_size/2,
'1 1 1',
1107 string victory_text = _(
"Game over!");
1110 victory_text = _(
"Well done! Click 'Next Level' to continue");
1112 vector win_pos = pos+
eY*(mySize_y-winfs_y)/2;
1137 ts_y = ( mySize_y - 2*player_fontsize_y ) / BD_TEAMS;
1140 vector tile_size =
'48 48 0';
1146 mypos_y += player_fontsize_y;
1153 if ( e.classname ==
"minigame_player" && e.team != BD_SPECTATOR_TEAM )
1157 entcs_GetName(e.minigame_playerslot-1),
1160 mypos_y += player_fontsize_y;
1161 string thepiece =
"bd/dozer";
1163 thepiece = bd_get_tile_pic(bd_curr_tile);
1164 const float tile_scale = 0.7;
1165 drawpic( mypos + tile_size * 0.5 * (1 - tile_scale),
1169 mypos_x += tile_size_x;
1178 string bd_turn_to_string(
int turnflags)
1181 return _(
"You are spectating");
1184 return _(
"Better luck next time!");
1189 return _(
"Tubular! Press \"Next Level\" to continue!");
1191 return _(
"Wicked! Press \"Next Level\" to continue!");
1195 return _(
"Press the space bar to change your currently selected tile");
1198 return _(
"Push the boulders onto the targets");
1204 void bd_make_move(
entity minigame,
string dir)
1212 void bd_editor_make_move(
entity minigame,
string dir)
1220 void bd_editor_fill(
entity minigame)
1228 void bd_set_curr_pos(
string s)
1236 bool bd_change_dozer_angle(
entity minigame)
1239 if(!dozer || dozer.bd_tiletype != BD_TILE_DOZER)
1242 switch(dozer.bd_dir)
1252 bd_editor_make_move(minigame, thedir);
1257 int bd_client_event(
entity minigame,
string event, ...)
1263 strcpy(minigame.message, bd_turn_to_string(minigame.minigame_flags));
1264 bd_set_curr_pos(
"");
1274 case "key_released":
1276 bool event_blocked = ((
event ==
"key_released")
1280 switch ( ...(0,
int) )
1286 bd_make_move(minigame,
"r");
1292 bd_make_move(minigame,
"l");
1298 bd_make_move(minigame,
"u");
1304 bd_make_move(minigame,
"d");
1311 switch ( ...(0,
int) )
1317 if ( ! bd_curr_pos )
1318 bd_set_curr_pos(
"a3");
1326 if ( ! bd_curr_pos )
1327 bd_set_curr_pos(
"c3");
1335 if ( ! bd_curr_pos )
1336 bd_set_curr_pos(
"a1");
1344 if ( ! bd_curr_pos )
1345 bd_set_curr_pos(
"a3");
1353 bd_editor_make_move(minigame,
"");
1358 if(bd_change_dozer_angle(minigame))
1361 if(bd_curr_tile > BD_TILE_LAST)
1369 case "mouse_pressed":
1375 bd_client_event(minigame,
"mouse_moved");
1376 bd_editor_make_move(minigame,
"");
1382 bd_client_event(minigame,
"mouse_moved");
1383 bd_editor_fill(minigame);
1397 bd_set_curr_pos(
"");
1401 case "network_receive":
1404 int sf = ...(1,
int);
1405 if ( sent.classname ==
"minigame" )
1409 strcpy(sent.message, bd_turn_to_string(sent.minigame_flags));
1414 else if(sent.classname ==
"minigame_board_piece")
1418 int letter = ReadByte();
1422 sent.bd_tiletype = ReadByte();
1424 sent.bd_dir = ReadByte();
1428 sent.bd_moves = ReadShort();
1442 if(...(0,
string) ==
"next")
1444 if(...(0,
string) ==
"restart")
1446 if(...(0,
string) ==
"edit")
1448 if(...(0,
string) ==
"save")
int bd_fix_dir(vector dir)
int minigame_tile_number(string id)
void bd_do_fill(entity minigame, entity player, string dir, string thetile)
void minigame_server_sendflags(entity ent, int mgflags)
void HUD_MinigameMenu_CustomEntry(entity parent, string menumessage, string event_arg)
REGISTER_MINIGAME(bd, _("Bulldozer"))
#define REGISTER_NET_LINKED(id)
#define FOREACH_MINIGAME_ENTITY(entityvar)
void bd_editor_place(entity minigame, entity player, string pos, int thetile, string thedir)
void bd_next_match(entity minigame, entity player, string next)
const int BD_SF_UPDATE_SINGLE
void bd_reset_moves(entity minigame)
entity bd_find_piece(entity minig, string tile, bool check_target)
vector minigame_hud_denormalize_size(vector v, vector pos, vector mySize)
void minigame_read_owner(entity this)
#define minigame_hud_fitsqare(pos, mySize)
entity msle_spawn(entity minigame_session, entity e)
int bd_tiletypes[BD_NUM_CNT]
void bd_set_next_match(entity minigame, string next)
bool bd_move_dozer(entity minigame, entity dozer)
void bd_fill_recurse(entity minigame, entity player, int thetype, int letter, int number)
#define NET_HANDLE(id, param)
vector minigame_hud_normalize(vector v, vector pos, vector mySize)
void bd_controller_update(entity controller, int number)
entity bd_find_controller(entity minig, int letter)
const int BD_TILE_BOULDER
entity bd_find_dozer(entity minig)
const int MINIG_SF_UPDATE
int bd_dir_fromname(string bdir)
vector bd_get_dir(int bdir)
string minigame_tile_name(vector pos, int rows, int columns)
const float DRAWFLAG_ADDITIVE
void bd_load_level(entity minigame)
const int MINIG_SF_CUSTOM
#define HUD_Panel_DrawBg()
void minigame_drawpic_centered(vector pos, string texture, vector sz, vector color, float thealpha, int drawflags)
string minigame_texture(string name)
void bd_set_nextlevel(entity minigame, string s)
string bd_save_piece(entity minigame, entity e)
vector minigame_tile_pos(string id, int rows, int columns)
vector minigame_drawcolorcodedstring_wrapped(float maxwidth, vector pos, string text, vector fontsize, float theAlpha, int drawflags, float align)
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
const int BD_SPECTATOR_TEAM
const int BD_SF_UPDATE_ALL
const float DRAWFLAG_NORMAL
int minigame_tile_letter(string id)
#define minigame_cmd(...)
string minigame_tile_buildname(int letter, int number)
void bd_check_winner(entity minig)
vector(float skel, float bonenum) _skel_get_boneabs_hidden
bool bd_canfill(int ttype)
void bd_do_next_match(entity minigame, entity player)
string minigame_relative_tile(string start_id, int dx, int dy, int rows, int columns)
void bd_move(entity minigame, entity player, string dir)
string bd_save_controller_piece(entity minigame, entity e, int number)
bool bd_valid_tile(string tile)
int minigame_count_players(entity minigame)
vector minigame_hud_denormalize(vector v, vector pos, vector mySize)
string bd_get_dir_name(int bdir)
#define new_pure(class)
purely logical entities (.origin doesn't work)
void minigame_drawcolorcodedstring_trunc(float maxwidth, vector pos, string text, vector fontsize, float theAlpha, int drawflags)
void minigame_hud_simpleboard(vector pos, vector mySize, string board_texture)
void bd_activate_editor(entity minigame, entity player)
void bd_load_piece(entity minigame, string s)
void bd_close_editor(entity minigame, entity player)
void bd_restart_match(entity minigame, entity player)
ERASEABLE bool fexists(string f)
void bd_do_move(entity minigame, entity player, string dir, string thetile, string thedir)
void bd_unfill_recurse(entity minigame, entity player, int thetype, int letter, int number)
bool bd_save_level(entity minigame)
vector minigame_drawstring_wrapped(float maxwidth, vector pos, string text, vector fontsize, vector color, float theAlpha, int drawflags, float align)
void bd_setup_pieces(entity minigame)
const int BD_SF_PLAYERMOVES