src/train_cmd.cpp
changeset 8658 fcfacbbf4400
parent 8653 a83f7a536919
child 8664 f3444d620972
equal deleted inserted replaced
8657:6e9eee9ac980 8658:fcfacbbf4400
  1025 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
  1025 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
  1026 
  1026 
  1027 		if (flags & DC_EXEC) src->unitnumber = unit_num;
  1027 		if (flags & DC_EXEC) src->unitnumber = unit_num;
  1028 	}
  1028 	}
  1029 
  1029 
  1030 	if (dst_head != NULL) {
  1030 	/*
  1031 		/* Check NewGRF Callback 0x1D */
  1031 	 * Check whether the vehicles in the source chain are in the destination
  1032 		uint16 callback = GetVehicleCallbackParent(CBID_TRAIN_ALLOW_WAGON_ATTACH, 0, 0, dst_head->engine_type, src, dst_head);
  1032 	 * chain. This can easily be done by checking whether the first vehicle
  1033 		if (callback != CALLBACK_FAILED) {
  1033 	 * of the source chain is in the destination chain as the Next/Previous
  1034 			if (callback == 0xFD) return_cmd_error(STR_INCOMPATIBLE_RAIL_TYPES);
  1034 	 * pointers always make a doubly linked list of it where the assumption
  1035 			if (callback < 0xFD) {
  1035 	 * v->Next()->Previous() == v holds (assuming v->Next() != NULL).
  1036 				StringID error = GetGRFStringID(GetEngineGRFID(dst_head->engine_type), 0xD000 + callback);
  1036 	 */
  1037 				return_cmd_error(error);
  1037 	bool src_in_dst = false;
  1038 			}
  1038 	for (Vehicle *v = dst_head; !src_in_dst && v != NULL; v = v->Next()) src_in_dst = v == src;
  1039 		}
  1039 
       
  1040 	/*
       
  1041 	 * If the source chain is in the destination chain then the user is
       
  1042 	 * only reordering the vehicles, thus not attaching a new vehicle.
       
  1043 	 * Therefor the 'allow wagon attach' callback does not need to be
       
  1044 	 * called. If it would be called strange things would happen because
       
  1045 	 * one 'attaches' an already 'attached' vehicle causing more trouble
       
  1046 	 * than it actually solves (infinite loops and such).
       
  1047 	 */
       
  1048 	if (dst_head != NULL && !src_in_dst) {
       
  1049 		/*
       
  1050 		 * When performing the 'allow wagon attach' callback, we have to check
       
  1051 		 * that for each and every wagon, not only the first one. This means
       
  1052 		 * that we have to test one wagon, attach it to the train and then test
       
  1053 		 * the next wagon till we have reached the end. We have to restore it
       
  1054 		 * to the state it was before we 'tried' attaching the train when the
       
  1055 		 * attaching fails or succeeds because we are not 'only' doing this
       
  1056 		 * in the DC_EXEC state.
       
  1057 		 */
       
  1058 		Vehicle *dst_tail = dst_head;
       
  1059 		while (dst_tail->Next() != NULL) dst_tail = dst_tail->Next();
       
  1060 
       
  1061 		Vehicle *orig_tail = dst_tail;
       
  1062 		Vehicle *next_to_attach = src;
       
  1063 		Vehicle *src_previous = src->Previous();
       
  1064 
       
  1065 		while (next_to_attach != NULL) {
       
  1066 			uint16 callback = GetVehicleCallbackParent(CBID_TRAIN_ALLOW_WAGON_ATTACH, 0, 0, dst_head->engine_type, next_to_attach, dst_head);
       
  1067 			if (callback != CALLBACK_FAILED) {
       
  1068 				StringID error = STR_NULL;
       
  1069 
       
  1070 				if (callback == 0xFD) error = STR_INCOMPATIBLE_RAIL_TYPES;
       
  1071 				if (callback < 0xFD) error = GetGRFStringID(GetEngineGRFID(dst_head->engine_type), 0xD000 + callback);
       
  1072 
       
  1073 				if (error != STR_NULL) {
       
  1074 					/*
       
  1075 					 * The attaching is not allowed. In this case 'next_to_attach'
       
  1076 					 * can contain some vehicles of the 'source' and the destination
       
  1077 					 * train can have some too. We 'just' add the to-be added wagons
       
  1078 					 * to the chain and then split it where it was previously
       
  1079 					 * separated, i.e. the tail of the original destination train.
       
  1080 					 * Furthermore the 'previous' link of the original source vehicle needs
       
  1081 					 * to be restored, otherwise the train goes missing in the depot.
       
  1082 					 */
       
  1083 					dst_tail->SetNext(next_to_attach);
       
  1084 					orig_tail->SetNext(NULL);
       
  1085 					if (src_previous != NULL) src_previous->SetNext(src);
       
  1086 
       
  1087 					return_cmd_error(error);
       
  1088 				}
       
  1089 			}
       
  1090 
       
  1091 			/*
       
  1092 			 * Adding a next wagon to the chain so we can test the other wagons.
       
  1093 			 * First 'take' the first wagon from 'next_to_attach' and move it
       
  1094 			 * to the next wagon. Then add that to the tail of the destination
       
  1095 			 * train and update the tail with the new vehicle.
       
  1096 			 */
       
  1097 			Vehicle *to_add = next_to_attach;
       
  1098 			next_to_attach = next_to_attach->Next();
       
  1099 
       
  1100 			to_add->SetNext(NULL);
       
  1101 			dst_tail->SetNext(to_add);
       
  1102 			dst_tail = dst_tail->Next();
       
  1103 		}
       
  1104 
       
  1105 		/*
       
  1106 		 * When we reach this the attaching is allowed. It also means that the
       
  1107 		 * chain of vehicles to attach is empty, so we do not need to merge that.
       
  1108 		 * This means only the splitting needs to be done.
       
  1109 		 * Furthermore the 'previous' link of the original source vehicle needs
       
  1110 		 * to be restored, otherwise the train goes missing in the depot.
       
  1111 		 */
       
  1112 		orig_tail->SetNext(NULL);
       
  1113 		if (src_previous != NULL) src_previous->SetNext(src);
  1040 	}
  1114 	}
  1041 
  1115 
  1042 	/* do it? */
  1116 	/* do it? */
  1043 	if (flags & DC_EXEC) {
  1117 	if (flags & DC_EXEC) {
  1044 		/* If we move the front Engine and if the second vehicle is not an engine
  1118 		/* If we move the front Engine and if the second vehicle is not an engine