I am getting a NPE (null-pointer exception) when placing any other item than the ones I have defined, or when drinking from a milk-bucket. I have tried adding isCanceled() == false to my EventHandler, but it breaks my RIGHT_CLICK_AIR action. Sorry, it sounds kind of complicated, any more info can be provided, thanks in advance!
#EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerInteract(PlayerInteractEvent event) {
Player p = event.getPlayer();
Location location = p.getLocation();
ItemStack item = event.getItem();
if(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK && event.hasItem() != false || event.isCancelled() == true) {
I'd think it's because of this line:
ItemStack item = event.getItem();
When the player is not holding an item, it returns null. Try a null check to see if there is an item in their hand.
if (event.getItem() != null)){
//do stuff
}
else{
//don't do it
}
Related
I am building a paint-like program in processing. I want to be able to adjust the r, g, and b values of the pen color. What I did is use the 'r' key to allow the user to change r. After hitting 'r' they use the '+' and '-' keys to adjust it. Then you hit 'd', and it finishes. '+' and '-' are already used for pen size so I had to do it this way. But when I run the code and hit r it freezes up and stops responding. Does anyone know what is wrong.
Here is the problematic part of the code:
if(key == 'r'){ // Activates if 'r' is pressed
actr = true; // Sets actr = to true
while (actr = true) { // Goes until actr is false
if (key == '=') { // Activates is '=' is pressed
r = r ++; // Increases r by one
}
if (key == '-'){ // Activates if '-' is pressed
r = r --; // Decreases r by one
}
if (key == 'd') { // Activates if 'd' is pressed
actr = false; // Sets actr = to false
}
}
}
Here is the full code: http://www.openprocessing.org/sketch/226658
You've got a few problems. First of all, look at this line:
while (actr = true) { // Goes until actr is false
You're not checking equality here, you're assigning the value of true to your actr variable, which will also evaluate to true. In other words, that will never be false. Instead, you should use:
while (actr == true) {
Or even better:
while (actr) {
However, even when you fix that, your while loop will still never exit. This is because you're busy waiting and blocking the program from continuing. This will prevent Processing from ever changing the key variable.
Instead of busy waiting, just keep track of which mode you're in, which determines what the + and - keys do. You could use a series of booleans:
boolean size = true;
boolean red = false;
boolean green = false;
boolean blue = false;
void keyPressed(){
if(key == 'r'){ // Activates if 'r' is pressed
if (key == '=') {
if(size){
x++;
}
else if(red){
r++;
}
}
else if (key == '-'){
if(size){
x++;
}
else if(red){
r++;
}
}
if (key == 'd') { // Activates if 'd' is pressed
size = true;
red = false;
blue = false;
green = false;
}
else if(key == 'r'){
size = false;
red = true;
blue = false;
green = false;
}
}
}
That's just one approach, and I didn't include all of the code, but that should be a better general idea than your busy waiting.
I am trying to implement a removeLast function for a linked list in objective-c. My add function property works well because I can see the node I created, but when I try to remove a node it does not work. I have tried looking up general solutions for this, but have not come up with anything. Is there something special with objective-c that I should take a look at?
-(void) removeLast{
Node *newNode = [[Node alloc]init];
Node *tail = [[Node alloc]init];
if (self.head == NULL){
NSLog(#"No items to remove");
}
else{
newNode = self.head;
tail= self.head;
while (tail != NULL) {
tail = tail.next;
if (tail != NULL){
newNode = tail;
}
}
newNode.next = NULL;
}
}
I believe you've overcomplicated the algorithm. You don't need to keep a reference to the previous link if you always look one step ahead:
- (void) removeLast {
if (self.head == NULL) {
NSLog(#"Empty list");
} else if (self.head.next == NULL) {
self.head = NULL;
} else {
Node* current = self.head;
while (current.next.next != NULL)
current = current.next;
current.next = NULL;
}
}
This iterates through until it reaches the next-to-last node when current.next.next will be null. Then it makes that the last node.
Using NetTopologySuite, these expressions are false:
Point.Empty.Equals(Point.Empty); // false
Polygon.Empty.Equals(Polygon.Empty); // false
Debugging shows that this behavior is implemented by
// Geometry
public IntersectionMatrix Relate(IGeometry g)
{
return RelateOp.Relate(this, g); // Point.Empty, Point.Empty
}
// IntersectionMatrix
public bool IsEquals(Dimension dimensionOfGeometryA, Dimension dimensionOfGeometryB)
{
if (dimensionOfGeometryA != dimensionOfGeometryB)
return false;
return IsTrue(_matrix[(int)Location.Interior, (int)Location.Interior]) &&
_matrix[(int)Location.Interior, (int)Location.Exterior] == Dimension.False &&
_matrix[(int)Location.Boundary, (int)Location.Exterior] == Dimension.False &&
_matrix[(int)Location.Exterior, (int)Location.Interior] == Dimension.False &&
_matrix[(int)Location.Exterior, (int)Location.Boundary] == Dimension.False;
}
I wonder what the reason behind this is. Presumably this behavior occurs in related libraries (jts, GEOS) as well and I also assume there is a justification known by geo-algebra insiders. Can someone explain?
I'm trying to write a chess game and find that I cannot find solutions to find a stalemate situation. I'm trying to google, but can't find anything. Is there a well-known algorithm or something?
Your move generator will be one of two different designs;
either it checks for legality while generating the moves
or you generate all possible moves and remove those that are illegal afterwards.
The former is better as it doesn't need post-processing.
A stalemate condition is simply one where there are no legal moves and the moving-side's king is not in check. A checkmate condition is one where there are no legal moves but the moving-side's king is in check.
In other words if you've figured out how to detect check and checkmate, you've already got everything necessary to detect stalemate.
Here is an Open-source code with all the rules for the classic Chess game:
https://github.com/cjortegon/basic-chess
You can run the project right after cloning the project (Android, iOS, Desktop and Web), or you can use the main logic, which is here: https://github.com/cjortegon/basic-chess/tree/master/libgdx/core/src/com/mountainreacher/chess/model
I based my solution on a 3-moments algorithm, first moment is when the player selects a piece from the board, then when the destination of this piece has been chosen and finally when the piece reaches that position (considering that it is an animated game, if not, you can merge step 2 and 3).
The following code has been implemented in Java. From the properties of the model class:
boolean turn;
GenericPiece selected, conquest;
ClassicBoard board;
List<int[]> possibleMovements;
int checkType;
The first method will handle moments 1, 2 and the special 'conquest' moment (applied to pawn piece only):
public boolean onCellClick(int row, int column) {
if (row == -1 && conquest != null) {
checkType = 0;
conquest.changeFigure(column);
return true;
} else if (selected != null) {
if (possibleMovements != null) {
for (int[] move : possibleMovements) {
if (move[0] == row && move[1] == column) {
// Move the PieceActor to the desired position
if (selected.moveTo(row, column)) {
turn = !turn;
}
break;
}
}
}
selected = null;
possibleMovements = null;
return true;
} else {
selected = board.getSelected(turn ? Piece.WHITE_TEAM : Piece.BLACK_TEAM, row, column);
if (selected != null) {
possibleMovements = new ArrayList<>();
possibleMovements.addAll(((GenericPiece) selected).getMoves(board, false));
// Checking the movements
board.checkPossibleMovements(selected, possibleMovements);
if (possibleMovements.size() == 0) {
possibleMovements = null;
selected = null;
return false;
} else {
return true;
}
}
}
return false;
}
And the following method will handle the 3rd moment (when animation finishes):
public void movedPiece(Piece piece) {
Gdx.app.log(TAG, "movedPiece(" + piece.getType() + ")");
// Killing the enemy
Piece killed = board.getSelectedNotInTeam(piece.getTeam(),
piece.getRow(), piece.getColumn());
if (killed != null) {
killed.setAvailable(false);
}
// Checking hacks
GenericPiece[] threat = board.kingIsInDanger();
if (threat != null) {
checkType = board.hasAvailableMoves(threat[0].getTeam()) ? CHECK : CHECK_MATE;
} else {
checkType = NO_CHECK;
}
// Checking castling
if (piece.getFigure() == Piece.ROOK && ((GenericPiece) piece).getMovesCount() == 1) {
Piece king = board.getSelected(piece.getTeam(),
piece.getRow(), piece.getColumn() + 1);
if (king != null && king.getFigure() == Piece.KING && ((GenericPiece) king).getMovesCount() == 0) {
// Left Rook
if (board.getSelected(piece.getRow(), piece.getColumn() - 1) == null) {
king.moveTo(piece.getRow(), piece.getColumn() - 1);
}
} else {
king = board.getSelected(piece.getTeam(),
piece.getRow(), piece.getColumn() - 1);
if (king != null && king.getFigure() == Piece.KING && ((GenericPiece) king).getMovesCount() == 0) {
// Right Rook
if (board.getSelected(piece.getRow(), piece.getColumn() + 1) == null) {
king.moveTo(piece.getRow(), piece.getColumn() + 1);
}
}
}
}
// Conquest
else if (piece.getFigure() == Piece.PAWN && (piece.getRow() == 0 || piece.getRow() == board.getRows() - 1)) {
conquest = (GenericPiece) piece;
checkType = CONQUEST;
}
}
That code covers all the rules from the classic chess, including: regular piece movements, castling, check, check-mate and conquests of pawns.
Greetings.
I try to make kid control application. The keyboard logger is a part of this application.
I use CGEventTapCreate to watch the keyboard. This works good, but sometimes I get duplicating key down events. They do not have [NSEvent isARepeat] set, just duplicates. For example I can type "qwerty" but application gets key down events for these characters: "qqwweerrttyy". Maybe somebody experienced smth like it? I get this problem on 10.5&10.6 (both are Intel).
I post here keyboard logger install & handler methods:
- (BOOL)installKeyboardLogger
{
CGEventMask keyboardMask = CGEventMaskBit(kCGEventKeyDown);
CGEventMask mouseMask = CGEventMaskBit(kCGEventMouseMoved) | CGEventMaskBit(kCGEventLeftMouseDown) |
CGEventMaskBit(kCGEventRightMouseDown);
CGEventMask mask = keyboardMask + mouseMask;// + mouseMask;//CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventMouseMoved);
// Try to create keyboard-only hook. It will fail if Assistive Devices are not set.
mMachPortRef = CGEventTapCreate(
kCGAnnotatedSessionEventTap,
kCGTailAppendEventTap, // kCGHeadInsertEventTap
kCGEventTapOptionListenOnly,
keyboardMask,
(CGEventTapCallBack)eventTapFunction,
self );
if (!mMachPortRef)
[mLogFile logNeedAssistiveDevice: #"Can't install keyboard hook."];
else
CFRelease(mMachPortRef);
mMachPortRef = CGEventTapCreate(
kCGAnnotatedSessionEventTap,
kCGTailAppendEventTap, // kCGHeadInsertEventTap
kCGEventTapOptionListenOnly,
mask,
(CGEventTapCallBack)eventTapFunction,
self );
if (!mMachPortRef)
{
[mLogFile logNeedAssistiveDevice: #"Can't install keyboard&mouse hook."];
return NO;
}
mKeyboardEventSrc = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, mMachPortRef, 0);
if ( !mKeyboardEventSrc )
return NO;
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
if ( !runLoop )
return NO;
CFRunLoopAddSource(runLoop, mKeyboardEventSrc, kCFRunLoopDefaultMode);
return YES;
}
CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
{
if (type != NX_KEYDOWN && type != NX_OMOUSEDOWN && type != NX_OMOUSEUP && type != NX_OMOUSEDRAGGED &&
type != NX_LMOUSEUP && type != NX_LMOUSEDOWN && type != NX_RMOUSEUP && type != NX_RMOUSEDOWN &&
type != NX_MOUSEMOVED && type != NX_LMOUSEDRAGGED && type != NX_RMOUSEDRAGGED)
return event;
NSEvent* sysEvent = [NSEvent eventWithCGEvent:event];
if (type == NX_KEYDOWN && [sysEvent type] == NSKeyDown)
{
if (![sysEvent isARepeat])
[(ControlPanelController*)refcon handleCapturedCharacters: [sysEvent characters]];
}
else
[(ControlPanelController*)refcon handleMouse];
return event;
}