/* -*- Objc -*- */ /* * $Id: LgCollision.m,v 1.1 2003/08/20 16:01:47 thunder Exp $ * * Copyright (C) 2003 Free Software Foundation, Inc. * * This file is part of GNU Hégémonie. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "GameLogic/LgCollision.h" #include "GameEngine/HgGame.h" #include "GameEngine/HgPlayer.h" #include "GameEngine/HgWeapon.h" #include "GameEngine/HgShip.h" #include "GameEngine/HgBonus.h" #include "Common/Coord.h" /** * Constants for the type of collision */ #define WEAPON_SHIP 0 #define SHIP_WEAPON 1 #define BONUS_SHIP 2 #define SHIP_BONUS 3 #define TWO_SHIP 4 #define INVALID_CASE 5 /** * Returns the type of collision */ int identCase(id obj1, id obj2) { BOOL firstIsWeapon = [obj1 isKindOf: NSClassFromString(@"HgWeapon")]; BOOL secondIsWeapon = [obj2 isKindOf: NSClassFromString(@"HgWeapon")]; BOOL firstIsShip = [obj1 isKindOf: NSClassFromString(@"HgShip")]; BOOL secondIsShip = [obj2 isKindOf: NSClassFromString(@"HgShip")]; BOOL firstIsBonus = [obj1 isKindOf: NSClassFromString(@"HgBonus")]; BOOL secondIsBonus = [obj2 isKindOf: NSClassFromString(@"HgBonus")]; if (firstIsWeapon & secondIsShip) return WEAPON_SHIP; if (firstIsShip & secondIsWeapon) return SHIP_WEAPON; if (firstIsBonus & secondIsShip) return BONUS_SHIP; if (firstIsShip & secondIsBonus) return SHIP_BONUS; if (firstIsShip & secondIsShip) return TWO_SHIP; return INVALID_CASE; } @implementation LgCollision /** * Initialize */ - (id) initWithGameName: (NSString *)gameName { self = [super init]; if (self != nil) { _game = [[HgGame alloc] initWithName: gameName]; } [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(collisionTreatment:) name:@"LgCollision" object: _game]; return self; } /** * Release */ - (void) dealloc { RELEASE (_game); [super dealloc]; } /** * The notification contains the two objects includes in the collision */ -(void) collisionTreatment: (NSNotification *)notification { id first = [[notification userInfo] objectForKey: @"firObject"]; id second = [[notification userInfo] objectForKey: @"secObject"]; int c = identCase(first, second); unsigned damage; int rest; double speed1, speed2; unsigned oldShieldS, newShieldS, oldShieldF, newShieldF; switch (c) { case WEAPON_SHIP: damage = [HgWeapon damage]; if (damage > [second deckShield]) { rest = damage - [second deckShield]; if (rest > [second health]) { [_game removePlayer: [second player]]; } else { [second setDeckShield: 0]; [second setHealth: [second health] - rest]; [[second player] addPoint: -rest]; } } break; case SHIP_WEAPON: damage = [HgWeapon damage]; if (damage > [first deckShield]) { rest = damage - [first deckShield]; if (rest > [first health]) { [_game removePlayer: [first player]]; } else { [first setDeckShield: 0]; [first setHealth: [first health] - rest]; [[first player] addPoint: -rest]; } } break; case BONUS_SHIP: [second addBonus: first]; [_game removeObject: first]; break; case SHIP_BONUS: [first addBonus: second]; [_game removeObject: second]; break; case TWO_SHIP: speed1 = VectorNorm([first velocity]); speed2 = VectorNorm([second velocity]); if (speed1 > speed2) { oldShieldS = [second deckShield]; newShieldS = oldShieldS - (speed1 * 10); if (newShieldS <= 0) [_game removeObject: second]; else [second setDeckShield: newShieldS]; } else { if (speed2 > speed1) { oldShieldF = [first deckShield]; newShieldF = oldShieldF - (speed2 * 10); if (newShieldF <= 0) [_game removeObject: first]; else [first setDeckShield: newShieldF]; } else { oldShieldF = [first deckShield]; newShieldF = oldShieldF - (speed1 * 5); oldShieldS = [second deckShield]; newShieldS = oldShieldS - (speed1 * 5); if (newShieldF <= 0) [_game removeObject: first]; else [first setDeckShield: newShieldF]; if (newShieldS <= 0) [_game removeObject: second]; else [second setDeckShield: newShieldF]; } } break; default: printf ("Invalid notification\n"); break; } } @end